2

現在、次のループを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

これまでのところ、すべて問題ないように見えますが、cells[i].* へのアクセスにはまだ Python 呼び出しが必要です。これにより、i ループの並列化が妨げられます。

これは cython フィードバックです (cython -a で生成されます):

cython - フィードバック

したがって、質問: これらの python コールバックを削除するにはどうすればよいですか (つまり、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エラーが表示されます:dtypeは「オブジェクト」、数値型、または構造体でなければなりません(宣言内のcell_tについて不平を言っています)

どうもありがとう。

4

2 に答える 2

2

Cythoncellsに引数の型を伝えていないため、 Pythonルックアップ メソッドを使用します。定義を次のように変更してみてください。

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

これにより、Cythonndarrayが型を取得していることがわかるため、 Cアクセスを使用できます。

于 2013-01-06T22:45:25.660 に答える
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.]
于 2013-01-07T04:23:26.473 に答える