1 /*
2 * Copyright (C) by Argonne National Laboratory
3 * See COPYRIGHT in top-level directory
4 */
5
6 /* Change for BG/L made by Hao Yu, yuh@us.ibm.com
7 */
8
9 #include "mpi.h"
10 #include <stdio.h>
11 #include <string.h>
12 #include <stdlib.h>
13
handle_error(int errcode,const char * str)14 static void handle_error(int errcode, const char *str)
15 {
16 char msg[MPI_MAX_ERROR_STRING];
17 int resultlen;
18 MPI_Error_string(errcode, msg, &resultlen);
19 fprintf(stderr, "%s: %s\n", str, msg);
20 MPI_Abort(MPI_COMM_WORLD, 1);
21 }
22
23 /* this test wants to compare the hints it gets from a file with a set of
24 * default hints. These hints are specific to the MPI-IO implementation, so if
25 * you want to test something besides the default you'll have to use a command
26 * line argument */
27
28 typedef struct hint_defaults {
29 int cb_buffer_size;
30 int ind_rd_buffer_size;
31 int ind_wr_buffer_size;
32 const char *romio_cb_read;
33 const char *romio_cb_write;
34 const char *cb_config_list;
35 } hint_defaults;
36
37 hint_defaults UFS_DEFAULTS = {
38 .cb_buffer_size = 16777216,
39 .ind_rd_buffer_size = 4194304,
40 .ind_wr_buffer_size = 524288,
41 .romio_cb_read = "automatic",
42 .romio_cb_write = "automatic",
43 .cb_config_list = "*:1"
44 };
45
46 hint_defaults BLUEGENE_DEFAULTS = {
47 .cb_buffer_size = 16777216,
48 .ind_rd_buffer_size = 4194304,
49 .ind_wr_buffer_size = 4194304,
50 .romio_cb_read = "enable",
51 .romio_cb_write = "enable",
52 .cb_config_list = NULL
53 };
54
55 /* #undef INFO_DEBUG */
56
57 /* Test will print out information about unexpected hint keys or values that
58 * differ from the default. Since this is often interesting but rarely an
59 * error, default will be to increment errror cound for true error conditions
60 * but not print out these "interesting" non-error cases. */
61
62 static int verbose = 0;
63 static int test_ufs = 0;
64 static int test_bluegene = 0;
65
main(int argc,char ** argv)66 int main(int argc, char **argv)
67 {
68 int i, len, nkeys, flag, mynod, default_striping_factor = 0, nprocs, errs = 0;
69 MPI_File fh;
70 MPI_Info info, info_used;
71 char *filename, key[MPI_MAX_INFO_KEY], value[MPI_MAX_INFO_VAL];
72 hint_defaults *defaults;
73 int ret;
74
75 MPI_Init(&argc, &argv);
76
77 MPI_Comm_rank(MPI_COMM_WORLD, &mynod);
78 MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
79
80 /* process 0 takes the file name as a command-line argument and
81 broadcasts it to other processes */
82 if (!mynod) {
83 i = 1;
84 while ((i < argc) && strcmp("-fname", *argv)) {
85 if (!strcmp("-v", *argv))
86 verbose = 1;
87 else if (!strcmp("-u", *argv))
88 test_ufs = 1;
89 else if (!strcmp("-b", *argv))
90 test_bluegene = 1;
91 i++;
92 argv++;
93 }
94 if (i >= argc) {
95 fprintf(stderr, "\n*# Usage: file_info [-v] -fname filename\n\n");
96 MPI_Abort(MPI_COMM_WORLD, 1);
97 }
98 argv++;
99 len = strlen(*argv);
100 filename = (char *) malloc(len + 1);
101 strcpy(filename, *argv);
102 MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD);
103 MPI_Bcast(filename, len + 1, MPI_CHAR, 0, MPI_COMM_WORLD);
104 MPI_Bcast(&verbose, 1, MPI_INT, 0, MPI_COMM_WORLD);
105 MPI_Bcast(&test_ufs, 1, MPI_INT, 0, MPI_COMM_WORLD);
106 MPI_Bcast(&test_bluegene, 1, MPI_INT, 0, MPI_COMM_WORLD);
107 } else {
108 MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD);
109 filename = (char *) malloc(len + 1);
110 MPI_Bcast(filename, len + 1, MPI_CHAR, 0, MPI_COMM_WORLD);
111 MPI_Bcast(&verbose, 1, MPI_INT, 0, MPI_COMM_WORLD);
112 MPI_Bcast(&test_ufs, 1, MPI_INT, 0, MPI_COMM_WORLD);
113 MPI_Bcast(&test_bluegene, 1, MPI_INT, 0, MPI_COMM_WORLD);
114 }
115 if (test_ufs) {
116 defaults = &UFS_DEFAULTS;
117 } else if (test_bluegene) {
118 defaults = &BLUEGENE_DEFAULTS;
119 } else {
120 defaults = NULL;
121 }
122
123 /* open the file with MPI_INFO_NULL */
124 ret = MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR,
125 MPI_INFO_NULL, &fh);
126 if (ret != MPI_SUCCESS)
127 handle_error(ret, "MPI_File_open");
128
129 /* check the default values set by ROMIO */
130 MPI_File_get_info(fh, &info_used);
131 MPI_Info_get_nkeys(info_used, &nkeys);
132
133 if (defaults != NULL) {
134 for (i = 0; i < nkeys; i++) {
135 MPI_Info_get_nthkey(info_used, i, key);
136 MPI_Info_get(info_used, key, MPI_MAX_INFO_VAL - 1, value, &flag);
137 #ifdef INFO_DEBUG
138 if (!mynod)
139 fprintf(stderr, "Process %d, Default: key = %s, value = %s\n", mynod, key, value);
140 #endif
141 if (!strcmp("striping_factor", key)) {
142 default_striping_factor = atoi(value);
143 /* no check */
144 } else if (!strcmp("cb_buffer_size", key)) {
145 if (atoi(value) != defaults->cb_buffer_size) {
146 errs++;
147 if (verbose)
148 fprintf(stderr, "cb_buffer_size is %d; should be %d\n",
149 atoi(value), defaults->cb_buffer_size);
150 }
151 } else if (!strcmp("romio_cb_read", key)) {
152 if (strcmp(defaults->romio_cb_read, value)) {
153 errs++;
154 if (verbose)
155 fprintf(stderr, "romio_cb_read is set to %s; should be %s\n",
156 value, defaults->romio_cb_read);
157 }
158 } else if (!strcmp("romio_cb_write", key)) {
159 if (strcmp(defaults->romio_cb_write, value)) {
160 errs++;
161 if (verbose)
162 fprintf(stderr, "romio_cb_write is set to %s; should be %s\n",
163 value, defaults->romio_cb_write);
164 }
165 } else if (!strcmp("cb_nodes", key)) {
166 /* unreliable test -- just ignore value */
167 } else if (!strcmp("romio_no_indep_rw", key)) {
168 if (strcmp("false", value)) {
169 errs++;
170 if (verbose)
171 fprintf(stderr, "romio_no_indep_rw is set to %s; should be %s\n",
172 value, "false");
173 }
174 } else if (!strcmp("ind_rd_buffer_size", key)) {
175 if (atoi(value) != defaults->ind_rd_buffer_size) {
176 errs++;
177 if (verbose)
178 fprintf(stderr, "ind_rd_buffer_size is %d; should be %d\n",
179 atoi(value), defaults->ind_rd_buffer_size);
180 }
181 } else if (!strcmp("ind_wr_buffer_size", key)) {
182 if (atoi(value) != defaults->ind_wr_buffer_size) {
183 errs++;
184 if (verbose)
185 fprintf(stderr, "ind_wr_buffer_size is %d; should be %d\n",
186 atoi(value), defaults->ind_wr_buffer_size);
187 }
188 } else if (!strcmp("romio_ds_read", key)) {
189 if (strcmp("automatic", value)) {
190 errs++;
191 if (verbose)
192 fprintf(stderr, "romio_ds_read is set to %s; should be %s\n",
193 value, "automatic");
194 }
195 } else if (!strcmp("romio_ds_write", key)) {
196 /* Unreliable test -- value is file system dependent. Ignore. */
197 } else if (!strcmp("cb_config_list", key)) {
198 #ifndef SKIP_CB_CONFIG_LIST_TEST
199 if (strcmp(defaults->cb_config_list, value)) {
200 errs++;
201 if (verbose)
202 fprintf(stderr, "cb_config_list is set to %s; should be %s\n",
203 value, defaults->cb_config_list);
204 }
205 #endif
206 }
207 /* don't care about the defaults for these keys */
208 else if (!strcmp("romio_cb_pfr", key)) {
209 } else if (!strcmp("romio_cb_fr_types", key)) {
210 } else if (!strcmp("romio_cb_fr_alignment", key)) {
211 } else if (!strcmp("romio_cb_ds_threshold", key)) {
212 } else if (!strcmp("romio_cb_alltoall", key)) {
213 } else {
214 if (verbose)
215 fprintf(stderr, "unexpected key %s (not counted as an error)\n", key);
216 }
217 }
218 }
219 MPI_Info_free(&info_used);
220
221 MPI_File_close(&fh);
222
223 /* delete the file */
224 if (!mynod)
225 MPI_File_delete(filename, MPI_INFO_NULL);
226 MPI_Barrier(MPI_COMM_WORLD);
227
228 /* set new info values. */
229
230 MPI_Info_create(&info);
231
232 /* The following four hints are accepted on all machines. They can
233 be specified at file-open time or later (any number of times). */
234
235 /* buffer size for collective I/O */
236 MPI_Info_set(info, "cb_buffer_size", "8388608");
237
238 /* number of processes that actually perform I/O in collective I/O */
239 sprintf(value, "%d", nprocs / 2);
240 MPI_Info_set(info, "cb_nodes", value);
241
242 /* buffer size for data sieving in independent reads */
243 MPI_Info_set(info, "ind_rd_buffer_size", "2097152");
244
245 /* buffer size for data sieving in independent writes */
246 MPI_Info_set(info, "ind_wr_buffer_size", "1048576");
247
248
249 /* The following three hints related to file striping are accepted only
250 on some parallel file systems and are ignored elsewhere.
251 They can be specified only at file-creation time; if specified later
252 they will be ignored. */
253
254 /* number of I/O devices across which the file will be striped.
255 * accepted only if 0 < value < default_striping_factor;
256 * ignored otherwise */
257 if (default_striping_factor - 1 > 0) {
258 sprintf(value, "%d", default_striping_factor - 1);
259 MPI_Info_set(info, "striping_factor", value);
260 } else {
261 sprintf(value, "%d", default_striping_factor);
262 MPI_Info_set(info, "striping_factor", value);
263 }
264
265 /* the striping unit in bytes */
266 MPI_Info_set(info, "striping_unit", "131072");
267
268 #ifndef SKIP_CB_CONFIG_LIST_TEST
269 /* set the cb_config_list so we'll get deterministic cb_nodes output */
270 MPI_Info_set(info, "cb_config_list", "*:*");
271 #endif
272
273 /* the I/O device number from which to start striping the file.
274 * accepted only if 0 <= value < default_striping_factor;
275 * ignored otherwise */
276 sprintf(value, "%d", default_striping_factor - 2);
277 MPI_Info_set(info, "start_iodevice", value);
278
279
280 /* The following hint about PFS server buffering is accepted only on
281 Intel PFS. It can be specified anytime. */
282 MPI_Info_set(info, "pfs_svr_buf", "true");
283
284 /* open the file and set new info */
285 ret = MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR, info, &fh);
286 if (ret != MPI_SUCCESS)
287 handle_error(ret, "MPI_File_open");
288
289 /* check the values set */
290 ret = MPI_File_get_info(fh, &info_used);
291 if (ret != MPI_SUCCESS)
292 handle_error(ret, "MPI_File_get_info");
293 MPI_Info_get_nkeys(info_used, &nkeys);
294
295 for (i = 0; i < nkeys; i++) {
296 MPI_Info_get_nthkey(info_used, i, key);
297 MPI_Info_get(info_used, key, MPI_MAX_INFO_VAL - 1, value, &flag);
298 #ifdef INFO_DEBUG
299 if (!mynod)
300 fprintf(stderr, "Process %d, key = %s, value = %s\n", mynod, key, value);
301 #endif
302 if (!strcmp("striping_factor", key)) {
303 if ((default_striping_factor - 1 > 0) && (atoi(value) != default_striping_factor - 1)) {
304 errs++;
305 if (verbose)
306 fprintf(stderr, "striping_factor is %d; should be %d\n",
307 atoi(value), default_striping_factor - 1);
308 } else if (atoi(value) != default_striping_factor) {
309 errs++;
310 if (verbose)
311 fprintf(stderr, "striping_factor is %d; should be %d\n",
312 atoi(value), default_striping_factor);
313 }
314 } else if (!strcmp("cb_buffer_size", key)) {
315 if (atoi(value) != 8388608) {
316 errs++;
317 if (verbose)
318 fprintf(stderr, "cb_buffer_size is %d; should be %d\n", atoi(value), 8388608);
319 }
320 }
321 /* only check the hints we set */
322 else if (!strcmp("cb_nodes", key)) {
323 /* unreliable test: just skip */
324 } else if (!strcmp("romio_no_indep_rw", key)) {
325 if (strcmp("false", value)) {
326 errs++;
327 if (verbose)
328 fprintf(stderr, "romio_no_indep_rw is set to %s; should be %s\n",
329 value, "false");
330 }
331 } else if (!strcmp("ind_rd_buffer_size", key)) {
332 if (atoi(value) != 2097152) {
333 errs++;
334 if (verbose)
335 fprintf(stderr, "ind_rd_buffer_size is %d; should be %d\n",
336 atoi(value), 2097152);
337 }
338 } else if (!strcmp("ind_wr_buffer_size", key)) {
339 if (atoi(value) != 1048576) {
340 errs++;
341 if (verbose)
342 fprintf(stderr, "ind_wr_buffer_size is %d; should be %d\n",
343 atoi(value), 1048576);
344 }
345 } else if (!strcmp("romio_ds_read", key)) {
346 if (strcmp("automatic", value)) {
347 errs++;
348 if (verbose)
349 fprintf(stderr, "romio_ds_read is set to %s; should be %s\n",
350 value, "automatic");
351 }
352 } else if (!strcmp("romio_ds_write", key)) {
353 /* Unreliable test -- value is file system dependent. Ignore. */
354 } else if (!strcmp("cb_config_list", key)) {
355 #ifndef SKIP_CB_CONFIG_LIST_TEST
356 if (strcmp("*:*", value)) {
357 errs++;
358 if (verbose)
359 fprintf(stderr, "cb_config_list is set to %s; should be %s\n", value, "*:*");
360 }
361 #endif
362 } else if (!strcmp("romio_cb_pfr", key)) {
363 if (strcmp("disable", value)) {
364 errs++;
365 if (verbose)
366 fprintf(stderr, "romio_cb_pfr is set to %s; should be %s\n",
367 value, "automatic");
368 }
369 } else if (!strcmp("romio_cb_fr_types", key)) {
370 if (strcmp("aar", value)) {
371 errs++;
372 if (verbose)
373 fprintf(stderr, "romio_cb_fr_types is set to %s; should be %s\n", value, "aar");
374 }
375 } else if (!strcmp("romio_cb_fr_alignment", key)) {
376 if (strcmp("1", value)) {
377 errs++;
378 if (verbose)
379 fprintf(stderr, "romio_cb_fr_alignment is set to %s; should be %s\n",
380 value, "1");
381 }
382 } else if (!strcmp("romio_cb_ds_threshold", key)) {
383 if (strcmp("0", value)) {
384 errs++;
385 if (verbose)
386 fprintf(stderr, "romio_cb_ds_threshold is set to %s; should be %s\n",
387 value, "0");
388 }
389 } else if (!strcmp("romio_cb_alltoall", key)) {
390 if (strcmp("automatic", value)) {
391 errs++;
392 if (verbose)
393 fprintf(stderr, "romio_cb_alltoall is set to %s; should be %s\n",
394 value, "automatic");
395 }
396 }
397
398 else {
399 if (verbose)
400 fprintf(stderr, "unexpected key %s (not counted as an error)\n", key);
401 }
402 }
403
404 /* Q: SHOULD WE BOTHER LOOKING AT THE OTHER PROCESSES? */
405 if (!mynod) {
406 if (errs)
407 fprintf(stderr, "Found %d errors.\n", errs);
408 else
409 printf(" No Errors\n");
410 }
411
412 MPI_File_close(&fh);
413
414 /* delete the file */
415 if (!mynod)
416 MPI_File_delete(filename, MPI_INFO_NULL);
417 MPI_Barrier(MPI_COMM_WORLD);
418
419 free(filename);
420 MPI_Info_free(&info_used);
421 MPI_Info_free(&info);
422 MPI_Finalize();
423 return 0;
424 }
425