/* L-19 MCS 572 Wednesday 22 February 2006 : prefix_sum
 * We sum the first 8 positive numbers on eight processors in 3 steps.
 * Compile this program as "mpicc -o prefix_sum prefix_sum.c" and
 * run it as "mpirun -np 8 prefix_sum". */

#include <stdio.h>
#include "mpi.h"
#define tag 100         /* tag for send/recv */

int main ( int argc, char *argv[] )
{
   int i,j,nb,b,s;
   MPI_Status status;
   const int p = 8;     /* run for a fixed number of processors: 8 */

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

   nb = i+1;            /* node i holds number i+1 */

   s = 1;               /* shift s will double in every step */

   for(j=0; j<3; j++)   /* 3 stages, as log2(8) = 3 */
   {
      if(i < p - s)     /* every one sends, except last s ones */
         MPI_Send(&nb,1,MPI_INT,i+s,tag,MPI_COMM_WORLD);

      if(i >= s)        /* every one receives, except first s ones */
      {
         MPI_Recv(&b,1,MPI_INT,i-s,tag,MPI_COMM_WORLD,&status);
         nb += b;       /* add received value to current number */
      }
      MPI_Barrier(MPI_COMM_WORLD);  /* synchronize computations */
      if(i < s)
         printf("At step %d, node %d has number %d.\n",j+1,i,nb);
      else
         printf("At step %d, Node %d has number %d = %d + %d.\n",
                j+1,i,nb,nb-b,b);

      fflush(stdout);   /* also interesting without flushing buffers */
      s *= 2;           /* double the shift */
   }
   if(i == p-1) printf("The total sum is %d.\n",nb);

   MPI_Finalize();
   return 0;
}
