下面的代碼沒有問題,編譯在用Cython:用Cython C代碼編譯失敗,類型化memoryviews
: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
然而,當我嘗試編譯生成的C代碼,gcc編譯器有錯誤停止
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);
我在做什麼錯誤在哪裏?請注意,使用標準內存類型時,相同的代碼沒有任何問題(例如,f
函數中的double[:] xs
參數)。
此外,有沒有辦法釋放f
函數中的gil與Double[:]
?如果我嘗試,我得到一個錯誤信息
test.pyx:13:10: Cannot access buffer with object dtype without gil
望着生成的代碼,我看到了幾個電話給__Pyx_INCREF
和__Pyx_DECREF
,然而這似乎並不需要我。
編輯
經過一些討論,我現在可以找到變通方法,並能夠編譯C代碼:例如,在函數定義使用object[:] xs
,然後在投(<Double>(xs[i])).incr()
for循環。但是,這些解決方法引入了更多的python交互,這實際上是我想避免的。
更籠統地說,問題是:有沒有辦法在cython中處理cdef class
(類型化緩衝區或類似的)的同類列表,這樣就沒有python開銷並且GIL可以被釋放?
謝謝。您鏈接的問題確實非常相似,我忽略了它:但是,沒有提供任何答案,並且只提供了一種解決方法。但是,解決方法引入了python開銷。另外,我仍然不明白爲什麼cython會將__Pyx_INCREF放入代碼中,因此不能以快速並行的方式使用這些構造。因此這個問題還沒有得到答案。 –
忘了提及:谷歌的建議沒有奏效,只有幾頁討論類似的問題,但沒有解決方案適用於我的情況:特別是,你提到的頁面討論了一個完全不同的問題, - 在不同文件中定義的兒童類。 –