This source file includes following definitions.
- main
1
2
3
4
5
6
7
8
9
10
11
12
13 #include <stdio.h>
14 #include <stdbool.h>
15 #include <sys/types.h>
16 #include <unistd.h>
17 #include <stdlib.h>
18 #include <time.h>
19 #include <sys/time.h>
20
21 #include <mpi.h>
22
23 int main(int argc, char* argv[])
24 {
25 int msg;
26 int rank, size, my_twin;
27 int ppn, my_node;
28 struct timeval tv;
29 unsigned long my_timestamp[2];
30 long *timestamps;
31 int i, maxrank;
32 unsigned long maxsec, maxusec, minutes, seconds;
33 unsigned long start_sec, start_usec;
34 float fsecs;
35 int nnodes;
36 bool odd_nnodes;
37 bool recvit;
38 char *ppnstr;
39
40 if (argc < 3) {
41 fprintf(stderr, "start times must be provided\n");
42 return 1;
43 }
44
45 ppnstr = getenv("OMPI_COMM_WORLD_LOCAL_SIZE");
46 ppn = strtol(ppnstr, NULL, 10);
47 start_sec = strtol(argv[1], NULL, 10);
48 start_usec = strtol(argv[2], NULL, 10);
49
50 MPI_Init(NULL, NULL);
51 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
52 MPI_Comm_size(MPI_COMM_WORLD, &size);
53
54
55 if (0 != (size % ppn)) {
56 if (0 == rank) {
57 fprintf(stderr, "The number of procs must be an integer multiple of the ppn\n"
58 "Given: num_procs %d ppn %d\n", size, ppn);
59 MPI_Abort(MPI_COMM_WORLD, 1);
60 } else {
61 goto cleanup;
62 }
63 }
64
65
66 nnodes = size / ppn;
67
68 odd_nnodes = false;
69 if (0 != (nnodes % 2)) {
70
71 odd_nnodes = true;
72 }
73
74
75
76
77
78
79
80
81
82
83
84
85 my_node = rank / ppn;
86
87 if (0 != (my_node % 2)) {
88
89
90
91
92 my_twin = rank - ppn;
93
94 MPI_Recv(&msg, 1, MPI_INT, my_twin, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
95
96
97
98 MPI_Send(&msg, 1, MPI_INT, my_twin, 1, MPI_COMM_WORLD);
99 } else {
100
101
102
103
104 my_twin = rank + ppn;
105
106
107
108
109 recvit = true;
110 if (my_twin >= size) {
111 my_twin = my_twin - size;
112 recvit = false;
113 }
114
115 MPI_Send(&msg, 1, MPI_INT, my_twin, 1, MPI_COMM_WORLD);
116
117
118
119
120 if (recvit) {
121 MPI_Recv(&msg, 1, MPI_INT, my_twin, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
122 }
123 }
124
125
126
127
128 if (odd_nnodes && 0 == my_node) {
129 my_twin = size - ppn + rank;
130 MPI_Recv(&msg, 1, MPI_INT, my_twin, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
131 }
132
133
134 gettimeofday(&tv, NULL);
135 my_timestamp[0] = tv.tv_sec;
136 my_timestamp[1] = tv.tv_usec;
137
138
139
140
141 timestamps = NULL;
142 if (0 == rank) {
143 timestamps = malloc(2 * size * sizeof(unsigned long));
144 if (NULL == timestamps) {
145 MPI_Abort(MPI_COMM_WORLD, 1);
146 }
147 }
148 MPI_Gather(&my_timestamp, 2, MPI_LONG,
149 timestamps, 2, MPI_LONG, 0, MPI_COMM_WORLD);
150 if (0 == rank) {
151
152
153
154
155 maxsec = start_sec;
156 maxusec = start_usec;
157 maxrank = -1;
158 for (i=0; i < 2*size; i+=2) {
159 if (timestamps[i] < maxsec) {
160 continue;
161 }
162 if (timestamps[i] == maxsec &&
163 timestamps[i+1] < maxusec) {
164 continue;
165 }
166 maxsec = timestamps[i];
167 maxusec = timestamps[i+1];
168 maxrank = i/2;
169 }
170 free(timestamps);
171
172 maxsec = maxsec - start_sec;
173 if (maxusec >= start_usec) {
174 maxusec = maxusec - start_usec;
175 } else {
176 maxsec--;
177 maxusec = 1000000 - start_usec + maxusec;
178 }
179
180 seconds = maxsec + (maxusec / 1000000l);
181 minutes = seconds / 60l;
182 seconds = seconds % 60l;
183 if (0 == minutes && 0 == seconds) {
184 fsecs = ((float)(maxsec)*1000000.0 + (float)maxusec) / 1000.0;
185 fprintf(stderr, "Time test was completed in %8.2f millisecs\nSlowest rank: %d\n",
186 fsecs, maxrank);
187 } else {
188 fprintf(stderr, "Time test was completed in %3lu:%02lu min:sec\nSlowest rank: %d\n",
189 minutes, seconds, maxrank);
190 }
191 }
192
193 cleanup:
194
195 MPI_Finalize();
196
197 return 0;
198 }