[Numpy-discussion] PyArray_SETITEM macro ends in semicolon
Dag Sverre Seljebotn
dagss@student.matnat.uio...
Thu Sep 25 06:10:10 CDT 2008
jason-sage@creativetrax.com wrote:
> I'm working on getting the Sage matrices for real/complex doubles to use
> numpy as a backend. In this, I'm using the PyArray_SETITEM macro from
> within Cython. However, Cython wraps the macro in a function call to
> convert the output to a Python value:
>
> __pyx_1 = PyInt_FromLong(PyArray_SETITEM(__pyx_v_self->_matrix_numpy,
> PyArray_GETPTR2(__pyx_v_self->_matrix_numpy, __pyx_v_i, __pyx_v_j),
> __pyx_v_value));
>
> However, after preprocessing, because of the semicolon at the end of the
> SETITEM macro, we get:
>
>
> PyInt_FromLong(((PyArrayObject
> *)(__pyx_v_self->_matrix_numpy))->descr->f->setitem((PyObject
> *)(__pyx_v_value), (char *)(((void *)((((PyArrayObject
> *)(__pyx_v_self->_matrix_numpy))->data) + (__pyx_v_i)*(((PyArrayObject
> *)(__pyx_v_self->_matrix_numpy))->strides)[0] +
> (__pyx_v_j)*(((PyArrayObject
> *)(__pyx_v_self->_matrix_numpy))->strides)[1]))), (PyArrayObject
> *)(__pyx_v_self->_matrix_numpy)););
>
> Note that at the end, we have a "););". The file refuses to compile.
> Presumably, since SETITEM returns a value, wrapping the return value in
> a function call seems to be a reasonable thing to do. Would there be a
> problem in eliminating the semicolon and instead wrapping the entire
> function body in parenthesis?
>
> I noticed that GETITEM also ended in a semicolon, though I didn't have
> the same problem as above since Cython didn't automatically wrap it in a
> function call (I'm not even sure if it returns something).
>
> On a side note, is the above the best way (i.e., fastest way given an
> arbitrary numpy array) to set/get
> an element?
>
If I get to where I want to be with Cython/NumPy integration, there
definitely shouldn't be a need to call PyArray_SETITEM from Cython.
As you already use Cython, and if you know that your array is
real/complex doubles (as indicated by your post), and also know that you
have two dimensions (as indicated by your code), then there are
definitely faster methods. Have you looked at the Cython numpy array
support, as explained in
http://wiki.cython.org/tutorials/numpy
? (This was mentored by Robert Bradshaw of Sage too). Your usecase looks
like a place where it can be used. I am actively developing this, so if
you wish you can send me proposals for changes to the Cython NumPy
support which fixes whatever issues you have with it. (Support for
access to complex numbers is an obvious one and that is worked on now.)
(As an aside, the int returned from PyArray_SETITEM is likely an error
return value (though I'm not 100% sure). Converting it to a Python long
is really inefficient, type the variable that is assigned to as an int.
But that really belongs on the Cython list.)
Dag Sverre
More information about the Numpy-discussion
mailing list