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

const double PI = 3.14;                        /* value for broadcast */

int main(int argc, char* argv[]) {
   
   int i, myrank, nproz;
   int neighbourID_le, neighbourID_ri;
   int recv_neighbourID_le, recv_neighbourID_ri;
   double pi; 
   MPI_Status status;


   MPI_Init( &argc, &argv );                    /* start n processes           */
   MPI_Comm_size( MPI_COMM_WORLD, &nproz );     /* ask for number of processes */
   MPI_Comm_rank( MPI_COMM_WORLD, &myrank );    /* ask for local ID            */

   printf("Process %2d of %2d\n", myrank, nproz);


   /* determine the neighbourhood */

   if ( 0 < myrank )
      neighbourID_le = myrank - 1;
   else 
      neighbourID_le = MPI_PROC_NULL;             /* no neighbour */

   if ( (nproz - 1) > myrank )
      neighbourID_ri = myrank + 1; 
   else
      neighbourID_ri = MPI_PROC_NULL;             /* no neighbour */

   
   /* broadcast pi from process 0 to all others */

   if ( 0 == myrank )
      pi = PI;
   else
      pi = 0.0;

   printf("Proz %2d : Before broadcast pi = %e\n", myrank, pi);

   MPI_Bcast( &pi, 1,MPI_DOUBLE, 0, MPI_COMM_WORLD );

   printf("Proz %2d : After broadcast pi = %e\n", myrank, pi);   


   /* send the own process ID to the left/right neighbour,      */
   /* ID of a non-existing neighbour is the value MPI_PROC_NULL  */

   MPI_Send( &myrank, 1, MPI_INT, neighbourID_le, 1, MPI_COMM_WORLD );
   MPI_Recv( &recv_neighbourID_ri, 1, MPI_INT, neighbourID_ri, 1, 
             MPI_COMM_WORLD, &status );

   if ( MPI_PROC_NULL != neighbourID_ri )
      printf("Proz %2d : ID right neighbour = %2d\n", myrank, recv_neighbourID_ri);
   else
      printf("Proz %2d : ID right neighbour = MPI_PROC_NULL\n", myrank);

   MPI_Send( &myrank, 1, MPI_INT, neighbourID_ri, 2, MPI_COMM_WORLD );
   MPI_Recv( &recv_neighbourID_le, 1, MPI_INT, neighbourID_le, 2,
             MPI_COMM_WORLD, &status );

   if ( MPI_PROC_NULL != neighbourID_le )
      printf("Proz %2d : ID left neighbour = %2d\n", myrank, recv_neighbourID_le);
   else
      printf("Proz %2d : ID left neighbour = MPI_PROC_NULL\n", myrank);
  
 
   fflush(stdout);                       /* write all output */
   fflush(stderr);			
   MPI_Barrier( MPI_COMM_WORLD );        /* synchronise all processes */
   MPI_Finalize();                       /* finish MPI */
 
   return 0;
}

