[Numpy-discussion] How to replace a loop for a ufunc (to test optimizations)

Travis E. Oliphant oliphant at enthought.com
Sat Aug 23 13:58:24 EDT 2008


Yesterday at the SciPy conference I suggested it would be a good idea to 
add a function to replace one of the inner loops in a ufunc so that an 
extension module could test an optimized inner loop more easily. 

It turns out that this is such a good idea that it's actually already in 
the code.   The UFUNC_API call that does this is called:

PyUFunc_ReplaceLoopBySignature

You would use it something like this

static void
_new_add_loopfunc(char **args,  intp *dimensions, intp *steps, void *func)
{
        /* my new faster code */
}

Then in the extension module (either in the init or in a method call) 
something like this:

PyUFuncObject *ufunc;
PyUFuncGenericFunction oldloopfunc, dummy;
int signature[3]   /* This should be the number of arguments to the 
ufunc you are replacing */
PyObject *module, *dict;

module = PyImport_ImportModule("umath");
dict = PyModule_GetDict(module);

ufunc = PyDict_GetItemString(dict, "add")  /* get the ufunc where you 
want to replace one of the loops */
signature[0] = NPY_DOUBLE;
signature[1] = NPY_DOUBLE;
signature[2] = NPY_DOUBLE;

if (PyUFunc_ReplaceLoopBySignature(ufunc, _new_add_loopfunc, signature, 
&old1dloop) < 0) {
    PyErr_SetString(PyExc_RuntimeError, "problem replacing loop");
    /* error return i.e. return NULL or return or return -1*/
}

Then to restore the original function:

if (PyUFunc_ReplaceLoopBySignature(ufunc, old1dloop, signature, &dummy) 
< 0) {
    /* error */
}

Remember to use import_umath() in the module you are using the UFUNC_API 
in.   Now, lot's of folks should be able to test optimizations.

-Travis
 



More information about the NumPy-Discussion mailing list