#include #include #include #include /* command line configurables */ int Ntrips; /* -t */ int Verbose; /* -v */ int parse_command_line_args(int argc, char **argv, int my_id) { int i; int error; /* default values */ Ntrips = 1; Verbose = 0; for (i = 1, error = 0; !error && i < argc; i ++) { if (!strcmp(argv[i], "-t")) { if (i + 1 < argc && (Ntrips = atoi(argv[i+1])) > 0) i ++; else error = 1; } else if (!strcmp(argv[i], "-v")) Verbose = 1; else error = 1; } /* endfor */ if (error && !my_id) { /* only Master prints usage message */ fprintf(stderr, "\n\tusage: %s {-t } {-v}\n\n", argv[0]); fprintf(stderr, "where\n\n"); fprintf(stderr, "\t-t \t- Number of trips around the ring. " "Default value 1.\n"); fprintf(stderr, "\t-v\t\t- Verbose. Master and all slaves log each step. \n"); fprintf(stderr, "\t\t\t Default value is FALSE.\n\n"); } /* endif */ return error; } /* end parse_command_line_args() */ int main(int argc, char **argv) { int numprocs, my_id, passed_num; int trip; MPI_Status status; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &numprocs); MPI_Comm_rank(MPI_COMM_WORLD, &my_id); if (parse_command_line_args(argc, argv, my_id)) { MPI_Finalize(); exit(1); } /* endif */ if (Verbose) printf("my_id %d numprocs %d\n", my_id, numprocs); if (numprocs > 1) { if (my_id == 0) { /* I am the Master */ passed_num = 0; for (trip = 1; trip <= Ntrips; trip ++) { passed_num ++; if (Verbose) printf("Master: starting trip %d of %d: " "before sending num=%d to dest=%d\n", trip, Ntrips, passed_num, 1); MPI_Send(&passed_num, /* buff */ 1, /* count */ MPI_INT, /* type */ 1, /* dest */ 0, /* tag */ MPI_COMM_WORLD); /* comm */ if (Verbose) printf("Master: inside trip %d of %d: " "before receiving from source=%d\n", trip, Ntrips, numprocs-1); MPI_Recv(&passed_num, /* buff */ 1, /* count */ MPI_INT, /* type */ numprocs-1, /* source */ 0, /* tag */ MPI_COMM_WORLD, /* comm */ &status); /* status */ printf("Master: end of trip %d of %d: " "after receiving passed_num=%d " "(should be =trip*numprocs=%d) from source=%d\n", trip, Ntrips, passed_num, trip*numprocs, numprocs-1); } /* endfor */ } else { /* I am a Slave */ for (trip = 1; trip <= Ntrips; trip ++) { if (Verbose) printf("Slave %d: top of trip %d of %d: " "before receiving from source=%d\n", my_id, trip, Ntrips, my_id-1); MPI_Recv(&passed_num, /* buff */ 1, /* count */ MPI_INT, /* type */ my_id-1, /* source */ 0, /* tag */ MPI_COMM_WORLD, /* comm */ &status); /* status */ if (Verbose) printf("Slave %d: inside trip %d of %d: " "after receiving passed_num=%d from source=%d\n", my_id, trip, Ntrips, passed_num, my_id-1); passed_num ++; if (Verbose) printf("Slave %d: inside trip %d of %d: " "before sending passed_num=%d to dest=%d\n", my_id, trip, Ntrips, passed_num, (my_id+1)%numprocs); MPI_Send(&passed_num, /* buff */ 1, /* count */ MPI_INT, /* type */ (my_id+1)%numprocs, /* dest */ 0, /* tag */ MPI_COMM_WORLD); /* comm */ if (Verbose) printf("Slave %d: bottom of trip %d of %d: " "after send to dest=%d\n", my_id, trip, Ntrips, (my_id+1)%numprocs); } /* endfor */ } /* endif */ } else printf("numprocs = %d, should be run with numprocs > 1\n", numprocs); MPI_Finalize(); exit(0); } /* end main() */