Commits

Anonymous committed 55af1d8

carraygetwrap for getting numpy array wrapper but not as a member

Comments (0)

Files changed (4)

carraygetwrap/carraygetwrapmodule.c

+#include <Python.h>
+#include "structmember.h"
+#include <numpy/arrayobject.h>
+
+#define CARRAYWRAP_VERBOSE
+#define CARRAYWRAP_MAXDIM 3
+
+typedef struct __CArrayWrap__{
+  PyObject_HEAD
+  char *data, *array;
+  int ndim, dims[CARRAYWRAP_MAXDIM];
+} CArrayWrap;
+
+static void       CArrayWrap_dealloc(CArrayWrap* self);
+static PyObject * CArrayWrap_new(PyTypeObject *type,
+				 PyObject *args, PyObject *kwds);
+static int CArrayWrap_init(CArrayWrap *self, PyObject *args, PyObject *kwds);
+
+static void print_indent(int inum)
+{
+  int i;
+  for (i = 0; i < inum; ++i){
+    printf("  ");
+  }
+}
+
+static void print_array_i1d(int *a1d, int *dims, int inum)
+{
+  int i;
+  print_indent(inum);
+  printf("[%d]", dims[0]);
+  for (i = 0; i < dims[0]; ++i){
+    printf(" %d", a1d[i]);
+  }
+  printf("\n");
+}
+
+static void print_array_i2d(int **a2d, int *dims, int inum)
+{
+  int i;
+  print_indent(inum);
+  printf("[%d]\n", dims[0]);
+  for (i = 0; i < dims[0]; ++i){
+    print_array_i1d(a2d[i], dims+1, inum+1);
+  }
+}
+
+static void print_array_i3d(int ***a3d, int *dims, int inum)
+{
+  int i;
+  print_indent(inum);
+  printf("[%d]\n", dims[0]);
+  for (i = 0; i < dims[0]; ++i){
+    print_array_i2d(a3d[i], dims+1, inum+1);
+  }
+}
+
+static PyObject *
+CArrayWrap_print_array(CArrayWrap *self)
+{
+  switch(self->ndim){
+  case 1:
+    print_array_i1d((int *)self->array, self->dims, 0);
+    break;
+  case 2:
+    print_array_i2d((int **)self->array, self->dims, 0);
+    break;
+  case 3:
+    print_array_i3d((int ***)self->array, self->dims, 0);
+    break;
+  }
+
+  return Py_BuildValue("");  /* return None */
+}
+
+static PyObject *
+CArrayWrap_get_array(CArrayWrap *self)
+{
+  PyObject *nparray;
+  nparray =
+    /* PyArray_New(&PyArray_Type, self->ndim, self->dims, NPY_LONG, NULL, */
+    /* 		(void *)self->data, 0, NPY_CARRAY, (PyObject *)self); */
+    PyArray_SimpleNewFromData( self->ndim, self->dims, NPY_LONG,
+    			       (void *)self->data );
+  if (nparray == NULL){
+    PyErr_SetString( PyExc_RuntimeError, "PyArray_SimpleNewFromData fails");
+    return NULL;
+  }
+  /* Py_INCREF(nparray); */
+
+/* #define CARRAYWRAP_TEST_OWNDATA_FAIL */
+#ifndef CARRAYWRAP_TEST_OWNDATA_FAIL
+  Py_INCREF(self);
+  PyArray_BASE(nparray) = (PyObject *)self;
+#endif
+  return nparray;
+}
+
+static PyMemberDef CArrayWrap_members[] = {
+  {NULL}  /* Sentinel */
+};
+
+static PyGetSetDef CArrayWrap_getseters[] = {
+  {NULL}  /* Sentinel */
+};
+
+static PyMethodDef CArrayWrap_methods[] = {
+  {"print_array",
+   (PyCFunction)CArrayWrap_print_array, METH_VARARGS, "print array"},
+  {"get_array",
+   (PyCFunction)CArrayWrap_get_array, METH_VARARGS, "get array"},
+  {NULL}  /* Sentinel */
+};
+
+static PyTypeObject CArrayWrapType = {
+    PyObject_HEAD_INIT(NULL)
+    0,				/*ob_size*/
+    "CArrayWrap",	/*tp_name*/
+    sizeof(CArrayWrap),		/*tp_basicsize*/
+    0,				/*tp_itemsize*/
+    (destructor)CArrayWrap_dealloc,	/*tp_dealloc*/
+    0,				/*tp_print*/
+    0,				/*tp_getattr*/
+    0,				/*tp_setattr*/
+    0,				/*tp_compare*/
+    0,				/*tp_repr*/
+    0,				/*tp_as_number*/
+    0,				/*tp_as_sequence*/
+    0,				/*tp_as_mapping*/
+    0,				/*tp_hash */
+    0,				/*tp_call*/
+    0,				/*tp_str*/
+    0,				/*tp_getattro*/
+    0,				/*tp_setattro*/
+    0,				/*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,	/*tp_flags*/
+    "CArrayWrap objects",		/* tp_doc */
+    0,				/* tp_traverse */
+    0,				/* tp_clear */
+    0,				/* tp_richcompare */
+    0,				/* tp_weaklistoffset */
+    0,				/* tp_iter */
+    0,				/* tp_iternext */
+    CArrayWrap_methods,		/* tp_methods */
+    CArrayWrap_members,		/* tp_members */
+    CArrayWrap_getseters,		/* tp_getset */
+    0,				/* tp_base */
+    0,				/* tp_dict */
+    0,				/* tp_descr_get */
+    0,				/* tp_descr_set */
+    0,				/* tp_dictoffset */
+    (initproc)CArrayWrap_init,	/* tp_init */
+    0,				/* tp_alloc */
+    CArrayWrap_new,			/* tp_new */
+};
+
+static PyMethodDef module_methods[] = {
+  {NULL}  /* Sentinel */
+};
+
+
+#ifndef PyMODINIT_FUNC	/* declarations for DLL import/export */
+#define PyMODINIT_FUNC void
+#endif
+PyMODINIT_FUNC
+initcarraygetwrap(void)
+{
+  PyObject* m;
+  if (PyType_Ready(&CArrayWrapType) < 0){ return; }
+
+  m = Py_InitModule3( "carraygetwrap", module_methods, "" );
+  if (m == NULL){ return; }
+
+  Py_INCREF(&CArrayWrapType);
+  PyModule_AddObject(m, "CArrayWrap", (PyObject *)&CArrayWrapType);
+  import_array();   /* required NumPy initialization */
+}
+
+static void
+CArrayWrap_dealloc(CArrayWrap* self)
+{
+#ifdef CARRAYWRAP_VERBOSE
+  printf("'%s' called\n", __func__);
+#endif
+  free(self->data);
+  switch(self->ndim){
+  case 2:
+    free(self->array);
+    break;
+  case 3:
+    free(((char **)self->array)[0]);
+    free(self->array);
+    break;
+  }
+  self->ob_type->tp_free((PyObject*)self);
+}
+
+static PyObject *
+CArrayWrap_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+  CArrayWrap *self;
+#ifdef CARRAYWRAP_VERBOSE
+  printf("'%s' called\n", __func__);
+#endif
+  self = (CArrayWrap *)type->tp_alloc(type, 0);
+  if (self == NULL){
+    return NULL;
+  }
+  self->ndim = 0;
+  return (PyObject *)self;
+}
+
+static int
+CArrayWrap_init(CArrayWrap *self, PyObject *args, PyObject *kwds)
+{
+  PyObject *obj;
+  int i, elemnum;
+#ifdef CARRAYWRAP_VERBOSE
+  printf("'%s' called\n", __func__);
+#endif
+
+  if (!PyTuple_Check(args)){
+    PyErr_SetString( PyExc_TypeError, "bad arguments");
+    goto fail;
+  }
+  /* check ndims */
+  self->ndim = PyTuple_Size(args);
+  if (self->ndim > CARRAYWRAP_MAXDIM){
+    PyErr_SetString( PyExc_ValueError, "too many arguments (ndim)");
+    goto fail;
+  }
+  /* set self->dims */
+  elemnum = 1;
+  for (i = 0; i < self->ndim; ++i){
+    obj = PyTuple_GetItem(args, i);
+    if (!PyInt_Check(obj)){
+      PyErr_Format( PyExc_ValueError, "value(%d) is not int", i);
+      goto fail;
+    }
+    self->dims[i] = PyInt_AsLong(obj);
+    if (self->dims[i] < 0){
+      PyErr_Format( PyExc_ValueError,
+		    "cannot get value(%d) or the value is not positive", i);
+      goto fail;
+    }
+    elemnum *= self->dims[i];
+  }
+  /* alloc self->data */
+  self->data = (char *)malloc(elemnum*sizeof(int));
+  if (self->data == NULL){
+    PyErr_SetString( PyExc_RuntimeError, "malloc for data fails");
+    goto fail;
+  }
+  /* set pointer */
+  switch(self->ndim){
+  case 1:
+    self->array = self->data;
+    break;
+  case 2:
+    {
+      int **a2d;
+      a2d = (int**)malloc(self->dims[0]*sizeof(int*));
+      a2d[0] = (int*)self->data;
+      for (i = 1; i < self->dims[0]; i++){
+	a2d[i] = a2d[0] + i * self->dims[1];
+      }
+      self->array = (char*)a2d;
+    }
+    break;
+  case 3:
+    {
+      int ***a3d;
+      int j;
+      a3d = (int***)malloc(self->dims[0]*sizeof(int**));
+      a3d[0] = (int**)malloc(self->dims[0]*self->dims[1]*sizeof(int*));
+      a3d[0][0] = (int*)self->data;
+      for (i = 0; i < self->dims[0]; i++) {
+	a3d[i] = a3d[0] + i * self->dims[1];
+	for (j = 0; j < self->dims[1]; j++){
+	  a3d[i][j] = a3d[0][0]
+	    + i * self->dims[1]*self->dims[2] + j * self->dims[2];
+	}
+      }
+      self->array = (char*)a3d;
+    }
+    break;
+  }
+
+  return 0;
+ fail:
+  free(self->data);
+  self->ndim = 0;
+  return -1;
+}

