*** glibc detected *** python: double free or corruption (!prev):
December 2, 2016 at 09:21 #1455
But the strange thing is the problem (as I mentioned in the post #1450) occurs already on C side, not python. When I move data do Accelerator, launch solver, move back data do host and leave the pointers it finds out the only problem is with x. When I print x values right after calling x.LeaveDataPtr(&xptr); then xptr is corrupted which in turn, when leaving C and going back to python, prints out python: free() error.
DamianDecember 3, 2016 at 11:57 #1457
in post #1450 the error is from a python free() call, according to the message you printed.
The x variable is the only place where paralution actually changes the data (unless you do matrix conversions), therefore my guess that it is some python wrapper related problem (which might be caused by different memory address spaces). Could you get rid of all python calls involved and have a pure C check?
NicoDecember 4, 2016 at 16:57 #1458
i found a workaround for this issue, which works for me.
If there is an accelerator available the MoveToAccelerator() method calls CopyFrom()
to copy the ‘host data’ from the host to the accelerator. After that the ‘host data’ is deleted by
this->vector_host_ = NULL;
In case of a LocalVector x, which is created by
x.SetDataPtr(&xptr, “x”, len_x);
xptr points to a buffer which was created by Python before.
Thus x.MoveToAccelerator() triggers free_host() on xptr, so that this python buffer gets destroyed.
As a workaround i copied the MoveToAccelerator() methods in src/base/local_vector.cpp and src/base/local_matrix.cpp to MyMoveToAccelerator() and commented out the delete and the ‘nullification’ line as follows
//this->matrix_host_ = NULL;
what prevents the premature deallocation of the python generated buffers. (‘virtual void MyMoveToAccelerator(void);’ needs to be added to local_vector.hpp and local_matrix.hpp also). Rebuild Paralution.
row_offsets, col, val, xptr and bptr are passed by the python wrapper and point to python allocated buffers.
//initialize Paralution vector/matrix objects
A.SetDataPtrCSR(&row_offsets, &col, &val, “A”, nnz, len_x, len_x);
b.SetDataPtr(&bptr, “b”, len_x);
auto xptr_bak = xptr; //make a backup copy of xptr, because xptr is nullified by x.SetDataPtr()
x.SetDataPtr(&xptr, “x”, len_x);
// use the modified MoveToAccelerator() Method
// set up your solver
CG<LocalMatrix<T>, LocalVector<T>, T> ls;
A.MoveToHost(); // can be omitted if there is an accelerator
b.MoveToHost(); // can be omitted if there is an accelerator
// copy x back to python
// we need the backed up pointer here
x.CopyToData(xptr_bak); // can be omitted if there is no accelerator
// perhaps this could be done by something like ‘x.MyMoveToHost(xptr_bak)’ to avoid double copy actions.
// call LeaveDataPtr* for all!!! objects/buffers that were created by SetDataPtr*
// if there is no accelerator segfaults will occur else.
A.LeaveDataPtrCSR(&row_offsets, &col, &val); // can be omitted if there is an accelerator
b.LeaveDataPtr(&bptr); // can be omitted if there is an accelerator
x.LeaveDataPtr(&xptr); // can be omitted if there is an accelerator
If you set
// Uncomment to define verbose level
#define VERBOSE_LEVEL 4
// Uncomment for debug mode
in ‘src/utils/def.hpp’ and print out the values of row_offsets, col, val, xptr and bptr you can see
what happens in detail…
Kalle.December 5, 2016 at 12:53 #1459
Thank you very, very much for your support. To be honest I was playing with the sources in this context but I skipped it at that time (can’t remember why:)
Anyway the solution you provided works – I can confirm. Thanks!:)
@nico Maybe we could add an extra attribute to MoveToAccelerator method which could be true by default. By setting it to false, though, we wouldn’t delete and set to null the pointer as in Kalle’s solution?
You must be logged in to reply to this topic.