2013-08-26 9 views
5

Quando provo a eseguire il codice cython qui sotto per generare un array vuoto, esso segfaults.array vuoti in cython: segfault quando si chiama PyArray_EMPTY

C'è un modo per generare array numpy vuoti in python senza chiamare 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

Cosa c'è di sbagliato su np.empty()? Se lo fai solo una volta nella fase di inizializzazione, non ti interessa se è leggermente più lento rispetto all'utilizzo diretto delle funzioni C. –

+2

Se si stanno eseguendo operazioni su array di dimensioni <1000, il costo di np.empty() solo è maggiore dell'intero ciclo. vedere (http://stackoverflow.com/questions/18410342/creating-small-arrays-in-cython-takes-a-humongous-amount-of-time) dove ho descritto il problema. Sto cercando di risolverlo, ma ora ho trovato un nuovo problema: vale a dire l'uso della funzione np.PyArray_EMPTY() – staticd

+1

Are 'np.NPY_INTP' e' np.int_t' lo stesso tipo nel tuo sistema? – Jaime

risposta

1

Potreste aver risolto questo molto tempo fa, ma a beneficio di tutti coloro che si imbatte in questa domanda durante il tentativo di capire perché i loro segfaults codice Cython, ecco una possibile risposta.

Quando si ottiene un segfault quando si utilizza l'API C numpy, la prima cosa da verificare è che si è chiamata la funzione import_array(). Questo potrebbe essere il problema qui.

Ad esempio, ecco 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 

Ecco un semplice setup.py per la costruzione del modulo di estensione:

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()]) 

Ecco il modulo in azione:

In [1]: import foo 

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

In [3]: foo.bar() 
Out[3]: array([0, 0, 0])