2015-03-25 11 views
6

Próbuję napisać kod Pythona, który wywołuje następujące test1 funkcyjnych Cython tak:funkcja wywoływania wycieku pamięci z funkcją cython z dużymi parametrami tablicy numpy?

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 

mój czysty kod Python nazywają test1 i przejść 3 tablice numpy jako parametry, a oni są bardzo duże (około 10^4 * 10^3). Test1 z kolei wywoła test2 zdefiniowany słowami kluczowymi cdef i przekaże te tablice. Ponieważ test1 musi wywołać test2 wiele razy (około 10^5), zanim powróci, a test2 nie musi być wywołany poza kodem cytonu, używam cdef zamiast def.

Ale problem polega na tym, że za każdym razem, gdy test1 wywołuje test2, pamięć zaczyna zwiększać się stopniowo. Próbowałem zadzwonić pod numer gc.collect() poza tym kodem cytonu, ale to nie działa. I w końcu program zostanie zabity przez system, ponieważ zjadł wszystkie wspomnienia. Zauważyłem, że ten problem występuje tylko z funkcją cdef i cpdef, a jeśli zmienię ją na def, to działa dobrze.

Myślę, że test1 ma przekazywać referencje tych tablic do test2 zamiast obiektu. Ale wydaje się, że tworzy nowe obiekty z tych tablic i przekazuje je do test2, a te obiekty nigdy nie są dotykane przez pytona gc.

Czy coś mi umknęło?

+0

Nie mogę odtworzyć problem. Przekazywanie 'np.ones ((10 ^^ 4, 10 ^^ 3), dtype = ...)' dla 'ndk, nkw, phi' i uruchomienie' test1' wiele razy działa dobrze. Pamięć nie wydaje się zbytnio rosnąć. – colinfang

Odpowiedz

2

Wciąż jestem zdezorientowany tym problemem. Ale znalazłem inny sposób na ominięcie tego problemu. Wystarczy powiedzieć wyraźnie Cython przekazać wskaźnik tak:

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 

Jednak trzeba będzie indeksem tablicy tak: ndk[i*row_len + j] szczegóły: https://github.com/cython/cython/wiki/tutorials-NumpyPointerToC

Powiązane problemy