[C++-sig] create boost array from a Numpy PyArray without copying data?
Sebastian Walter
walter at mathematik.hu-berlin.de
Tue Jan 20 10:27:02 CET 2009
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hey,
Thanks for the hint :),
Your code is a little to heavyweight for my purposes,
but I learned quite a lot how boost::python converters work.
And it also gave me the idea that finally solved my problem!
I don't have to convert the PyArray to boost::python::numeric::array
since the indirection over the boost array is presumably also
implemented as a converter (which basically undoes my wrapping, i guess).
So I figured, if that is the case, it should be possible to return the
PyArray directly.
And it does.
At least my test example works as wished:
- -------------------- test.cpp ----------------------------
#define PY_ARRAY_UNIQUE_SYMBOL PyArrayHandle
#include <iostream>
#include <boost/python.hpp>
#include <numpy/noprefix.h>
using namespace std;
using namespace boost;
using namespace boost::python;
using namespace boost::python::numeric;
// global to guarantee that the data is not freed after
test_function_that_doesnt_copy returns
double x[] = {1.,2.,3.};
// this function copies PyArray when the boost array constructor is called
array test_function_that_copies(){
int N = 3;
double x[] = {1.,2.,3.};
array numpy_x(static_cast<array>(handle<>(PyArray_SimpleNewFromData(1,
&N, PyArray_DOUBLE, x))));
double *y = static_cast<double*> PyArray_DATA(numpy_x.ptr());
y[0] = 37.;
for(int n = 0; n<N; ++n){
cout<<"numpy_x[n]="<<y[n]<<"\t\t"<<"x[n]="<<x[n]<<endl;
}
return numpy_x;
}
// this function takes an existing pointer *x
// creates a Numpy PyArray from its data
// and returns the PyArray as PyObject
// Changes in Python result in changes of *x.
PyObject* test_function_that_doesnt_copy(){
int N = 3;
PyArrayObject *retval = (PyArrayObject*)PyArray_SimpleNewFromData(1,
&N, PyArray_DOUBLE, x);
double *y = static_cast<double*> PyArray_DATA(retval);
y[0] = 37.;
for(int n = 0; n<N; ++n){
cout<<"PyArray[n]="<<y[n]<<"\t\t"<<"x[n]="<<x[n]<<endl;
}
return (PyObject *)retval;
}
BOOST_PYTHON_MODULE(_test)
{
import_array();
array::set_module_and_type("numpy", "ndarray");
def("test_function_that_copies", test_function_that_copies);
def("test_function_that_doesnt_copy", test_function_that_doesnt_copy);
}
- --------------- test.py ------------------------
from _test import *
if __name__ == "__main__":
print 'calling test_function_that_copies() from Python'
test_function_that_copies()
print 'calling test_function_that_doesnt_copy() from Python'
test_function_that_doesnt_copy()
print 'changing a value of *x from Python'
y = test_function_that_doesnt_copy()
y[1] = 54634.
test_function_that_doesnt_copy()
- --------------- shell output --------------------
walter at wronski$ python test.py
calling test_function_that_copies() from Python
numpy_x[n]=37 x[n]=1
numpy_x[n]=2 x[n]=2
numpy_x[n]=3 x[n]=3
calling test_function_that_doesnt_copy() from Python
PyArray[n]=37 x[n]=37
PyArray[n]=2 x[n]=2
PyArray[n]=3 x[n]=3
changing a value of *x from Python
PyArray[n]=37 x[n]=37
PyArray[n]=2 x[n]=2
PyArray[n]=3 x[n]=3
PyArray[n]=37 x[n]=37
PyArray[n]=54634 x[n]=54634
PyArray[n]=3 x[n]=3
regards,
Sebastian
Ravi schrieb:
> On Monday 19 January 2009 07:16:10 Sebastian Walter wrote:
>> My question is:
>> How can I create a
>> boost::python::numeric::array from a Numpy Pyarray without copying data?
>
> See http://mail.python.org/pipermail/cplusplus-sig/2008-October/013825.html
> for a full solution. In particular, see the following class:
>
> template <typename T> struct ublas_vector_from_numpy
>
> Regards,
> Ravi
>
>
>
> _______________________________________________
> Cplusplus-sig mailing list
> Cplusplus-sig at python.org
> http://mail.python.org/mailman/listinfo/cplusplus-sig
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.4-svn0 (GNU/Linux)
Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org
iD8DBQFJdZjm9PBA5IG0h0ARAnEPAJ9yWG1AUu94qMGij3w9wvwboXYpEACeKA0N
fDFO2ev8dvaBmjbyQdvlSvk=
=SWB+
-----END PGP SIGNATURE-----
More information about the Cplusplus-sig
mailing list