首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >PyArray_SimpleNewFromData中的奇异分割故障

PyArray_SimpleNewFromData中的奇异分割故障
EN

Stack Overflow用户
提问于 2017-01-09 16:40:14
回答 1查看 2K关注 0票数 1

我的问题“精神上”与SimpleNewFromData相似。

我有一个C代码,如下所示:(原始代码实际上测试malloc()是否返回NULL)

代码语言:javascript
运行
复制
  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代码:

代码语言:javascript
运行
复制
  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

我用它来测试

代码语言:javascript
运行
复制
  # 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)

并获得以下输出

代码语言:javascript
运行
复制
$ 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代替它,分段故障就会消失)。调试时,我尝试了许多事情:

  • 将维数改为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数组的其他方式吗?)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-01-09 17:14:51

我认为问题在于,当PyArray_SimpleNewFromData需要一个指向整数的指针时,它将传递一个Python作为第二个参数。我有点惊讶这会编出来。

尝试:

代码语言:javascript
运行
复制
ret = np.PyArray_SimpleNewFromData(
                     4,
                     &dim_w[0], # pointer to first element
                     np.NPY_FLOAT64,
                     dW)

注意,我还将类型更改为NPY_FLOAT64,因为它应该与double匹配。

我还会将dim_w的定义更改为

代码语言:javascript
运行
复制
np.ndarray[np.NPY_INTP, ndim=1, mode="c"] dim_w

以确保数组的类型与numpy所期望的匹配。这还可能需要将calculate_dW的签名更改为double *calculate_dW(intptr_t *dim_w)以匹配。

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

代码语言:javascript
运行
复制
np.import_array()

在您的Cython文件中(就在顶层,在导入之后)。这会为numpy做一些设置。原则上,我认为文档建议您在执行cimport numpy时始终包括它。在实践中,它只是有时重要,而这正是其中之一。

(答案现已测试)

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41552718

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档