【发布时间】:2017-04-28 16:46:39
【问题描述】:
编辑: 在不改变 ulimit 的情况下爆炸的新示例,与 c 部分中的内容无关。
我是一名 python 用户(我从 edX 课程中学习),我一直在使用 ctypes 和 c(但我并不真正了解 c)。 当我使用一些特定参数(基本上是一个大数组大小)运行我的代码时,我的代码出现“分段错误:11”问题,这是一个复制我的代码所做的小例子:
test1.py:
import numpy as np
from numpy.ctypeslib import ndpointer
import ctypes as cy
Lib_Path = './lib.so'
class Simulacion:
def __init__(self, ss,tm):
self.tm = tm;
self.ss = ss;
def ejecutar(self):
self.data = np.empty((int(self.ss), self.tm), dtype = float)
lib = cy.CDLL(Lib_Path)
dblc = cy.c_double; pntrc = ndpointer(dblc); intc = cy.c_long
lib.trisolve.argtypes = [intc, pntrc, intc]
lib.trisolve(self.tm, self.data, self.ss)
return self.data
ss = 10
tm = int(1e6);
sim = Simulacion(ss,tm)
data = sim.ejecutar()
test1.c
void trisolve(int tm, double* data, int ss){
}
制作文件
SRC=test1
GCC=gcc-6
all:
$(GCC) -fPIC -fopenmp -lm -c -O3 $(SRC).c
$(GCC) -shared -lgomp -o lib.so $(SRC).o
clean:
rm lib.so
rm $(SRC).o
此代码在不更改 ulimit 的情况下爆炸。
对于我的真实代码,我使用的是“ulimit -s 65532”,这是我的 mac 中的最大堆栈大小。这限制了我正在使用的数组的大小,目前我需要复制它的大小。 对于我发现的问题,问题是数组存储在堆栈而不是堆中,因此由于 SO,我有这个硬限制。 所以我的问题是,如何将那个大数组传递给 C,将其存储在堆中,然后将其带回 python?
我主要使用python,而c部分的代码我在这个lenguaje中没有很好的格式,所以“堆栈”、“堆”和可能的“malloc”对我来说是新术语。
谢谢!
【问题讨论】:
-
"但我真的不知道 c" - 好吧,你应该去学习它。你正在尝试做一些比较高级的事情,但是你犯了一些基本的错误,比如混淆了
int和long,更不用说在 C 中使用 NumPy 数组的更复杂的部分了。 -
我真的不需要比我已经知道的更多地学习它(除了我在这里问的)。因为我只使用 c 来解决矩阵(因为比 python 快得多),所以我可能可以对代码进行市长版并绕过我的问题,但我想知道如何像现在一样修复代码。谢谢。
-
“我只使用 c 来求解矩阵” - 什么,比如求解线性方程组? NumPy has that built in,它已经自动委托给 LAPACK。
-
正如所写,这不是使用堆栈来存储数组。它在堆上分配,然后你迭代它。我也不明白为什么
omp parallel for会导致这个问题。但 CPython 本身至少需要 32K 的堆栈。 -
比那更复杂,但是我不想在这里解释一切xD,在代码中我有一个很大的
while,里面有几个for来设置条款矩阵,然后是它的解,然后对结果进行一些修改,然后再次迭代。 @eryksun 如果不使用堆栈,为什么当我使用ulimit -s 16时,会出现分段错误,但如果我将其设置为例如 65532,代码可以正常工作吗?omp parallel for不是这里的问题,程序甚至没有开始运行 c 代码。 (如果我把print放在那里,分段错误会发生在它之前)。
标签: python c ctypes heap-memory stack-memory