C (cpp) extension in Python works on one machine but does not on the other -
sorry if question bit vague, , might not appropriate @ stackoverflow, giving shot, maybe have clue reason or give ways test, problem is.
i have c (cpp?) extension works fine on 13.04 lubuntu gcc 4.7.3, python 2.7.4, numpy 1.7.1 not work in 12.04 ubuntu gcc 4.6.3, python 2.7.3, numpy 1.6.1 on machine. seems build/install fine, when try run thing, gives me error:
typeerror: array type 7 didn't match expected type -1
i not want spam build codes, include 2 codes, think main. first cpp file
#define py_array_unique_symbol j_sad_pyarray #include "common/jassert.h" #include "python.h" #include "numpy/arrayobject.h" #include "common/jpythoncommon.h" extern "c" pyobject *sad_correlation(pyobject *self, pyobject *args) { // inputs pyarrayobject *a, *b; // list of coordinates input polygons (2d double numpy array) // parse input arrays *args if (!pyarg_parsetuple(args, "o!o!", &pyarray_type, &a, &pyarray_type, &b)) { pyerr_format(pyerr_newexception((char*)"exceptions.typeerror", null, null), "unable parse array!"); return null; } // expect , b two-dimensional double arrays. // following constructors check requirements jpythonarray2d<double> window1(a); jpythonarray2d<double> window2(b); if (pyerr_occurred()) return null; // always_assert(window1.ndims() == 2); // always_assert(window2.ndims() == 2); if ((window1.ndims() != 2) || (window1.ndims() != 2)) { pyerr_format(pyerr_newexception((char*)"exceptions.typeerror", null, null), "expected 2 2d arrays parameters"); return null; } int maxdx = window2.dims()[0] - window1.dims()[0]; int maxdy = window2.dims()[1] - window1.dims()[1]; // always_assert(maxdx >= 0); // always_assert(maxdy >= 0); if ((maxdx < 0) || (maxdy < 0)) { pyerr_format(pyerr_newexception((char*)"exceptions.typeerror", null, null), "expected second array bigger or equal first array"); return null; } npy_intp output_dims[2] = { maxdx+1, maxdy+1 }; pyarrayobject *result = (pyarrayobject *)pyarray_simplenew(2, output_dims, npy_double); jpythonarray2d<double> resultarray(result); // every possible shift of 'a' relative 'b', calculate sad // printf("array sizes %ldx%ld, %ldx%ld\n", window1.dims()[0], window1.dims()[1], window2.dims()[0], window2.dims()[1]); int w1width = window1.dims()[0]; int w1height = window1.dims()[1]; (int dy = 0; dy <= maxdy; dy++) (int dx = 0; dx <= maxdx; dx++) { int sad = 0; (int y = 0; y < w1height; y++) (int x = 0; x < w1width; x++) { // ***** correct way round? always_assert(window1[0].dims()[0] == window1.dims()[1]); sad += abs(window1[x][y] - window2[x+dx][y+dy]); } resultarray[dx][dy] = sad; // printf("result[%d][%d] = %d\n", dx, dy, sad); } return pyarray_return(result); } /* define methods table module */ static pymethoddef corr_methods[] = { {"sad_correlation", sad_correlation, meth_varargs}, {null,null} }; /* initialisation - register methods python interpreter */ extern "c" void initj_py_sad_correlation(void) { (void) py_initmodule("j_py_sad_correlation", corr_methods); import_array(); }
and .py file:
# run following command: # python setup.py build; python setup.py install # in order compile , install j_py_sad_correlation module j_py_sad_correlation import * import numpy n = n.random.randint(0, 100, (4,4)) b = n.random.randint(0, 100, (4,4)) print print b sad_using_c_code = sad_correlation(a, b) print sad_using_c_code sad_using_python_code = n.zeros((b.shape[0] - a.shape[0] + 1, b.shape[1] - a.shape[1] + 1)) z in range(sad_using_python_code.shape[1]): q in range(sad_using_python_code.shape[0]): sad_using_python_code[q,z] = sum(sum(abs(a - b[q:q+a.shape[0], z:z+a.shape[1]]))) print sad_using_python_code print "success if these values both zero:", (sad_using_python_code - sad_using_c_code).max(), (sad_using_python_code - sad_using_c_code).min()
i unable update gcc on machine (whatever do, end same one), think problem (i.e. gcc version) ? there ways track problem down ?
the part of jpythonarray.h:
template<class type> class jpythonarray1d : public jpythonarray<type> { public: jpythonarray1d(pyarrayobject *init) : jpythonarray<type>(init, 1) { } jpythonarray1d(pyobject *init) : jpythonarray<type>(init, 1) { } jpythonarray1d(type *indata, npy_intp *indims, npy_intp *instrides) : jpythonarray<type>(indata, 1, indims, instrides) { } type &operator[](int i) // note return reference here, can used lvalue, e.g. my1darray[0] = 1.0, or my2darray[0][0] = 1.0; { // printf("access element %d of %d\n", i, jpythonarray<type>::dims[0]); always_assert(i < jpythonarray<type>::dims[0]); return jpythonarray<type>::data[i * jpythonarray<type>::strides[0]]; } type &getindex_canpromote(int i) { // behaves operator[], if have single value in array returns value regardless of // isn't ideal - it's way of working around fact object used initialize array may scalar value if (jpythonarray<type>::dims[0] == 1) return jpythonarray<type>::data[0]; else return operator[](i); } }; template<class type> class jpythonarray2d : public jpythonarray<type> { public: jpythonarray2d(pyarrayobject *init) : jpythonarray<type>(init, 2) { } jpythonarray2d(pyobject *init) : jpythonarray<type>(init, 2) { } jpythonarray2d(type *indata, npy_intp *indims, npy_intp *instrides) : jpythonarray<type>(indata, 2, indims, instrides) { } jpythonarray1d<type> operator[](int i) { // check in range (check against dims[0]) return jpythonarray1d<type>(jpythonarray<type>::data + jpythonarray<type>::strides[0] * i, jpythonarray<type>::dims + 1, jpythonarray<type>::strides + 1); } }; template<class type> class jpythonarray3d : public jpythonarray<type> { public: jpythonarray3d(pyarrayobject *init) : jpythonarray<type>(init, 3) { } jpythonarray3d(pyobject *init) : jpythonarray<type>(init, 3) { } jpythonarray2d<type> operator[](int i) { // check in range (check against dims[0]) return jpythonarray2d<type>(jpythonarray<type>::data + jpythonarray<type>::strides[0] * i, jpythonarray<type>::dims + 1, jpythonarray<type>::strides + 1); } }; template<class type> jpythonarray2d<type> promoteto2d(pyarrayobject *init) { if (pyarray_ndim(init) == 1) { npy_intp dims[2] = { 1, pyarray_dims(init)[0] }; npy_intp strides[2] = { 0, pyarray_strides(init)[0] / sizeof(type) }; return jpythonarray2d<type>((type *)pyarray_data(init), dims, strides); } else { // fail (if example given 3d array), if happens suitable error should reported return jpythonarray2d<type>(init); } }
and full jpythonarray.cpp:
#include "jpythonarray.h" template<> int arraytype<double>(void) { return npy_double; } template<> int arraytype<float>(void) { return npy_float; } template<> int arraytype<int>(void) { return npy_int; }
Comments
Post a Comment