当前位置:  开发笔记 > 编程语言 > 正文

PyArray_SimpleNewFromData中的奇怪分段错误

如何解决《PyArray_SimpleNewFromData中的奇怪分段错误》经验,为你挑选了1个好方法。

我的问题与PyArray_SimpleNewFromData中的细分错误在精神上类似

我有一个看起来像这样的C代码:(原始代码实际上测试是否malloc()返回NULL)

  1 #include 
  2 #include   // (Not sure if right import)
  3 #include 
  4 #include 
  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()的调用中出现了SegFault(如果我将其替换ret = 1为Segmentation Fault消失了)。在调试时,我尝试了很多事情:

将尺寸数更改为1;

增加分配的内存量malloc()(以确保我没有访问我不应该访问的任何内容);

更改np.NPY_FLOAT32np.float32;

改变我传递新数组“形状”的方式。

我相信我会严格遵循文档说明以及对其他问题的解答。我似乎没有收到任何编译器错误或警告。

不过,我确实注意到,互联网上所有其他代码在调用PyArray_SimpleNewFromData时都在使用C(而不是Python)。我尝试PyObject*从C函数返回a ,但无法对其进行编译。

另外,我确实得到一些“使用不推荐使用的NumPy API,通过#defining NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION禁用它”警告;但我读过,我可以放心地忽略它们。(使用MemoryView时,有关NPY_NO_DEPRECATED_API的Cython Numpy警告)

有什么建议吗?(此外,还可以使用其他任何方法来创建numpy数组dW吗?)



1> DavidW..:

我认为问题在于,您正在传递Python列表作为第二个参数,PyArray_SimpleNewFromData即它期望指向整数的指针。我对此编译感到有些惊讶。

尝试:

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_dWdouble *calculate_dW(intptr_t *dim_w)搭配了。


编辑:第二个问题是您需要包括该行

np.import_array()

在您的Cython文件中(在导入后位于顶层)。这会为numpy做一些设置。原则上,我认为文档建议您在执行操作时始终将其包括在内cimport numpy。在实践中,这仅在某些时候很重要,而这就是其中之一。


(现在已测试答案)

推荐阅读
ar_wen2402851455
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有