eakyurek
eakyurek

Reputation: 124

MPI_Recv is not blocking

I have a MPI_Isend and MPI_Recv program. Assume that i have 2 processors and both of them are like this.

  1. MPI_Isend
  2. MPI_Recv
  3. MPI_Wait

What i expect from this is sending the data on both processors without blocking. Then wait for the data to come. Then resume, like this.

  1. 0 sends to 1
  2. 1 sends to 0
  3. 0 receives from 1
  4. 1 receives from 0

But what i get is this.

  1. 0 sends to 1
  2. 0 receives from 1 (although 1 didn't send!)
  3. 1 sends to 0 (now it sends)
  4. 1 receives from 0

I thought that MPI_Recv should wait until the data comes. What may be causing this?

Upvotes: 2

Views: 3099

Answers (2)

Spiros
Spiros

Reputation: 2346

What you can do to have kind of an unbuffered output is to perform the output and flush with interleaved MPI_Barrier. Provided you have P processes, the rank of the current process is stored in the variable rank and you are using the communicator comm, you can do:

for (int p = 0; p < P; ++p)
{
    // Only one process writes at this time
    // std::endl flushes the buffer
    if (p == rank)
        std::cout << "Message from process " << rank << std::endl;

    // Block the other processes until the one that is writing
    // flushes the buffer
    MPI_Barrier(comm);
}

Of course this is just a C++ example. You may have to translate it into C of Fortran. Also notice that this code still does not guarantee with 100% probability that the output will actually be what you are expecting, but there are good probabilities.

Anyway, the principle is to always add a barrier between two output operations and to flush the buffer.

Upvotes: 0

ebo
ebo

Reputation: 9215

MPI_Recv does block.

You just do not see the messages in the correct order because standard output is buffered and you do not see all outputs at once.

Upvotes: 1

Related Questions