Trace of Master0.c
Parallel Programming: PVM Program #1
- SIMD model: Single instruction set (single process) and Multiple Data
There is one 'task' program - slave0.c - that operates on multiple data.
(the other type of parallel program is MIMD - multiple instruction sets,
processors,
and multiple data
- #define SLAVENAME "slave0"
The spawned task names for this program are all 'slave0.c'
- #define MAXTASKS 10 10 tasks will be spawned (each running slave0.c)
- int tids[MAXTASKS] Each of the spawned tasks will have an id (tid task
id)
The array 'tids' will store the ids of all of the spawned tasks
- numtasks = pvm_spawn(SLAVENAME, (char**)0, 0, "", nproc, tids);
Explanation: This command, pvm_spawn, spawns a task by running the program
SLAVENAME (slave0).
'nproc' is the number of tasks spawned.
'tids' is the array of task ids that is returned after successful spawning
of these tasks.
If these tasks are spawned correctly, this function returns the number of
correctly
spawned tasks (nproc). numtasks should be the same as nprocs
- msgtype = 99; The programmer defines a label, 99, for the message that is
being sent
- pvm_initsend(PvmDataDefault); Initialize the buffer to hold the message
that is being sent.
- pvm_pkint(&num, 1, 1); "Pack" - pk - the number being sent into the
message buffer.
- pvm_send(tids[num], msgtype) Send the message buffer with this number to
the task id specified in tids[num] (one of the tasks created in pvm_spawn)
Also send the message identifier tag, msgtype (99).
- This process is repeated by the for loop 10 times (nproc = 10).
- Now wait for the responses from the "slave processes".
- msgtype = 55; The programmer defines a new message label (55) for the identifier of the
messages
coming back from the spawned tasks (processes).
- pvm_recv( -1, msgtype ); Wait for a message with the correct label (55).
The '-1' is a wild card, receives any messages, and then checks the label.
- pvm_upkint( &who, 1, 1 ); unpack the message.
'who' is the process id of the sending 'slave'
'who' is a reference parameter in C, &who = 'address of who'
- pvm_upkfloat(&reciprocal, 1, 1); Unpack the value of the reciprocal sent
in this message. 'Reciprocal' is a reference parameter - &reciprocal
('address of' reciprocal)
- Slave0.c:
- mytid = pvm_mytid(); retrieve the id number of this particular spawned
task
- msgtype = 99; The programmer defines a message label - 99 for this message
buffer that is being received. (this corresponds to the one in master0.c)
- pvm_recv( -1, msgtype ); Receive, with a wild card (-1) a message with the
correct label, 99
- pvm_upkint(&num,1, 1); Unpack the value of the number that is sent in the
message buffer
- Calculate the reciprocal
- pvm_initsend( PvmDataDefault ); Initialize the message buffer
- pvm_pkint( &mytid, 1, 1 ); Pack the id of this task into this message
buffer
- pvm_pkfloat( &reciprocal, 1, 1); Pack the value of the reciprocal into this
buffer
- msgtype = 55; The programmer defines a label identifier (55), this
corresponds
to the one in master0.c
- master = pvm_parent(); Obtain the process id tag of master0.c, the "parent"
process
- pvm_send( master, msgtype ); Send the message buffer to this process id
tag of the parent. Also send the message identifying tag (55 in this case)
- pvm_exit(); IMPORTANT: Exit PVM before stopping this process.
- Sample output:
Process: 786448 Reciprocal: 0.250000
Process: 262167 Reciprocal: 0.142857
Process: 262168 Reciprocal: 0.125000
Process: 786449 Reciprocal: 0.200000
Process: 524309 Reciprocal: 0.000000
Process: 786450 Reciprocal: 0.166667
Process: 524310 Reciprocal: 1.000000
Process: 524311 Reciprocal: 0.500000
Process: 524312 Reciprocal: 0.333333
Process: 262169 Reciprocal: 0.111111