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

Fernando Perez fperez.net at gmail.com
Fri Nov 11 06:29:30 CET 2005


PL wrote:

> 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[i]   = arr_dimensions[i];
        strides[i] = arr_strides[i]/T_size;
    }
    return Array<T,N>((T*) arr_obj->data,shape,strides,neverDeleteData);
}
#endif  // PY_TO_BLITZ_H


Cheers,

f




More information about the Python-list mailing list