[Numpy-discussion] blitz++ and numarray
Faheem Mitha
faheem at email.unc.edu
Tue Mar 30 13:45:06 CST 2004
On Mon, 29 Mar 2004, Fernando Perez wrote:
> The following should be enough to get you started:
>
> #include "Python.h"
> #include "Numeric/arrayobject.h"
> #include "blitz/array.h"
>
> using namespace std;
> 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(PyArrayObject* arr_obj)
> {
> 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);
> }
>
> This is what I use for exactly the problem you are describing, and this code
> was pretty much lifted, with minor changes, from weave's auto-generated C++.
> What I do, to sidestep the memory management problems, is let python allocate
> all my Numeric arrays (using zeros() if I have no data). I then use those
> inside my C++ code as blitz++ arrays via the above snippet. Any changes made
> by the C++ code are automatically reflected in the Numeric arary, since the
> blitz object is using the Numeric data area.
>
> I hope this helps. Let me know if you need more help, I can mail you complete
> example code.
Thanks. That is very helpful. I've incorporated this into my code, and
managed to get a simple example with boost working (extracting an element
of an array). See below.
Do you have a similar function which converts a blitz array to a
numarray/Numeric one? If not, I can easily concoct one for myself.
I now need to try to figure out what this reference counting stuff is
about. I read the official Python docs but am still currently very
confused.
Faheem.
***************************************************************************
#include "Python.h"
#include "Numeric/arrayobject.h"
#include <blitz/array.h>
using namespace std;
using namespace blitz;
template<class T, int N>
static Array<T,N> py_to_blitz(PyArrayObject* arr_obj);
static PyObject * arrmod_elem(PyObject *self, PyObject *args);
static PyMethodDef arrmod_methods[] =
{
{"elem", (PyCFunction)arrmod_elem, METH_VARARGS, "Returns the trace of a two-dimensional array.\n"},
{NULL, NULL, 0, NULL}
};
PyMODINIT_FUNC initarrmod(void)
{
(void) Py_InitModule3("arrmod", arrmod_methods, "Returns the Trace of a two-dimensional array.\n");
import_array();
}
static PyObject * arrmod_elem(PyObject *self, PyObject *args)
{
PyObject *input, *result;
PyArrayObject *array;
double el;
int i, j;
if (!PyArg_ParseTuple(args, "Oii", &input, &i, &j))
return NULL;
array = (PyArrayObject *)
PyArray_ContiguousFromObject(input, PyArray_DOUBLE, 2, 2);
if (array == NULL)
return NULL;
Array<double,2> arr = py_to_blitz<double,2>(array);
el = arr(i,j);
result = Py_BuildValue("d",el);
return result;
}
// 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(PyArrayObject* arr_obj)
{
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);
}
More information about the Numpy-discussion
mailing list