Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Re: C API: array of floats/ints from python to C and back

Reply
Thread Tools

Re: C API: array of floats/ints from python to C and back

 
 
Daniel Fetchinson
Guest
Posts: n/a
 
      12-28-2008
>> This is the function I have, the corresponding python function will
>> take two equal length lists of integers and the C function will
>> compute their sum and return the result as a python tuple.
>>
>>
>> static PyObject *func( PyObject * self, PyObject * args )
>> {
>> int j, N;
>> int * src1, * src2;
>> PyObject *list1, *list2;
>>
>> list1 = PyTuple_GetItem( args, 0 );
>> N = PyList_Size( list1 );
>> src1 = ( int * ) malloc( N * sizeof( int ) );
>> for( j = 0; j < N; j++ )
>> {
>> src1[j] = (int)PyInt_AsLong( PyList_GetItem( list1, j ) );
>> }
>>
>> list2 = PyTuple_GetItem( args, 1 );
>> N = PyList_Size( list2 );
>> src2 = ( int * ) malloc( N * sizeof( int ) );
>> for( j = 0; j < N; j++ )
>> {
>> src2[j] = (int)PyInt_AsLong( PyList_GetItem( list2, j ) );
>> }
>>
>> PyObject * tuple;
>> tuple = PyTuple_New( N );
>> for( j = 0; j < N; j++ )
>> {
>> PyTuple_SetItem( tuple, j, PyInt_FromLong( (long)( src1[j] +
>> src2[j] ) ) );
>> }
>>
>> free( src1 );
>> free( src2 );
>>
>> return tuple;
>> }

>
> As others already said, using a Numpy array or an array.array object would
> be more efficient (and even easier - the C code gets a pointer to an array
> of integers, as usual).


I looked for this in the C API docs but couldn't find anything on how
to make an array.array python object appear as a pointer to integers
(or floats, etc) in C code. On

http://docs.python.org/c-api/concret...quence-objects

There is only list and tuple or maybe you mean byte array? That has
only been introduced in python 2.6 and I'm working on 2.5.

Daniel

--
Psss, psss, put it down! - http://www.cafepress.com/putitdown
 
Reply With Quote
 
 
 
 
Daniel Fetchinson
Guest
Posts: n/a
 
      12-28-2008
>>> You MUST check EVERY function call for errors!
>>
>> Yes, I know
>>

>
> Believe me, if you don't, there is a risk of crashing the program. And
> they're a lot harder to find and fix.


Sure, what I meant by the smiley is just that it was a quick and dirty
example, not real code. In a real code I do check these sorts of
things.

>>> And check the argument's type (how do you know it is a list?). Once you
>>> are sure the first parameter *is* a list, you may use the "macro"
>>> version
>>> of several functions, like PyList_GET_SIZE and PyList_GET_ITEM.

>>
>> The macro versions are preferable because they are faster?

>
> Yes, because they don't do any additional checking. PyList_GET_ITEM just
> retrieves the item; PyList_GetItem checks whether it is called on a list
> object, then checks if index is out of bounds, and only then goes to
> retrieve the item.


Thanks, I was wondering what the difference between these versions
are, now it's clear.

>>> You should check that both lists have the same length too.
>>> And you should check that elements are integers, or convertible to
>>> integers (in case of error, PyInt_AsLong returns -1 and PyErr_Occurred()
>>> is true)
>>> To fill the resulting tuple, use PyTuple_SET_ITEM instead. BTW, why
>>> return
>>> a tuple and not a list?

>>
>> No particular reason, other than the fact that I won't need to modify
>> these lists/tuples from python so whenever something will not change,
>> I use a tuple because it's immutable. Or this is not a very good
>> practice? There is no difference between lists and tuples in terms of
>> speed I suppose (getitem, setitem, etc).

>
> Usually lists represent an ordered collection of similar items, where
> position is not relevant (the third item is treated more or less the same
> as the tenth); by example, a list of attendants to certain event. It makes
> sense to process the whole list doing the same thing to each element, and
> it makes sense to ask "is this item in the list?."
>
> Tuples represent an ordered collection of dissimilar items, where position
> is relevant (because it identifies each item); by example, a row from a
> database table (name, address, age, phone number), or a point (x,y,z) in
> space. It isn't common to process the whole tuple doing the same thing for
> each element, and usually it doesn't make sense to look for certain item
> in the tuple. But it does make sense to refer to individual items like
> t[2], or t.age (namedtuple, 2.6 and up)
>
> From this point of view, lists and tuples are conceptually different -
> tuples aren't "frozen" lists. But this is just common usage, or maybe
> historical intent; of course you are free to use whatever structure you
> feel adequate.
>
> Once the list/tuple is created and filled, there is no speed difference
> accessing the individual items. Creating an empty list that grows one
> element at a time is slow for large lists (the memory block has to be
> re-allocated and copied over evry time it gets full) but this doesn't
> happen if you provide the final size when creating the list.


