numpy arrays inside a cython extesion classes

1,185 views
Skip to first unread message

Vineet Jain

unread,
Mar 10, 2011, 12:44:11 PM3/10/11
to cython...@googlegroups.com
def fastaccess(np.ndarray[numpy.float64_t, ndim=2] numpy2darray)
    return numpy2darray[0, 0]

cdef class test:
    cdef public cnumpy.ndarray numpy2darray

    cde __init__(self):
        self.numpy2darray = zeros((100, 100), (numpy.float64_t, numpy.float64_t))
        
    cdef slowaccess(self):
        return fastaccess(self.numpy2darray)

right now if I want to have fast access numpy2darray, I have to pass it into a function with the function declaration. Is there any way to do this without having to declare function fastaccess and pass numpy2darray as a param

Kurt Smith

unread,
Mar 10, 2011, 1:20:06 PM3/10/11
to cython...@googlegroups.com

import numpy as np
cimport numpy as np

cdef class test:
cdef public np.ndarray np2darray

def __init__(self):
self.np2darray = np.zeros((100, 100), dtype=np.float64)

cdef access(self):
# create a function-local 'fast' buffer
cdef np.ndarray[np.float64_t, ndim=2, mode='c'] np2darray
# acquire the buffer; access to np2darray will do what you have above
np2darray = self.np2darray
return np2darray[0,0]

Vineet Jain

unread,
Mar 10, 2011, 1:23:44 PM3/10/11
to cython...@googlegroups.com, Kurt Smith
Thanks, much better. Hopefully, it is on the road map so that you don't have to create a fast local variable. 

Robert Bradshaw

unread,
Mar 10, 2011, 3:07:19 PM3/10/11
to cython...@googlegroups.com
On Thu, Mar 10, 2011 at 10:23 AM, Vineet Jain <vinj...@gmail.com> wrote:
> Thanks, much better. Hopefully, it is on the road map so that you don't have
> to create a fast local variable.

It is, though it's unclear how to do so. In particular, the stride and
pointer information must be stack-local variables for gcc to nicely
optimize the indexing code.

Sturla Molden

unread,
Mar 11, 2011, 9:08:53 AM3/11/11
to cython...@googlegroups.com
It is unboxed in the local scope for fast access.

You always end up with this:

import numpy as np
cimport numpy as np
cimport cython

cdef class Test:

    cdef object array

    @cython.boundscheck(False)
    @cython.wraparound(False)
    def method(Test self):
        # declare a local copy
        np.ndarray[double, ndim=1, mode="c"] array
        # unbox shape and strides
        array = self.array


If you want to avoid this, the only option is avoid NumPy arrays and use some C construct or C++ object instead, or just forget about Cython and use Fortran 95.

Passing subarrays is still slow. For that you will find that Fortran is the only language that really works.


Sturla







Robert Bradshaw

unread,
Mar 11, 2011, 2:16:47 PM3/11/11
to cython...@googlegroups.com

Or assembly :P. (Just kidding, Fortran may be a viable choice here,
but I have my own obvious bias.) Eventually, I do want to be able to
at least make this transparent to the user (perhaps even the stride
information could be cached on the object itself, and NumPy arrays
could be augmented with a "dirty" bit for flagging when they are
reallocate or reshaped).

> Passing subarrays is still slow.

Well, at least it's still O(1) with NumPy.

> For that you will find that Fortran is the
> only language that really works.

That's because the only way to allocate memory in Fortran was to
allocate a huge array at the start then manually partition it out... I
also see Cython eventually supporting this, passing around raw buffer
structs in many cases.

- Robert

Reply all
Reply to author
Forward
0 new messages