Global Numpy vector with Swig
Hi, I need to pass a Numpy array to a C code wrapped by Swig. The array in the C code is a global variable declared as double *vec and I would like to set it in the calling Python module foo using e.g. foo.cvar.vec = numpy.zeros(10) so that the array is manipulated in place. I found out the examples in the numpy/doc/swig dir and adapted them to my code, so now I can pass a Numpy array to a function. But in the examples I was not able to recognize any suggestion (any typedef?) to translate an array into a variable. I'm just writing an intermediate function that does the job, but I feel like writing a wrapping function that will be wrapped again by Swig... Any practical example is highly appreciated! Regards, Andrea
It seems to me you would need to %ignore vec, so that it is not wrapped as a raw pointer to a double, and then in your interface file create a PyArrayObject whose data buffer points to vec (the most efficient way to do this is with %inline). Then use %rename to rename whatever you called your PyArrayObject to "vec" (or not, if you do not care about the name). Finally, foo.cvar.vec = numpy.zeros(10) is going to decrement (and probably delete) your original vec and replace it with the new array of zeros (I think, unless there are some safeties put in place for cvars, in which case you would get an exception). Use foo.cvar.vec[:] = ... to manipulate the data in-place. On Feb 15, 2007, at 1:18 AM, Andrea Tomadin wrote:
Hi, I need to pass a Numpy array to a C code wrapped by Swig. The array in the C code is a global variable declared as double *vec and I would like to set it in the calling Python module foo using e.g. foo.cvar.vec = numpy.zeros(10) so that the array is manipulated in place.
I found out the examples in the numpy/doc/swig dir and adapted them to my code, so now I can pass a Numpy array to a function. But in the examples I was not able to recognize any suggestion (any typedef?) to translate an array into a variable. I'm just writing an intermediate function that does the job, but I feel like writing a wrapping function that will be wrapped again by Swig...
Any practical example is highly appreciated!
Regards, Andrea
_______________________________________________ Numpy-discussion mailing list Numpy-discussion@scipy.org http://projects.scipy.org/mailman/listinfo/numpy-discussion
** Bill Spotz ** ** Sandia National Laboratories Voice: (505)845-0170 ** ** P.O. Box 5800 Fax: (505)284-5451 ** ** Albuquerque, NM 87185-0370 Email: wfspotz@sandia.gov **
Il giorno 15/feb/07, alle ore 22:26, Bill Spotz ha scritto:
It seems to me you would need to %ignore vec, so that it is not wrapped as a raw pointer to a double, and then in your interface file create a PyArrayObject whose data buffer points to vec (the most efficient way to do this is with %inline). Then use %rename to rename whatever you called your PyArrayObject to "vec" (or not, if you do not care about the name). Finally,
foo.cvar.vec = numpy.zeros(10)
is going to decrement (and probably delete) your original vec and replace it with the new array of zeros (I think,
Thank you Bill for your help, even if writing this code is not straightforward for me. Anyway, while I was reading the docs, I became aware of the varin, varout typemap options. I wonder if I can define a typemap(varin) double * declaration, and insert in it the same code that in "numpy.i" translates the PyArrayObject into a C array and vice versa. But I cannot find an example of typemp(varin) for Python, so I don't know what to use for the output, instead of $1. Where are the typemaps (varin) for Python? It seems strange that nobody wrote a public code for such a simple task, as I read that Swig supports Python since the 90s! I suspect I have just not looked in the right places?! Thank you again for help! Andrea
Andrea, It is my understanding that swig typemaps only apply to function arguments. Since what you are talking about is a global variable, I don't believe typemaps will help you. I would try %{ #include "header-that-contains-vec.h" npy_intp vec_dims[ ] = { (npy_intp) length_of_vec }; %} %rename(vec) numpy_vec; %ignore vec; %include "header-that-contains-vec.h" %inline %{ PyObject * numpy_vec = PyArray_SimpleNewFromData(1, vec_dims, NPY_DOUBLE, (void*)vec); %} I guess it would be nice if you could force a "Py_DECREF(numpy_vec);" before the module is destroyed, but I'll leave that as an exercise... On Feb 16, 2007, at 10:59 AM, Andrea Tomadin wrote:
Il giorno 15/feb/07, alle ore 22:26, Bill Spotz ha scritto:
It seems to me you would need to %ignore vec, so that it is not wrapped as a raw pointer to a double, and then in your interface file create a PyArrayObject whose data buffer points to vec (the most efficient way to do this is with %inline). Then use %rename to rename whatever you called your PyArrayObject to "vec" (or not, if you do not care about the name). Finally,
foo.cvar.vec = numpy.zeros(10)
is going to decrement (and probably delete) your original vec and replace it with the new array of zeros (I think,
Thank you Bill for your help, even if writing this code is not straightforward for me. Anyway, while I was reading the docs, I became aware of the varin, varout typemap options. I wonder if I can define a typemap(varin) double * declaration, and insert in it the same code that in "numpy.i" translates the PyArrayObject into a C array and vice versa. But I cannot find an example of typemp(varin) for Python, so I don't know what to use for the output, instead of $1. Where are the typemaps (varin) for Python? It seems strange that nobody wrote a public code for such a simple task, as I read that Swig supports Python since the 90s! I suspect I have just not looked in the right places?!
Thank you again for help! Andrea
** Bill Spotz ** ** Sandia National Laboratories Voice: (505)845-0170 ** ** P.O. Box 5800 Fax: (505)284-5451 ** ** Albuquerque, NM 87185-0370 Email: wfspotz@sandia.gov **
OK, I looked at the varin, varout descriptions in the online manual, and they specifically mention global variables, but WOW is that documentation minimal. I would suggest asking Swig- user@lists.sourceforge.net for some assistance. On Feb 16, 2007, at 1:10 PM, Bill Spotz wrote:
Andrea,
It is my understanding that swig typemaps only apply to function arguments. Since what you are talking about is a global variable, I don't believe typemaps will help you. I would try
%{ #include "header-that-contains-vec.h" npy_intp vec_dims[ ] = { (npy_intp) length_of_vec }; %} %rename(vec) numpy_vec; %ignore vec; %include "header-that-contains-vec.h" %inline %{ PyObject * numpy_vec = PyArray_SimpleNewFromData(1, vec_dims, NPY_DOUBLE, (void*)vec); %}
I guess it would be nice if you could force a "Py_DECREF (numpy_vec);" before the module is destroyed, but I'll leave that as an exercise...
On Feb 16, 2007, at 10:59 AM, Andrea Tomadin wrote:
Il giorno 15/feb/07, alle ore 22:26, Bill Spotz ha scritto:
It seems to me you would need to %ignore vec, so that it is not wrapped as a raw pointer to a double, and then in your interface file create a PyArrayObject whose data buffer points to vec (the most efficient way to do this is with %inline). Then use %rename to rename whatever you called your PyArrayObject to "vec" (or not, if you do not care about the name). Finally,
foo.cvar.vec = numpy.zeros(10)
is going to decrement (and probably delete) your original vec and replace it with the new array of zeros (I think,
Thank you Bill for your help, even if writing this code is not straightforward for me. Anyway, while I was reading the docs, I became aware of the varin, varout typemap options. I wonder if I can define a typemap(varin) double * declaration, and insert in it the same code that in "numpy.i" translates the PyArrayObject into a C array and vice versa. But I cannot find an example of typemp(varin) for Python, so I don't know what to use for the output, instead of $1. Where are the typemaps (varin) for Python? It seems strange that nobody wrote a public code for such a simple task, as I read that Swig supports Python since the 90s! I suspect I have just not looked in the right places?!
Thank you again for help! Andrea
** Bill Spotz ** ** Sandia National Laboratories Voice: (505)845-0170 ** ** P.O. Box 5800 Fax: (505)284-5451 ** ** Albuquerque, NM 87185-0370 Email: wfspotz@sandia.gov **
** Bill Spotz ** ** Sandia National Laboratories Voice: (505)845-0170 ** ** P.O. Box 5800 Fax: (505)284-5451 ** ** Albuquerque, NM 87185-0370 Email: wfspotz@sandia.gov **
participants (2)
-
Andrea Tomadin -
Bill Spotz