Download the ring.c program.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mpi.h>
/* command line configurables */
int Ntrips; /* -t <ntrips> */
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;
}
}
if (error && !my_id) {
/* only Master prints usage message */
fprintf(stderr, "\n\tusage: %s {-t <ntrips>} {-v}\n\n", argv[0]);
fprintf(stderr, "where\n\n");
fprintf(stderr,"\t-t <ntrips>\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");
}
}
return error;
}
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);
}
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);
}
} 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);
}
}
}
} else {
printf("numprocs = %d, should be run with numprocs > 1\n", numprocs);
}
MPI_Finalize();
//exit(0);
}
|