*** glibc detected *** python: double free or corruption (!prev):

Front page Forums General *** glibc detected *** python: double free or corruption (!prev):

This topic contains 18 replies, has 3 voices, and was last updated by  damian1976 1 year ago.

Viewing 15 posts - 1 through 15 (of 19 total)
  • Author
    Posts
  • #1438

    damian1976
    Member

    Hi everybody,
    I’m new to this forum and recently started to work with Paralution.
    I have a python software from which I need to call C function where I, in turn, call gmres iterative solver. I use SWIG to generate appropriate wrapper . C function works well until I call Paralutiob piece of code:

    LocalMatrix<double> A;
    A.SetDataPtrCSR(&row_offsets, &col, &val, “A matrix”, nnz, ncols, nrows);
    in my case.
    All pointers (row_offsets, col, val) and values ( nnz, ncols, nrows) are corretly set and passed from python.
    When leaving C function I get glibc detected *** python: double free or corruption (!prev): error

    Do you know why is it happening?

    Regards,
    Damian

    #1439

    nico
    Participant

    Hi Damian,

    this looks like you are trying to free memory which has been free’d already. Please keep in mind, that the SetDataPtr functions do not copy any data. If you set them to a PARALUTION structure, the initial pointers will be nullified.

    Best
    Nico

    #1440

    damian1976
    Member

    Hi Nico,
    Thank you for the clarification. Really, there is a small note on this fact in documentation:) I missed it.
    Anyway, How correclty pass the buffers (from python to paralution in this case) not allocating memory again.
    I would like to avoid the case where I create buffers in Python first, then I (re)create them as LocalMatrix/Vector (which in turn creates new memory buffer) and finally copy the data from (python’s) buffer to Paralution’s buffers.
    Let’s say (in the simplest case) from python I call C function as shown below (code has been shortened to clarify the case):

    //Python code
    //declarations and allocations of buffers

    A_row_offsets = …
    A_col = …
    A_val = …
    array_1d_double = npct.ndpointer(dtype=np.float64, ndim=1, flags=’CONTIGUOUS’)
    array_1d_int = npct.ndpointer(dtype=c_int, ndim=1, flags=’CONTIGUOUS’)
    libp = npct.load_library(“mylib”, “.”)
    # setup the return types and argument types
    libp.my_func.restype = None
    libp.my_func.argtypes = [array_1d_int, c_int, array_1d_int, c_int, array_1d_double, c_int, c_int,c_int,c ]
    libp.my_func(A_row_offsets, len(A_row_offsets), A_col, len(A_col), A_val, len(A_val), nrows, ncols, nnz)

    //C/Paralution Code
    void my_func(int* row_offsets, int n1, int* col, int n2, double* val, nt n4, int nrows, int ncols, int nnz){

    LocalMatrix<double> A;
    A.AllocateCSR(“A”, nnz, nrows, ncols) ;
    A.CopyFromCSR(row_offsets, col, val) ;
    }

    The above doubles buffers where first have been created in python and now they are recreated in Paralutions what halfes the size of available memory.
    Is there other simple way to use python’s buffers in Paralution (I thought A.SetDataPtrCSR(&row_offsets, &col, &val, “A matrix”, nnz, ncols, nrows); will do this job but this is wrong because, when returning to python, I get the exception due to reasons you mentioned)

    regards,
    Damian

    #1441

    nico
    Participant

    Hi Damian,

    you can use the LeaveDataPtr functions to extract the PARALUTION structure pointers (this will nullify the PARALUTION object). However, in case you are using different matrix formats, make sure to convert it back before leaving the data pointers back to your python code.
    Please have a look at the user manual page 34.

    Best
    Nico

    • This reply was modified 1 year ago by  nico.
    #1443

    damian1976
    Member

    Hi Nico,
    I’ve seen this already but it looks like it doesn’t work for me.
    What I would like to gain is :
    1/allocate necessary input/output memory buffers in python
    2/ work on these bufferes in paralution
    3/ exit paralution with data inside output buffer

    More or less it would look like (assuming all buffers: rows, col, val, x_ptr, b_ptr are allocated in python):

    LocalMatrix<double> A;
    LocalVector<double> b;
    LocalVector<double> x;

    //And now: how to get data into A & b without memory allocation ?
    A.SetDataPtrCSR(&row_offsets, &col, &val, “A”, nnz, ncols, nrows); //row_offsets && col && val are now nullified
    b.SetDataPtr(&b_ptr, “b”, b_len); //b_ptr is nullified



    ls.Solve(b, &x);

    A.LeaveDataPtrCSR(&row_offsets , &col , &val ) ; // get back the pointers to python’s buffers
    x.LeaveDataPtr(&xptr);// get the output python’s buffer

    Will that work? if not what will be the correct solution

    To be honest I still don’t get how to get input data into Matrix A and buffer b without additional memory allocation/copying.

    Best
    Damian

    #1444

    damian1976
    Member

    Just to add to what I wrote myself before.
    With

    x.SetDataPtr(&xptr, “x”, nrows);

    when setting pointers it looks like it works for host. In other words this is the solution to my problem. Am I right?

    I’ve read the notes on Page 35, and what I understand from that, especially from “If the object is moved to and from the accelerator then the original pointer will be invalid.” is that if I set the data pointers with SetDataPtrCSR & SetDataPtr and then move A,b & x to accelerator then at the and LeaveDataPtr(CSR) will not work? I will get data corruption . If so, how to use SetDataPtr* functions along with moving data to accelerator there and back at the same time without memory problems?

    Damian

    #1445

    damian1976
    Member

    So if I want use python’s buffers in GPU accelerato I need
    1. create Paralution object
    2. Move it to accelerator
    3. create memory there
    4. copy data from pointer to gpu buffer
    5. At the end copy the data back to output buffer pointer
    6. clear all paralution objects

    In other words calculations using solver is different for host from calculaions for gpu(s). In first case we can use SeDataPtr* functions. In the second one – no.
    Is the above correct?

    I would be grateful for the explanasions:)

    Thanx again,
    Damian

    #1446

    nico
    Participant

    Hi Damian,

    if you move the paralution objects to the accelerator, the host buffers will be free’d. The SetDataPtr and LeaveDataPtr functions will always expect/deliver the pointers on the current backend of the object you are calling it. If you want to leave the pointers back to the host system, you will have to move the paralution object back to host before leaving the data pointers.
    You do not have to copy any data using the Set/LeaveDataPtr functions.

    Best
    Nico

    #1447

    damian1976
    Member

    Hi, so in general of I want to do computations on GPU using SetDataPtr* I should :
    1/create paralution objects
    2/call setvDataPtr* for all objects/passed from put on buffers
    3/move them to accelerator
    4/do computations
    5/movetohost
    6/call LeaveDataPtr for all objects /buffers

    Is the above (order) ok?
    Regards,
    Damian
    Is the Computing done on all (e. g. 2)GPus done by default when datthey are moved there or only on one of them?

    #1448

    nico
    Participant

    Hi Damian,

    yes, correct.
    The free GPL version of PARALUTION is limited to 1 GPU.

    Best
    Nico

    #1449

    damian1976
    Member

    Thank you Nico for the clarification! :)
    With regards to your last post – did you mean 1GPU per node or 1GPU in total? :)
    BTW – is there any gmres multinode example available?…

    Best
    Damian

    #1450

    damian1976
    Member

    Hi Nico,
    In addition to my last post/question and doing computations on GPU I tried the following:

    /* MATRIX A*/
    A.SetDataPtrCSR(&row_offsets, &col, &val, “A”, nnz, ncols, nrows);
    A.MoveToAccelerator();
    A.info();
    /* VECTOR B*/
    b.SetDataPtr(&bptr, “b”, nrows);
    b.MoveToAccelerator();
    b.info();
    /* VECTOR X */
    x.SetDataPtr(&xptr, “x”, nrows);
    x.MoveToAccelerator();
    x.info();

    ls.Solve(b, &x);
    A.MoveToHost();
    b.MoveToHost();
    x.MoveToHost();
    A.LeaveDataPtrCSR(&row_offsets ,&col, &val ) ;
    x.LeaveDataPtr(&xptr);
    b.LeaveDataPtr(&bptr);

    The above causes
    *** glibc detected *** python: free(): invalid pointer: 0x00000000028a4a40 ***
    in python

    If I only comment out all MoveToAccelerator(); methods calls everything is ok…

    Regards,
    Damian

    #1451

    nico
    Participant

    Hi Damian,

    the free GPL version of PARALUTION does neither support multi node nor multi GPU.
    I do not know how the python C++ interface looks like. Maybe there are some issues when moving to the GPU. Could you verify that all pointers data are correct after leaving them?

    Best
    Nico

    #1452

    damian1976
    Member

    Hi Nico,

    Sorry for late reply I was busy ith other stuff in the meantime. I double checked it.
    After solver execution and
    A.MoveToHost();
    b.MoveToHost();
    x.MoveToHost();
    A.LeaveDataPtrCSR(&row_offsets ,&col, &val ) ;
    x.LeaveDataPtr(&xptr);
    b.LeaveDataPtr(&bptr);

    row_offsets, &col, &val, bptr are okayand x is corrupted.
    The corruption happends only when I first move data to accelerator and at the end move the data back to host to get their pointers as in the above example. When I do all on CPU everything is okay….

    Best,
    Damian

    #1454

    nico
    Participant

    Hi Damian,

    mhm interesting. Maybe there is some issues with changing addresses of the pointers within the python wrapper you are using? Is the invalid free only with respect to the x pointer? Can you free all other memory?

    Best
    Nico

Viewing 15 posts - 1 through 15 (of 19 total)

You must be logged in to reply to this topic.