#include <stdio.h>
#include "mpi.h"
int main( argc, argv )
int argc;
char **argv;
{
int rank, size;
MPI_Comm new_comm;
MPI_Init( &argc, &argv );
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
MPI_Comm_split( MPI_COMM_WORLD, rank == 0, 0, &new_comm );
if (rank == 0)
master_io( MPI_COMM_WORLD, new_comm );
else
slave_io( MPI_COMM_WORLD, new_comm );
MPI_Finalize( );
return 0;
}
#define MSG_EXIT 1
#define MSG_PRINT_ORDERED 2
#define MSG_PRINT_UNORDERED 3
/* This is the master */
int master_io( master_comm, comm )
MPI_Comm comm;
{
int i,j, size, nslave, firstmsg;
char buf[256], buf2[256];
MPI_Status status;
MPI_Comm_size( master_comm, &size );
nslave = size - 1;
while (nslave > 0) {
MPI_Recv( buf, 256, MPI_CHAR, MPI_ANY_SOURCE, MPI_ANY_TAG,
master_comm, &status );
switch (status.MPI_TAG) {
case MSG_EXIT: nslave--; break;
case MSG_PRINT_UNORDERED:
fputs( buf, stdout );
break;
case MSG_PRINT_ORDERED:
/* This lets us get any of the ordered messages first, and then
start printing them. There are other ways to do this
(see related exercises) */
firstmsg = status.MPI_SOURCE;
for (i=1; i<size; i++) {
if (i == firstmsg)
fputs( buf, stdout );
else {
MPI_Recv( buf2, 256, MPI_CHAR, i, MSG_PRINT_ORDERED,
master_comm, &status );
fputs( buf2, stdout );
}
}
break;
}
}
return 0;
}
/* This is the slave */
int slave_io( master_comm, comm )
MPI_Comm comm;
{
char buf[256];
int rank;
MPI_Comm_rank( comm, &rank );
sprintf( buf, "Hello from slave %d\n", rank );
MPI_Send( buf, strlen(buf) + 1, MPI_CHAR, 0, MSG_PRINT_ORDERED,
master_comm );
sprintf( buf, "Goodbye from slave %d\n", rank );
MPI_Send( buf, strlen(buf) + 1, MPI_CHAR, 0, MSG_PRINT_ORDERED,
master_comm );
sprintf( buf, "I'm exiting (%d)\n", rank );
MPI_Send( buf, strlen(buf) + 1, MPI_CHAR, 0, MSG_PRINT_UNORDERED,
master_comm );
MPI_Send( buf, 0, MPI_CHAR, 0, MSG_EXIT, master_comm );
return 0;
}