All right, this is clear then too, I'll probably use a list.

Cheers,
Daniel


--
Psss, psss, put it down! - http://www.cafepress.com/putitdown
 
Reply With Quote
 
 
 
 
Gabriel Genellina
Guest
Posts: n/a
 
      12-28-2008
En Sun, 28 Dec 2008 01:47:08 -0200, Daniel Fetchinson
<(E-Mail Removed)> escribió:

>> As others already said, using a Numpy array or an array.array object
>> would
>> be more efficient (and even easier - the C code gets a pointer to an
>> array
>> of integers, as usual).

>
> I looked for this in the C API docs but couldn't find anything on how
> to make an array.array python object appear as a pointer to integers
> (or floats, etc) in C code. On
>
> http://docs.python.org/c-api/concret...quence-objects
>
> There is only list and tuple or maybe you mean byte array? That has
> only been introduced in python 2.6 and I'm working on 2.5.


array is a library module, and isn't really part of the API. You're
looking for the buffer protocol:
PyObject_AsReadBuffer/PyObject_AsWriteBuffer; see
http://docs.python.org/c-api/objbuffer.html

Given an array.array('l') (containing C long integers):

int do_something(PyObject* obj)
{
long *vec;
Py_ssize_t nbytes, nitems, i;

if (PyObject_AsReadBuffer(obj, (const void **)&vec, &nbytes) != 0)
return NULL;
nitems = nbytes/sizeof(long);
for (i=0; i<nitems; i++) {
/* do something with vec[i] */
}
return ret;
}

From Python you can get "vec" and "nitems" using the buffer_info() method
of array objects.

--
Gabriel Genellina

 
Reply With Quote
 
Daniel Fetchinson
Guest
Posts: n/a
 
      12-28-2008
>>> As others already said, using a Numpy array or an array.array object
>>> would
>>> be more efficient (and even easier - the C code gets a pointer to an
>>> array
>>> of integers, as usual).

>>
>> I looked for this in the C API docs but couldn't find anything on how
>> to make an array.array python object appear as a pointer to integers
>> (or floats, etc) in C code. On
>>
>> http://docs.python.org/c-api/concret...quence-objects
>>
>> There is only list and tuple or maybe you mean byte array? That has
>> only been introduced in python 2.6 and I'm working on 2.5.

>
> array is a library module, and isn't really part of the API. You're
> looking for the buffer protocol:
> PyObject_AsReadBuffer/PyObject_AsWriteBuffer; see
> http://docs.python.org/c-api/objbuffer.html
>
> Given an array.array('l') (containing C long integers):
>
> int do_something(PyObject* obj)
> {
> long *vec;
> Py_ssize_t nbytes, nitems, i;
>
> if (PyObject_AsReadBuffer(obj, (const void **)&vec, &nbytes) != 0)
> return NULL;
> nitems = nbytes/sizeof(long);
> for (i=0; i<nitems; i++) {
> /* do something with vec[i] */
> }
> return ret;
> }
>
> From Python you can get "vec" and "nitems" using the buffer_info() method
> of array objects.


Thanks very much, this was very helpful!

Cheers,
Daniel

--
Psss, psss, put it down! - http://www.cafepress.com/putitdown
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
const and array of array (of array ...) Mara Guida C Programming 3 09-03-2009 07:54 AM
how do i pass an array to a function .. and also return an array back from the func???? bhejafry.mmk@gmail.com C Programming 3 11-30-2006 05:05 PM
Configuring VPN through Cisco PIX and ISA Server in Back-to-back scenario Dejan Gambin Cisco 0 10-16-2003 01:53 PM
Re: Passing pointer to array from C to Python..and modifying same array in python? J W Python 0 07-14-2003 02:59 PM
Passing pointer to array from C to Python..and modifying same array in python? JW Python 1 07-12-2003 10:45 PM



Advertisments