From: edu <mog...@gm...> - 2007-07-10 18:19:53
|
I cannot reproduce the segfaults with that you report > with the latest Easdif (version 1.3.1) > which you find in cvs and with swig 1.3.31. Both methods work > perfectly for me under linux and the sample script test.py > that you can find in the swig/python directory. > > What os are you working with? > Hi. I'm using linux->debian/sid, Easdif 1.3.0, using SWIG 1.3.31. I will try 1.3.31 and see if I still get the segfaults. I can confirm that the problem is from SWIG because accessing directly the library with python/ctypes works ok. > > > Also, in order to read the matrix more efficiently in python, I > > > implemented small helper functions in sdif_matrix.cpp to read a whole > > > matrix into a python array.. > > what would that look like? If it could be of general use I > could put it into the official source. > Here are the extra functions to access matrices either as a whole or the rows/cols. The caller is responsible for allocating and deallocating the array. On the python side, the arrays are actually numpy arrays of the desired type (no need to deallocate anything). The caller is also responsible for sending an array of the right size. In the SWIG interface file this should be implemented to use numpy arrays (not normal lists, which is what SWIG does by default). I found it a bit troublesome to get the typemaps work correctly in SWIG and on the profiling I did, the ctypes module in python is in fact more efficient than SWIG, but of course it would be more elegant to have all done with SWIG, as it is much easier to maintain. The python module sdiflib is a wrapper on eaSDIF to make it still easier to read / write sdifs. Insbesondere it uses a double implementation which allows to iterate through the data as: import sdiflib entity = sdiflib.Entity('mysdif.sdif' [,selection=':1TRC/1TRC']) for frame in entity: for matrix in frame: data = matrix() # data is now a numpy array holding the whole matrix or for frame in entity: matrix = frame[0] # do something with matrix and also entity(t, y) -> returns an interpolation of matrix at y of the frames before and after t This is only useful if wanting to access a specific part of the data. matrices having the same size are buffered on the python side so for sdifs like 1GB0 allocation is done only once. The caller is responsible to copy the data if needed. here are the added functions (only interface code actually): extern "C" void Matrix_GetRow_double(Easdif::SDIFMatrix* matrix, int irow, double* out) { matrix->mInter->GetRow(&(out[0]), irow); } extern "C" void Matrix_GetCol_double(Easdif::SDIFMatrix* matrix, int icol, double* out) { matrix->mInter->GetCol(&(out[0]), icol); } extern "C" void Matrix_GetRows_double(Easdif::SDIFMatrix* matrix, int row0, int row1, double* out) { for (int row = row0; row < row1; row++) { matrix->mInter->GetRow(&(out[row]), row); } } extern "C" void Matrix_GetRow_int(Easdif::SDIFMatrix* matrix, int irow, int* out) { matrix->mInter->GetRow(&(out[0]), irow); } extern "C" void Matrix_GetCol_int(Easdif::SDIFMatrix * matrix, int icol, int * out) { matrix->mInter->GetCol(&(out[0]), icol); } extern "C" void Matrix_GetRows_int(Easdif::SDIFMatrix * matrix, int row0, int row1, int * out) { for (int row = row0; row < row1; row++) { matrix->mInter->GetRow(&(out[row]), row); } } extern "C" void Matrix_GetRow_float(Easdif::SDIFMatrix * matrix, int irow, float * out) { matrix->mInter->GetRow(&(out[0]), irow); } extern "C" void Matrix_GetCol_float(Easdif::SDIFMatrix * matrix, int icol, float * out) { matrix->mInter->GetCol(&(out[0]), icol); } extern "C" void Matrix_GetRows_float(Easdif::SDIFMatrix * matrix, int row0, int row1, float * out) { for (int row = row0; row < row1; row++) { matrix->mInter->GetRow(&(out[row]), row); } } extern "C" int Matrix_GetNbRows(Easdif::SDIFMatrix * matrix) { return matrix->GetNbRows(); } extern "C" int Matrix_GetNbCols(Easdif::SDIFMatrix * matrix) { return matrix->GetNbCols(); } extern "C" void Matrix_SetRows_double(Easdif::SDIFMatrix * matrix, double * in, int nrows) { int num_cols = matrix->GetNbCols(); for (int row = 0; row < nrows; row++) { matrix->mInter->SetRow(&(in[row * num_cols]),row); } } extern "C" void Matrix_SetRows_float(Easdif::SDIFMatrix * matrix, float * in, int nrows) { int num_cols = matrix->GetNbCols(); for (int row = 0; row < nrows; row++) { matrix->mInter->SetRow(&(in[row * num_cols]),row); } } extern "C" void Matrix_SetRows_int(Easdif::SDIFMatrix * matrix, int * in, int nrows) { int num_cols = matrix->GetNbCols(); for (int row = 0; row < nrows; row++) { matrix->mInter->SetRow(&(in[row * num_cols]),row); } } extern "C" void Matrix_SetRow_int(Easdif::SDIFMatrix * matrix, int irow, int * in) { matrix->mInter->SetRow(&(in[0]), irow); } extern "C" void Matrix_SetRow_float(Easdif::SDIFMatrix * matrix, int irow, float * in) { matrix->mInter->SetRow(&(in[0]), irow); } extern "C" void Matrix_SetRow_double(Easdif::SDIFMatrix * matrix, int irow, double * in) { matrix->mInter->SetRow(&(in[0]), irow); } |