通过Cython将NUMPY数组传递给C++方法

2024-04-25 20:17:54 发布

您现在位置:Python中文网/ 问答频道 /正文

关于在cython中使用numpy有很多问题,一个特别有用的问题是Simple wrapping of C code with cython

然而,cython/numpy接口api seems to have changed a bit,特别是确保内存连续数组的传递。

用cython编写包装函数的最佳方法是:

  • 采用可能但不一定连续的numpy数组
  • 调用具有签名{^ }的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!


Tags: 方法runimportnumpyasnpmyclass数组
1条回答
网友
1楼 · 发布于 2024-04-25 20:17:54

你基本上是对的。首先,希望优化不是什么大事。理想情况下,大部分时间都在C++内核中使用,而不是在CythNo包装代码中使用。

有一些风格上的改变,你可以做,这将简化你的代码。(1) 不需要在一维和二维阵列之间重新整形。当你知道数据的内存布局(C++命令与FORTRAN命令、跨步等)时,你可以看到数组只是一块内存,你将用C++来索引自己,所以NUMPY的NDIM在C++方面没有什么关系,只是看到了指针。(2) 使用cython的运算符&的地址,您可以使用&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

相关问题 更多 >