Search code examples
cythonmemoryview

Cython: How to pass a numpy memoryview to a nogil cdef function


I would like to send a numpy array (memoryview) to another Cython function.

cdef int function(int[:,:] ref) nogil:
    pass

cpdef test():
    cdef np.ndarray[int, ndim=2] ref = np.full((10,10),0)
    with nogil:
        function(ref)

This compiles okay, but gives me Windows fatal exception: access violation when I execute. This all works okay, if I remove nogil, but I would prefer not to do this if possible.

Thanks


Solution

  • My opinion is that it shouldn't compile, and that you should report the compiling and the exception as a bug to github.com/cython/cython/issues.

    Python Object -> memoryview does require the GIL (although memoryview -> memoryview doesn't). Therefore you need to initialize a memoryview outside the nogil block:

    cpdef test():
        cdef np.ndarray[int, ndim=2] ref = np.full((10,10),0)
        cdef int[:,:] ref_view = ref
        with nogil:
            function(ref_view)
    

    or move the nogil block into function (if that makes sense in your real code).

    There probably isn't a huge advantage to setting the type np.ndarray[int, ndim=2] - the only thing that gives you is faster element indexing (which is also what memoryviews give you).