c++ - 通过 swig 将二维数组从 numpy 传递到 c++ 不能使用 float**

标签 c++ numpy swig

我正在探索使用 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/

相关文章:

numpy 矩阵跟踪行为

python - 何时使用 new.instancemethod 与将方法分配给类

c++ - 为什么 Q_OBJECT 宏会导致问题 (Qt)?

c++ - 如何以这种方式使用 vector ?

C++ 模板特化

python - 将 4 个一对一映射列表转换为字典列表(python)

c++ - 对于以 "."(例如 : ".NET"))开头的目录,文件列表失败

python - 从一组起点和终点绘制线段

java - 将可变大小的数组从 C 返回到 Java

java - 在模板类中包装 C++ 模板构造函数