#include#define WORKTAG 1#define DIETAG 2/* Local functions */static void master(void);static void slave(void);static unit_of_work_t get_next_work_item(void);static void process_results(unit_result_t result);static unit_result_t do_work(unit_of_work_t work);intmain(int argc, char **argv){ int myrank; /* Initialize MPI */ MPI_Init(&argc, &argv); /* Find out my identity in the default communicator */ MPI_Comm_rank(MPI_COMM_WORLD, &myrank); if (myrank == 0) { master(); } else { slave(); } /* Shut down MPI */ MPI_Finalize(); return 0;}static voidmaster(void){ int ntasks, rank; unit_of_work_t work; unit_result_t result; MPI_Status status; /* Find out how many processes there are in the default communicator */ MPI_Comm_size(MPI_COMM_WORLD, &ntasks); /* Seed the slaves; send one unit of work to each slave. */ for (rank = 1; rank < ntasks; ++rank) { /* Find the next item of work to do */ work = get_next_work_item(); /* Send it to each rank */ MPI_Send(&work, /* message buffer */ 1, /* one data item */ MPI_INT, /* data item is an integer */ rank, /* destination process rank */ WORKTAG, /* user chosen message tag */ MPI_COMM_WORLD); /* default communicator */ } /* Loop over getting new work requests until there is no more work to be done */ work = get_next_work_item(); while (work != NULL) { /* Receive results from a slave */ MPI_Recv(&result, /* message buffer */ 1, /* one data item */ MPI_DOUBLE, /* of type double real */ MPI_ANY_SOURCE, /* receive from any sender */ MPI_ANY_TAG, /* any type of message */ MPI_COMM_WORLD, /* default communicator */ &status); /* info about the received message */ /* Send the slave a new work unit */ MPI_Send(&work, /* message buffer */ 1, /* one data item */ MPI_INT, /* data item is an integer */ status.MPI_SOURCE, /* to who we just received from */ WORKTAG, /* user chosen message tag */ MPI_COMM_WORLD); /* default communicator */ /* Get the next unit of work to be done */ work = get_next_work_item(); } /* There's no more work to be done, so receive all the outstanding results from the slaves. */ for (rank = 1; rank < ntasks; ++rank) { MPI_Recv(&result, 1, MPI_DOUBLE, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status); } /* Tell all the slaves to exit by sending an empty message with the DIETAG. */ for (rank = 1; rank < ntasks; ++rank) { MPI_Send(0, 0, MPI_INT, rank, DIETAG, MPI_COMM_WORLD); }}static void slave(void){ unit_of_work_t work; unit_result_t results; MPI_Status status; while (1) { /* Receive a message from the master */ MPI_Recv(&work, 1, MPI_INT, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &status); /* Check the tag of the received message. */ if (status.MPI_TAG == DIETAG) { return; } /* Do the work */ result = do_work(work); /* Send the result back */ MPI_Send(&result, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD); }}static unit_of_work_t get_next_work_item(void){ /* Fill in with whatever is relevant to obtain a new unit of work suitable to be given to a slave. */}static void process_results(unit_result_t result){ /* Fill in with whatever is relevant to process the results returned by the slave */}static unit_result_tdo_work(unit_of_work_t work){ /* Fill in with whatever is necessary to process the work and generate a result */}