# [C++-sig] create boost array from a Numpy PyArray without copying data?

Sebastian Walter walter at mathematik.hu-berlin.de
Wed Jan 21 09:40:00 CET 2009

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Ravi schrieb:
> On Tuesday 20 January 2009 04:27:02 Sebastian Walter wrote:
>> 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!
>
> Good.
>
>> // global to guarantee that the data is not freed after
>> test_function_that_doesnt_copy returns
>> double x[] = {1.,2.,3.};
>
> In this case, you run into the problem of lifetime management. Unless you use
> globals, how do you guarantee that once all users of the array are done with
> it, the array is deleted? The array must be deleted from either the python
> side (via numpy) or from the C++ side (by yourself). Handling this problem is
> the cause for much of my code (which may still be too heavyweight for you).
>
Yes, doing it as I posted above caused a memory corruption.
Apparently Python frees the memory of the Numpy array when it's not
needed anymore in Python.
Apparently I have to increase the refcount manually when I return a raw
PyObject. So I wrote getter functions like that:

PyObject* get_rhs(){
return incref((PyObject *) _array_my_rhs);
}
I'm not sure that this is the way it should be done. But it solved the
memory corruption problem.

With heavyweight I meant that I don't want to use ublas nor do I want to
write a converter. I simply don't have the time to check out the inner
workings of boost::python. And writing a converter requires a fair
amount of template meta programming + knowledge of boost::python.

What I'm trying to accomplish is the following: I have a DAE-solver
which is implemented in C++.
A DAE is basically an ODE + algebraic equations:
\dot xd = f(t,xd,xa)
0 = g(t,xd,xa)
where xd/xa are the differential resp. algebraic state variables.

In C++ I give the integrator a function pointer to a function:
void f(double *t, double *x, double *rhs);

The integrator is responsible for the memory management of *t, *x, *rhs
and just calls the function f. The function f should then convert the
raw pointers to numpy arrays and then call the implementation of f which
is in Python.

void f(double *t, double *x, double *rhs){
1) create PyArray with PyArray_FromDimsAndData(1, &Nx,
PyArray_DOUBLE, (char*) t);
2) then call a callable python object with those PyArrays as argument.
}

> 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

iD8DBQFJdt9g9PBA5IG0h0ARAlY4AJ0T0M2ljLLjegLYikBeRuDeaJelUgCdEF4q
sORViEHb8BmzhNSyhdmNWZA=
=eSRA
-----END PGP SIGNATURE-----