cython C code compilation fails with typed memoryv

2019-07-10 06:10发布

问题:

The following code compiles without issues in cython:

cdef class Double:
    cdef double v
    def __init__(self, double v):
        self.v = v
    cdef double incr(self) nogil:
        self.v += 1
        return self.v

cdef int f(Double[:] xs):
    cdef int i, N
    N = xs.shape[0]
    for i in range(N):
        xs[i].incr()
    return 0

However, when I try to compile the generated C code, the gcc compiler stops with an error:

test.c: In function '__pyx_f_4test_f':
test.c:1491:55: error: 'PyObject {aka struct _object}' has no member named '__pyx_vtab'
     ((struct __pyx_vtabstruct_4test_Double *)__pyx_t_3->__pyx_vtab)->incr(__pyx_t_3);

Where is the error I am making? Note that the same code does not have any problem when I use standard memorytypes (for example, with a double[:] xs parameter in the f function).

Additionally, is there a way to release the gil inside the f function with Double[:]? If I try that, I get an error message

test.pyx:13:10: Cannot access buffer with object dtype without gil

Looking at the generated code, I see a couple of calls to __Pyx_INCREF and __Pyx_DECREF, which however seems not needed to me.

EDIT

Following some discussion, I can now find workarounds and be able to compile the C code: for example use object[:] xs in the function definition, and then cast (<Double>(xs[i])).incr() in the for loop. However, these workaround introduce even more python interaction, which is really what I would like to avoid.

In more general terms, the question is: is there a way in cython to deal with a homogeneous list of cdef class (a typed buffer or similar) so that there is no python overhead and the GIL can be released?

回答1:

Please check this topic, your case is probably similar to it: Cython: have sequence of Extension Types as attribute of another Extension Type with access to cdef methods

Please also try Googling for __pyx_vtab - search results shows questions from peoples who has similar problem, I checked first one briefly and looks that some solution is there too: https://groups.google.com/forum/#!topic/cython-users/3tUDIc11Xak