This source file includes following definitions.
- handle_error
- cb_gather_name_array
- default_str
- reverse_str
- reverse_alternating_str
- simple_shuffle_str
- main
- test_file
1
2
3
4
5
6 #include "mpi.h"
7 #include <stdio.h>
8 #include <string.h>
9 #include <stdlib.h>
10
11
12
13
14
15
16
17
18
19
20
21
22
23 #define STARTING_SIZE 5000
24
25 int test_file(char *filename, int mynod, int nprocs, char * cb_hosts,
26 const char *msg, int verbose);
27
28 #define ADIOI_Free free
29 #define ADIOI_Malloc malloc
30 #define FPRINTF fprintf
31
32
33 struct ADIO_cb_name_arrayD {
34 int refct;
35 int namect;
36 char **names;
37 };
38 typedef struct ADIO_cb_name_arrayD *ADIO_cb_name_array;
39
40 void handle_error(int errcode, const char *str);
41 int cb_gather_name_array(MPI_Comm comm, ADIO_cb_name_array *arrayp);
42 void default_str(int mynod, int len, ADIO_cb_name_array array, char *dest);
43 void reverse_str(int mynod, int len, ADIO_cb_name_array array, char *dest);
44 void reverse_alternating_str(int mynod, int len, ADIO_cb_name_array array, char *dest);
45 void simple_shuffle_str(int mynod, int len, ADIO_cb_name_array array, char *dest);
46
47
48 void handle_error(int errcode, const char *str)
49 {
50 char msg[MPI_MAX_ERROR_STRING];
51 int resultlen;
52 MPI_Error_string(errcode, msg, &resultlen);
53 fprintf(stderr, "%s: %s\n", str, msg);
54 MPI_Abort(MPI_COMM_WORLD, 1);
55 }
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70 int cb_gather_name_array(MPI_Comm comm, ADIO_cb_name_array *arrayp)
71 {
72
73
74
75
76
77 char my_procname[MPI_MAX_PROCESSOR_NAME], **procname = 0;
78 int *procname_len = NULL, my_procname_len, *disp = NULL, i;
79 int commsize, commrank;
80 ADIO_cb_name_array array = NULL;
81
82 MPI_Comm_size(comm, &commsize);
83 MPI_Comm_rank(comm, &commrank);
84
85 MPI_Get_processor_name(my_procname, &my_procname_len);
86
87
88 array = (ADIO_cb_name_array) malloc(sizeof(*array));
89 if (array == NULL) {
90 return -1;
91 }
92 array->refct = 1;
93
94 if (commrank == 0) {
95
96 array->namect = commsize;
97
98 array->names = (char **) ADIOI_Malloc(sizeof(char *) * commsize);
99 if (array->names == NULL) {
100 return -1;
101 }
102 procname = array->names;
103
104 procname_len = (int *) ADIOI_Malloc(commsize * sizeof(int));
105 if (procname_len == NULL) {
106 return -1;
107 }
108 }
109 else {
110
111 array->namect = 0;
112 array->names = NULL;
113 }
114
115 MPI_Gather(&my_procname_len, 1, MPI_INT,
116 procname_len, 1, MPI_INT, 0, comm);
117
118 if (commrank == 0) {
119 #ifdef CB_CONFIG_LIST_DEBUG
120 for (i=0; i < commsize; i++) {
121 FPRINTF(stderr, "len[%d] = %d\n", i, procname_len[i]);
122 }
123 #endif
124
125 for (i=0; i < commsize; i++) {
126
127
128
129
130 procname_len[i]++;
131 procname[i] = malloc(procname_len[i]);
132 if (procname[i] == NULL) {
133 return -1;
134 }
135 }
136
137
138
139
140
141
142
143
144
145 disp = malloc(commsize * sizeof(int));
146 disp[0] = 0;
147 for (i=1; i < commsize; i++) {
148 disp[i] = (int) (procname[i] - procname[0]);
149 }
150
151 }
152
153
154 if (commrank == 0) {
155 MPI_Gatherv(my_procname, my_procname_len + 1, MPI_CHAR,
156 procname[0], procname_len, disp, MPI_CHAR,
157 0, comm);
158 }
159 else {
160
161
162
163 MPI_Gatherv(my_procname, my_procname_len + 1, MPI_CHAR,
164 NULL, NULL, NULL, MPI_CHAR, 0, comm);
165 }
166
167 if (commrank == 0) {
168
169 free(disp);
170 free(procname_len);
171
172 #ifdef CB_CONFIG_LIST_DEBUG
173 for (i=0; i < commsize; i++) {
174 fprintf(stderr, "name[%d] = %s\n", i, procname[i]);
175 }
176 #endif
177 }
178
179 *arrayp = array;
180 return 0;
181 }
182
183 void default_str(int mynod, int len, ADIO_cb_name_array array, char *dest)
184 {
185 char *ptr;
186 int i, p;
187 if (!mynod) {
188 ptr = dest;
189 for (i=0; i<array->namect; i++ ) {
190 p = snprintf(ptr, len, "%s,", array->names[i]);
191 ptr += p;
192 }
193
194 dest[strlen(dest) - 1] = '\0';
195 }
196 MPI_Bcast(dest, len, MPI_CHAR, 0, MPI_COMM_WORLD);
197 }
198 void reverse_str(int mynod, int len, ADIO_cb_name_array array, char *dest)
199 {
200 char *ptr;
201 int i, p;
202 if (!mynod) {
203 ptr = dest;
204 for (i=(array->namect - 1); i >= 0; i-- ) {
205 p = snprintf(ptr, len, "%s,", array->names[i]);
206 ptr += p;
207 }
208 dest[strlen(dest) - 1] = '\0';
209 }
210 MPI_Bcast(dest, len, MPI_CHAR, 0, MPI_COMM_WORLD);
211 }
212
213 void reverse_alternating_str(int mynod, int len, ADIO_cb_name_array array, char *dest)
214 {
215 char *ptr;
216 int i, p;
217 if (!mynod) {
218 ptr = dest;
219
220 for (i=(array->namect - 1); i>= 0; i-=2 ) {
221 p = snprintf(ptr, len, "%s,", array->names[i]);
222 ptr += p;
223 }
224
225 for (i=(array->namect - 2); i > 0; i-=2 ) {
226 p = snprintf(ptr, len, "%s,", array->names[i]);
227 ptr += p;
228 }
229 dest[strlen(dest) - 1] = '\0';
230 }
231 MPI_Bcast(dest, len, MPI_CHAR, 0, MPI_COMM_WORLD);
232 }
233
234 void simple_shuffle_str(int mynod, int len, ADIO_cb_name_array array, char *dest)
235 {
236 char *ptr;
237 int i, p;
238 if (!mynod) {
239 ptr = dest;
240 for (i=(array->namect / 2 ); i < array->namect; i++) {
241 p = snprintf(ptr, len, "%s,", array->names[i]);
242 ptr += p;
243 }
244 for (i=0; i < (array->namect / 2); i++ ) {
245 p = snprintf(ptr, len, "%s,", array->names[i]);
246 ptr += p;
247 }
248 dest[strlen(dest) - 1] = '\0';
249 }
250 MPI_Bcast(dest, len, MPI_CHAR, 0, MPI_COMM_WORLD);
251 }
252
253 int main(int argc, char **argv)
254 {
255 int i, mynod, nprocs, len, errs=0, sum_errs=0, verbose=0;
256 char *filename;
257 char * cb_config_string;
258 int cb_config_len;
259 ADIO_cb_name_array array;
260
261
262 MPI_Init(&argc,&argv);
263 MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
264 MPI_Comm_rank(MPI_COMM_WORLD, &mynod);
265
266
267
268
269 if (!mynod) {
270 i = 1;
271
272 while ((i < argc) && strcmp("-fname", *argv)) {
273 i++;
274 argv++;
275 }
276 if (i >= argc) {
277 fprintf(stderr, "\n*# Usage: noncontig_coll -fname filename\n\n");
278 MPI_Abort(MPI_COMM_WORLD, 1);
279 }
280 argv++;
281 len = strlen(*argv);
282 filename = (char *) malloc(len+1);
283 strcpy(filename, *argv);
284 MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD);
285 MPI_Bcast(filename, len+1, MPI_CHAR, 0, MPI_COMM_WORLD);
286 }
287 else {
288 MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD);
289 filename = (char *) malloc(len+1);
290 MPI_Bcast(filename, len+1, MPI_CHAR, 0, MPI_COMM_WORLD);
291 }
292
293
294 cb_gather_name_array(MPI_COMM_WORLD, &array);
295
296
297 if (!mynod) {
298 if (array->namect < 2 ) {
299 fprintf(stderr, "Run this test on two or more hosts\n");
300 MPI_Abort(MPI_COMM_WORLD, 1);
301 }
302 }
303
304 if (!mynod) {
305 cb_config_len = 0;
306 for (i=0; i < array->namect; i++) {
307
308 cb_config_len += strlen(array->names[i]) + 1;
309 }
310 ++cb_config_len;
311 }
312 MPI_Bcast(&cb_config_len, 1, MPI_INT, 0, MPI_COMM_WORLD);
313 if ( (cb_config_string = malloc(cb_config_len)) == NULL ) {
314 perror("malloc");
315 MPI_Abort(MPI_COMM_WORLD, 1);
316 }
317
318
319 errs += test_file(filename, mynod, nprocs, NULL, "collective w/o hinting", verbose);
320
321
322 default_str(mynod, cb_config_len, array, cb_config_string);
323 errs += test_file(filename, mynod, nprocs, cb_config_string, "collective w/ hinting: default order", verbose);
324
325
326 reverse_str(mynod, cb_config_len, array, cb_config_string);
327 errs += test_file(filename, mynod, nprocs, cb_config_string, "collective w/ hinting: reverse order", verbose);
328
329
330 reverse_alternating_str(mynod, cb_config_len, array, cb_config_string);
331 errs += test_file(filename, mynod, nprocs, cb_config_string,"collective w/ hinting: permutation1", verbose);
332
333
334 simple_shuffle_str(mynod, cb_config_len, array, cb_config_string);
335 errs += test_file(filename, mynod, nprocs, cb_config_string, "collective w/ hinting: permutation2", verbose);
336
337 MPI_Allreduce(&errs, &sum_errs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
338
339 if (!mynod) {
340 if (sum_errs) fprintf(stderr, "Found %d error cases\n", sum_errs);
341 else printf(" No Errors\n");
342 }
343 free(filename);
344 free(cb_config_string);
345 MPI_Finalize();
346 return 0;
347 }
348
349 #define SEEDER(x,y,z) ((x)*1000000 + (y) + (x)*(z))
350
351 int test_file(char *filename, int mynod, int nprocs, char * cb_hosts, const char *msg, int verbose)
352 {
353 MPI_Datatype typevec, newtype, t[3];
354 int *buf, i, b[3], errcode, errors=0;
355 MPI_File fh;
356 MPI_Aint d[3];
357 MPI_Status status;
358 int SIZE = (STARTING_SIZE/nprocs)*nprocs;
359 MPI_Info info;
360
361 if (mynod==0 && verbose) fprintf(stderr, "%s\n", msg);
362
363 buf = (int *) malloc(SIZE*sizeof(int));
364 if (buf == NULL) {
365 perror("test_file");
366 MPI_Abort(MPI_COMM_WORLD, -1);
367 }
368
369
370 if (cb_hosts != NULL ) {
371 MPI_Info_create(&info);
372 MPI_Info_set(info, "cb_config_list", cb_hosts);
373 } else {
374 info = MPI_INFO_NULL;
375 }
376
377 MPI_Type_vector(SIZE/nprocs, 1, nprocs, MPI_INT, &typevec);
378
379 b[0] = b[1] = b[2] = 1;
380 d[0] = 0;
381 d[1] = mynod*sizeof(int);
382 d[2] = SIZE*sizeof(int);
383 t[0] = MPI_LB;
384 t[1] = typevec;
385 t[2] = MPI_UB;
386
387 MPI_Type_struct(3, b, d, t, &newtype);
388 MPI_Type_commit(&newtype);
389 MPI_Type_free(&typevec);
390
391 if (!mynod) {
392 if(verbose) fprintf(stderr, "\ntesting noncontiguous in memory, noncontiguous in file using collective I/O\n");
393 MPI_File_delete(filename, info);
394 }
395 MPI_Barrier(MPI_COMM_WORLD);
396
397 errcode = MPI_File_open(MPI_COMM_WORLD, filename,
398 MPI_MODE_CREATE | MPI_MODE_RDWR, info, &fh);
399 if (errcode != MPI_SUCCESS) {
400 handle_error(errcode, "MPI_File_open");
401 }
402
403 MPI_File_set_view(fh, 0, MPI_INT, newtype, "native", info);
404
405 for (i=0; i<SIZE; i++) buf[i] = SEEDER(mynod,i,SIZE);
406 errcode = MPI_File_write_all(fh, buf, 1, newtype, &status);
407 if (errcode != MPI_SUCCESS) {
408 handle_error(errcode, "nc mem - nc file: MPI_File_write_all");
409 }
410
411 MPI_Barrier(MPI_COMM_WORLD);
412
413 for (i=0; i<SIZE; i++) buf[i] = -1;
414
415 errcode = MPI_File_read_at_all(fh, 0, buf, 1, newtype, &status);
416 if (errcode != MPI_SUCCESS) {
417 handle_error(errcode, "nc mem - nc file: MPI_File_read_at_all");
418 }
419
420
421
422
423
424
425
426
427 for (i=0; i<mynod; i++ ) {
428 if ( buf[i] != -1 ) {
429 if(verbose) fprintf(stderr, "Process %d: buf is %d, should be -1\n", mynod, buf[i]);
430 errors++;
431 }
432 }
433
434
435
436
437 for(; i<SIZE; i++) {
438 if ( ((i-mynod)%nprocs) && buf[i] != -1) {
439 if(verbose) fprintf(stderr, "Process %d: buf %d is %d, should be -1\n",
440 mynod, i, buf[i]);
441 errors++;
442 }
443 if ( !((i-mynod)%nprocs) && buf[i] != SEEDER(mynod,i,SIZE) ) {
444 if(verbose) fprintf(stderr, "Process %d: buf %d is %d, should be %d\n",
445 mynod, i, buf[i], SEEDER(mynod,i,SIZE));
446 errors++;
447 }
448 }
449 MPI_File_close(&fh);
450
451 MPI_Barrier(MPI_COMM_WORLD);
452
453 if (!mynod) {
454 if(verbose) fprintf(stderr, "\ntesting noncontiguous in memory, contiguous in file using collective I/O\n");
455 MPI_File_delete(filename, info);
456 }
457 MPI_Barrier(MPI_COMM_WORLD);
458
459 MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR,
460 info, &fh);
461
462 for (i=0; i<SIZE; i++) buf[i] = SEEDER(mynod,i,SIZE);
463 errcode = MPI_File_write_at_all(fh, mynod*(SIZE/nprocs)*sizeof(int),
464 buf, 1, newtype, &status);
465 if (errcode != MPI_SUCCESS)
466 handle_error(errcode, "nc mem - c file: MPI_File_write_at_all");
467
468 MPI_Barrier(MPI_COMM_WORLD);
469
470 for (i=0; i<SIZE; i++) buf[i] = -1;
471
472 errcode = MPI_File_read_at_all(fh, mynod*(SIZE/nprocs)*sizeof(int),
473 buf, 1, newtype, &status);
474 if (errcode != MPI_SUCCESS)
475 handle_error(errcode, "nc mem - c file: MPI_File_read_at_all");
476
477
478 for (i=0; i<mynod; i++ ) {
479 if ( buf[i] != -1 ) {
480 if(verbose) fprintf(stderr, "Process %d: buf is %d, should be -1\n", mynod, buf[i]);
481 errors++;
482 }
483 }
484 for(; i<SIZE; i++) {
485 if ( ((i-mynod)%nprocs) && buf[i] != -1) {
486 if(verbose) fprintf(stderr, "Process %d: buf %d is %d, should be -1\n",
487 mynod, i, buf[i]);
488 errors++;
489 }
490 if ( !((i-mynod)%nprocs) && buf[i] != SEEDER(mynod,i,SIZE)) {
491 if(verbose) fprintf(stderr, "Process %d: buf %d is %d, should be %d\n",
492 mynod, i, buf[i], SEEDER(mynod,i,SIZE) );
493 errors++;
494 }
495 }
496
497 MPI_File_close(&fh);
498
499 MPI_Barrier(MPI_COMM_WORLD);
500
501 if (!mynod) {
502 if(verbose) fprintf(stderr, "\ntesting contiguous in memory, noncontiguous in file using collective I/O\n");
503 MPI_File_delete(filename, info);
504 }
505 MPI_Barrier(MPI_COMM_WORLD);
506
507 MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR,
508 info, &fh);
509
510 MPI_File_set_view(fh, 0, MPI_INT, newtype, "native", info);
511
512 for (i=0; i<SIZE; i++) buf[i] = SEEDER(mynod, i, SIZE);
513 errcode = MPI_File_write_all(fh, buf, SIZE, MPI_INT, &status);
514 if (errcode != MPI_SUCCESS)
515 handle_error(errcode, "c mem - nc file: MPI_File_write_all");
516
517 MPI_Barrier(MPI_COMM_WORLD);
518
519 for (i=0; i<SIZE; i++) buf[i] = -1;
520
521 errcode = MPI_File_read_at_all(fh, 0, buf, SIZE, MPI_INT, &status);
522 if (errcode != MPI_SUCCESS)
523 handle_error(errcode, "c mem - nc file: MPI_File_read_at_all");
524
525
526 for (i=0; i<SIZE; i++) {
527 if (buf[i] != SEEDER(mynod, i, SIZE)) {
528 if(verbose) fprintf(stderr, "Process %d: buf %d is %d, should be %d\n", mynod, i, buf[i], SEEDER(mynod, i, SIZE));
529 errors++;
530 }
531 }
532
533 MPI_File_close(&fh);
534
535 MPI_Type_free(&newtype);
536 free(buf);
537 if (info != MPI_INFO_NULL) MPI_Info_free(&info);
538 return errors;
539 }