[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