Bab
Bab

Reputation: 443

How does MPI blocking send and receive work?

I am reading about MPI blocking send and receive, and there are some things I am not sure of.

While doing some research I found this example (page 6-7) of MPI blocking send and receive

#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
#define  MASTER 0

int main (int argc, char *argv[])
{
  int  numtasks, taskid, len, partner, message;
  char hostname[MPI_MAX_PROCESSOR_NAME];
  MPI_Status status;

  MPI_Init(&argc, &argv);
  MPI_Comm_rank(MPI_COMM_WORLD, &taskid);
  MPI_Comm_size(MPI_COMM_WORLD, &numtasks);

  /* need an even number of tasks  */
  if (numtasks % 2 != 0) {
   if (taskid == MASTER) 
    printf("Quitting. Need an even number of tasks: numtasks=%d\n", numtasks);
  } else {
    if (taskid == MASTER) 
      printf("MASTER: Number of MPI tasks is: %d\n",numtasks);

    MPI_Get_processor_name(hostname, &len);
    printf ("Hello from task %d on %s!\n", taskid, hostname);

    /* determine partner and then send/receive with partner */
    if (taskid < numtasks/2) {
      partner = numtasks/2 + taskid;
      MPI_Send(&taskid, 1, MPI_INT, partner, 1, MPI_COMM_WORLD);
      MPI_Recv(&message, 1, MPI_INT, partner, 1, MPI_COMM_WORLD, &status);
    } else if (taskid >= numtasks/2) {
      partner = taskid - numtasks/2;
      MPI_Recv(&message, 1, MPI_INT, partner, 1, MPI_COMM_WORLD, &status);
      MPI_Send(&taskid, 1, MPI_INT, partner, 1, MPI_COMM_WORLD);
    }

    /* print partner info and exit*/
    printf("Task %d is partner with %d\n",taskid,message);
  }

  MPI_Finalize();
}

Something I am wondering about:

Upvotes: 0

Views: 1321

Answers (1)

Gilles Gouaillardet
Gilles Gouaillardet

Reputation: 8395

If all MPI tasks MPI_Send() and then MPI_Recv(), then it is incorrect with respect to the MPI standard.

The reason is MPI_Send() might block until a matching received is posted, and in your case, that would mean a deadlock.

In order to avoid the deadlock, and hence write a correct program, there are several options :

  • order send and receive (e.g. half send then receive, and the other half receive and then send)
  • use non blocking receive (e.g. all MPI tasks MPI_Irecv(), then MPI_Send() and finally MPI_Wait()
  • use MPI_Sendrecv(), this is the best fit since your program exchanges data between two tasks.

Upvotes: 1

Related Questions