Hello,

thanks for the quick answer. I am sorry that I forgot to mention this: I did compile OpenMPI with MPI_THREAD_MULTIPLE support and test if required == provided after the MPI_Thread_init call.

I do not see any mechanism for protecting the accesses to the requests to a 
single thread? What is the thread model you're using?

Again I am sorry that this was not clear: In the pseudo code below I wanted to indicate the access-protection I do by thread-id dependent calls if(0 == thread-id) and by using the trylock(...) (using pthread-mutexes). In the code all accesses concerning one MPI_Request (which are pthread-global-pointers in my case) are protected and called in sequential order, i.e. MPI_Isend/recv is returns before any thread is allowed to call the corresponding MPI_Test and no-one can call MPI_Test any more when a thread is allowed to call MPI_Wait. I did this in the same manner before with other MPI implementations, but also on the same machine with the same (untouched) OpenMPI implementation, also using pthreads and MPI in combination, but I used

MPI_Request req;

instead of

MPI_Request* req;
(and later)
req = (MPI_Request*)malloc(sizeof(MPI_Request));


In my recent (problem) code, I also tried not using pointers, but got the same problem. Also, as I described in the first mail, I tried everything concerning the memory allocation of the MPI_Request objects. I tried not calling malloc. This I guessed wouldn't work, but the OpenMPI documentation says this:

" Nonblocking calls allocate a communication request object and associate it with the request handle the argument request). " [http://www.open-mpi.org/doc/v1.4/man3/MPI_Isend.3.php] and

" [...] if the communication object was created by a nonblocking send or receive, then it is deallocated and the request handle is set to MPI_REQUEST_NULL." [http://www.open-mpi.org/doc/v1.4/man3/MPI_Test.3.php] and (in slightly different words) [http://www.open-mpi.org/doc/v1.4/man3/MPI_Wait.3.php]

So I thought that it might do some kind of optimized memory stuff internally.

I also tried allocating req (for each used MPI_Request) once before the first use and deallocation after the last use (which I thought was the way it was supposed to work), but that crashes also.

I tried replacing the pointers through global variables

MPI_Request req;

which didn't do the job...

The only thing that seems to work is what I mentioned below: Allocate every time I am going to need it in the MPI_Isend/recv, use it in MPI_Test/Wait and after that deallocate it by hand each time. I don't think that this is supposed to be like this since I have to do a call to malloc and free so often (for multiple MPI_Request objects in each iteration) that it will most likely limit performance...

Anyway I still have the same problem and am still unclear on what kind of memory allocation I should be doing for the MPI_Requests. Is there anything else (besides MPI_THREAD_MULTIPLE support, thread access control, sequential order of MPI_Isend/recv, MPI_Test and MPI_Wait for one MPI_Request object) I need to take care of? If not, what could I do to find the source of my problem?

Thanks again for any kind of help!

Kind regards,
David



> From an implementation perspective, your code is correct only if you 
initialize the MPI library with MPI_THREAD_MULTIPLE and if the library accepts. 
Otherwise, there is an assumption that the application is single threaded, or that 
the MPI behavior is implementation dependent. Please read the MPI standard 
regarding to MPI_Init_thread for more details.

Regards,
   george.

On May 19, 2011, at 02:34 , David Büttner wrote:

Hello,

I am working on a hybrid MPI (OpenMPI 1.4.3) and Pthread code. I am using 
MPI_Isend and MPI_Irecv for communication and MPI_Test/MPI_Wait to check if it 
is done. I do this repeatedly in the outer loop of my code. The MPI_Test is 
used in the inner loop to check if some function can be called which depends on 
the received data.
The program regularly crashed (only when not using printf...) and after 
debugging it I figured out the following problem:

In MPI_Isend I have an invalid read of memory. I fixed the problem with not 
re-using a

MPI_Request req_s, req_r;

but by using

MPI_Request* req_s;
MPI_Request* req_r

and re-allocating them before the MPI_Isend/recv.

The documentation says, that in MPI_Wait and MPI_Test (if successful) the 
request-objects are deallocated and set to MPI_REQUEST_NULL.
It also says, that in MPI_Isend and MPI_Irecv, it allocates the Objects and 
associates it with the request object.

As I understand this, this either means I can use a pointer to MPI_Request 
which I don't have to initialize for this (it doesn't work but crashes), or 
that I can use a MPI_Request pointer which I have initialized with 
malloc(sizeof(MPI_REQUEST)) (or passing the address of a MPI_Request req), 
which is set and unset in the functions. But this version crashes, too.
What works is using a pointer, which I allocate before the MPI_Isend/recv and 
which I free after MPI_Wait in every iteration. In other words: It only uses if 
I don't reuse any kind of MPI_Request. Only if I recreate one every time.

Is this, what is should be like? I believe that a reuse of the memory would be 
a lot more efficient (less calls to malloc...). Am I missing something here? Or 
am I doing something wrong?


Let me provide some more detailed information about my problem:

I am running the program on a 30 node infiniband cluster. Each node has 4 single 
core Opteron CPUs. I am running 1 MPI Rank per node and 4 threads per rank (->  
one thread per core).
I am compiling with mpicc of OpenMPI using gcc below.
Some pseudo-code of the program can be found at the end of this e-mail.

I was able to reproduce the problem using different amount of nodes and even 
using one node only. The problem does not arise when I put printf-debugging 
information into the code. This pointed me into the direction that I have some 
memory problem, where some write accesses some memory it is not supposed to.
I ran the tests using valgrind with --leak-check=full and --show-reachable=yes, 
which pointed me either to MPI_Isend or MPI_Wait depending on whether I had the 
threads spin in a loop for MPI_Test to return success or used MPI_Wait 
respectively.

I would appreciate your help with this. Am I missing something important here? 
Is there a way to re-use the request in the different iterations other than I 
thought it should work?
Or is there a way to re-initialize the allocated memory before the 
MPI_Isend/recv so that I at least don't have to call free and malloc each time?

Thank you very much for your help!
Kind regards,
David Büttner

_____________________
Pseudo-Code of program:

MPI_Request* req_s;
MPI_Request* req_w;
OUTER-LOOP
    if(0 == threadid)
    {
        req_s = malloc(sizeof(MPI_Request));
        req_r = malloc(sizeof(MPI_Request));
        MPI_Isend(..., req_s)
        MPI_Irecv(..., req_r)
    }
    pthread_barrier
    INNER-LOOP (while NOT_DONE or RET)
        if(TRYLOCK&&  NOT_DONE)
        {
            if(MPI_TEST(req_r))
            {
                    Call_Function_A;
                    NOT_DONE = 0;
            }

        }
        RET =  Call_Function_B;
    }
    pthread_barrier_wait
    if(0 == threadid)
    {
        MPI_WAIT(req_s)
        MPI_WAIT(req_r)
        free(req_s);
        free(req_r);
    }
_____________


--
David Büttner, Informatik, Technische Universität München
TUM I-10 - FMI 01.06.059 - Tel. 089 / 289-17676

_______________________________________________
users mailing list
us...@open-mpi.org
http://www.open-mpi.org/mailman/listinfo.cgi/users
"To preserve the freedom of the human mind then and freedom of the press, every 
spirit should be ready to devote itself to martyrdom; for as long as we may think as we 
will, and speak as we think, the condition of man will proceed in improvement."
   -- Thomas Jefferson, 1799


_______________________________________________
users mailing list
us...@open-mpi.org
http://www.open-mpi.org/mailman/listinfo.cgi/users

--
David Büttner, Informatik, Technische Universität München
TUM I-10 - FMI 01.06.059 - Tel. 089 / 289-17676

Reply via email to