Previous Next Contents

4.6   The master/slave model




#include "pvm3.h"
#define SLAVENAME "slave"

main()
{
  int mytid ;                  /* my task id */
  int tids[32] ;               /* slave task ids */
  int n, nproc, i, who, msgtype ;
  float data[100], result[32] ;
  
  /* enroll in pvm */
  mytid = pvm_mytid () ;

  /* start up slave tasks */
  puts ("How many slave programs (1-32)?") ;
  scanf ("%d", &nproc) ;
  
  pvm_spawn (SLAVENAME, (char**)0, 0, "", nproc, tids) ;
  
  /* Begin User Program */
  n = 100 ;
  /* initialize_data (data, n) ; */
  for (i=0; i<n; i++){
    data[i] = 1 ;
  }
      



  /* Broadcast initial data to slave tasks */
  pvm_initsend (PvmDataDefault) ;
  pvm_pkint (&nproc, 1, 1) ;
  pvm_pkint (tids, nproc, 1) ;
  pvm_pkint (&n, 1, 1) ;
  pvm_pkfloat (data, n, 1) ;
  pvm_mcast (tids, nproc, 0) ;
  
  /* Wait for results from slaves */
  msgtype = 5 ;
  for (i=0; i<nproc; i++){
    pvm_recv (-1, msgtype) ;
    pvm_upkint (&who, 1, 1) ;
    pvm_upkfloat (&result[who], 1, 1) ;
    printf ("I got %f from %d\n", result[who], who) ;
    }
  /* Program Finished exit PVM before stopping */
  pvm_exit () ;
}
      



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

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

  /* Receive data from master */
  msgtype = 0 ;
  pvm_recv (-1, msgtype) ;
  pvm_upkint (&nproc, 1, 1) ; pvm_upkint (tids, nproc, 1) ;
  pvm_upkint (&n, 1, 1) ;     pvm_upkfloat (data, n, 1) ;
  
  /* Determine which slave I am (0 -- nproc-1) */
  for (i=0; i<nproc ; i++)
    if (mytid == tids[i]) { me = i ; break ; }
  
  /* Do calculations with data */
  result = work (me, n, data, tids, nproc) ;
  
  /* Send result to master */
  pvm_initsend (PvmDataDefault) ;
  pvm_pkint (&me, 1, 1) ;  pvm_pkfloat (&result, 1, 1) ;
  msgtype = 5 ;            master = pvm_parent () ;
  pvm_send (master, msgtype) ;
  
  /* Program finished. Exit PVM before stopping */
  pvm_exit () ;
}
      



float work (int me; int n; float *data; int *tids; int nproc)
{
  int i, dest ;
  float psum = 0.0 ;
  float sum = 0.0 ;
  for (i=0  ; i<n  ; i++)
    sum += me * data[i] ;
    
  /* illustrate node-to-node communication */
  pvm_initsend (PvmDataDefault) ;
  pvm_pkfloat (&sum, 1, 1) ;
  dest = me+1 ;
  if (dest == nproc) dest = 0 ;
  pvm_send (tids[dest], 22) ;
  pvm_recv (-1, 22) ;
  pvm_upkfloat (&psum, 1, 1) ;
  
  return (sum+psum) ;
}
      


Previous Next Contents