// 
// Torbert, 8.20.2008
// 
// MPI Demo, Version 1.0
// 
//   Input: size of communication group and hostlist provided to mpirun
// Process: each worker makes a bogus calculation and reports it to the manager
//  Output: manager prints each worker's rank, total size and their result
// 
// Manager-Worker model for parallel processing.
// 

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

int main(int argc, char* argv[])
{
	int						rank,size;
	MPI_Status				status;  // status used later in asynchronous send-recv
	int						k,tag=0; // we don't use the tag
	double					y;

	MPI_Init(&argc,&argv);        // boilerplate
	MPI_Comm_size(MPI_COMM_WORLD,&size);
	MPI_Comm_rank(MPI_COMM_WORLD,&rank);

	if(rank==0)            // MANAGER
	{
		for(k=1;k<size;k++)        // could use MPI_ANY_SOURCE
		{
			MPI_Recv(&y,1,MPI_DOUBLE,k,tag,MPI_COMM_WORLD,&status);
			printf("\n%d %d %20.16f\n\n",k,size,y);
		}
	}
	else                   // WORKER
	{
		y=cos(M_PI*rank/size);
		MPI_Send(&y,1,MPI_DOUBLE,0,tag,MPI_COMM_WORLD);
	}

	MPI_Finalize();               // boilerplate

	return 0;
}

// 
// Notes
// -----
// mpicc -lm mpi_demo_0.c
// mpirun -np 4 -machinefile hosts.txt a.out
//
// Leave off machinefile option to use automatic file:
//    mpirun -np 4 a.out
// 
