2011-10-11 9 views
8

Estoy tratando de entender cómo funciona el Python C-Api, y quiero intercambiar matrices numpy entre Python y una extensión C.Numpy C-Api ejemplo da un SegFault

Así, empecé este tutorial: http://dsnra.jpl.nasa.gov/software/Python/numpydoc/numpy-13.html

tratado de hacer el primer ejemplo allí, un módulo C que calcula la traza de una matriz numpy 2d, era muy ordenado para mí, ya que yo quiero hacer operaciones elementales en arreglos 2d también.

#include <Python.h> 
#include "Numeric/arrayobject.h" 
#include<stdio.h> 

int main(){ 
Py_Initialize(); 
import_array(); 
} 

static char doc[] = 
"This is the C extension for xor_masking routine"; 

    static PyObject * 
    trace(PyObject *self, PyObject *args) 
    { 
    PyObject *input; 
    PyArrayObject *array; 
    double sum; 
    int i, n; 

    if (!PyArg_ParseTuple(args, "O", &input)) 
    return NULL; 
    array = (PyArrayObject *) 
    PyArray_ContiguousFromObject(input, PyArray_DOUBLE, 2, 2); 
    if (array == NULL) 
    return NULL; 

    n = array->dimensions[0]; 
    if (n > array->dimensions[1]) 
    n = array->dimensions[1]; 
    sum = 0.; 
    for (i = 0; i < n; i++) 
    sum += *(double *)(array->data + i*array->strides[0] + i*array->strides[1]); 
    Py_DECREF(array); 
    return PyFloat_FromDouble(sum); 
    } 

static PyMethodDef TraceMethods[] = { 
    {"trace", trace, METH_VARARGS, doc}, 
    {NULL, NULL, 0, NULL} 
}; 

PyMODINIT_FUNC 
inittrace(void) 
{ 
    (void) Py_InitModule("trace", TraceMethods); 
} 


} 

El nombre del módulo es dejar rastro, y se compila con el archivo setup.py:

from distutils.core import setup, Extension 

module = Extension('trace', sources = ['xor_masking.cpp']) 
setup(name = 'Trace Test', version = '1.0', ext_modules = [module]) 

El archivo se compila, trace.so se importa en IPython, pero cuando trato de usar el método trace(), obtengo una falla de segmentación, no sé por qué.

corro esto con Fedora 15, Python 2.7.1, GCC 4.3.0, 1.5.1 Numpy

+0

Tenga en cuenta que el tutorial que está siguiendo es para * Numeric *, la biblioteca anterior reemplazada por Numpy actual. Numpy es * en su mayoría * compatible con versiones anteriores, pero no completamente. (Sí, también * Numeric * se llamaba informalmente "Numpy", lo que genera confusión ...) –

+0

Entonces, ¿debo importar '#include" Numpy/arrayobject.h' en su lugar? –

Respuesta

15

Su función init del módulo tiene que llamar

import_array(); 

después

(void) Py_InitModule("trace", TraceMethods); 

Menciona esto en el tutorial cerca de la parte superior, pero es fácil pasar por alto. Sin esto, segfaults en PyArray_ContiguousFromObject.

+0

¡Muchas gracias! Sí, yo ha tenido dificultad para comprender la inicialización. Funciona como un amuleto. –

+0

Guau. ¡Estaba rompiéndome la cabeza por esto! Gracias –

Cuestiones relacionadas