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;
}

My Supercomp front page.
This page was created by Gary Sivek for 7th Period Supercomp.