#include #include /* command line configurables */ int Ntrips; /* -t */ int Verbose; /* -v */ int Reverse; /* -r */ int Alternate; /* -a */ int parse_command_line_args(int argc, char **argv, int my_id) { int i; int error; /* default values */ Ntrips = 10000; Verbose = 0; Reverse = 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], "-a")) Alternate = 1; else if (!strcmp(argv[i], "-r")) Reverse = 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 } {-r} {-a} {-v}\n\n", argv[0]); fprintf(stderr, "where\n\n"); fprintf(stderr, "\t-v \t- Number of trips around the ring. " "Default value 1.\n"); fprintf(stderr, "\t-r\t\t- Reverse direction. By default first trip's direction" " is 0->1->2 etc. '-r' reverses direction.\n"); fprintf(stderr, "\t-a\t\t- Alternate direction. When ntrips > 1 alternate the" "direction of each trip. Default is no alternate.\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() */ main(int argc, char **argv) { int numprocs, my_id, passed_num; int trip; int dest_f, src_f; int dest_r, src_r; int *dest, *src; 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) { dest_f = src_r = (my_id+1) % numprocs; src_f = dest_r = (my_id ? my_id-1 : numprocs-1); dest = (Reverse ? &dest_r : &dest_f); src = (Reverse ? &src_r : &src_f); 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, *dest); MPI_Send(&passed_num, /* buff */ 1, /* count */ MPI_INT, /* type */ *dest, /* dest */ 0, /* tag */ MPI_COMM_WORLD); /* comm */ if (Verbose) printf("Master: inside trip %d of %d: before receiving " "from source=%d\n", trip, Ntrips, *src); MPI_Recv(&passed_num, /* buff */ 1, /* count */ MPI_INT, /* type */ *src, /* source */ 0, /* tag */ MPI_COMM_WORLD, /* comm */ &status); /* status */ printf("Master: initial direction=%s: end of trip %d of %d: " "after receiving passed_num=%d " "(should be =trip*numprocs=%d) from source=%d\n", (Reverse ? "reverse" : "forward"), trip, Ntrips, passed_num, trip*numprocs, *src); if (Alternate) { dest = (dest == &dest_f ? &dest_r : &dest_f); src = (src == &src_f ? &src_r : &src_f ); } /* endif */ } /* 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, *src); MPI_Recv(&passed_num, /* buff */ 1, /* count */ MPI_INT, /* type */ *src, /* 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, *src); 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, *dest); MPI_Send(&passed_num, /* buff */ 1, /* count */ MPI_INT, /* type */ *dest, /* 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, *dest); if (Alternate) { dest = (dest == &dest_f ? &dest_r : &dest_f); src = (src == &src_f ? &src_r : &src_f ); } /* endif */ } /* endfor */ } /* endif */ } else printf("numprocs = %d, should be run with numprocs > 1\n", numprocs); MPI_Finalize(); } /* end main() */