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?