[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