// The Master program will send an integer to the slave and will expect to 
// receive back the reciprocal of that number

#include <stdio.h>
#include "/usr/local/pvm3/include/pvm3.h"
#define SLAVENAME "slave0"
#define MAXTASKS 10

main()
{
    int nproc, numtasks, num, i, who, msgtype, nhost;
    int mytid;                  /* my task id */
    float reciprocal;		/* reciprocal */
    int tids[MAXTASKS];		/* slave task ids */
    struct pvmhostinfo *hostp[MAXTASKS]; /* pointers to host information */

/* Enroll in pvm */
    mytid = pvm_mytid();

/* Set number of slave processes desired */
nproc = MAXTASKS;

/* Start up slave tasks */  

// If the number of tasks spawned does not match nproc, there's a problem!

    numtasks = pvm_spawn(SLAVENAME, (char**)0, 0, "", nproc, tids);

/* Broadcast data to each slave task */
msgtype = 99;

   for (i=0; i < nproc; i++)		// Cycle through all processes
      { num = i;
	pvm_initsend(PvmDataDefault); 	// Get ready to send message buffer
	pvm_pkint(&num, 1, 1);    	// Send Loop Value 
    	pvm_send(tids[num], msgtype);	// Send to identified processor
      }

/* Wait for results from slaves */

    msgtype = 55;  	// This value is arbitrary, just for ID purposes

    for( i=0 ; i < nproc ; i++ )  	// Wait for replies from all processes
      {
    	pvm_recv( -1, msgtype );	// Wait for message of right type
    	pvm_upkint( &who, 1, 1 );	// Find out who sent message
        pvm_upkfloat(&reciprocal, 1, 1);	// Unpack Reciprocal

	// Display results
    	printf("Process:  %d  Reciprocal: %10.6f\n",  who, reciprocal  );  
    }

/* Program Finished - exit PVM before stopping */
    pvm_exit();
}

