[Numpy-discussion] C extension compiling question

Henry Gomersall whg21@cam.ac...
Fri Oct 29 08:11:41 CDT 2010


I'm trying to get a really simple toy example for a numpy extension
working (you may notice its based on the example in the numpy docs and
the python extension docs). The code is given below.

The problem I am having is running the module segfaults at any attempt
to access &PyArray_Type (so, as presented, the segfault occurs at the
call to PyArg_ParseTuple). I've been assuming that importing numpy into
the calling python code implicitly provides the numpy libraries that are
necessary for linking. I can only assume I'm missing something. Do i
need some additional includes etc in my compile flags?

I'm currently using the distutils.core module and not the distutils
module that comes with numpy if that makes a difference.

I'm actually pretty keen to document what I've learnt as a 5 minute
how-to for writing basic numpy extensions, if there is demand for it. It
doesn't seem to exist as a coherent whole at the moment.

Thanks,

Henry

#include <Python.h>
#include <numpy/arrayobject.h>

PyMODINIT_FUNC
initspam(void);

static PyObject *
spam_system(PyObject *self, PyObject *args);

void
worker_function(double *input, double *output, npy_intp size);

static PyMethodDef SpamMethods[] = {
    {"system",  spam_system, METH_VARARGS,
     "Execute a shell command."},
    {NULL, NULL, 0, NULL}        /* Sentinel */
};

PyMODINIT_FUNC
initspam(void)
{
    (void) Py_InitModule("spam", SpamMethods);
}

static PyObject *
spam_system(PyObject *self, PyObject *args)
{
    int n;
    int ndims;
    
    PyObject *inarg=NULL, *outarg=NULL;
    PyObject *inarr=NULL, *outarr=NULL;
    
    /* Both input and output need to be PyArray_Type type*/
    if (!PyArg_ParseTuple(args, "O!O!", &PyArray_Type, &inarg,
&PyArray_Type, &outarg));
        return NULL;
    
    inarr = PyArray_FROM_OTF(inarg, NPY_DOUBLE, NPY_IN_ARRAY);
    if (inarr == NULL) goto fail;

    outarr = PyArray_FROM_OTF(outarg, NPY_DOUBLE, NPY_OUT_ARRAY);
    if (outarr == NULL) goto fail;
    
    /* Check the shape of the two arrays is the same */
    ndims = ((PyArrayObject *)outarr)->nd;
    if (((PyArrayObject *)inarr)->nd != ndims)
        goto fail;
    
    /* ...still checking...*/
    for (n=1; n<ndims; n++)
    {
        if (PyArray_DIM(inarr,n) != PyArray_DIM(outarr,n))
            goto fail;
    }
    
    /* Now actually do something with the arrays */
    worker_function((double *)PyArray_DATA(inarr), 
                        (double *)PyArray_DATA(outarr),
                        PyArray_Size(inarr));

    Py_DECREF(inarr);
    Py_DECREF(outarr);
    return Py_None;

fail:
    Py_XDECREF(inarr);
    Py_XDECREF(outarr);
    return NULL;
}

void
worker_function(double *input, double *output, npy_intp size)
{
    npy_intp n;

    for (n=0;n<size;n++)
    {
        output[n] = input[n] + 10;
    }
    return;
}




More information about the NumPy-Discussion mailing list