Go Back
// This program uses Gregory's Formula to calculate pi. Gregory's Formula
// combines the convergent series for the arctangent of a number and the
// fact the 4atan(1)=pi to calculate it. The exact formula used is:
// pi = 4/1 - 4/3 + 4/5 - 4/7 + 4/9 - 4/11 + ...
// The formula converges really slowly, though...
#include <stdio.h>
#include "/usr/local/pvm3/include/pvm3.h"
#define SLAVENAME "slavepvm"
#define MAXTASKS 10
#define MAXTASKSINC (MAXTASKS+1)
unsigned long NUMITERATIONS = 1E9;
int main()
{
int nproc, numtasks, num, i, who, msgtype;
int mytid;
double tempsum, sum = 0;
int tids[MAXTASKS];
unsigned long starts[MAXTASKSINC];
unsigned long first, last;
printf("This program calculates pi by using the painfully slow");
printf(" Gregory's Formula:\n pi = 4atan(1)\nIt calculates half a");
printf(" billion iterations and still only gets 9 digits\nright,");
printf(" but hey, if we're gonna use PVM we might as well do");
printf(" something slow.\n\n");
// Enroll in PVM
mytid = pvm_mytid();
// Set number of slave processes desired
nproc = MAXTASKS;
// Start up slave tasks
// Spawn slave tasks
numtasks = pvm_spawn(SLAVENAME, (char**)0, 0, "", nproc, tids);
// Initialize ranges for each slave to compute
for (i = 0; i < nproc; i++)
starts[i] = (long)i * (NUMITERATIONS / (long)nproc) + 1;
starts[nproc] = NUMITERATIONS+1;
// Send data to each slave
msgtype = 314;
// Cycle through all the processes
for (i = 0; i < nproc; i++)
{
num = i;
first = starts[i];
last = starts[i+1];
// Send number of task ID and first and last values in the range
pvm_initsend(PvmDataDefault);
pvm_pkint(&num, 1, 1);
pvm_pklong(&first, 1, 1);
pvm_pklong(&last, 1, 1);
pvm_send(tids[num], msgtype);
}
// Get results from slaves
msgtype = 2718;
// Get results from all machines
for(i = 0 ; i < nproc ; i++ )
{
// Get machine task ID and partial sum
pvm_recv(-1, msgtype);
pvm_upkint(&who, 1, 1);
pvm_upkdouble(&tempsum, 1, 1);
// Display results
first = starts[who]; last = starts[who+1]-1;
// Print partial sum info
printf("First: %10d, Last: %11d; Partial Sum: %1.10lf\n",
first, last, tempsum );
// Add partial sum to the total sum
sum += tempsum;
}
// Print final approximation of pi
printf("\nPi is approximately %1.10lf\n", sum);
// Exit PVM, then exit the program
pvm_exit();
return 0;
}