[Numpy-discussion] [EXTERNAL] numpy.i and INPLACE_ARRAY1[ANY]

Kaspar Emanuel kaspar.emanuel at gmail.com
Fri Nov 22 19:11:24 EST 2013


Here is the typemap for anyone with a similar problem:

/* Typemap suite for (DATA_TYPE* INPLACE_ARRAY1)
 */
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
           fragment="NumPy_Macros")
  (DATA_TYPE* INPLACE_ARRAY1)
{
  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
                                                 DATA_TYPECODE);
}
%typemap(in,
         fragment="NumPy_Fragments")
  (DATA_TYPE* INPLACE_ARRAY1)
  (PyArrayObject* array=NULL)
{
  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
  if (!array || !require_dimensions(array,1) || !require_contiguous(array)
      || !require_native(array)) SWIG_fail;
  $1 = (DATA_TYPE*) array_data(array);
}

It seems I have to put it in numpy.i for it to be used.


On 22 November 2013 23:56, Kaspar Emanuel <kaspar.emanuel at gmail.com> wrote:

> OK yeah, I tested with float data_location[] but then it expects and
> array of length 0, (shape [0] it says). With float data_location[64] I
> can use 64 size array but this isn't very useful in this instance. I
> will try and make a typemap for just (float* INPLACE_ARRAY) without a
> DIM1 as that's probably the cleanest.
>
> When I  was playing with the typemaps before I put %typecheck and
> %typemap in lilv.i just under  %include "numpy.i" (as in attached) but
> I don't think they were actually noticed till I put them in numpy.i
> itself. Where is the appropriate place to extend these?
>
> On 22 November 2013 23:44, Bill Spotz <wfspotz at sandia.gov> wrote:
> > Yes, typemaps are checked against individual arguments or contiguous
> groups of arguments, not necessarily the entire argument list.
> >
> > I believe the argument would have to be "float data_location[]",
> signifying a null-terminated array, rather than float*, for the
> INPLACE_ARRAY1[ANY] to work.
> >
> > On Nov 22, 2013, at 4:32 PM, Kaspar Emanuel wrote:
> >
> >> Cool! That seems to have worked. Many thanks. So I didn't need my own
> >> typemap for this at all as it will already ignore the rest of the
> >> arguments?
> >>
> >> What I still don't understand is that there seems to be a typemap for
> >> INPLACE_ARRAY1[ANY] without any DIM1. How come I can't apply that?
> >>
> >>> Be sure you understand the use case.  The (data_location, unused)
> >> pair is going to be provided by a numpy array and its length.  You
> >> might want to do a check to make sure variable "unused" has the
> >> correct value before you pass the numpy array data on to your
> >> function.
> >>
> >> The only point where the check could be made would be in the run
> >> function which should not be run with a value longer than the array
> >> length.
> >>
> >>
> >> On 22 November 2013 23:19, Bill Spotz <wfspotz at sandia.gov> wrote:
> >>> I think you are getting close.  Application of the typemap simply
> requires
> >>>
> >>>    %apply (float* INPLACE_ARRAY1, int DIM1) {(float* data_location,
> int unused)}
> >>>
> >>> rather than the entire argument list.
> >>>
> >>> Be sure you understand the use case.  The (data_location, unused) pair
> is going to be provided by a numpy array and its length.  You might want to
> do a check to make sure variable "unused" has the correct value before you
> pass the numpy array data on to your function.
> >>>
> >>> Typemaps are generally non-intuitive.  But once you understand all the
> rules, they start to make sense.
> >>>
> >>> -Bill
> >>>
> >>> On Nov 22, 2013, at 4:05 PM, Kaspar Emanuel wrote:
> >>>
> >>>> Hi Bill,
> >>>>
> >>>> thanks for your response. So the function I am actually trying to
> wrap is:
> >>>>
> >>>> static inline void
> >>>> lilv_instance_connect_port(LilvInstance* instance,
> >>>>                           uint32_t      port_index,
> >>>>                           void*         data_location)
> >>>>
> >>>> It just passes on the pointer to the data_location (the audio buffer)
> and then you call lilv_instance_run(int nframes) where nframes could be the
> dimension of your buffer, or possibly less if you really want.
> >>>>
> >>>> So following your recommendations I tried to make a wrapper function:
> >>>>
> >>>> lilv_instance_pyconnect(LilvInstance* instance,
> >>>>                           uint32_t      port_index,
> >>>>                           float*         data_location, int unused)
> >>>>
> >>>> and then a typemap following what is in numpy.i :
> >>>>
> >>>>
> >>>> %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
> >>>>           fragment="NumPy_Macros")
> >>>>  (UNUSED1* UNUSED2, UNUSED3 UNUSED4, DATA_TYPE* INPLACE_ARRAY1,
> DIM_TYPE DIM1)
> >>>> {
> >>>>  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
> >>>>                                                 DATA_TYPECODE);
> >>>> }
> >>>> %typemap(in,
> >>>>         fragment="NumPy_Fragments")
> >>>>  (UNUSED1* UNUSED2, UNUSED3 UNUSED4, DATA_TYPE* INPLACE_ARRAY1,
> DIM_TYPE DIM1)
> >>>>  (PyArrayObject* array=NULL, int i=1)
> >>>> {
> >>>>  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
> >>>>  if (!array || !require_dimensions(array,1) ||
> !require_contiguous(array)
> >>>>      || !require_native(array)) SWIG_fail;
> >>>>  $1 = (DATA_TYPE*) array_data(array);
> >>>>  $2 = 1;
> >>>>  for (i=0; i < array_numdims(array); ++i) $2 *= array_size(array,i);
> >>>> }
> >>>>
> >>>> which I tried to apply with:
> >>>>
> >>>>
> >>>> %apply (LilvInstance* instance, uint32_t port_index, float*
> INPLACE_ARRAY1, int DIM1) {(LilvInstance* instance, uint32_t port_index,
> float* data_location, int unused)}
> >>>>
> >>>> But it doesn’t seem to do anything an I just get a TypeError.
> >>>>
> >>>> You might have noticed I am a little bit out of my depth…
> >>>>
> >>>> Ta,
> >>>>
> >>>> Kaspar
> >>>>
> >>>>
> >>>>
> >>>> On 22 November 2013 22:40, Bill Spotz <wfspotz at sandia.gov> wrote:
> >>>> Kaspar,
> >>>>
> >>>> Yes, in order for numpy.i typemaps to work, you need to provide
> dimensions.  How is lilv_test(float*) supposed to know how large the float
> array is?  Is it actually a method where the class knows the size?  In
> cases where dimensions are not passed through the argument list, you have
> two options:
> >>>>
> >>>>  1. Write a proxy function that does have dimension arguments and
> calls the original function, and then wrap that instead of the original
> function.
> >>>>
> >>>>  2. Use the functions and macros in numpy.i to write new typemaps
> that work for your case.
> >>>>
> >>>> -Bill
> >>>>
> >>>> On Nov 22, 2013, at 3:30 PM, Kaspar Emanuel wrote:
> >>>>
> >>>>> Hey,
> >>>>> I am trying to improve the Lilv Python bindings to include numpy.i
> to allow for creation and verification of audio test buffers using NumPy.
> >>>>>
> >>>>> I am just trying to get something working at the moment so I am
> tring to wrap a test function.
> >>>>>
> >>>>> static inline void
> >>>>> lilv_test(float* data_location){}
> >>>>>
> >>>>> and I have in lilv.i:
> >>>>>
> >>>>> %apply (float* INPLACE_ARRAY1) {(float* data_location)};
> >>>>> This doesn’t produce any warnings or anything but when I try and use
> it from Python I get:
> >>>>>
> >>>>> TypeError: in method 'lilv_test', argument 1 of type 'float *'
> >>>>> What does work is if I have:
> >>>>>
> >>>>> lilv_test(float* data_location, int n){}
> >>>>> and
> >>>>>
> >>>>> %apply (float* INPLACE_ARRAY1, int DIM1) {(float* data_location, int
> n)};
> >>>>> but this doesn’t fit very well with the functions I eventually want
> to wrap, as they don’t have a dimension argument.
> >>>>>
> >>>>> Is it not possible to use INPLACE_ARRAY1 without a dimension?
> >>>>>
> >>>>> Thanks for any help,
> >>>>>
> >>>>> Kaspar
> >>>>>
> >>>>>
> >>>>> _______________________________________________
> >>>>> NumPy-Discussion mailing list
> >>>>> NumPy-Discussion at scipy.org
> >>>>> http://mail.scipy.org/mailman/listinfo/numpy-discussion
> >>>>
> >>>> ** 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 **
> >>>>
> >>>>
> >>>>
> >>>>
> >>>>
> >>>> _______________________________________________
> >>>> NumPy-Discussion mailing list
> >>>> NumPy-Discussion at scipy.org
> >>>> http://mail.scipy.org/mailman/listinfo/numpy-discussion
> >>>>
> >>>> _______________________________________________
> >>>> NumPy-Discussion mailing list
> >>>> NumPy-Discussion at scipy.org
> >>>> http://mail.scipy.org/mailman/listinfo/numpy-discussion
> >>>
> >>> ** 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 **
> >>>
> >>>
> >>>
> >>>
> >>>
> >>> _______________________________________________
> >>> NumPy-Discussion mailing list
> >>> NumPy-Discussion at scipy.org
> >>> http://mail.scipy.org/mailman/listinfo/numpy-discussion
> >> _______________________________________________
> >> NumPy-Discussion mailing list
> >> NumPy-Discussion at scipy.org
> >> http://mail.scipy.org/mailman/listinfo/numpy-discussion
> >
> > ** 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 **
> >
> >
> >
> >
> >
> > _______________________________________________
> > NumPy-Discussion mailing list
> > NumPy-Discussion at scipy.org
> > http://mail.scipy.org/mailman/listinfo/numpy-discussion
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/numpy-discussion/attachments/20131123/1822d284/attachment.html>


More information about the NumPy-Discussion mailing list