/* A simple MPI example program using non-blocking send              */
/* The program does exactly the same as code6.c                      */

/* The program consists of one sender process and one receiver       */
/* The sender process sends a message containing its identifier      */
/* to the receiver. This receives the message and sends it back      */
/* Both processes use non-blocking send and receive operations       */
/* (MPI_Isend and MPI_Irecv, and MPI_Wait to wait until the message  */
/* has arrived)                                                      */

/* Compile the program with 'mpicc -o code8 code8.c'                */
/* Run the program with 'mpirun -machinefile hostfile -np 2 code8   */



#include <stdio.h>
#include "mpi.h"

main(int argc, char* argv[]) {
  int x, y, np, me;
  int tag = 42;
  MPI_Status status;
  MPI_Request send_req, recv_req;    /* Request object for send and receive */

  MPI_Init(&argc, &argv);              /* Initialize MPI */
  MPI_Comm_size(MPI_COMM_WORLD, &np);  /* Get number of processes */
  MPI_Comm_rank(MPI_COMM_WORLD, &me);  /* Get own identifier */
  
  x = me;
  if (me == 0) {    /* Process 0 does this */
    
    printf("Process %d sending\n",me);
    MPI_Isend(&x, 1, MPI_INT, 1, tag, MPI_COMM_WORLD, &send_req);
    printf("Process %d receiving\n", me);
    MPI_Irecv (&y, 1, MPI_INT, 1, tag, MPI_COMM_WORLD, &recv_req);
    /* We could do computations here while we are waiting for communication */
    MPI_Wait(&send_req, &status);
    MPI_Wait(&recv_req, &status);
    printf("Process %d received a message containing value %d\n", me, y);    
    
  } else {         

    MPI_Irecv (&y, 1, MPI_INT, 0, tag, MPI_COMM_WORLD, &recv_req);
    MPI_Isend (&x, 1, MPI_INT, 0, tag, MPI_COMM_WORLD, &send_req);
    /* We could do computations here while we are waiting for communication */
    MPI_Wait(&recv_req, &status);
    MPI_Wait(&send_req, &status);

  }

  MPI_Finalize();
  exit(0);
}
