[Numpy-discussion] Please help - pointer to slice

Sebastian Haase haase at msg.ucsf.edu
Mon Mar 10 12:33:35 EST 2003


<snip>

> Well, in case you (or others) find it useful, I'm including here a little
> library I wrote for accessing general Numeric 2-d arrays (contiguous or
not)
> in an easy manner.
>
> Here's a snippet of a simple (included) example of a function to print an
> integer array:
>
> static PyObject *idisp(PyObject *self, PyObject *args)
> {
>      PyArrayObject *array;
>      int **arr;  // for the data area
>      int i,j,cs;
>
>      if (!PyArg_ParseTuple(args, "O!",&PyArray_Type,&array ) )
> return NULL;
>
>      arr = imatrix_data(array,&cs);
>      for (i=0;i<array->dimensions[0];++i) {
>        for (j=0;j<cs*array->dimensions[1];j+=cs)
> printf("%5d ",arr[i][j]);
>        printf("\n");
>      }
>      free(arr);
>
>      Py_INCREF(Py_None);
>      return Py_None;
> }
>
> You get the **arr pointer and you can then manipulate it as a[i][j]
> conveniently.  The supplied example file may be enough for many to write
their
> Numpy C extensions without much trouble.
>
> > Again: thanks so much.
> > BTW: Is there general interest in my SWIG typemaps. (SWIG is maybe the
> > easiest way to wrap C/C++ functions (and classes)
> > into Python (and/or Perl, Java, Ruby,...) ?  I think especially for
> > numerical stuff, that "link" in of interest.
>
> I'd love to see them.  So far I've either used high-level stuff like
> weave.inline() or just written the extensions by hand (as in the code I'm
> supplying here).  I'd like to see this, especially if there is an easy way
to
> handle contiguity issues with it.

You are using Numeric  not numarray , right?

In any case :
My thinking goes as follows:
I was looking for a wrapping-solution that would be most transparent to the
people that would write the C/C++ code (or even Fortran, BTW)
Since I already had some experience using SWIG, that's what I wanted to use
to handle the "numarray binding".
SWIG has a quite strong (meaning: flexible, general) way of handling data
types. They call it "type maps":
Once you have that in place (later more) the whole "binding" looks like
this: (an example)

C side:
 double sebFunc(float *arr, int nx, int ny, int nz) { double a =0; for(int
i=0;i<nx*ny*nz;i++) a+= arr[i]; return a; }

Then there is the SWIG interface file (suggested file extension ".i"):
double sebFunc(float *array3d, int nx, int ny, int nz);

((This has (in firts approx.) the same syntax as a normal C-header file -
just that SWIG "bites" on the argument-variable names,
in this case (float *array3d, int nx, int ny, int nz)  and realizes (because
of my "type map") that this should be a python-(numeric) array

Then you call it from python just like that...
import myModule
print myModule.sebFunc(array)

So the magic is all hidden in the the typemap:
For that I have a separate SWIG-interface that gets #included into the above
mentioned one.
Here is  that interface file ( just the part for 3d float arrays)

%typecheck(SWIG_TYPECHECK_FLOAT) (float *array2d, int nx, int ny) {
  if(!PyArray_Check($input)) $1=0;
  else if(((PyArrayObject*)$input)->descr->type_num != tFloat32) $1=0;
  else if(((PyArrayObject*)$input)->nd != 2) $1=0;
  else $1=1;
}

%typemap(python,in)
  (float *array3d, int nx, int ny, int nz)
  (PyArrayObject *temp=NULL)
{
  debugPrintf("debug: float *array3d  -> NA_InputArray\n");
  PyArrayObject *NAimg  = NA_InputArray($input, tFloat32, NUM_C_ARRAY);

  if (!NAimg) {
 printf("**** no (float) numarray *****\n");
 return 0;
  }
  temp = NAimg;

  $1 = (float *) (NAimg->data + NAimg->byteoffset);
  switch(NAimg->nd) {
  case 1:
    $2 = NAimg->dimensions[0];
    $3=1;
    break;
  case 2:
    $2 = NAimg->dimensions[1];
    $3=NAimg->dimensions[0];
    break;
  default:
    debugPrintf(" **** numarray dim >2 (ns=%d)\n", NAimg->nd);
    _SWIG_exception(SWIG_RuntimeError, "numarray dim > 2");
    return 0;
}

%typemap(python,freearg)
  (float *array3d, int nx, int ny, int nz)
{
  Py_XDECREF(temp$argnum);
}


The first part (%typecheck) is needed so that SWIG call even handle
overloaded functioned correctly. (BTW, SWIG happily wraps my template
functions to; just with classes (that keep a reference to an array) I not
that sure yet [reference counting])

I think I don't have all necessary error handling parts implemented yet.

But this is already a VERY useful tool for me
- and I am in fact working right now on convincing some ( C and Fortran
only) people to try this  ;-)
 [ once they see how cool it is to call their (Fortran or C) directly from
Python, maybe they start to realize that there is "something new out there"
(emm, I meant Python ]


So what is the status on this list: Are people familiar with (know and/or
using) SWIG ?

Cheers,
Sebastian







More information about the NumPy-Discussion mailing list