PI
/* pi.c
*
* Computation of pi by a "montecarlo" method:
* Every process computes a number of points in the unit square
* and returns the number of hits in the quarter circle
* pi is #hits/#total * 4
*
* usage:
* pi [total]
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <mpi.h>
#define TAG_WORK 1
#define TAG_RESULT 2
#define DEFAULT_ANZAHL 10000L /* Defaultwert für Anzahl */
void main(int argc, char *argv[])
{
int myid;
void master(int argc, char *argv[]);
void slave(void);
/* start MPI */
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
if (myid == 0) {
master(argc, argv);
} else {
slave();
}
/* leave MPI */
MPI_Finalize();
}
void master(int argc, char *argv[])
{
long total; /* total number of points */
long mytotal; /* number of points per process */
long myhits; /* number of hits per process */
long totalhits; /* total number of hits */
double pi; /* result */
int nproc; /* number of processes */
MPI_Status status;
int i;
long calc(long total); /* calculation */
/* compute number of points per process */
if (argc != 2) {
total = DEFAULT_ANZAHL;
} else {
total = 1000 * atol(argv[1]);
}
MPI_Comm_size(MPI_COMM_WORLD, &nproc);
mytotal = (long) ceil(total/nproc);
total = nproc * mytotal; /* correct total */
/* send work to all processes */
for (i=1; i<nproc; i++) {
MPI_Send(&mytotal, 1, MPI_LONG, i, TAG_WORK, MPI_COMM_WORLD);
}
/* compute partial results */
myhits = calc(mytotal);
/* combine partial results */
totalhits = myhits;
for (i = 1; i < nproc; i++) {
MPI_Recv(&myhits, 1, MPI_LONG, MPI_ANY_SOURCE, TAG_RESULT,
MPI_COMM_WORLD, &status);
totalhits += myhits;
}
/* compute final result */
pi = totalhits/(double)total*4;
printf("\nPI = %lf\n", pi);
}
void slave(void)
{
long mytotal; /* number of points per process */
long myhits; /* number of hits per process */
MPI_Status status;
long calc(long total); /* calculation */
/* get work from master */
MPI_Recv(&mytotal, 1, MPI_LONG, 0, TAG_WORK, MPI_COMM_WORLD, &status);
/* compute partial results */
myhits = calc(mytotal);
/* send result to master */
MPI_Send(&myhits, 1, MPI_LONG, 0, TAG_RESULT, MPI_COMM_WORLD);
}
#include <sys/types.h>
long calc(long total)
{
/*
* compute total random points in the unit square
* and return the number of hits in the sector (x*x + y*y < 1)
*/
double x, y; /* random coordinates */
long hits = 0; /* number of hits */
long i;
/* initialize random generator (otherwise all return the same result!) */
srand(getpid());
for(i=0; i<total; i++) {
x = ((double) rand())/RAND_MAX;
y = ((double) rand())/RAND_MAX;
if ( x*x + y*y <= 1.0 ) {
hits++;
}
}
return(hits);
}

Peter Junglas 11.5.2000