/* L-15 MCS 572 Monday 13 February 2006 : pipelining as a ring.
 * This program illustrates how the processors are aligned in a ring.
 * Compile this program as "mpicc -o pipe_ring pipe_ring.c",
 * and then run on p processors by "mpirun -np p pipe_ring". */

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

#define tag 100  /* tag for sending a number */

int main ( int argc, char *argv[] )
{
   int i,p,n;
   MPI_Status status;

   MPI_Init(&argc,&argv);
   MPI_Comm_size(MPI_COMM_WORLD,&p);
   MPI_Comm_rank(MPI_COMM_WORLD,&i);

   if(i==0) /* manager prompts the user for a number */
   {
      printf("Give a number : "); scanf("%d",&n);
      printf("Manager sends %d to the pipe...\n",n);
      fflush(stdout);
      MPI_Send(&n,1,MPI_INT,1,tag,MPI_COMM_WORLD);
      MPI_Recv(&n,1,MPI_INT,p-1,tag,MPI_COMM_WORLD,&status);
      printf("Manager received %d.\n",n);
   }
   else     /* workers pass the number through the pipe */
   {
      MPI_Recv(&n,1,MPI_INT,i-1,tag,MPI_COMM_WORLD,&status);
      printf("Processor %d receives %d from node %d.\n",i,n,i-1);
      fflush(stdout);
      n *= 2;                      /* double the number */
      if(i < p-1)
         MPI_Send(&n,1,MPI_INT,i+1,tag,MPI_COMM_WORLD);
      else
         MPI_Send(&n,1,MPI_INT,0,tag,MPI_COMM_WORLD);
   }

   MPI_Finalize();
   return 0;
}
