next up previous
Next: The synopsis of Up: Lesson 3 -- Previous: ``Arming'' a program

The listing of fourth.c

 

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include "mpi.h"

int main ( int argc, char **argv )
{
    int pool_size, my_rank, host_rank, destination, source, node_name_length,
        *host_rank_ptr, found_flag, int_buffer[BUFSIZ];
    char char_buffer[BUFSIZ], my_node_name[BUFSIZ], console_name[BUFSIZ],
         host_name[BUFSIZ]; 
    MPI_Status status;
    boolean_t i_am_the_master = B_FALSE; 

#include "preamble.c"

    {

#define COLS 100
#define ROWS 100

        int a[ROWS][COLS], b[ROWS], c[ROWS], i, j;

        if (i_am_the_master) {

           int row, count, sender;

           for (i = 0; i < COLS; i++) {
              b[i] = 1;
              for (j = 0; j < ROWS; j++) a[i][j] = i;
           }

           MPI_Bcast(b, ROWS, MPI_INT, host_rank, MPI_COMM_WORLD);

           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 (i = 0; i < ROWS; i++) {
              MPI_Recv (int_buffer, BUFSIZ, MPI_INT, MPI_ANY_SOURCE, 
                        MPI_ANY_TAG, MPI_COMM_WORLD, &status);
              sender = status.MPI_SOURCE;
              row = status.MPI_TAG;
              c[row] = int_buffer[0];
              printf("\treceived row %d from %d\n", row, sender);
              if (count < ROWS) {
                 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;
              }
              else {
                 MPI_Send(0, 0, MPI_INT, sender, ROWS, MPI_COMM_WORLD);
                 printf("terminated process %d with tag %d\n", sender, ROWS);

                 /*
                  Exercise: why will the master process hang if we use
                  0 instead of ROWS to terminate the slave, as suggested 
                  in the MPI book?
                  */
              }
           }
        }
        else { /* I am not the master */

           int sum, row;
           FILE *log_file;

           log_file = fopen ("/tmp/gustav_log", "w");

           MPI_Bcast(b, COLS, MPI_INT, host_rank, MPI_COMM_WORLD);
           fprintf(log_file, "received broadcast from %d\n", host_rank);
           fflush(log_file);
           MPI_Recv(int_buffer, COLS, MPI_INT, host_rank, MPI_ANY_TAG,
                    MPI_COMM_WORLD, &status);
           fprintf(log_file, "received a message from %d, tag %d\n",
                   status.MPI_SOURCE, status.MPI_TAG);
           fflush(log_file);
           while (status.MPI_TAG != ROWS) { /* The job is not finished */
              row = status.MPI_TAG; sum = 0;
              for (i = 0; i < COLS; i++) sum = sum + int_buffer[i] * b[i];
              int_buffer[0] = sum;
              MPI_Send (int_buffer, 1, MPI_INT, host_rank, row, MPI_COMM_WORLD);
              fprintf(log_file, "sent row %d to %d\n", row, host_rank);
              fflush(log_file);
              MPI_Recv (int_buffer, COLS, MPI_INT, host_rank, MPI_ANY_TAG,
                        MPI_COMM_WORLD, &status);
              fprintf(log_file, "received a message from %d, tag %d\n",
                      status.MPI_SOURCE, status.MPI_TAG);
              fflush(log_file);
           }
           fprintf(log_file, "exiting on  tag %d\n", status.MPI_TAG);
           fflush(log_file);
        }
    }

    MPI_Finalize ();
}



Zdzislaw Meglicki
Tue Feb 28 15:07:51 EST 1995