[Numpy-discussion] Problem with using PyArray_AsCArray
Ng, Enrico
enrico.ng at lmco.com
Fri Dec 9 14:25:43 EST 2011
I am trying to pass a multi-dimensional ndarray to C as a multi-dimensional C array for the purposes of passing it to mathematica. I am using PyArray_AsCArray but getting an error.
######################################################
Python Code:
import Image
from scipy.misc import fromimage
img = Image.open("../APLS/image709_enhanced_2.tif")
nimg = fromimage(img)
...
mathlink_PutIntegerArray(nimg)
######################################################################
C Wrapper Code:
static PyObject * mathlink_PutIntegerArray(mathlink_Link *self, PyObject *args)
{
npy_intp dims[3]; /* PyArray_AsCArray is for ndim <= 3 */
PyObject *o1;
double *d1;
long result;
i=PyArray_AsCArray(&o1, (void *)&d1, dims, PyArray_NDIM(o1), PyArray_DescrFromType(PyArray_TYPE(o1)));
...
}
Program received signal SIGSEGV, Segmentation fault.
0x00002aaaaefa3d2e in PyArray_AsCArray (op=0x7fffffffdf68, ptr=0x7fffffffdf60,
dims=0x7fffffffdf40, nd=3, typedescr=<value optimized out>)
at numpy/core/src/multiarray/multiarraymodule.c:218
218 ptr3[i][j] = ap->data + i*ap->strides[0] + j*ap->strides[1]
#################################################################################
I am able to read i,j,ap->data, ap->strides[0], ap->strides[1] so the error seems to be in the assignment to ptr3[i][j]
This happens on the first instance i=0 j=0
#################################################################################
PyArray_AsCArray code is below.
NPY_NO_EXPORT int
PyArray_AsCArray(PyObject **op, void *ptr, npy_intp *dims, int nd,
PyArray_Descr* typedescr)
{
PyArrayObject *ap;
npy_intp n, m, i, j;
char **ptr2;
char ***ptr3;
if ((nd < 1) || (nd > 3)) {
PyErr_SetString(PyExc_ValueError,
"C arrays of only 1-3 dimensions available");
Py_XDECREF(typedescr);
return -1;
}
if ((ap = (PyArrayObject*)PyArray_FromAny(*op, typedescr, nd, nd,
CARRAY, NULL)) == NULL) {
return -1;
}
switch(nd) {
case 1:
*((char **)ptr) = ap->data;
break;
case 2:
n = ap->dimensions[0];
ptr2 = (char **)_pya_malloc(n * sizeof(char *));
if (!ptr2) {
goto fail;
}
for (i = 0; i < n; i++) {
ptr2[i] = ap->data + i*ap->strides[0];
}
*((char ***)ptr) = ptr2;
break;
case 3:
n = ap->dimensions[0];
m = ap->dimensions[1];
ptr3 = (char ***)_pya_malloc(n*(m+1) * sizeof(char *));
if (!ptr3) {
goto fail;
}
for (i = 0; i < n; i++) {
ptr3[i] = ptr3[n + (m-1)*i];
for (j = 0; j < m; j++) {
ptr3[i][j] = ap->data + i*ap->strides[0] + j*ap->strides[1];
}
}
*((char ****)ptr) = ptr3;
}
memcpy(dims, ap->dimensions, nd*sizeof(npy_intp));
*op = (PyObject *)ap;
return 0;
fail:
PyErr_SetString(PyExc_MemoryError, "no memory");
return -1;
}
More information about the NumPy-Discussion
mailing list