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