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

Bill Spotz wfspotz at sandia.gov
Fri Nov 22 18:44:29 EST 2013


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








More information about the NumPy-Discussion mailing list