-
Notifications
You must be signed in to change notification settings - Fork 0
/
laten.c
270 lines (209 loc) · 7.86 KB
/
laten.c
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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
/*
This work was produced at the University of California, Lawrence Livermore
National Laboratory (UC LLNL) under contract no. W-7405-ENG-48 (Contract
48) between the U.S. Department of Energy (DOE) and The Regents of the
University of California (University) for the operation of UC LLNL. The
rights of the Federal Government are reserved under Contract 48 subject to
the restrictions agreed upon by the DOE and University as allowed under DOE
Acquisition Letter 97-1.
DISCLAIMER
This work was prepared as an account of work sponsored by an agency of the
United States Government. Neither the United States Government nor the
University of California nor any of their employees, makes any warranty,
express or implied, or assumes any liability or responsibility for the
accuracy, completeness, or usefulness of any information, apparatus,
product, or process disclosed, or represents that its use would not
infringe privately-owned rights. Reference herein to any specific
commercial products, process, or service by trade name, trademark,
manufacturer or otherwise does not necessarily constitute or imply its
endorsement, recommendation, or favoring by the United States Government or
the University of California. The views and opinions of authors expressed
herein do not necessarily state or reflect those of the United States
Government or the University of California, and shall not be used for
advertising or product endorsement purposes.
NOTIFICATION OF COMMERCIAL USE
Commercialization of this product is prohibited without notifying the
Department of Energy (DOE) or Lawrence Livermore National Laboratory
(LLNL).
UCRL-CODE-2001-028
laten.c
Description:
This test uses MPI_Send and MPI_Recv to perform 0-length ping-pong
messages between pairs of MPI processes. The latency for a single
message is calculated by dividing the round-trip time by 2.
*/
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include <stdio.h>
#include <hmpi.h>
#include "util.h"
static char* outputFormat = " %20d %17.3f\n";
static char* outputCharFormat = " %20s %17s\n";
static char* command;
void printReportHeader(void);
void printUse(void);
void printParameters(int iters, char *procFile, int procsPerNode,
char allocPattern, int useBarrier);
main(int argc, char** argv)
{
int rank, wsize, iters, i, procs, currtarg, dummy;
double diff = 0.0;
double start, max, mintime = 9999;
MPI_Status stat;
char comBuf;
MPI_Comm activeComm;
char* procFile = NULL;
int* procList = NULL;
int procListSize;
int messStart, messStop, messFactor;
int procsPerNode, procIdx, useBarrier, printPairs, useNearestRank;
char allocPattern;
command = argv[0];
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &wsize);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if ( !processArgs(argc, argv, rank, wsize, &iters,
&dummy, &messStart, &messStop, &messFactor,
&procFile, &procsPerNode, &allocPattern,
&printPairs, &useBarrier, &useNearestRank) )
{
if ( rank == 0 )
printUse();
MPI_Finalize();
exit(-1);
}
if ( ! getProcList(procFile, wsize, &procList, &procListSize,
procsPerNode, allocPattern) )
{
if ( procFile )
printf("Failed to get process list from file %s.\n", procFile);
else
printf("Failed to allocate process list.\n");
exit(-1);
}
if ( rank == 0 )
printReportHeader();
currtarg = getTargetRank(rank, wsize, procsPerNode, useNearestRank);
for ( procIdx = 0; procIdx < procListSize; procIdx++ )
{
procs = procList[procIdx];
if ( printPairs )
{
printActivePairs(procs, rank, wsize, procsPerNode,
allocPattern, useNearestRank);
}
/* Create Communicator of all active processes */
createActiveComm(procs, rank, wsize, procsPerNode,
allocPattern, printPairs, useNearestRank, &activeComm);
if ( isActiveProc(rank, wsize, procsPerNode, procs,
allocPattern, useNearestRank) )
{
if ( rank < currtarg )
{
/* Ensure pair communication has been initialized */
MPI_Recv(&comBuf, 0, MPI_INT, currtarg, 0, MPI_COMM_WORLD, &stat);
MPI_Send(&comBuf, 0, MPI_INT, currtarg, 0, MPI_COMM_WORLD);
}
else
{
/* Ensure pair communication has been initialized */
MPI_Send(&comBuf, 0, MPI_INT, currtarg, 0, MPI_COMM_WORLD);
MPI_Recv(&comBuf, 0, MPI_INT, currtarg, 0, MPI_COMM_WORLD, &stat);
}
//generic_barrier(activeComm);
MPI_Barrier(activeComm);
//generic_barrier(activeComm);
MPI_Barrier(activeComm);
if ( rank < currtarg )
{
/* Time operation loop */
start = MPI_Wtime();
for ( i = 0; i < iters; i++ )
{
MPI_Send(&comBuf, 0, MPI_INT, currtarg, 0, MPI_COMM_WORLD);
MPI_Recv(&comBuf, 0, MPI_INT, currtarg, 0, MPI_COMM_WORLD, &stat);
}
}
else
{
/* Time operation loop */
start = MPI_Wtime();
for ( i = 0; i < iters; i++ )
{
MPI_Recv(&comBuf, 0, MPI_INT, currtarg, 0, MPI_COMM_WORLD, &stat);
MPI_Send(&comBuf, 0, MPI_INT, currtarg, 0, MPI_COMM_WORLD);
}
}
if ( useBarrier )
MPI_Barrier(activeComm);
//generic_barrier(activeComm);
diff = MPI_Wtime() - start;
}
if ( activeComm != MPI_COMM_NULL )
MPI_Comm_free(&activeComm);
/* Get maximum sample length */
MPI_Reduce(&diff, &max, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD);
if ( rank == 0 )
{
if ( max < mintime )
mintime = max;
printf(outputFormat, procs, max/iters/2*1000000);
}
}
if ( rank == 0 )
{
printParameters(iters, procFile, procsPerNode,
allocPattern, useBarrier);
}
printReportFooter(mintime, rank, wsize, procsPerNode, useNearestRank);
MPI_Finalize();
exit(0);
}
void printReportHeader(void)
{
char buf[128];
size_t i, len;
printf("MPI Bidirectional latency test (Send/Recv)\n");
sprintf(buf, outputCharFormat, "Processes", "Max Latency (us)");
printf("%s", buf);
len = strlen(buf);
for ( i = 1; i < len; i++ )
putchar('-');
putchar('\n');
}
void printUse(void)
{
printf("\n%s : MPI interprocess communication latency benchmark\n\n", command);
printf(" syntax: %s [OPTION]...\n\n", command);
printf(" -f [process count source file]\n");
printf(" -o [number of operations between measurements]\n");
printf(" -p [allocate processes: c(yclic) or b(lock)] default=%c\n", ALLOC_DEF);
printf(" -t [processes per SMP]\n");
printf(" -h : print use information\n");
printf(" -i : print process pair information default=%s\n",
PRINT_PAIRS_DEF ? "true" : "false" );
printf(" -n : do not use barrier within measurement default=%s\n",
USE_BARRIER_DEF ? "barrier used" : "barrier not used");
printf(" -r : partner processes with nearby rank default=%s\n",
NEAREST_RANK_DEF ? "true" : "false" );
printf("\n");
}
void printParameters(int iters, char *procFile, int procsPerNode,
char allocPattern, int useBarrier)
{
printf("\nTest Parameters\n");
printf("---------------\n");
printf("Operations per measurement : %8d\n", iters);
if ( procFile )
printf("Process count file : %s\n", procFile);
if (procsPerNode > 0 )
printf("Processes per SMP : %8d\n", procsPerNode);
if ( allocPattern == 'b' )
printf("Process pair allocation : %8s\n", "block");
else
printf("Process pair allocation : %8s\n", "cyclic");
if ( ! useBarrier )
printf("\nBarrier not included in measurement.\n");
printf("\n");
}