/**************************************************/
/*  PVM Example Program                           */
/*  Multicast with Arrays        slave2.c         */
/*                                                */
/**************************************************/

#include <stdio.h> 
#include "/usr/pvm3/include/pvm3.h"
#define MAXTASKS 10
#define MAXOPERATIONS 8

/* Add up all the values in the specific row in an array */
float add_row(int me, float data[MAXTASKS][MAXOPERATIONS] )
{float sum=0.0;
    int i;
    for( i=0 ; i < MAXOPERATIONS-1 ; i++ ){
       sum += data[me][i];  }
    return( sum );
}

main()
{  int mytid;       /* my task id */
   int tids[MAXTASKS];    /* task ids   */
   int n, me, i, nproc, master, msgtype;
   float data[MAXTASKS][MAXOPERATIONS], result;

    /* enroll in pvm */
       mytid = pvm_mytid();               // Get my processor ID

    /* Receive data from master */
       msgtype = 0;  				// Establish message type to receive
       pvm_recv( -1, msgtype );                 // Get ready to receive initial data
       pvm_upkint(&nproc, 1, 1);                // Unpack number of slave processors
       pvm_upkint(tids, nproc, 1);              // Unpack array of processor IDs
       pvm_upkint(&n, 1, 1);                    // Unpack number of tasks
       pvm_upkfloat(data, MAXTASKS*MAXOPERATIONS, 1); // Unpack data array

    /* Determine which slave I am (0 -- nproc-1) */
    for( i=0; i<nproc ; i++ )
       if( mytid == tids[i] ){ me = i; break; }  // Determine array position

    /* Do calculations with data */
    result = add_row( me, data );

    /* Send result to master */
    pvm_initsend( PvmDataDefault );                    // Get ready to send data
    pvm_pkint( &me, 1, 1 );                      // Pack which processor I am
    pvm_pkfloat( &result, 1, 1 );                // Pack the resultant sum
    msgtype = 5;                          // Identify message type to send
    master = pvm_parent();                       // Find out where I came from
    pvm_send( master, msgtype );                 // Send message back to parent process

    /* Program finished. Exit PVM before stopping */
    pvm_exit();
}

