Можно ли использовать тип расширения Cython в разделе nogil? - PullRequest
0 голосов
/ 27 мая 2020

Я создал тип расширения Cython и хотел бы использовать его в контексте nogil. Но компилятор всегда выдает ошибку. Вот простой пример того, что я пытаюсь сделать:

  1 # cython: language_level=3
  2 
  3 from cython.parallel import prange
  4 
  5 cdef class C1:
  6 
  7     cdef public:
  8         int val
  9 
 10     def __cinit__(self, value):
 11         self.val = value
 12 
 13 def iterate_C1():
 14 
 15     cdef int i
 16     cdef int N = 4
 17     cdef C1 c1_i
 18 
 19     # This compiles fine
 20     c1 = C1(4)
 21     print(f'c1.val={c1.val}')
 22 
 23     # But this doesn't
 24     with nogil:
 25         for i in prange(N):
 26             c1_i = C1(i)

У меня есть несколько исключений, но все они выглядят так:

Compiling c_one.pyx because it changed.
[1/1] Cythonizing c_one.pyx

Error compiling Cython file:
------------------------------------------------------------
...
    print(f'c1.val={c1.val}')

    # But this doesn't
    with nogil:
        for i in prange(N):
            c1_i = C1(i)
           ^
------------------------------------------------------------

c_one.pyx:26:12: Assignment of Python object not allowed without gil

Error compiling Cython file:
------------------------------------------------------------
...
    print(f'c1.val={c1.val}')

    # But this doesn't
    with nogil:
        for i in prange(N):
            c1_i = C1(i)
                    ^
------------------------------------------------------------

c_one.pyx:26:21: Calling gil-requiring function not allowed without gil

Так разве это невозможно? использовать типы расширений Cython в контексте nogil?

1 Ответ

1 голос
/ 27 мая 2020

Вы определенно не можете создавать экземпляры типов расширений cdef внутри блока nogil. В конечном итоге они являются объектами Python и требуют подсчета ссылок (в том числе в некоторых неочевидных местах, таких как объект типа), выделения Python -управляемой памяти и освобождения предыдущего содержимого ci, включая вызов его деструктор.

Вы должны иметь доступ к их cdef members (например, val для этого класса) и вызывать их cdef функции, отмеченные как nogil.

...