2013-08-26 7 views
5

Kiedy próbuję uruchomić poniższy kod cythonu, aby wygenerować pustą tablicę, ulega ona uszkodzeniu.puste tablice w cython: segfault podczas wywoływania PyArray_EMPTY

Czy istnieje sposób generowania pustych numpy tablice w python bez wywoływania np.empty()?

cdef np.npy_intp *dims = [3] 
cdef np.ndarray[np.int_t, ndim=1] result = np.PyArray_EMPTY(1, dims, 
                  np.NPY_INTP, 0) 
+0

Co jest złego np.empty()? Jeśli robisz to tylko raz na etapie inicjalizacji, nie przejmujesz się, czy jest to marginalnie wolniejsze niż bezpośrednie korzystanie z funkcji C. –

+2

Jeśli wykonujesz operacje na tablicach o wielkości <1000, koszt samego np.empty() jest większy niż cała pętla. zobacz (http://stackoverflow.com/questions/18410342/creating-small-arrays-in-cython-takes-a-humongous-amount-of-time), gdzie opisałem problem. Próbuję go rozwiązać, ale teraz znalazłem nowy problem: wykorzystanie funkcji np.PyArray_EMPTY() – staticd

+1

Czy 'np.NPY_INTP' i' np.int_t' są tego samego typu w twoim systemie? – Jaime

Odpowiedz

1

Możecie rozwiązali to bardzo dawno temu, ale z korzyścią dla każdego, kto natyka się na to pytanie, gdy próbuje dowiedzieć się, dlaczego ich naruszenia ochrony pamięci kodu Cython, oto możliwa odpowiedź.

Kiedy pojawi się błąd segmentu przy użyciu numpy C API, pierwszą rzeczą do sprawdzenia jest to, że wywołałeś funkcję import_array(). To może być problem tutaj.

Na przykład, oto foo.pyx:

cimport numpy as cnp 


cnp.import_array() # This must be called before using the numpy C API. 

def bar(): 
    cdef cnp.npy_intp *dims = [3] 
    cdef cnp.ndarray[cnp.int_t, ndim=1] result = \ 
     cnp.PyArray_EMPTY(1, dims, cnp.NPY_INTP, 0) 
    return result 

Oto prosty setup.py na budowę modułu rozszerzeń:

from distutils.core import setup 
from distutils.extension import Extension 
from Cython.Distutils import build_ext 
import numpy as np 


setup(cmdclass={'build_ext': build_ext}, 
     ext_modules=[Extension('foo', ['foo.pyx'])], 
     include_dirs=[np.get_include()]) 

oto moduł w akcji:

In [1]: import foo 

In [2]: foo.bar() 
Out[2]: array([4314271744, 4314271744, 4353385752]) 

In [3]: foo.bar() 
Out[3]: array([0, 0, 0]) 
Powiązane problemy