next up previous index
Next: The Slave Program Up: Bank Queue Previous: Bank Queue

The Master Program

The first thing that the master process does is to initialize vector b and matrix A. Vector b is set to 1and matrix A is set to Aij = i:

      for (i = 0; i < COLS; i++) {
         b[i] = 1;
         for (j = 0; j < ROWS; j++) a[i][j] = i;
      }
Then the master process broadcasts b to all processes (including itself):
      MPI_Bcast(b, ROWS, MPI_INT, MASTER_RANK, MPI_COMM_WORLD);
Now the master process initializes the counter, count, which is going to be used to number rows sent to the slave processes, and send the first batch of jobs to all slave processes. In this program the master does not participate in the computation, so it does not send a job to itself:
      count = 0;
      for (destination = 0; destination < pool_size; destination++) {
         if (destination != my_rank) {
            for (j = 0; j < COLS; j++) int_buffer[j] = a[count][j];
            MPI_Send(int_buffer, COLS, MPI_INT, destination, count,
                     MPI_COMM_WORLD);
            printf("sent row %d to %d\n", count, destination);
            count = count + 1;
         }
      }
For clarity, I have made the master process transfer a row from A to a send buffer called int_buffer, and then send the data to the slave process. The data could be sent directly from matrix A, which would be faster, but then you would have to remember how C stores matrices (it stores them in a row-major fashion, so this would actually work in this program).

Observe also that I have used count in place of the message tag. The slave processes, as you will see later, will use the tag number associated with the message in order to figure out, which particular row of matrix Athey are about to work with. Now, the slaves don't really have to know that, but the master does. So when the slave sends the answer back to the master, it will use the same tag number, to remind the master process about the row number that the answer corresponds to.

Every time a matrix row is sent to a slave process, the master process logs it on standard output.

The following for loop is the tricky part of the master program. The master process waits for a message to arrive, from any process, and from any source: how is the master process to know, which slave process is going to be the first with an answer. Some may be slower and busier than others depending on what else runs on their CPUs.

Once a message has arrived, the master process checks where the message has come from by inspecting the status structure associated with the message:

         sender = status.MPI_SOURCE;
and inspects the tag number of the message, so that it is reminded about the row number that the answer relates to:
         row = status.MPI_TAG;
The answer itself is then placed in an appropriate slot of vector c:
         c[row] = int_buffer[0];
and the whole operation logged on standard output:
         printf("\treceived row %d from %d\n", row, sender);

Now the master process has to respond to the slave process that was so kind to deliver the answer. The master process checks if there is still any work left:

         if (count < ROWS) {
            blah... blah... blah...
         }
         else {
            MPI_Send(NULL, 0, MPI_INT, sender, ROWS, MPI_COMM_WORLD);
            printf("terminated process %d with tag %d\n", sender, ROWS);
         }
and if there isn't, it sends a null message to the slave process in question, whose tag is ROWS, and logs it on standard output.

Now, in C arrays are numbered from 0 through $\hbox{length} - 1$, and all processes know that matrix A has ROWS rows, numbered from 0 through $\hbox{{\tt ROWS}} - 1$. So if the tag of the message is ROWS the slave process is going to know that something's amiss. As a matter of fact it will know that this is a termination message, so it will go away and terminate itself.

If there is still some work left though, then the master process transfers the corresponding row of matrix A to its send buffer, int_buffer, and sends its content to the slave process that has just delivered the answer. This operation is again logged on standard output, and the counter, that counts how many rows of matrix A have been sent out so far, is incremented by 1:

            for (j = 0; j < COLS; j++) int_buffer[j] = a[count][j];
            MPI_Send(int_buffer, COLS, MPI_INT, sender, count,
                     MPI_COMM_WORLD);
            printf("sent row %d to %d\n", count, sender);
            count = count + 1;

After the master process has collected answers to all problems that it sent to the slave processes, there is nothing else left for it to do, so it hits MPI_Finalize() and terminates itself together with all the slaves that by now should have been waiting for her at the barrier.

They jump off the cliff together.


next up previous index
Next: The Slave Program Up: Bank Queue Previous: Bank Queue
Zdzislaw Meglicki
2001-02-26