您似乎无法将 float** 传递给 numpy C API,因为它们不是先验兼容的内存表示。
在 numpy 中,数组中的数据必须位于一个连续的内存区域中(可能有空洞,但它们必须位于一个块中,例如 malloc 分配的):
data -> | - | - | - | ..... | - | # this is allocated in one block
a0 a1 a2 an
使用浮点数**时,您的内存模型很可能是:
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] | ....
这实际上几乎总是一种不好的数值计算格式,因为你不能在一个块中传递数据(对内存局部性不好,等等......),几乎每个值得盐分的数值库都使用这种格式。参见例如this 解释一下。
尽管如此,假设你不能修改你的代码,你可以很容易地将单块格式转换为 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 中分配函数,这只是为了让您了解在两种格式之间进行转换。