[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
following:
%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