内存泄漏调用具有大型numpy数组参数的cython函数?

我试图编写如下所示的调用以下cython函数test1的python代码:

def test1( np.ndarray[np.int32_t, ndim=2] ndk, 
           np.ndarray[np.int32_t, ndim=2] nkw, 
           np.ndarray[np.float64_t, ndim=2] phi):

    for _ in xrange(int(1e5)):
        test2(ndk, nkw, phi)


cdef int test2(np.ndarray[np.int32_t, ndim=2] ndk,
               np.ndarray[np.int32_t, ndim=2] nkw,
               np.ndarray[np.float64_t, ndim=2] phi):
    return 1

我的纯Python代码将调用test1并传递3个numpy数组作为参数,它们非常大(大约10 ^ 4 * 10 ^ 3)。 test1将依次调用使用cdef关键字定义的test2并传递这些数组。 由于test1在返回之前需要多次调用test2(大约10 ^ 5),并且test2不需要在cython代码之外调用,所以我使用cdef而不是def

但问题是,每次test1调用test2时,内存开始稳步增加。 我试图在这个cython代码之外调用gc.collect() ,但它不起作用。 最后,该程序将被系统杀死,因为它已经吃掉了所有的记忆。 我注意到这个问题只发生在cdefcpdef函数中,如果我把它改成def,它可以正常工作。

我认为test1应该将这些数组的引用传递给test2而不是object。 但它似乎创建了这些数组的新对象并将它们传递给test2,之后这些对象从未被python gc触及。

我错过了什么?


我仍然对这个问题感到困惑。 但我发现了另一种绕过这个问题的方法。 只要明确告诉cython传递指针就可以了:

def test1( np.ndarray[np.int32_t, ndim=2] ndk, 
           np.ndarray[np.int32_t, ndim=2] nkw, 
           np.ndarray[np.float64_t, ndim=2] phi):

for _ in xrange(int(1e5)):
    test2(&ndk[0,0], &nkw[0,0], &phi[0,0])


cdef int test2(np.int32_t* ndk,
               np.int32_t* nkw,
               np.float64_t* phi):
    return 1

但是,您需要像这样对数组进行索引: ndk[i*row_len + j]详细信息:https://github.com/cython/cython/wiki/tutorials-NumpyPointerToC

链接地址: http://www.djcxy.com/p/87927.html

上一篇: memory leak calling cython function with large numpy array parameters?

下一篇: Cython: overloaded constructor initialization using raw pointer