Hello, I am using swig to wrap some numerical code. I have managed to make swig understand and convert between numarrays and C arrays. However if I use NA_IoArray to make the convertion and pass an integer array when a double array is expected the changes are not copied back to the original array. Let me give a "minimal" example. When I want to wrap the following function: void inc(int len, double *v) { int i; for (i = 0; i < len; i++) v[i]++; } Swig generates the following code, that looks right to me. static PyObject *_wrap_inc(PyObject *self, PyObject *args) { PyObject *resultobj; int arg1 ; double *arg2 = (double *) 0 ; PyArrayObject *NAimg2 = NULL ; PyObject * obj1 = 0 ; if(!PyArg_ParseTuple(args,(char *)"iO:inc",&arg1,&obj1)) goto fail; { PyArrayObject *NAimg2 = NA_IoArray(obj1, tFloat64, NUM_C_ARRAY); if (!NAimg2) { printf("**** no (double) numarray *****\n"); SWIG_exception(SWIG_RuntimeError, "No double Array Found"); return 0; } arg2 = (double *) NA_OFFSETDATA(NAimg2); } inc(arg1,arg2); Py_INCREF(Py_None); resultobj = Py_None; { Py_XDECREF(NAimg2); } return resultobj; fail: { Py_XDECREF(NAimg2); } return NULL; } However if I run the following python code:
import test_na_ioarray from numarray import * v = zeros((5,)) test_na_ioarray(5, v) print v [0 0 0 0 0]
Shouldn't the resultant array be full of ones (when casting the Float64 array of ones to int)? Thanks, Paulo Obs: The code runs fine if the original vector is already a Float64 array.
On Fri, 2004-11-19 at 18:06 -0200, Paulo J. S. Silva wrote:
Hello,
I am using swig to wrap some numerical code. I have managed to make swig understand and convert between numarrays and C arrays. However if I use NA_IoArray to make the convertion and pass an integer array when a double array is expected the changes are not copied back to the original array. Let me give a "minimal" example.
When I want to wrap the following function:
void inc(int len, double *v) { int i; for (i = 0; i < len; i++) v[i]++; }
Swig generates the following code, that looks right to me.
static PyObject *_wrap_inc(PyObject *self, PyObject *args) { PyObject *resultobj; int arg1 ; double *arg2 = (double *) 0 ; PyArrayObject *NAimg2 = NULL ; PyObject * obj1 = 0 ;
if(!PyArg_ParseTuple(args,(char *)"iO:inc",&arg1,&obj1)) goto fail; { PyArrayObject *NAimg2 = NA_IoArray(obj1, tFloat64, NUM_C_ARRAY); if (!NAimg2) { printf("**** no (double) numarray *****\n"); SWIG_exception(SWIG_RuntimeError, "No double Array Found"); return 0; } arg2 = (double *) NA_OFFSETDATA(NAimg2); } inc(arg1,arg2);
I definitely see the problem now: you have NAimg2 in two places, and the "real" NAimg2 goes out of scope so the one at function scope (NULL) is the one that is DECREF'ed, not the real one. Regards, Todd
Py_INCREF(Py_None); resultobj = Py_None; { Py_XDECREF(NAimg2); } return resultobj; fail: { Py_XDECREF(NAimg2); } return NULL; }
However if I run the following python code:
import test_na_ioarray from numarray import * v = zeros((5,)) test_na_ioarray(5, v) print v [0 0 0 0 0]
Shouldn't the resultant array be full of ones (when casting the Float64 array of ones to int)?
Thanks,
Paulo
Obs: The code runs fine if the original vector is already a Float64 array.
------------------------------------------------------- This SF.Net email is sponsored by: InterSystems CACHE FREE OODBMS DOWNLOAD - A multidimensional database that combines robust object and relational technologies, making it a perfect match for Java, C++,COM, XML, ODBC and JDBC. www.intersystems.com/match8 _______________________________________________ Numpy-discussion mailing list Numpy-discussion@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/numpy-discussion
On Fri, 2004-11-19 at 18:06 -0200, Paulo J. S. Silva wrote:
Hello,
I am using swig to wrap some numerical code. I have managed to make swig understand and convert between numarrays and C arrays. However if I use NA_IoArray to make the convertion and pass an integer array when a double array is expected the changes are not copied back to the original array. Let me give a "minimal" example.
When I want to wrap the following function:
void inc(int len, double *v) { int i; for (i = 0; i < len; i++) v[i]++; }
Swig generates the following code, that looks right to me.
static PyObject *_wrap_inc(PyObject *self, PyObject *args) { PyObject *resultobj; int arg1 ; double *arg2 = (double *) 0 ; PyArrayObject *NAimg2 = NULL ; PyObject * obj1 = 0 ;
if(!PyArg_ParseTuple(args,(char *)"iO:inc",&arg1,&obj1)) goto fail; { PyArrayObject *NAimg2 = NA_IoArray(obj1, tFloat64, NUM_C_ARRAY); if (!NAimg2) { printf("**** no (double) numarray *****\n"); SWIG_exception(SWIG_RuntimeError, "No double Array Found"); return 0; } arg2 = (double *) NA_OFFSETDATA(NAimg2); } inc(arg1,arg2);
Py_INCREF(Py_None); resultobj = Py_None; { Py_XDECREF(NAimg2); } return resultobj; fail: { Py_XDECREF(NAimg2); } return NULL; }
However if I run the following python code:
import test_na_ioarray from numarray import * v = zeros((5,)) test_na_ioarray(5, v)
This looks a suspicious here: you're calling the module. I suspect this would raise an exception so you must be "paraphrasing" what you really did. For bug submissions, it's best to just cut and paste the real deal from a python session.
print v [0 0 0 0 0]
Shouldn't the resultant array be full of ones (when casting the Float64 array of ones to int)?
Yes, once everything is set up right and called correctly, this should work as you intend or there's a bug. Another problem may be that NAimg2 goes out of scope before it gets used or DECREF'ed; I'm not sure why it compiles or even positive it shouldn't work, but my programmer's hackles are up. Other than that, I don't see anything wrong with the wrapper so I recommend sticking in some printfs or stepping through with a debugger. One final thing. Look at PyArrayObject and consider using ->nd and ->dimensions instead of arg1. The array knows how big it is. Regards, Todd --=-MnQ5niAbGzyrVGUyx5aw--
Thanks for answering so quickly.
Another problem may be that NAimg2 goes out of scope before it gets used or DECREF'ed;
Bingo that was the problem. My SWIG typemap was declaring NAimg2 twice, and thats an error. The inner NAimg2 got the array data and was getting out of scope. The outer NAimg2 was being DECREF'ed, but it had NULL and nothing was happening. Thanks, I was staring this code for some time now and couldn't see the error. Once I read your message it took me half minute to find the problem and fix it. Paulo. Obs: I am CC the list, then everyone gets to know the solution.
participants (2)
-
Paulo J. S. Silva
-
Todd Miller