[英]Passing and returning numpy arrays to C++ methods via Cython
在这个网站上有很多关于在cython中使用numpy的问题,一个特别有用的问题是使用cython 简单包装C代码 。
但是,cython / numpy接口api 似乎有所改变 ,特别是在确保内存连续数组的传递方面。
在cython中编写包装函数的最佳方法是:
double* data_in, double* data_out
调用C ++类方法 double*
的numpy数组? 我的尝试如下:
cimport numpy as np
import numpy as np # as suggested by jorgeca
cdef extern from "myclass.h":
cdef cppclass MyClass:
MyClass() except +
void run(double* X, int N, int D, double* Y)
def run(np.ndarray[np.double_t, ndim=2] X):
cdef int N, D
N = X.shape[0]
D = X.shape[1]
cdef np.ndarray[np.double_t, ndim=1, mode="c"] X_c
X_c = np.ascontiguousarray(X, dtype=np.double)
cdef np.ndarray[np.double_t, ndim=1, mode="c"] Y_c
Y_c = np.ascontiguousarray(np.zeros((N*D,)), dtype=np.double)
cdef MyClass myclass
myclass = MyClass()
myclass.run(<double*> X_c.data, N, D, <double*> Y_c.data)
return Y_c.reshape(N, 2)
此代码编译但不一定是最佳的。 您对改进上面的代码段有什么建议吗?
(2)在运行时调用它时抛出并且“np未在 X_c = ...
行上定义”。确切的测试代码和错误消息如下:
import numpy as np import mywrapper mywrapper.run(np.array([[1,2],[3,4]], dtype=np.double)) # NameError: name 'np' is not defined [at mywrapper.pyx":X_c = ...] # fixed!
你基本上做对了。 首先,希望优化不应该是一个大问题。 理想情况下,大部分时间都花在C ++内核中,而不是在cythnon包装器代码中。
您可以进行一些风格上的更改,以简化您的代码。 (1)不需要在1D和2D阵列之间进行重塑。 当你知道你的数据的内存布局(C顺序与fortran顺序,跨越等)时,你可以看到数组只是你要用C ++索引自己的一块内存,所以numpy的ndim不会在C ++方面很重要 - 它只是看到了指针。 (2)使用cython的address-of运算符&
,您可以使用&X[0,0]
以更清晰的方式获取指向数组开头的指针 - 无需显式&X[0,0]
。
这是我原始代码段的编辑版本:
cimport numpy as np
import numpy as np
cdef extern from "myclass.h":
cdef cppclass MyClass:
MyClass() except +
void run(double* X, int N, int D, double* Y)
def run(np.ndarray[np.double_t, ndim=2] X):
X = np.ascontiguousarray(X)
cdef np.ndarray[np.double_t, ndim=2, mode="c"] Y = np.zeros_like(X)
cdef MyClass myclass
myclass = MyClass()
myclass.run(&X[0,0], X.shape[0], X.shape[1], &Y[0,0])
return Y
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.