我的问题“精神上”与SimpleNewFromData相似。
我有一个C代码,如下所示:(原始代码实际上测试malloc()
是否返回NULL)
1 #include <Python.h>
2 #include <numpy/arrayobject.h> // (Not sure if right import)
3 #include <stdlib.h>
4 #include <stdio.h>
5
6 double *calculate_dW(npy_intp *dim_w) {
7 int i;
8 double* data = (double*)malloc(sizeof(double) * dim_w[0]);
9
10 /* Inserts some dummy data */
11 for (i = 0; i < dim_w[0]; i++)
12 data[i] = i;
13
14 return data;
15 }
然后是一个将其封装在函数中的Cython代码:
1 import cython
2 import numpy as np
3 cimport numpy as np
4
5 cdef extern double *calculate_dW(np.npy_intp *dim_w)
6
7 def run_calculate_dW(np.ndarray[np.npy_intp, ndim=1, mode="c"] dim_w):
8 print("Will call calculate_dW")
9 cdef double *dW = calculate_dW(&dim_w[0])
10
11 print("Will call PyArray_SimpleNewFromData")
12 ret = np.PyArray_SimpleNewFromData(
13 1,
14 &dim_w[0],
15 np.NPY_FLOAT64,
16 dW)
17 print("Will print")
18 print(ret)
19 print("Will return")
20 return ret
我用它来测试
# runTest.py
1 import numpy as np
2 import multiply
3 a = np.array((10,)) # as expected, using `np.array(10)` won't work
4 print a
5 multiply.run_calculate_dW(a)
并获得以下输出
$ PYTHONPATH=build/lib.linux-x86_64-2.7/ python runTest.py
[10]
Will call calculate_dW
Will call PyArray_SimpleNewFromData
Segmentation fault (core dumped)
(也就是说,调用PyArray_SimpleNewFromData()中的一个PyArray_SimpleNewFromData()(如果我用ret = 1
代替它,分段故障就会消失)。调试时,我尝试了许多事情:
malloc()
分配的内存量(以保证我没有访问任何我不应该访问的东西);np.NPY_FLOAT32
改为np.float32
;我相信我正在精确地跟踪文档,以及另一个问题的答案。我似乎没有收到任何编译器错误或警告。
不过,我确实注意到,互联网上的所有其他代码在调用PyArray_SimpleNewFromData时都使用C(而不是Python)。我试着从C函数返回一个PyObject*
,但是无法编译它。
此外,我也收到了一些“使用不推荐的NumPy API,通过#定义NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION来禁用它”的警告;但是我已经读到我可以安全地忽略它们。(使用MemoryView时的API )
有什么建议吗?(还有,用dW
创建numpy数组的其他方式吗?)
发布于 2017-01-09 17:14:51
我认为问题在于,当PyArray_SimpleNewFromData
需要一个指向整数的指针时,它将传递一个Python作为第二个参数。我有点惊讶这会编出来。
尝试:
ret = np.PyArray_SimpleNewFromData(
4,
&dim_w[0], # pointer to first element
np.NPY_FLOAT64,
dW)
注意,我还将类型更改为NPY_FLOAT64
,因为它应该与double
匹配。
我还会将dim_w
的定义更改为
np.ndarray[np.NPY_INTP, ndim=1, mode="c"] dim_w
以确保数组的类型与numpy所期望的匹配。这还可能需要将calculate_dW
的签名更改为double *calculate_dW(intptr_t *dim_w)
以匹配。
编辑:第二个问题是您需要包含行
np.import_array()
在您的Cython文件中(就在顶层,在导入之后)。这会为numpy做一些设置。原则上,我认为文档建议您在执行cimport numpy
时始终包括它。在实践中,它只是有时重要,而这正是其中之一。
(答案现已测试)
https://stackoverflow.com/questions/41552718
复制相似问题