/* A simple MPI example program using buffered 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 buffered send operations (MPI_Ssend)          */

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


#include <stdio.h>
#include "mpi.h"
#define BUFFSIZE 100    /* Size of the message buffer */

main(int argc, char* argv[]) {
  int x, y, np, me;
  int buff[BUFFSIZE];   /* Buffer to be used in the communication */
  int size = BUFFSIZE;
  int tag = 42;
  MPI_Status  status;

  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 */

  MPI_Buffer_attach(buff, size);       /* Create a buffer */

  x = me;

  if (me == 0) {    /* Process 0 does this */
    
    printf("Sending to process 1\n");
    MPI_Bsend(&x, 1, MPI_INT, 1, tag, MPI_COMM_WORLD);  /* Buffered send */
    printf("Receiving from process 1\n");
    MPI_Recv (&y, 1, MPI_INT, 1, tag, MPI_COMM_WORLD, &status);
    printf("Process %d received a message containing value %d\n", me, y);
    
  } else {         /* Process 1 does this */

    /* This program would work even though we changed the order of   */
    /* the send and receive calls here, because the messages are     */
    /* buffered and the processes can continue the execution without */
    /* waiting for the other process to receive the message          */
    MPI_Recv (&y, 1, MPI_INT, 0, tag, MPI_COMM_WORLD, &status);
    MPI_Bsend (&x, 1, MPI_INT, 0, tag, MPI_COMM_WORLD);  /* Buffered send */

  }

  MPI_Buffer_detach(&buff, &size);  /* Detach the buffer */
  MPI_Finalize();
  exit(0);
}

