Parallel Processing Clusters & PVM
by David J. Powers

Example 1: 

Loop n times
{
     spawn child task;
     send message to child;
     receive result from child;    // blocking operation
}


Example 2:
 
Loop n times
{
     // asynchronous (non-blocking) operations
     spawn child task;
     send message to child;
}
Loop n times
{
     // synchronous (blocking) operations
     receive result from child;    
}


Listing One

(a)

#include <stdio.h>
#include <string.h>
#include <time.h>
#include <pvm3.h>

// David J. Powers. This program spawns another 10 tasks, sends a text message
// to each child task, then waits to receive a message from each child task.

void itoa(int n, char w[]);

int main(int argc, char *argv[])
{
    struct tm *p1, *p2;
    time_t     t1, t2;
    int r;      // spawn return code
    int m = 1;  // mesage id
    int PTid;   // parent task id
    int Tid[10]; // array of child task id's
    char mess[100]; // send buffer
    long res;       // result value
    PTid = pvm_mytid();
    printf("P5: Parent id = %d\n",PTid);
    t1 = time(NULL);
    p1 = localtime(&t1);
    printf("P5: Start time: %d:%d:%d \n",p1->tm_hour,p1->tm_min,p1->tm_sec);
        for (int k=0; k<10; k++)
        {
            // spawn child task, p6
                // no argument values, let pvm select host
                // spawn 1 task and save child task id in Tid[k]
                pvm_spawn("p6",NULL,PvmTaskDefault,"",1,&Tid[k]);

            // send message
            itoa(k+27,mess);
            printf("P5:  message:%s: \n",mess);
            pvm_initsend(PvmDataDefault);
            pvm_pkstr(mess);
            pvm_send(Tid[k],m);

            // receive message:  blocking
            pvm_recv(Tid[k],m);
            pvm_upklong(&res,1,1);

            // display result
            printf("P5: k = %d, Fibonacci number = %ld \n",(k+27),res);
        }
    t2 = time(NULL);
    p2 = localtime(&t2);
    printf("P5: Stop  time: %d:%d:%d \n",p2->tm_hour,p2->tm_min,p2->tm_sec);
    printf("P5: Elapsed time = %d seconds. \n",(t2-t1));
    pvm_exit();
    return 0;
}
void itoa(int n, char w[])
{
   int i=0;
    int j, c;
    do
    {
        w[i++] = n % 10 + '0';
    }
    while ( (n /= 10) > 0);
    w[i] = '\0';
    // now reverse the chars
    for (i=0, j = strlen(w) - 1;  i<j;  i++, j--)
    {
        c = w[i];
        w[i] = w[j];
        w[j] = c;
    }
}  // end of itoa

(b)
#include <stdio.h>
#include <stdlib.h>
#include <pvm3.h>

// David J. Powers. This program receives a text message. The ASCII string is 
// converted to an integer value which is used as n in a Fibonacci function.  
// The Fibonacci number is sent back to the calling task.

long fibr(long k);
int main(int argc, char *argv[])
{
    int m=1;         // message id
      int PTid;        // parent task id
      char mess[100];  // send buffer
      int num;         // float value received
      long res;        // result after division
      PTid = pvm_parent();  // get parent task id
      printf("P6: Parent id = %d\n",PTid);

    // receive value:  blocking
    pvm_recv(PTid,m);
    pvm_upkstr(mess);

    // calculate Fibonacci number
    num = atoi(mess);
      res = fibr(num);

    // send results
      pvm_initsend(PvmDataDefault);
    pvm_pklong(&res,1,1);
    pvm_send(PTid,m);

    pvm_exit();
    return 0;
}
// recursive Fibonacci function
long fibr(long k)
{
  if (k==0 || k==1) return k;
  return fibr(k-1) + fibr(k-2);
}



3


