Numeric and swig (or, how to wrap functions).

Hello all. I'm trying to figure out a (simple) way to wrap extension functions using Numeric and swig. I want to use swig because I find the method described i ch. 12 of the user manual a bit too elaborate. The problem I'm facing with swig is that I cannot figure out a way to pass arrays to the functions expecting double pointers as input. Say, for example, that I want to wrap daxpy: 1. I put the function call interface into a swig file: void daxpy(int* n,double* a, double* x,int* incx, double* y, int* incy) 2. I want the function call visible to python to be something like: x = Numeric.arange(0.0,10.0) y = a[:] a = 1.0 daxpy(a,x,y) 3. To achieve 2. I make a python function that does the real call to daxpy: def daxpy(a,x,y): <Do consistency checking between x and y> n = len(x) d_x = GetDataPointer(x) inc_x = <x's incrment> . . . daxpy_c(n,a,d_x,inc_x,d_y,inc_y) (daxpy_c is the real daxpy) The problem I'm facing is that I cannot grab the internal data pointer from Numeric arrays and pass it to a function. Is there a simple way to do that without having to write a wrapper function in c for every function I want to use? How should I write the function GetDataPointer()? Any hints is greatly appreciated. Best regards, Roy. The Computer Center, University of Tromsø, N-9037 TROMSØ, Norway. phone:+47 77 64 41 07, fax:+47 77 64 41 00 Roy Dragseth, High Perfomance Computing System Administrator Direct call: +47 77 64 62 56. email: royd@cc.uit.no

* Roy Dragseth [snip Numeric and swig questions about how to give a numpy array to a swigged c function]
Any hints is greatly appreciated.
I've done this a few times. What you need to do is help swig understand that a numpy array is input and how to treat this as a C array. With swig you can do this with a typemap. Here's an example: we can create a swig interface file like %module exPyC %{ #include <Python.h> #include <arrayobject.h> /* Remember this one */ #include <math.h> %} %init %{ import_array() /* Initial function for NumPy */ %} %typemap(python,in) double * { PyArrayObject *py_arr; /* first check if it is a NumPy array */ if (!PyArray_Check($source)) { PyErr_SetString(PyExc_TypeError, "Not a NumPy array"); return NULL; } if (PyArray_ObjectType($source,0) != PyArray_DOUBLE) { PyErr_SetString(PyExc_ValueError, "Array must be of type double"); return NULL; } /* check that array is 1D */ py_arr = PyArray_ContiguousFromObject($source, PyArray_DOUBLE, 1, 1); /* set a double pointer to the NumPy allocated memory */ $target = py_arr->data; } /* end of typemap */ %inline %{ void arrayArg(double *arr, int n) { int i; for (i = 0; i < n; i++) { arr[i] = f(i*1.0/n); } } %} Now, compile your extension, and test
You can also get rid of the length argument with a typemap(python,ignore), see the swig docs. For more info about the safety checks in the typemap check the numpy docs. Lykke til! :-) HTH, Roger

* Roy Dragseth [snip Numeric and swig questions about how to give a numpy array to a swigged c function]
Any hints is greatly appreciated.
I've done this a few times. What you need to do is help swig understand that a numpy array is input and how to treat this as a C array. With swig you can do this with a typemap. Here's an example: we can create a swig interface file like %module exPyC %{ #include <Python.h> #include <arrayobject.h> /* Remember this one */ #include <math.h> %} %init %{ import_array() /* Initial function for NumPy */ %} %typemap(python,in) double * { PyArrayObject *py_arr; /* first check if it is a NumPy array */ if (!PyArray_Check($source)) { PyErr_SetString(PyExc_TypeError, "Not a NumPy array"); return NULL; } if (PyArray_ObjectType($source,0) != PyArray_DOUBLE) { PyErr_SetString(PyExc_ValueError, "Array must be of type double"); return NULL; } /* check that array is 1D */ py_arr = PyArray_ContiguousFromObject($source, PyArray_DOUBLE, 1, 1); /* set a double pointer to the NumPy allocated memory */ $target = py_arr->data; } /* end of typemap */ %inline %{ void arrayArg(double *arr, int n) { int i; for (i = 0; i < n; i++) { arr[i] = f(i*1.0/n); } } %} Now, compile your extension, and test
You can also get rid of the length argument with a typemap(python,ignore), see the swig docs. For more info about the safety checks in the typemap check the numpy docs. Lykke til! :-) HTH, Roger
participants (2)
-
Roger Hansen
-
Roy Dragseth