
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; }

Dear Henry, You need to call import_array() in initspam. See: http://docs.scipy.org/doc/numpy-1.5.x/user/c-info.how-to-extend.html HTH, Jon On 29/10/2010 15:11, Henry Gomersall wrote:
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; }
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion

On Fri, 2010-10-29 at 15:33 +0200, Jon Wright wrote:
You need to call import_array() in initspam. See: http://docs.scipy.org/doc/numpy-1.5.x/user/c-info.how-to-extend.html
Thanks, that solves it. It would be really useful to have a complete example somewhere. As in, a set of files for a minimum example that builds and runs. Thanks, Henry

On Fri, Oct 29, 2010 at 08:45, Henry Gomersall <whg21@cam.ac.uk> wrote:
On Fri, 2010-10-29 at 15:33 +0200, Jon Wright wrote:
You need to call import_array() in initspam. See: http://docs.scipy.org/doc/numpy-1.5.x/user/c-info.how-to-extend.html
Thanks, that solves it.
It would be really useful to have a complete example somewhere. As in, a set of files for a minimum example that builds and runs.
http://github.com/numpy/numpy/tree/master/doc/newdtype_example/ -- Robert Kern "I have come to believe that the whole world is an enigma, a harmless enigma that is made terrible by our own mad attempt to interpret it as though it had an underlying truth." -- Umberto Eco

----- Original Message ---- From: Henry Gomersall <whg21@cam.ac.uk> To: numpy-discussion <numpy-discussion@scipy.org> Sent: Fri, October 29, 2010 9:11:41 AM Subject: [Numpy-discussion] C extension compiling question 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. --------------------------------------------------------------- If you're trying to use numpy and standard pythons types, you might want to look into ctypes which allows you to write C extensions that pass arrays in a much easier way. I was into writing "bare" C extensions from the ground up like you when someone put me onto ctypes. MUCH easier and cleaner and, as a result, easier to debug. I recommend it. -- Lou Pecora, my views are my own.
participants (4)
-
Henry Gomersall
-
Jon Wright
-
Lou Pecora
-
Robert Kern