This source file includes following definitions.
- ADIOI_cb_bcast_rank_map
- ADIOI_cb_gather_name_array
- ADIOI_cb_config_list_parse
- ADIOI_cb_copy_name_array
- ADIOI_cb_delete_name_array
- match_procs
- match_this_proc
- find_name
- get_max_procs
- cb_config_list_lex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 #include "adio.h"
21 #include "mpi.h"
22 #include "adio_cb_config_list.h"
23 #include <stdio.h>
24 #include <string.h>
25 #include <stdlib.h>
26
27
28 #define AGG_WILDCARD 1
29 #define AGG_STRING 2
30 #define AGG_COMMA 3
31 #define AGG_COLON 4
32 #define AGG_ERROR -1
33 #define AGG_EOS 0
34
35 #undef CB_CONFIG_LIST_DEBUG
36
37
38 int ADIOI_cb_config_list_keyval = MPI_KEYVAL_INVALID;
39 static char *yylval;
40 static char *token_ptr;
41
42
43 static int get_max_procs(int cb_nodes);
44 static int match_procs(char *name, int max_per_proc, char *procnames[],
45 char used_procnames[],
46 int nr_procnames, int ranks[], int nr_ranks,
47 int *nr_ranks_allocated);
48 static int match_this_proc(char *name, int cur_proc, int max_matches,
49 char *procnames[], char used_procnames[],
50 int nr_procnames, int ranks[],
51 int nr_ranks, int nr_ranks_allocated);
52 static int find_name(char *name, char *procnames[], char used_procnames[],
53 int nr_procnames, int start_ind);
54 static int cb_config_list_lex(void);
55
56
57
58
59
60
61
62
63
64
65 int ADIOI_cb_bcast_rank_map(ADIO_File fd)
66 {
67 int my_rank;
68 char *value;
69 int error_code = MPI_SUCCESS;
70 static char myname[] = "ADIOI_cb_bcast_rank_map";
71 char *p;
72 int i;
73
74 MPI_Bcast(&(fd->hints->cb_nodes), 1, MPI_INT, 0, fd->comm);
75 if (fd->hints->cb_nodes > 0) {
76 MPI_Comm_rank(fd->comm, &my_rank);
77 if (my_rank != 0) {
78 fd->hints->ranklist = ADIOI_Malloc(fd->hints->cb_nodes*sizeof(int));
79 if (fd->hints->ranklist == NULL) {
80 error_code = MPIO_Err_create_code(error_code,
81 MPIR_ERR_RECOVERABLE,
82 myname,
83 __LINE__,
84 MPI_ERR_OTHER,
85 "**nomem2",0);
86 return error_code;
87 }
88 }
89 MPI_Bcast(fd->hints->ranklist, fd->hints->cb_nodes, MPI_INT, 0,
90 fd->comm);
91 }
92
93
94 value = (char *) ADIOI_Malloc((MPI_MAX_INFO_VAL+1)*sizeof(char));
95 ADIOI_Snprintf(value, MPI_MAX_INFO_VAL+1, "%d", fd->hints->cb_nodes);
96 ADIOI_Info_set(fd->info, "cb_nodes", value);
97 p = value;
98
99
100
101
102 for (i=0; i< fd->hints->cb_nodes; i++) {
103 int incr, remain = (MPI_MAX_INFO_VAL) - (p-value);
104 incr = ADIOI_Snprintf(p, remain, "%d ", fd->hints->ranklist[i]);
105 if (incr >= remain) break;
106 p += incr;
107 }
108 ADIOI_Info_set(fd->info, "romio_aggregator_list", value);
109 ADIOI_Free(value);
110
111 return 0;
112 }
113
114
115
116
117
118
119
120
121
122
123
124
125
126 int ADIOI_cb_gather_name_array(MPI_Comm comm,
127 MPI_Comm dupcomm,
128 ADIO_cb_name_array *arrayp)
129 {
130 char my_procname[MPI_MAX_PROCESSOR_NAME], **procname = 0;
131 int *procname_len = NULL, my_procname_len, *disp = NULL, i;
132 int commsize, commrank, found;
133 ADIO_cb_name_array array = NULL;
134 int alloc_size;
135
136 if (ADIOI_cb_config_list_keyval == MPI_KEYVAL_INVALID) {
137
138 MPI_Comm_create_keyval((MPI_Comm_copy_attr_function *) ADIOI_cb_copy_name_array,
139 (MPI_Comm_delete_attr_function *) ADIOI_cb_delete_name_array,
140 &ADIOI_cb_config_list_keyval, NULL);
141 }
142 else {
143 MPI_Comm_get_attr(comm, ADIOI_cb_config_list_keyval, (void *) &array, &found);
144 if (found) {
145 ADIOI_Assert(array != NULL);
146 *arrayp = array;
147 return 0;
148 }
149 }
150
151 MPI_Comm_size(dupcomm, &commsize);
152 MPI_Comm_rank(dupcomm, &commrank);
153
154 MPI_Get_processor_name(my_procname, &my_procname_len);
155
156
157 array = (ADIO_cb_name_array) ADIOI_Malloc(sizeof(*array));
158 if (array == NULL) {
159 return -1;
160 }
161 array->refct = 2;
162
163 if (commrank == 0) {
164
165 array->namect = commsize;
166
167 array->names = (char **) ADIOI_Malloc(sizeof(char *) * commsize);
168 if (array->names == NULL) {
169 return -1;
170 }
171 procname = array->names;
172
173 procname_len = (int *) ADIOI_Malloc(commsize * sizeof(int));
174 if (procname_len == NULL) {
175 return -1;
176 }
177 }
178 else {
179
180 array->namect = 0;
181 array->names = NULL;
182 }
183
184 MPI_Gather(&my_procname_len, 1, MPI_INT,
185 procname_len, 1, MPI_INT, 0, dupcomm);
186
187 if (commrank == 0) {
188 #ifdef CB_CONFIG_LIST_DEBUG
189 for (i=0; i < commsize; i++) {
190 FPRINTF(stderr, "len[%d] = %d\n", i, procname_len[i]);
191 }
192 #endif
193
194 alloc_size = 0;
195 for (i=0; i < commsize; i++) {
196
197
198
199
200 alloc_size += ++procname_len[i];
201 }
202
203 procname[0] = ADIOI_Malloc(alloc_size);
204 if (procname[0] == NULL) {
205 ADIOI_Free(array);
206 return -1;
207 }
208
209 for (i=1; i < commsize; i++) {
210 procname[i] = procname[i-1] + procname_len[i-1];
211 }
212
213
214
215
216
217 disp = ADIOI_Malloc(commsize * sizeof(int));
218 disp[0] = 0;
219 for (i=1; i < commsize; i++) {
220 disp[i] = (int) (procname[i] - procname[0]);
221 }
222
223 }
224
225
226 if (commrank == 0) {
227 MPI_Gatherv(my_procname, my_procname_len + 1, MPI_CHAR,
228 procname[0], procname_len, disp, MPI_CHAR,
229 0, dupcomm);
230 }
231 else {
232
233
234
235 MPI_Gatherv(my_procname, my_procname_len + 1, MPI_CHAR,
236 NULL, NULL, NULL, MPI_CHAR, 0, dupcomm);
237 }
238
239 if (commrank == 0) {
240
241 ADIOI_Free(disp);
242 ADIOI_Free(procname_len);
243
244 #ifdef CB_CONFIG_LIST_DEBUG
245 for (i=0; i < commsize; i++) {
246 FPRINTF(stderr, "name[%d] = %s\n", i, procname[i]);
247 }
248 #endif
249 }
250
251
252
253
254
255
256
257
258
259 MPI_Comm_set_attr (comm, ADIOI_cb_config_list_keyval, array);
260 MPI_Comm_set_attr (dupcomm, ADIOI_cb_config_list_keyval, array);
261 *arrayp = array;
262 return 0;
263 }
264
265
266
267
268
269
270
271
272
273
274 int ADIOI_cb_config_list_parse(char *config_list,
275 ADIO_cb_name_array array,
276 int ranklist[],
277 int cb_nodes)
278 {
279 int token, max_procs, cur_rank = 0, nr_procnames;
280 char *cur_procname, *cur_procname_p, **procnames;
281 char *used_procnames;
282
283 nr_procnames = array->namect;
284 procnames = array->names;
285
286
287
288
289
290 cur_procname = ADIOI_Malloc((MPI_MAX_INFO_VAL+1) * sizeof(char));
291 if (cur_procname == NULL) {
292 return -1;
293 }
294
295 yylval = ADIOI_Malloc((MPI_MAX_INFO_VAL+1) * sizeof(char));
296 if (yylval == NULL) {
297 ADIOI_Free(cur_procname);
298 return -1;
299 }
300
301 token_ptr = config_list;
302
303
304 if (cb_nodes > nr_procnames) cb_nodes = nr_procnames;
305
306
307
308
309 used_procnames = ADIOI_Malloc(array->namect * sizeof(char));
310 if (used_procnames == NULL) {
311 ADIOI_Free(cur_procname);
312 ADIOI_Free(yylval);
313 yylval = NULL;
314 return -1;
315 }
316 memset(used_procnames, 0, array->namect);
317
318
319
320
321
322 if (strcmp(config_list, "*:*") == 0) {
323 for (cur_rank = 0; cur_rank < cb_nodes; cur_rank++) {
324 ranklist[cur_rank] = cur_rank;
325 }
326 ADIOI_Free(cur_procname);
327 ADIOI_Free(yylval);
328 yylval = NULL;
329 ADIOI_Free(used_procnames);
330 return cb_nodes;
331 }
332
333 while (cur_rank < cb_nodes) {
334 token = cb_config_list_lex();
335
336 if (token == AGG_EOS) {
337 ADIOI_Free(cur_procname);
338 ADIOI_Free(yylval);
339 yylval = NULL;
340 ADIOI_Free(used_procnames);
341 return cur_rank;
342 }
343
344 if (token != AGG_WILDCARD && token != AGG_STRING) {
345
346 FPRINTF(stderr, "error parsing config list\n");
347 ADIOI_Free(cur_procname);
348 ADIOI_Free(yylval);
349 yylval = NULL;
350 ADIOI_Free(used_procnames);
351 return cur_rank;
352 }
353
354 if (token == AGG_WILDCARD) {
355 cur_procname_p = NULL;
356 }
357 else {
358
359
360 ADIOI_Strncpy(cur_procname, yylval, MPI_MAX_INFO_VAL+1);
361 cur_procname_p = cur_procname;
362 }
363
364
365 max_procs = get_max_procs(cb_nodes);
366
367 #ifdef CB_CONFIG_LIST_DEBUG
368 if (token == AGG_WILDCARD) {
369 FPRINTF(stderr, "looking for *:%d\n", max_procs);
370 }
371 else {
372 FPRINTF(stderr, "looking for %s:%d\n", cur_procname, max_procs);
373 }
374 #endif
375
376
377 match_procs(cur_procname_p, max_procs, procnames, used_procnames,
378 nr_procnames, ranklist, cb_nodes, &cur_rank);
379 }
380 ADIOI_Free(cur_procname);
381 ADIOI_Free(yylval);
382 yylval = NULL;
383 ADIOI_Free(used_procnames);
384 return cur_rank;
385 }
386
387
388
389 int ADIOI_cb_copy_name_array(MPI_Comm comm,
390 int keyval,
391 void *extra,
392 void *attr_in,
393 void **attr_out,
394 int *flag)
395 {
396 ADIO_cb_name_array array;
397
398 ADIOI_UNREFERENCED_ARG(comm);
399 ADIOI_UNREFERENCED_ARG(keyval);
400 ADIOI_UNREFERENCED_ARG(extra);
401
402 array = (ADIO_cb_name_array) attr_in;
403 if (array != NULL) array->refct++;
404
405 *attr_out = attr_in;
406 *flag = 1;
407
408 return MPI_SUCCESS;
409 }
410
411
412
413 int ADIOI_cb_delete_name_array(MPI_Comm comm,
414 int keyval,
415 void *attr_val,
416 void *extra)
417 {
418 ADIO_cb_name_array array;
419
420 ADIOI_UNREFERENCED_ARG(comm);
421 ADIOI_UNREFERENCED_ARG(extra);
422
423 array = (ADIO_cb_name_array) attr_val;
424 ADIOI_Assert(array != NULL);
425 array->refct--;
426
427 if (array->refct <= 0) {
428
429
430 if (array->namect) {
431
432
433
434 ADIOI_Free(array->names[0]);
435 }
436 if (array->names != NULL) ADIOI_Free(array->names);
437 ADIOI_Free(array);
438 }
439 return MPI_SUCCESS;
440 }
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460 static int match_procs(char *name,
461 int max_per_proc,
462 char *procnames[],
463 char used_procnames[],
464 int nr_procnames,
465 int ranks[],
466 int nr_ranks,
467 int *nr_ranks_allocated)
468 {
469 int wildcard_proc, cur_proc, old_nr_allocated, ret;
470
471
472 old_nr_allocated = *nr_ranks_allocated;
473
474 if (name == NULL) {
475
476
477
478 if (max_per_proc == 0) {
479
480 for (cur_proc = 0; cur_proc < nr_procnames; cur_proc++) {
481 used_procnames[cur_proc] = 1;
482 }
483 return 0;
484 }
485
486
487
488
489
490
491
492
493 wildcard_proc = 0;
494
495 while (nr_ranks - *nr_ranks_allocated > 0) {
496
497 while ((wildcard_proc < nr_procnames) &&
498 (used_procnames[wildcard_proc] != 0))
499 {
500 wildcard_proc++;
501 }
502
503 if (wildcard_proc == nr_procnames) {
504
505 return *nr_ranks_allocated - old_nr_allocated;
506 }
507
508 #ifdef CB_CONFIG_LIST_DEBUG
509 FPRINTF(stderr, "performing wildcard match (*:%d) starting with %s (%d)\n",
510 max_per_proc, procnames[wildcard_proc], wildcard_proc);
511 #endif
512
513 cur_proc = wildcard_proc;
514
515 #ifdef CB_CONFIG_LIST_DEBUG
516 FPRINTF(stderr, " assigning name %s (%d) to rank %d in mapping\n",
517 procnames[cur_proc], cur_proc, *nr_ranks_allocated);
518 #endif
519
520
521
522
523
524 ranks[*nr_ranks_allocated] = cur_proc;
525 *nr_ranks_allocated = *nr_ranks_allocated + 1;
526 cur_proc++;
527
528
529
530
531
532
533 ret = match_this_proc(procnames[wildcard_proc], cur_proc,
534 max_per_proc-1, procnames, used_procnames,
535 nr_procnames,
536 ranks, nr_ranks, *nr_ranks_allocated);
537 if (ret > 0) *nr_ranks_allocated = *nr_ranks_allocated + ret;
538
539
540
541
542 used_procnames[wildcard_proc] = 1;
543 wildcard_proc++;
544 }
545 }
546 else {
547
548 #ifdef CB_CONFIG_LIST_DEBUG
549 FPRINTF(stderr, "performing name match (%s:%d)\n", name, max_per_proc);
550 #endif
551
552 ret = match_this_proc(name, 0, max_per_proc, procnames, used_procnames,
553 nr_procnames, ranks, nr_ranks,
554 *nr_ranks_allocated);
555 if (ret > 0) *nr_ranks_allocated = *nr_ranks_allocated + ret;
556 }
557 return *nr_ranks_allocated - old_nr_allocated;
558 }
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580 static int match_this_proc(char *name,
581 int cur_proc,
582 int max_matches,
583 char *procnames[],
584 char used_procnames[],
585 int nr_procnames,
586 int ranks[],
587 int nr_ranks,
588 int nr_ranks_allocated)
589 {
590 int ranks_remaining, nr_to_alloc, old_nr_allocated;
591
592 old_nr_allocated = nr_ranks_allocated;
593
594
595 ranks_remaining = nr_ranks - nr_ranks_allocated;
596 nr_to_alloc = (max_matches < ranks_remaining) ?
597 max_matches : ranks_remaining;
598
599 while (nr_to_alloc > 0) {
600 cur_proc = find_name(name, procnames, used_procnames, nr_procnames,
601 cur_proc);
602 if (cur_proc < 0) {
603
604 return nr_ranks_allocated - old_nr_allocated;
605 }
606
607
608 #ifdef CB_CONFIG_LIST_DEBUG
609 FPRINTF(stderr, " assigning name %s (%d) to rank %d in mapping\n",
610 procnames[cur_proc], cur_proc, nr_ranks_allocated);
611 #endif
612
613 ranks[nr_ranks_allocated] = cur_proc;
614 nr_ranks_allocated++;
615 used_procnames[cur_proc] = 1;
616
617 cur_proc++;
618 nr_to_alloc--;
619 }
620
621
622 while (cur_proc >= 0) {
623 cur_proc = find_name(name, procnames, used_procnames, nr_procnames,
624 cur_proc);
625 if (cur_proc >= 0) {
626 #ifdef CB_CONFIG_LIST_DEBUG
627 FPRINTF(stderr, " taking name %s (%d) out of procnames\n",
628 procnames[cur_proc], cur_proc);
629 #endif
630 used_procnames[cur_proc] = 1;
631 cur_proc++;
632 }
633 }
634 return nr_ranks_allocated - old_nr_allocated;
635 }
636
637
638
639
640
641
642
643 static int find_name(char *name,
644 char *procnames[],
645 char used_procnames[],
646 int nr_procnames,
647 int start_ind)
648 {
649 int i;
650
651 for (i=start_ind; i < nr_procnames; i++) {
652 if (!used_procnames[i] && !strcmp(name, procnames[i])) break;
653 }
654
655 if (i < nr_procnames) return i;
656 else return -1;
657 }
658
659
660
661
662
663
664
665
666
667
668 static int get_max_procs(int cb_nodes)
669 {
670 int token, max_procs = -1;
671 char *errptr;
672
673 token = cb_config_list_lex();
674
675 switch(token) {
676 case AGG_EOS:
677 case AGG_COMMA:
678 return 1;
679 case AGG_COLON:
680 token = cb_config_list_lex();
681 if (token != AGG_WILDCARD && token != AGG_STRING) return -1;
682 if (token == AGG_WILDCARD) max_procs = cb_nodes;
683 else if (token == AGG_STRING) {
684 max_procs = (int)strtol(yylval, &errptr, 10);
685 if (*errptr != '\0') {
686
687 max_procs = 1;
688 }
689 }
690
691 token = cb_config_list_lex();
692 if (token != AGG_COMMA && token != AGG_EOS) return -1;
693
694
695 if (max_procs < 0) return -1;
696 else return max_procs;
697 }
698 return -1;
699 }
700
701
702
703
704
705
706 #if defined(BGQPLATFORM)
707
708
709 #define COLON ':'
710 #define COMMA ';'
711 #define DELIMS ":;"
712 #else
713
714 #define COLON ':'
715 #define COMMA ','
716 #define DELIMS ":,"
717 #endif
718
719 static int cb_config_list_lex(void)
720 {
721 int slen;
722
723 if (*token_ptr == '\0') return AGG_EOS;
724
725 slen = (int)strcspn(token_ptr, DELIMS);
726
727 if (*token_ptr == COLON) {
728 token_ptr++;
729 return AGG_COLON;
730 }
731 if (*token_ptr == COMMA) {
732 token_ptr++;
733 return AGG_COMMA;
734 }
735
736 if (*token_ptr == '*') {
737
738 if (slen == 1) {
739 token_ptr++;
740 return AGG_WILDCARD;
741 }
742 else return AGG_ERROR;
743 }
744
745
746
747
748
749
750
751
752 ADIOI_Strncpy(yylval, token_ptr, slen);
753 yylval[slen] = '\0';
754 token_ptr += slen;
755 return AGG_STRING;
756 }