need an example of Python numarray to C++ and back again, Boost / SWIG?

P

PL

I want to pass a 2D array from Python to C++, manipulate it in C++ (for
example, add 1 to each element) and pass it back to Python.

With these building blocks I will be able to figure out all the rest of
what I need to do for my project. I am very familiar with Python, but
less so with C++ and Boost or SWIG.

Does anyone have an example with all steps that I can follow? More
specifically I am looking for the C++ code, ".i" file for SWIG and/or
the analagous setup files that Boost would need to do this.

Thanks in advance for any help you can provide,
 
F

Fernando Perez

PL said:
I want to pass a 2D array from Python to C++, manipulate it in C++ (for
example, add 1 to each element) and pass it back to Python.

With these building blocks I will be able to figure out all the rest of
what I need to do for my project. I am very familiar with Python, but
less so with C++ and Boost or SWIG.

Does anyone have an example with all steps that I can follow? More
specifically I am looking for the C++ code, ".i" file for SWIG and/or
the analagous setup files that Boost would need to do this.

You may want to look into weave.inline or weave.blitz, from scipy. Typemaps for
conversion to blitz++ were recently posted on the scipy list:

http://aspn.activestate.com/ASPN/Mail/Message/numpy-discussion/2883831

In particular look at Stefan's post.

For info on weave, here you can find some old slides and example code:

http://amath.colorado.edu/faculty/fperez/python/

Cheers,

f
 
P

PL

I looked at Stefan's post - but he remarks that "Unfortunately, Blitz
jealously guards its data (restricted pointers), so that it is not so
easy to do the conversion in the other direction. If anyone knows an
answer to this problem, I'd be glad to hear it"

I've previously looked at Phillip Austin's 'num_util' and Paulo J. S.
Silva's 'COIN' example, but even from those two, I can't figure out a
way to do: Python 2D numarray --> C++ (process array) --> Python 2D
numarray.

I forgot about "weave" - I had looked there before and will revisit it
to see if it will work. But I was intending to do this with a compiled
extension. I wish there was a simple example of this in either the
SWIG or Boost docs or a faq/howto posted somewhere . . .

-Paul
 
F

Fernando Perez

PL said:
I looked at Stefan's post - but he remarks that "Unfortunately, Blitz
jealously guards its data (restricted pointers), so that it is not so
easy to do the conversion in the other direction. If anyone knows an
answer to this problem, I'd be glad to hear it"

I've previously looked at Phillip Austin's 'num_util' and Paulo J. S.
Silva's 'COIN' example, but even from those two, I can't figure out a
way to do: Python 2D numarray --> C++ (process array) --> Python 2D
numarray.

I may be missing something, but what I've done in the past for this is have the
C++ code simply reuse the Numeric data pointer. This way, when I exit the C++
extension (I've used blitz++ for the job), the array as seen from the python
side has been 'magically' modified. Obviously this means that I can't allocate
new arrays in C++ which can be transfered over to python without paying the
price of a copy, but in my cases that hasn't been a problem: I do all
'allocations' in python (via arr=Numeric.empty(...)) and let the blitz code
fill in the arrays.

This has the advantage that the blitz array creation is extremely cheap, as only
the shape tuple needs to be copied (not the data region). The following little
snippet is pretty much all that's needed if the above description happens to
work for you. This code is mostly taken from weave's internals:

// -*- C++ -*-
#ifndef PY_TO_BLITZ_H
#define PY_TO_BLITZ_H

#include "Python.h"
#include "Numeric/arrayobject.h"
#include "blitz/array.h"

using namespace blitz;

// Convert a Numpy array to a blitz one, using the original's data (no copy)
template<class T, int N>
static Array<T,N> py_to_blitz(const PyArrayObject* arr_obj)
{
const int T_size = sizeof(T);
TinyVector<int,N> shape(0);
TinyVector<int,N> strides(0);
int *arr_dimensions = arr_obj->dimensions;
int *arr_strides = arr_obj->strides;

for (int i=0;i<N;++i) {
shape = arr_dimensions;
strides = arr_strides/T_size;
}
return Array<T,N>((T*) arr_obj->data,shape,strides,neverDeleteData);
}
#endif // PY_TO_BLITZ_H


Cheers,

f
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,825
Latest member
VernonQuy6

Latest Threads

Top