python - C++ class member function returns PyObject* segmentation fault -
within framework of simulation of biophysical model have c++ class implements model member function needs return pyarrayobject*. class defined in header file ng_networks.h reads like:
#include <stdio.h> #include <math.h> #include <python.h> #include <numpy/arrayobject.h> /* numpy seen c */ struct ngn{...}; /* structure of model parameter */ class ngn_rate{ /* model class */ int neq; ngn pars; double *y,*dy; public: ngn_rate(); // constructor ~ngn_rate(); // destructor pyobject* bifsystem(); } ngn_rate::ngn_rate(){ // set ngn pars default values ... // allocate memory model variables , rhs of equations y = (double*)calloc(neq,sizeof(double)); dy = (double*)calloc(neq,sizeof(double)); } ngn_rate::~ngn_rate{ free(y); free(dy); } pyobject* ngn_rate::bifsystem(){ long int numel = neq; // pyarray creation function requires (long int*) // operations on y,dy ... // build pyobject* dy // create python array object... pyobject* out_array = pyarray_simplenew(1,&numel,npy_double); // ... , make c pointer point double* dy_aux = (double*)((pyarrayobject*)out_array)->data; // copy dy pyobject out_array for(int i=0;i<numel;i++) dy_aux[i] = dy[i]; return out_array; } as may guess class called python module. regard using scipy.weave interface c code python. calling python module looks like:
def ngn_rate_py(): support_code = """ #include <python.h> #include "ng_networks.h" """ source_files = [...] # list of c/cpp source file names libs = ['m'] dirs = [...] # list of #include dirs # c code interface python code = """ //initialize model ngn_rate network(); //return dy_dt return_val = network.bifsystem(); """ vars = [] dy = weave.inline(code, vars, support_code = support_code, sources = source_files, libraries = libs, library_dirs = dirs, include_dirs = dirs, runtime_library_dirs = dirs, type_converters = converters.blitz, compiler = 'gcc', extra_compile_args = ['-std=c++11'], force = 1) return dy when run above module unfortunately produces segmentation fault. after debugging , trial-and-error figured out problem caused reason initialization of pyobject* out_array in ng_networks.h. indeed when create pyobject* in c code in weave works perfectly: modify ngn_rate::bifsystem() class member function returns double* , build pyobject* latter within weave interface:
class ngn_rate{ /* model class */ ... public: ... double* bifsystem(); } double* ngn_rate::bifsystem(){ long int numel = neq; // pyarray creation function requires (long int*) // operations on y,dy ... return dy; } and in weave interface:
def ngn_rate_py(): support_code = """ #include <python.h> #include "ng_networks.h" """ code = """ //initialize model ngn_rate network(); //create temporary dy double *dy = network.bifsystem(); //create pyobject* pyobject* out_array = pyarray_simplenew(1, &numel, npy_double); double* dy_aux = (double*) ((pyarrayobject*) out_array)->data; //assign dy pyobject for(int i=0;i<numel;i++) dy_aux[i]=dy[i]; return_val = out_array; i cannot figure out why above works whereas segmentation fault if make pyobject* returned class. noteworthy in other code had static/non-member c-function returned pyobject* when called weave worked fine. guess there issues pyobject* used within c class object. cannot figure out what. , although can work above code creating pyobject* within weave interface, portability i'd rather have directly provided class ngn_rate.
thanks in advance feedback.
m
a solution segmentation fault - suggested comments - make sure initialize python-c api , numpy array. can done py_initialize() , import_array() macros, opportunely included in constructor of class ngn_rate, i.e.,
#include <python.h> #include <numpy/arrayobject.h> class ngn_rate{ ... public: ngn_rate(); ... }; ngn_rate::ngn_rate{ py_initialize(); import_array(); ... }
Comments
Post a Comment