嵌入一个 python/cython numpy 数组:将 numpy 数组传递给 c 指针
Embedding a python/cython numpy array: Passing numpy array to c pointer
我正在尝试将 cython-numpy 数组传递给 c 结构。这有时会起作用,但如果数组变得太 'large' 就会崩溃。虽然这并不是很大(比如 <100k 双类型条目),但我不知道这个限制是从哪里来的。一些代码片段(附上完整代码)。
基于 Win7、Cython 0.28.4、Python3.6、mingw64
我用不同长度的数组试过了。我最近发现,如果数组长度大于 2**16-512 个条目,它总是会崩溃。但我不知道为什么。
cython 文件:
//cy_file.pyx
//...
cdef public struct Container:
double* np_array
// ...
cdef public void create_np_array(Container *container):
cdef numpy.ndarray[numpy.float_t, ndim=1, mode = 'c'] np_array
# just create a numpy array
longarray = np.linspace(1.0, 5.0, 100000)
np_array = numpy.ascontiguousarray(numpy.array(longarray), dtype=float)
container.np_array = <double*> np_array.data
对于 c 文件:
//c_file.c
#include "Python.h"
#include "cy_file.h"
struct Container container;
//...
Py_Initialize();
PyInit_cy_file();
// and call the cython function that fills up the numpy array
create_np_array(&container, start, stop, n_elements, n);
// shutdown of python interpreter
Py_Finalize();
// *** here comes the crash if the array longarray is 'too long' ***
container.np_array[0]
谁能告诉我这里出了什么问题或如何调试?
感谢和欢呼,
蒂姆
内存归 Numpy 数组所有,当 numpy 数组的引用计数降为零时被释放,这很可能是在 create_np_array
结束时。 Py_Finalize()
尝试释放 所有 剩余的 Python 个对象失败。
您访问此内存的尝试总是无效 - 它仅对特定大小的数组失败的事实只是"luck"。
没有任何一种好的解决方案,但这里有一些建议:
使用Py_INCREF
手动增加拥有的numpy数组的引用计数(然后当你用完它持有的内存时再次手动减少它)这样它就不会被破坏在函数的末尾。确保在 Py_Finalize
.
之前保持内存访问
处理 C 代码中的内存分配并将其分配给 Numpy 数组,以便使用 PyArray_SimpleNewFromData
使 numpy 数组不拥有它。您必须注意 Numpy 数组的寿命不会超过内存。
好的,终于找到了有用提示的答案:
这个想法在 blog post 中得到了最好的描述,包括 github 上的完整代码示例。所以我只是参考这个 post 在这里,它非常详细地回答了这个问题。
谢谢!
我正在尝试将 cython-numpy 数组传递给 c 结构。这有时会起作用,但如果数组变得太 'large' 就会崩溃。虽然这并不是很大(比如 <100k 双类型条目),但我不知道这个限制是从哪里来的。一些代码片段(附上完整代码)。
基于 Win7、Cython 0.28.4、Python3.6、mingw64
我用不同长度的数组试过了。我最近发现,如果数组长度大于 2**16-512 个条目,它总是会崩溃。但我不知道为什么。
cython 文件:
//cy_file.pyx
//...
cdef public struct Container:
double* np_array
// ...
cdef public void create_np_array(Container *container):
cdef numpy.ndarray[numpy.float_t, ndim=1, mode = 'c'] np_array
# just create a numpy array
longarray = np.linspace(1.0, 5.0, 100000)
np_array = numpy.ascontiguousarray(numpy.array(longarray), dtype=float)
container.np_array = <double*> np_array.data
对于 c 文件:
//c_file.c
#include "Python.h"
#include "cy_file.h"
struct Container container;
//...
Py_Initialize();
PyInit_cy_file();
// and call the cython function that fills up the numpy array
create_np_array(&container, start, stop, n_elements, n);
// shutdown of python interpreter
Py_Finalize();
// *** here comes the crash if the array longarray is 'too long' ***
container.np_array[0]
谁能告诉我这里出了什么问题或如何调试?
感谢和欢呼, 蒂姆
内存归 Numpy 数组所有,当 numpy 数组的引用计数降为零时被释放,这很可能是在 create_np_array
结束时。 Py_Finalize()
尝试释放 所有 剩余的 Python 个对象失败。
您访问此内存的尝试总是无效 - 它仅对特定大小的数组失败的事实只是"luck"。
没有任何一种好的解决方案,但这里有一些建议:
使用
Py_INCREF
手动增加拥有的numpy数组的引用计数(然后当你用完它持有的内存时再次手动减少它)这样它就不会被破坏在函数的末尾。确保在Py_Finalize
. 之前保持内存访问
处理 C 代码中的内存分配并将其分配给 Numpy 数组,以便使用
PyArray_SimpleNewFromData
使 numpy 数组不拥有它。您必须注意 Numpy 数组的寿命不会超过内存。
好的,终于找到了有用提示的答案:
这个想法在 blog post 中得到了最好的描述,包括 github 上的完整代码示例。所以我只是参考这个 post 在这里,它非常详细地回答了这个问题。
谢谢!