<< Chapter < Page | Chapter >> Page > |
% cat mast.c
#include<stdio.h>#include "pvm3.h"#define MAXPROC 5
#define JOBS 20main(){
int mytid,info;int tids[MAXPROC];int tid,input,output,answers,work;mytid = pvm_mytid();
info=pvm_spawn("slav", (char**)0, 0, "", MAXPROC, tids);/* Send out the first work */for(work=0;work<MAXPROC;work++) {
pvm_initsend(PvmDataDefault);pvm_pkint(&work, 1, 1 ) ;
pvm_send(tids[work],1) ;/* 1 = msgtype */
}/* Send out the rest of the work requests */work = MAXPROC;
for(answers=0; answers<JOBS ; answers++) {
pvm_recv( -1, 2 ); /* -1 = any task 2 = msgtype */pvm_upkint(&tid, 1, 1 );
pvm_upkint(&input, 1, 1 );
pvm_upkint(&output, 1, 1 );
printf("Thanks to %d 2*%d=%d\n",tid,input,output);pvm_initsend(PvmDataDefault);
if ( work<JOBS ) {
pvm_pkint(&work, 1, 1 ) ;
work++;} else {
input = -1;pvm_pkint(&input, 1, 1 ) ; /* Tell them to stop */
}pvm_send(tid,1) ;
}pvm_exit();}
%
One of the interesting aspects of the PVM interface is the separation of calls to prepare a new message, pack data into the message, and send the message. This is done for several reasons. PVM has the capability to convert between different floating-point formats, byte orderings, and character formats. This also allows a single message to have multiple data items with different types.
The purpose of the message type in each PVM send or receive is to allow the sender to wait for a particular type of message. In this example, we use two message types. Type one is a message from the master to the slave, and type two is the response.
When performing a receive, a process can either wait for a message from a specific process or a message from any process.
In the second phase of the computation, the master waits for a response from any slave, prints the response, and then doles out another work unit to the slave or tells the slave to terminate by sending a message with a value of -1.
The slave code is quite simple — it waits for a message, unpacks it, checks to see if it is a termination message, returns a response, and repeats:
% cat slav.c
#include<stdio.h>#include "pvm3.h"/* A simple program to double integers */
main(){
int mytid;int input,output;
mytid = pvm_mytid();while(1) {pvm_recv( -1, 1 ); /* -1 = any task 1=msgtype */
pvm_upkint(&input, 1, 1);
if ( input == -1 ) break; /* All done */output = input * 2;pvm_initsend( PvmDataDefault );
pvm_pkint(&mytid, 1, 1 );
pvm_pkint(&input, 1, 1 );
pvm_pkint(&output, 1, 1 );
pvm_send( pvm_parent(), 2 );}
pvm_exit();}
%
When the master program is executed, it produces the following output:
% pheat
Thanks to 262204 2*0=0Thanks to 262205 2*1=2
Thanks to 262206 2*2=4Thanks to 262207 2*3=6
Thanks to 262204 2*5=10Thanks to 262205 2*6=12
Thanks to 262206 2*7=14Thanks to 262207 2*8=16
Thanks to 262204 2*9=18Thanks to 262205 2*10=20
Thanks to 262206 2*11=22Thanks to 262207 2*12=24
Thanks to 262205 2*14=28Thanks to 262207 2*16=32
Thanks to 262205 2*17=34Thanks to 262207 2*18=36
Thanks to 262204 2*13=26Thanks to 262205 2*19=38
Thanks to 262206 2*15=30Thanks to 262208 2*4=8
%
Notification Switch
Would you like to follow the 'High performance computing' conversation and receive update notifications?