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])
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. –
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
Czy 'np.NPY_INTP' i' np.int_t' są tego samego typu w twoim systemie? – Jaime