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 }