#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>    
#include <pvm3.h>

#define SLAVENAME "spsum"
#define PROC 10
#define NELEM 1000

main()
  {
  int mytid;                   /* my task id */
  int tids[PROC];              /* slave task ids */
  int n = NELEM;               /* number of data elements */
  int nproc = PROC;            /* number of processes */
  int numt, i, who, msgtype;
  int data[NELEM];             /* data array */
  int result[PROC];            /* array of partial sums from slaves */ 
  int tot = 0;                 /* total sum of data elements */
  char fn[255];                /* array used for path name */
  FILE *fp;                    /* pointer to the input file */
  struct timeval tv1, tv2;      /* for timing */
  int dt1, dt2;                 /* time for one iter */
  int at1, at2;                 /* accum. time */          

  /* Enroll In PVM */
  mytid = pvm_mytid();

  /* Start Slave Tasks */
  numt = pvm_spawn(SLAVENAME, (char**)0, 0, "", nproc, tids);
  if (numt < nproc)
    {
    printf("Trouble spawning slaves. Aborting. Error codes are: \n");
    for (i=numt; i<nproc; i++)
      printf("TID %d %d\n", i, tids[i]);
    for (i=0; i<numt; i++)
      pvm_kill(tids[i]);
    pvm_exit();
    exit(1);
    }

  /* Get Proper Path For Input File */
  strcpy(fn,getenv("HOME"));
  strcat(fn,"/pvm3/src/rand_data.txt");

  /* Open Input File and Initialize Data */
  if ((fp = fopen(fn,"r")) == NULL)
    {
    printf("Can't open the input file: %s\n\n", fn);
    exit(1);
    }
  for (i=0; i<n; i++)
    fscanf(fp,"%d", &data[i]);

 gettimeofday (&tv1, (struct timezone *) 0); /* start of send */

  /* Broadcast Initial Data To Slaves */
  pvm_initsend(PvmDataDefault);
  pvm_pkint(&nproc, 1, 1);
  pvm_pkint(tids, nproc, 1);
  pvm_pkint(&n, 1, 1);
  pvm_pkint(data, n, 1);
  pvm_mcast(tids, nproc, 0);

  






/* Wait For Results From The Slaves */
  msgtype = 5;
  for (i=0; i<nproc; i++)
    {
    pvm_recv(-1, msgtype);
    pvm_upkint(&who, 1, 1);
    pvm_upkint(&result[who], 1, 1);
    printf("I got %d from %d\n", result[who], who);
    }

 gettimeofday (&tv2, (struct timezone *) 0);
    dt1 = (tv2.tv_sec - tv1.tv_sec) * 1000000
      + tv2.tv_usec - tv1.tv_usec;
    printf ("#Data values: %2d Elapsed Time %8d uSec\n", n, dt1);   

  /* Compute The Global Sum */
  for (i=0; i<nproc; i++)
    tot += result[i];
  printf ("Sum: %d.\n\n", tot);

  /* Program Finished. Exit PVM */
  pvm_exit();
  return(0);
  }





