我正在探索使用 SWIG 包装 C++ 类并从 numpy 传递数据
我可以使用以下类型映射成功传入一维数组
(float*, IN_ARRAY1, int DIM1)
数组的大小在编译时是未知的,所以我不能使用类型映射
(float, IN_ARRAY2[DIM1][DIM2])
numpy.i 帮助建议使用
(float*, IN_ARRAY2, int DIM1, int DIM2)
但是我的 C++ 类需要一个指向 float 指针的指针
void Initialise(float** buffer, long dim1, long dim2)
要使用 float* IN_ARRAY2 类型 map ,我需要交错我的两个维度吗? urg 我希望不会,有没有人成功地做到这一点,你是怎么做的。
最佳答案
你似乎不能将 float** 传递给 numpy C API,因为它们不是先验兼容的内存表示。
在 numpy 中,数组中的数据必须在一个单独的连续内存区域中(可以有空洞,但它们必须位于由例如 malloc 分配的一个 block 中):
data -> | - | - | - | ..... | - | # this is allocated in one block
a0 a1 a2 an
当使用 float **时,您的内存模型可能是:
float** a;
int n = 10, m = 20; // n,m matrix
a = malloc(sizeof(*a) * n) // ten rows
for (int i=0; i < n; ++i) {
a[i] = malloc(sizeof(*a[i]) * m); // one row of 29 items
}
也就是说,内存方面:
a -> | a[0] | -> | a[0][0] | a[0][1] | a[0][2] |
| a[1] | -> | a[1][0] | ....
对于数值计算来说,这实际上几乎总是一种糟糕的格式,因为你不能在一个 block 中传递数据(对内存局部性不利,等等),几乎每个值得它盐分的数值库都使用这种格式。参见例如this寻求解释。
尽管如此,假设您无法修改代码,您可以轻松地将单 block 格式转换为 float** 格式而无需复制(相反的情况是不可能的):
void convert(float *in, int n, int m, float ***out)
{
float **data;
int i;
data = malloc(sizeof(*data) * n);
for(i = 0; i < n; ++i) {
data[i] = in + i * m:
}
*out = data;
}
你这样调用这个函数
float **a;
convert((float*)numpy_data, n, m, &a);
Initialise(a, n, m);
实际上最好不要在 API POV 的函数中进行分配,这只是为了让您了解如何在两种格式之间进行转换。
关于c++ - 通过 swig 将二维数组从 numpy 传递到 c++ 不能使用 float**,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4660881/