2016-06-16 76 views
0

下面的代碼沒有問題,編譯在用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可以被釋放?

回答

1

請檢查這個話題,你的情況可能是類似的: Cython: have sequence of Extension Types as attribute of another Extension Type with access to cdef methods

另外,請嘗試谷歌搜索__pyx_vtab - 搜索結果顯示了誰了,我查了第一個簡要類似的問題,看起來是民族問題一些解決方案也存在: https://groups.google.com/forum/#!topic/cython-users/3tUDIc11Xak

+0

謝謝。您鏈接的問題確實非常相似,我忽略了它:但是,沒有提供任何答案,並且只提供了一種解決方法。但是,解決方法引入了python開銷。另外,我仍然不明白爲什麼cython會將__Pyx_INCREF放入代碼中,因此不能以快速並行的方式使用這些構造。因此這個問題還沒有得到答案。 –

+0

忘了提及:谷歌的建議沒有奏效,只有幾頁討論類似的問題,但沒有解決方案適用於我的情況:特別是,你提到的頁面討論了一個完全不同的問題, - 在不同文件中定義的兒童類。 –