carraygetwrap/setup.py

+from numpy.distutils.core import setup, Extension
+
+module1 = Extension(
+    'carraygetwrap',
+    sources = ['carraygetwrapmodule.c'],
+    extra_compile_args = ["-fPIC"],
+    ## extra_compile_args = ["-fPIC", "-g", "-traceback"],
+)
+
+setup( ext_modules = [module1] )
+
+# compile: python setup.py build_ext -i -f

carraygetwrap/test_owndata.py

+import numpy
+from carraygetwrap import *
+
+caw = CArrayWrap(2,2)
+a = caw.get_array()
+a.fill(0)
+
+print "print a.flag"
+print a.flags
+print "print a"
+print a
+print "del caw"
+del caw
+print "print a"
+print a
+print "del a"
+del a
+print "done"

carraygetwrap/use_caw.py

+import numpy
+from carraywrap import *
+
+def print_2way(caw):
+    print caw.nparray
+    caw.print_array()
+
+def set_range(caw):
+    caw.nparray[:] = numpy.arange(
+        numpy.prod(caw.nparray.shape)).reshape(caw.nparray.shape)
+
+caw = CArrayWrap(3,3,3)
+
+caw.nparray.fill(0)
+print_2way(caw)
+
+set_range(caw)
+print_2way(caw)
+
+caw = CArrayWrap(3,3)
+
+caw.nparray.fill(0)
+print_2way(caw)
+
+set_range(caw)
+print_2way(caw)
+
+caw = CArrayWrap(3)
+
+caw.nparray.fill(0)
+print_2way(caw)
+
+set_range(caw)
+print_2way(caw)