2013-01-06 262 views
2

我目前正試圖轉換下面的循環,以用Cython:蟒蛇用Cython - 消除蟒蛇電話

cimport numpy as np 
cimport cython 
@cython.boundscheck(False) # turn of bounds-checking for entire function 
def Interpolation(cells, int nmbcellsx): 
    cdef np.ndarray[float, ndim=1] x,y,z 
    cdef int i,j,len 
    for i in range(nmbcellsx): 
     x = cells[i].x 
     y = cells[i].y 
     z = cells[i].z 
     len = x.size 
     for j in range(len): 
     x[j] = x[j] * y[j] * z[j] 

    return 0 

到目前爲止,一切看起來都種好了,但訪問細胞[I] *仍然需要。 python調用。這防止了i-循環的並行化。

下面是一個用Cython反饋(與用Cython -a生成):

cython -a feedback

因此這樣的問題:如何刪除這些蟒回調(即,使得線9-12成爲白色)?

當試圖增加該小區的種類是這樣的:

cimport numpy as np 
cimport cython 

cdef class cell_t: 
    cdef np.ndarray x,y,z 

@cython.boundscheck(False) # turn of bounds-checking for entire function 
def Interpolation(np.ndarray[cell_t,ndim=1] cells, int nmbcellsx): 
    cdef np.ndarray[float, ndim=1] x,y,z 
    cdef int i,j,len 
    for i in range(nmbcellsx): 
     x = cells[i].x 
     y = cells[i].y 
     z = cells[i].z 
     len = x.size 
     for j in range(len): 
     x[j] = x[j] * y[j] * z[j] 

    return 0 

我收到以下用Cython誤差:D型細胞必須是「對象」,數值類型或一個結構(它被抱怨cell_t聲明)

多謝內。

+1

什麼類型是'cells'說法。如果你給Cython提示它,你可能會讓它識別它。 – Wessie

+1

也作爲附註。你似乎沒有從與循環相關的函數中返回任何東西,也沒有循環變異任何非本地的東西。只是單挑。 – Wessie

+0

這只是一個更復雜功能的簡單例子。細胞實際上是一個叫做細胞的對象的一個​​numpy ndarray。我們只是說Cell類只有numpy數組x,y和z。我該如何解決這個問題? – user1829358

回答

2

你沒有告訴用Cythoncells參數的類型,因此它將使用Python的查找方法。嘗試改變的定義如下:

def Interpolation(np.ndarray cells, int nmbcellsx):

這將告訴用Cython它得到ndarray類型,從而可以使用Ç訪問。

+0

不幸的是,這並沒有改變任何東西。我的猜測是我必須告訴cython Cell的確切組成,但我該怎麼做?順便說一句。你可以用「用Cython -a file.py」編譯上面的例子,然後查看生成的file.html(9-12行需要成爲(淡)白色) – user1829358

2

如何使用Typed Memoryview

cimport cython 

cdef class cell_t: 
    cdef public float[:] x, y, z 

    def __init__(self, x, y, z): 
     self.x = x 
     self.y = y 
     self.z = z 


@cython.boundscheck(False) # turn of bounds-checking for entire function 
def Interpolation(cell_t[:] cells, int nmbcellsx): 
    cdef float[:] x,y,z 
    cdef int i,j,length 
    cdef cell_t cell 
    for i in range(nmbcellsx): 
     cell = cells[i] 
     x = cell.x 
     y = cell.y 
     z = cell.z 
     length = len(x) 
     for j in range(length): 
      x[j] = x[j] * y[j] * z[j] 
    return 0 

下面是測試代碼:

import numpy as np 
from cells import cell_t, Interpolation 

x = np.array([1,2,3], np.float32) 
y = np.array([4,5,6], np.float32) 
z = np.array([7,8,9], np.float32) 
c1 = cell_t(x, y, z) 

x = np.array([1,1,1,1,1], np.float32) 
y = np.array([2,2,2,2,2], np.float32) 
z = np.array([3,3,3,3,3], np.float32) 
c2 = cell_t(x, y, z) 

cells = np.array([c1, c2], object) 

Interpolation(cells, 2) 

print c1.x.base 
print c2.x.base 

和輸出:

[ 28. 80. 162.] 
[ 6. 6. 6. 6. 6.] 
+0

謝謝,這是非常接近實際的解決方案,但並行化仍然存在一個小的障礙。用Cython似乎增加一些檢查wheter在x,y和z陣列NOT NULL(見[這裏](http://i48.tinypic.com/jqgyhk.png))。看看[這個頁面](http://wiki.cython。org /增強/ compilerdirectives)我找不到一個選項來關閉此檢查。你知道這是可能的嗎?在旁註中,目標是取消註釋第21行。 – user1829358