I want to design a cdef class whose methods can be run in parallel and therefore I need to set them as nogil
. I see I can do this for cdef
methods, but for some reason I cannot understand I am not allowed to do the same with cpdef
methods. This in particular fails
cdef class Test:
cdef int i
def __init__(self):
self.i = 0
cpdef int incr(self) nogil:
self.i += 1;
return self.i
while the same with cdef int incr
would work. This is somewhat surprising, because in normal cpdef
functions the nogil
attribute is allowed:
cpdef int testfunc(int x) nogil:
return x + 1
Am I missing something or doing something wrong here?
If you look at the C code generated (omitting nogil
) you'll see that the first thing the method does is check to see whether the it has been overridden by a Python subclass. This requires the GIL.
(Note that this can't happen for a cdef
function since it is never known about by Python, so there is no issue there.)
Fortunately, it is easy to make it so that your Cython class cannot be subclassed and the problem goes away (it compiles fine with nogil
):
cimport cython
@cython.final
cdef class Test:
# the rest of your code is exactly the same so isn't reproduced...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With