/*----------------------------------------------------------------*/
 Brought To You By CToHTML 
http://www.cs.washington.edu/homes/zahorjan/homepage/Tools/index.htm
 
/*----------------------------------------------------------------*/

/* MPI program that uses a monte carlo method to compute the value of PI */
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <mpi.h>
#define USE_MPI   
#define SEED 35791246

main(int argc, char *argv[])
{
    int niter=0;
    double x,y;
    int i,j,count=0,mycount,mpi_error; 
    double z;
    double pi;
    int myid,numprocs,proc,namelen;
    MPI_Status status;
    int master =0;
    int tag = 123;             
    char processor_name[MPI_MAX_PROCESSOR_NAME];


    MPI_Init(&argc,&argv);
    MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
    MPI_Comm_rank(MPI_COMM_WORLD,&myid);
    MPI_Get_processor_name(processor_name,&namelen);
    if (myid == 0) {
        printf("How many iterations do you want each process to do?\n ");
        fflush(stdout);

        scanf("%d",&niter);
    }
    MPI_Bcast(&niter, 1, MPI_INT, 0, MPI_COMM_WORLD);

    /* initialize random numbers */
    srand(SEED+123*myid);
    /*Just make up a different seed for each process they might not be independent.*/
    mycount=0;
    for ( i=0; i<niter; i++) {
        x = (double)rand()/RAND_MAX;
        y = (double)rand()/RAND_MAX;
        z = x*x+y*y;
        if (z<=1) mycount++;
    }

    if (myid ==0) { /* if I am the master process gather results from others */
        count=mycount;
        printf("Process %d running on processor %s sending hit count= %d to master process\n",myid,processor_name,mycount );
        for (proc=1; proc<numprocs; proc++) {
            MPI_Recv(&mycount,1,MPI_REAL,proc,tag,MPI_COMM_WORLD,&status);
            count +=mycount;        
        }
        pi=(double)count/(niter*numprocs)*4;
        printf("\n # of trials= %d , estimate of pi is %.16f \n",niter*numprocs,pi);
    } else { /* for all the slave processes send results to the master */
        printf("Process %d running on processor %s sending hit count= %d to master process\n",myid,processor_name,mycount );
        MPI_Send(&mycount,1,MPI_REAL,master,tag,MPI_COMM_WORLD);
    }

    mpi_error=MPI_Finalize();
    if (MPI_SUCCESS!=mpi_error)
        return mpi_error;
    else
        return 0;
}