[Numpy-discussion] swig numpy2carray converters

Bill Spotz wfspotz@sandia....
Tue Nov 20 16:20:11 CST 2007

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*) 

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, ...)

However myFunction() alters your internal matrix, it will be  
reflected in the array m.

What I don't understand is if double* matrix is *internal*, why is it  
in the argument list?  Does myFunction() actually allocate the  
matrix?  If so, then getMatrix() won't be able to get access to the  
matrix, but myFunction() is really a factory function or  
constructor.  If this is true, then writing a simple function like  
getMatrix() as a SUBSTITUTE wrapper for myFunction() (i.e., that  
calls myFunction()) is MUCH, MUCH simpler than trying to maintain a  
general typemap that does the same thing.

If my assumptions are wrong then you will need to explain to me  
exactly what myFunction() expects of its arguments, and why double*  
matrix is in the argument list at all.

On Nov 20, 2007, at 1:38 PM, Georg Holzmann wrote:

> Hallo!
>> OK, so the key here is the *internal* matrix.  I think you need to  
>> provide a way to extract that matrix from the C++ application as a  
>> numpy array.  Then you can provide it to your function/method as  
>> an INPLACE array.  No new memory will be allocated.
> [...]
>> The INPLACE typemaps force you to provide the allocated memory.   
>> If you do it by accessing whatever your C++ app has already  
>> allocated, you should be fine.
> Hm ... I still don't understand that ...
> With INPLACE I have to allocate the numpy array before, then pass  
> it to my getMyMatrix(my_inplace_numarray) method, then copy the  
> data in that method to the my_inplace_numarray - right ?

No.  INPLACE means "in place".  The typemap expects that the array  
has already been allocated -- either you allocated something new or  
you obtained the array from existing data -- it doesn't care.  It  
passes the pointer to the buffer to the function, which can alter the  
data IN PLACE, and you will see these changes to your array after the  
wrapper returns control to python.

> But I am still not convinced by the INPLACE method - the more  
> natural way for me is to simply return the matrix ...

This is only natural or makes sense if the function allocates the  
data for the matrix.  Does it?  If so, then multiple calls to it  
ensures duplicate allocations, which you indicate is not possible.   
If not, then the function expects the data to be allocated elsewhere.

> Maybe the most usefull way would be to add also OUT_WITHOUTCOPY  
> macros to numpy.i, where the data is allocated with  
> PyArray_FromDimsAndData() ?
> (as a "long term" goal ...)

> 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.

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

More information about the Numpy-discussion mailing list