[Numpy-discussion] PyArray_SETITEM macro ends in semicolon

Dag Sverre Seljebotn dagss at student.matnat.uio.no
Thu Sep 25 07:10:10 EDT 2008


jason-sage at 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