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