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?
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