Commits

Anonymous committed 240749d

getsetcarray

Comments (0)

Files changed (4)

 syntax: glob
 build/
 convsrc/*.c
+getsetcarray/*.c

getsetcarray/getsetcarraymodule.c.src

+/* -*- c -*- */
+#include <Python.h>
+#include "structmember.h"
+#include <numpy/arrayobject.h>
+
+#define GETSETCARRAY_VERBOSE
+#ifdef GETSETCARRAY_VERBOSE
+#define GETSETCARRAY_DEBUGFUNCCALL \
+  printf("'%s' called\n", __func__)
+#else
+#define GETSETCARRAY_DEBUGFUNCCALL
+#endif
+
+typedef struct getsetcarray_{
+  PyObject_HEAD
+  PyObject *np1d, *np2d, *np3d;
+  int *i1d, **i2d, ***i3d;
+} GetSetCArray;
+
+/* -------------------- int 1D array -------------------- */
+static void i1d_dealloc(int *i1d)
+{
+  GETSETCARRAY_DEBUGFUNCCALL;
+  return;
+}
+
+static int i1d_new(int *i1d, PyObject *np1d)
+{
+  GETSETCARRAY_DEBUGFUNCCALL;
+  i1d = (int*)PyArray_DATA(np1d);
+  return 0;
+}
+
+static int i1d_check_pointer(int *i1d, PyObject *np1d)
+{
+  int i,*dims;
+  GETSETCARRAY_DEBUGFUNCCALL;
+
+  dims = PyArray_DIMS(np1d);
+  for (i = 0; i < dims[0]; ++i){
+    printf("%d", i);
+    if (PyArray_GETPTR1(np1d,i) != (void*)&i1d[i]){
+      return -1;
+    }
+  }
+  return 0;
+}
+
+/* -------------------- int 2D array -------------------- */
+static void i2d_dealloc(int **i2d)
+{
+  GETSETCARRAY_DEBUGFUNCCALL;
+  free(i2d);
+  return;
+}
+
+static int i2d_new(int **i2d, PyObject *np2d)
+{
+  int i,*dims;
+  GETSETCARRAY_DEBUGFUNCCALL;
+
+  dims = PyArray_DIMS(np2d);
+  i2d = (int**)malloc(dims[0]*sizeof(int*));
+  if (i2d == NULL){
+    return -1;
+  }
+
+  i2d[0] = (int*)PyArray_DATA(np2d);
+  for (i = 1; i < dims[0]; i++){
+    i2d[i] = i2d[0] + i * dims[1];
+  }
+  return 0;
+}
+
+static int i2d_check_pointer(int **i2d, PyObject *np2d)
+{
+  int i,j,*dims;
+  GETSETCARRAY_DEBUGFUNCCALL;
+
+  dims = PyArray_DIMS(np2d);
+  for (i = 0; i < dims[0]; ++i){
+    for (j = 0; j < dims[1]; ++j){
+      if (PyArray_GETPTR2(np2d,i,j) != (void*)&i2d[i][j]){
+	return -1;
+      }
+    }
+  }
+  return 0;
+}
+
+/* -------------------- int 3D array -------------------- */
+static void i3d_dealloc(int ***i3d)
+{
+  GETSETCARRAY_DEBUGFUNCCALL;
+  free(i3d[0]);
+  free(i3d);
+  return;
+}
+
+static int i3d_new(int ***i3d, PyObject *np3d)
+{
+  int i,j,*dims;
+  GETSETCARRAY_DEBUGFUNCCALL;
+
+  dims = PyArray_DIMS(np3d);
+  i3d = (int***)malloc(dims[0]*sizeof(int**));
+  if (i3d == NULL){
+    return -1;
+  }
+
+  i3d[0] = (int**)malloc(dims[0]*dims[1]*sizeof(int*));
+  if (i3d[0] == NULL){
+    free(i3d);
+    return -1;
+  }
+
+  i3d[0][0] = (int*)PyArray_DATA(np3d);
+  for (i = 0; i < dims[0]; i++) {
+    i3d[i] = i3d[0] + i * dims[1];
+    for (j = 0; j < dims[1]; j++){
+      i3d[i][j] = i3d[0][0] + i * dims[1]*dims[2] + j * dims[2];
+    }
+  }
+  return 0;
+}
+
+static int i3d_check_pointer(int ***i3d, PyObject *np3d)
+{
+  int i,j,k,*dims;
+  GETSETCARRAY_DEBUGFUNCCALL;
+
+  dims = PyArray_DIMS(np3d);
+  for (i = 0; i < dims[0]; ++i){
+    for (j = 0; j < dims[1]; ++j){
+      for (k = 0; k < dims[2]; ++k){
+	if (PyArray_GETPTR3(np3d,i,j,k) != (void*)&i3d[i][j][k]){
+	  return -1;
+	}
+      }
+    }
+  }
+  return 0;
+}
+
+/* -------------------- GetSetCArray -------------------- */
+static void
+GetSetCArray_dealloc(GetSetCArray* self)
+{
+  GETSETCARRAY_DEBUGFUNCCALL;
+  Py_XDECREF(self->np1d);
+  Py_XDECREF(self->np2d);
+  Py_XDECREF(self->np3d);
+  i1d_dealloc(self->i1d);
+  i2d_dealloc(self->i2d);
+  i3d_dealloc(self->i3d);
+  self->ob_type->tp_free((PyObject*)self);
+}
+
+static PyObject *
+GetSetCArray_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+  GetSetCArray *self;
+  GETSETCARRAY_DEBUGFUNCCALL;
+
+  self = (GetSetCArray *)type->tp_alloc(type, 0);
+  if (self == NULL){
+    return NULL;
+  }
+  self->i1d = NULL;
+  self->i2d = NULL;
+  self->i3d = NULL;
+  self->np1d = NULL;
+  self->np2d = NULL;
+  self->np3d = NULL;
+
+  return (PyObject *)self;
+}
+
+static int
+GetSetCArray_init(GetSetCArray *self, PyObject *args, PyObject *kwds)
+{
+  GETSETCARRAY_DEBUGFUNCCALL;
+  return 0;
+}
+
+/* -------------------- getter and setter -------------------- */
+
+/**begin repeat
+   #ndim=1,2,3#
+*/
+static PyObject *
+GetSetCArray_getter_np@ndim@d(GetSetCArray *self, void *closure)
+{
+  if (self->np@ndim@d == NULL){
+    return Py_BuildValue("");
+  }
+  Py_INCREF(self->np@ndim@d);
+  return self->np@ndim@d;
+}
+
+static int
+GetSetCArray_setter_np@ndim@d(GetSetCArray *self, PyObject *value, 
+			      void *closure)
+{
+  if (value == NULL) {
+    PyErr_SetString( PyExc_TypeError,"Cannot delete this attribute");
+    return -1;
+  }
+  if ( PyArray_Check(value) != 1 ){
+    PyErr_SetString( PyExc_ValueError,"got non-numpy array object");
+    return -1;
+  }
+  if ( PyArray_NDIM(value) != @ndim@ ){
+    PyErr_Format( PyExc_ValueError, "ndim(=%d) should be @ndim@",
+		  PyArray_NDIM(value));
+    return -1;
+  }
+  if ( PyArray_TYPE(value) != NPY_LONG ){
+    PyErr_SetString( PyExc_ValueError, "array dtype is not numpy.int" );
+    return -1;
+  }
+  if (i@ndim@d_new(self->i@ndim@d, value) < 0){
+    PyErr_SetString( PyExc_RuntimeError, "fail while preparing c array" );
+    return -1;
+  }
+  if (i@ndim@d_check_pointer(self->i@ndim@d, value) < 0){
+    PyErr_SetString( PyExc_RuntimeError, "fail while checking pointer" );
+    return -1;
+  }
+
+  Py_DECREF(self->np@ndim@d);
+  Py_INCREF(value);
+  self->np@ndim@d = (PyObject *) value;
+  return 0;
+}
+/**end repeat**/
+
+
+static PyMemberDef GetSetCArray_members[] = {
+  {NULL}  /* Sentinel */
+};
+
+static PyGetSetDef GetSetCArray_getseters[] = {
+/**begin repeat
+   #ndim=1,2,3#
+*/
+  {"np@ndim@d", 
+   (getter)GetSetCArray_getter_np@ndim@d,
+   (setter)GetSetCArray_setter_np@ndim@d,
+   "@ndim@-dim numpy-c array interface",
+   NULL},
+/**end repeat**/
+  {NULL}  /* Sentinel */
+};
+
+static PyMethodDef GetSetCArray_methods[] = {
+  {NULL}  /* Sentinel */
+};
+
+static PyTypeObject GetSetCArrayType = {
+    PyObject_HEAD_INIT(NULL)
+    0,				/*ob_size*/
+    "GetSetCArray",	/*tp_name*/
+    sizeof(GetSetCArray),		/*tp_basicsize*/
+    0,				/*tp_itemsize*/
+    (destructor)GetSetCArray_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*/
+    "GetSetCArray objects",		/* tp_doc */
+    0,				/* tp_traverse */
+    0,				/* tp_clear */
+    0,				/* tp_richcompare */
+    0,				/* tp_weaklistoffset */
+    0,				/* tp_iter */
+    0,				/* tp_iternext */
+    GetSetCArray_methods,		/* tp_methods */
+    GetSetCArray_members,		/* tp_members */
+    GetSetCArray_getseters,		/* tp_getset */
+    0,				/* tp_base */
+    0,				/* tp_dict */
+    0,				/* tp_descr_get */
+    0,				/* tp_descr_set */
+    0,				/* tp_dictoffset */
+    (initproc)GetSetCArray_init,	/* tp_init */
+    0,				/* tp_alloc */
+    GetSetCArray_new,			/* tp_new */
+};
+
+static PyMethodDef module_methods[] = {
+  {NULL}  /* Sentinel */
+};
+
+
+#ifndef PyMODINIT_FUNC	/* declarations for DLL import/export */
+#define PyMODINIT_FUNC void
+#endif
+PyMODINIT_FUNC
+initgetsetcarray(void)
+{
+  PyObject* m;
+  if (PyType_Ready(&GetSetCArrayType) < 0){ return; }
+
+  m = Py_InitModule3( "getsetcarray", module_methods, "" );
+  if (m == NULL){ return; }
+
+  Py_INCREF(&GetSetCArrayType);
+  PyModule_AddObject(m, "GetSetCArray", (PyObject *)&GetSetCArrayType);
+  import_array();   /* required NumPy initialization */
+}

getsetcarray/setup.py

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

getsetcarray/test_getset.py

+from getsetcarray import *
+import numpy
+
+gs = GetSetCArray()
+
+gs.np1d = numpy.arange(5)
+gs.np2d = numpy.arange(4).reshape(2,2)
+gs.np3d = numpy.arange(8).reshape(2,2,2)