Trace of Master0.c
Parallel Programming: PVM Program #1

  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

  2. #define SLAVENAME "slave0"
    The spawned task names for this program are all 'slave0.c'

  3. #define MAXTASKS 10 10 tasks will be spawned (each running slave0.c)

  4. 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

  5. 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

  6. msgtype = 99; The programmer defines a label, 99, for the message that is being sent

  7. pvm_initsend(PvmDataDefault); Initialize the buffer to hold the message that is being sent.

  8. pvm_pkint(&num, 1, 1); "Pack" - pk - the number being sent into the message buffer.

  9. 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).

  10. This process is repeated by the for loop 10 times (nproc = 10).

  11. Now wait for the responses from the "slave processes".

  12. msgtype = 55; The programmer defines a new message label (55) for the identifier of the messages
    coming back from the spawned tasks (processes).

  13. 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.

  14. 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'

  15. pvm_upkfloat(&reciprocal, 1, 1); Unpack the value of the reciprocal sent
    in this message. 'Reciprocal' is a reference parameter - &reciprocal
    ('address of' reciprocal)

  16. Slave0.c:

  17. mytid = pvm_mytid(); retrieve the id number of this particular spawned task

  18. 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)

  19. pvm_recv( -1, msgtype ); Receive, with a wild card (-1) a message with the
    correct label, 99

  20. pvm_upkint(&num,1, 1); Unpack the value of the number that is sent in the
    message buffer

  21. Calculate the reciprocal

  22. pvm_initsend( PvmDataDefault ); Initialize the message buffer

  23. pvm_pkint( &mytid, 1, 1 ); Pack the id of this task into this message buffer

  24. pvm_pkfloat( &reciprocal, 1, 1); Pack the value of the reciprocal into this buffer

  25. msgtype = 55; The programmer defines a label identifier (55), this corresponds
    to the one in master0.c

  26. master = pvm_parent(); Obtain the process id tag of master0.c, the "parent" process

  27. 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)

  28. pvm_exit(); IMPORTANT: Exit PVM before stopping this process.

  29. 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