[英]how to pass numpy array to Cython function correctly?
这在许多地方都有描述,但我根本无法让它发挥作用。 我从Cython调用C ++函数:
cimport numpy as np
cdef extern from "test.h" namespace "mytest":
void test(double *A, int m)
cdef int foo():
cdef np.ndarray[double,mode="c"] a = np.array([1,2,3,4,5],dtype=float)
# pass ptr to first element of 'a'
test(&a[0], len(a))
return 0
foo()
test.cpp只是:
#include <stdio.h>
namespace mytest {
void test(double *A, int m)
{
for (int i = 0; i < m; i++)
{
printf("%d is %f\n", i, A[i]);
}
}
}
test.h只有:
namespace mytest {
void test(double *A, int m);
}
这似乎有效,但什么时候需要np.ascontiguousarray
? 这样做是否足够:
cdef np.ndarray[double,mode="c"] a = np.array([1,2,3,4,5],dtype=float)
或者你需要:
cdef np.ndarray[double,mode="c"] a = np.ascontiguousarray(np.array([1,2,3,4,5],dtype=float))
第二,更重要的是,这如何推广到二维阵列?
处理2d数组
这是我尝试将2d numpy数组传递给C ++,但这不起作用:
cdef np.ndarray[double,mode="c",ndim=2] a = np.array([[1,2],[3,4]],dtype=float)
被称为:
test(&a[0,0], a.shape[0], a.shape[1])
在cpp代码中:
void test(double *A, int m, int n)
{
printf("reference 0,0 element\n");
printf("%f\n", A[0][0]);
}
更新:正确的答案
正确的答案是对数组使用线性索引而不是[][]
语法。 打印2d数组的正确方法是:
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
printf("%d, %d is %f\n", i, j, A[i*m + j]);
}
}
对于2D数组,您只需要ndim
关键字:
cdef np.ndarray[double, mode="c", ndim=2]
结果可能会也可能不会与原始内容共享内存。 如果它与原始内存共享内存,则阵列可能不是连续的,或者可能具有不寻常的跨步配置。 在这种情况下,直接将缓冲区传递给C / C ++将是灾难性的。
除非您的C / C ++代码准备处理非连续数据,否则您应该始终使用ascontiguousarray
(在这种情况下,您需要将所有相关的步幅数据从Cython传递到C函数中)。 如果输入数组已连续,则不会进行任何复制。 确保兼容通过dtype
到ascontiguousarray
,这样你就不会冒险的第二个副本(例如,具有从连续转换float
阵列上的连续double
阵列)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.