[Numpy-discussion] swig numpy2carray converters

Bill Spotz wfspotz at sandia.gov
Sun Nov 25 22:55:56 EST 2007

OK, I'm going to try to get to this soon, but I want to discuss the  
interface some before committing to development.

First, my plan is to add to numpy.i, typemaps for signatures like the  

     %typemap(argout) (double** ARGOUT_ARRAY1, int* DIM1)

It is important to note that even though the same argument *names*  
are used, this is a different typemap signature than

     %typemap(argout) (double* ARGOUT_ARRAY1, int DIM1)

and thus can have (logically) different implementations.  For the  
latter, the typemap allocates a new numpy array and passes the buffer  
pointer and dimension in; for the former, the buffer pointer and  
dimension will be obtained from the wrapped function and used to  
build a new numpy array.

As for having a COPY version of the first typemap signature (in  
addition to the non-copy, or "view" version), I currently do not plan  
to do this.  Here's why: the only case I can conceive of for needing  
it is when the class provides a "view" method but not a "copy"  
method.  Since there is no copy method to apply a typemap to, the  
swig user will have to add a new one with %extend, in which case the  
swig user can provide the copy logic.

The example Georg gives in his link below is not a counter-example to  
this.  He provides two methods,

     void getBigData(double **mtx, int *rows, int *cols)
     void getBigDataCopy(double **cpmtx, int *cprows, int *cpcols)

but in addition to the same argument types, they have the exact same  
implementation.  The only thing that is different is the names of the  
arguments, which is clearly so that we can apply different swig  
typemaps to the two methods.  I submit that you will not find a class  
written by someone else that will be designed this way.  You will  
only find it if you have control over the class, in which case you  
should put the copy logic inside the second method.  (It is important  
to understand that if you have a class with functioning view and copy  
methods, then the view version of the typemap will work for both.)

Maybe I'm wrong.  But that is why I want to discuss this before  
committing to code.

On Nov 21, 2007, at 10:07 AM, Georg Holzmann wrote:

> Hallo!
> As chris said, I need to make an example:
> http://grh.mur.at/software/numpy2carray.tar.gz
> I added the following class-example:
> class_example.h: the C++ code
> class_example.i: the SWIG interface file
> class_example_usage.py: example usage in python
> And some comments:
> Bill Spotz schrieb:
>> Here is what I am proposing you do: in your interface file, add  
>> something like
>>     PyObject * getMatrix()
>>     {
>>         npy_intp dims[2] = { /* Obtain the dimensions to your  
>> internal matrix */ };
>>         double * data = /* Obtain the pointer to you internal  
>> matrix */;
>>         return PyArray_SimpleNewFromData(2, dims, NPY_DOUBLE,  
>> (void*)data);
>>     }
>> For your function, use the INPLACE_ARRAY2 typemap:
>>     %apply (double* INPLACE_ARRAY2, int DIM1, int DIM2) {(double*  
>> matrix, int rows, int cols)};
>>     void myFunction(double* matrix, int rows, int cols, double  
>> parameter, ...);
>> And then in python you can do this:
>>     m = getMatrix()
>>     myFunction(m, 3.14, ...)
> I see ... but what I mean with output of a matrix without copy is  
> actually only your getMatrix() funtion I guess - this is basically  
> what getBigData() does in class_example.h together with  
> class_example.i.
> BTW: what is the difference between PyArray_SimpleNewFromData() and  
> PyArray_FromDimsAndData() ?
> (I don't have this book ...)
>>> Again I do not see the problem - see e.g. ARRAY2_OUT_COPY in  
>>> numpy2carray.i, shouldn't this be the same ?
>> I do not understand the use case for which that typemap works.   
>> You create "ttype t1", then pass its address to the function as  
>> the pointer to the data.  This has to be useless to the function.   
>> After the function returns, you access this pointer as if it  
>> points to meaningful data.  How is this possible?  The address of  
>> t1 isn't going to change, and only a single element is allocated.
> See also the class_example_usage.py - there I used the  
> ARRAY2_OUT_COPY for the getBigDataCopy() method.
> LG
> Georg

** Bill Spotz                                              **
** Sandia National Laboratories  Voice: (505)845-0170      **
** P.O. Box 5800                 Fax:   (505)284-0154      **
** Albuquerque, NM 87185-0370    Email: wfspotz at sandia.gov **

More information about the NumPy-Discussion mailing list