Ignore:
Timestamp:
05/31/18 16:32:39 (6 years ago)
Author:
yushan
Message:

save dev

File:
1 edited

Legend:

Unmodified
Added
Removed
  • XIOS/dev/branch_openmp/extern/ep_dev/ep_intercomm_kernel.cpp

    r1513 r1515  
    1414    int ep_size, num_ep, mpi_size; 
    1515 
    16     ep_rank = local_comm->ep_comm_ptr->size_rank_info[0].first; 
     16    ep_rank     = local_comm->ep_comm_ptr->size_rank_info[0].first; 
    1717    ep_rank_loc = local_comm->ep_comm_ptr->size_rank_info[1].first; 
    18     mpi_rank = local_comm->ep_comm_ptr->size_rank_info[2].first; 
    19     ep_size = local_comm->ep_comm_ptr->size_rank_info[0].second; 
    20     num_ep = local_comm->ep_comm_ptr->size_rank_info[1].second; 
    21     mpi_size = local_comm->ep_comm_ptr->size_rank_info[2].second; 
    22  
    23  
    24     // step 1 : local leaders exchange ep_size then bcast to all ep in local_comm 
     18    mpi_rank    = local_comm->ep_comm_ptr->size_rank_info[2].first; 
     19    ep_size     = local_comm->ep_comm_ptr->size_rank_info[0].second; 
     20    num_ep      = local_comm->ep_comm_ptr->size_rank_info[1].second; 
     21    mpi_size    = local_comm->ep_comm_ptr->size_rank_info[2].second; 
     22 
     23    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
     24    // step 1 : local leaders exchange ep_size, leader_rank_in_peer, leader_rank_in_peer_mpi, leader_rank_in_world. // 
     25    //          local leaders bcast results to all ep in local_comm                                                 // 
     26    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
     27 
     28    bool is_local_leader = ep_rank==local_leader? true: false; 
     29 
     30 
     31     
     32    int local_leader_rank_in_peer; 
     33    int local_leader_rank_in_peer_mpi; 
     34    int local_leader_rank_in_world; 
    2535 
    2636    int remote_ep_size; 
    27     bool is_local_leader = ep_rank==local_leader? true: false; 
     37    int remote_leader_rank_in_peer; 
     38    int remote_leader_rank_in_peer_mpi; 
     39    int remote_leader_rank_in_world; 
     40 
     41    int send_quadruple[4]; 
     42    int recv_quadruple[4]; 
     43 
    2844 
    2945    if(is_local_leader) 
    3046    { 
    31       MPI_Request request[2]; 
    32       MPI_Status status[2]; 
    33       MPI_Isend(&ep_size, 1, MPI_INT, remote_leader, tag, peer_comm, &request[0]); 
    34       MPI_Irecv(&remote_ep_size, 1, MPI_INT, remote_leader, tag, peer_comm, &request[1]); 
    35       MPI_Waitall(2, request, status); 
    36     } 
    37  
    38     MPI_Bcast(&remote_ep_size, 1, MPI_INT, local_leader, local_comm); 
    39  
    40 #ifdef _showinfo 
    41     MPI_Barrier(peer_comm); 
    42     MPI_Barrier(peer_comm); 
    43     #pragma omp critical(stdoutput) 
     47      MPI_Comm_rank(peer_comm, &local_leader_rank_in_peer); 
     48      ::MPI_Comm_rank(to_mpi_comm(peer_comm->mpi_comm), &local_leader_rank_in_peer_mpi); 
     49      ::MPI_Comm_rank(to_mpi_comm(MPI_COMM_WORLD->mpi_comm), &local_leader_rank_in_world); 
     50 
     51      send_quadruple[0] = ep_size; 
     52      send_quadruple[1] = local_leader_rank_in_peer; 
     53      send_quadruple[2] = local_leader_rank_in_peer_mpi; 
     54      send_quadruple[3] = local_leader_rank_in_world; 
     55 
     56      MPI_Request request; 
     57      MPI_Status status; 
     58 
     59 
     60      if(remote_leader > local_leader_rank_in_peer) 
     61      { 
     62        MPI_Isend(send_quadruple, 4, MPI_INT, remote_leader, tag, peer_comm, &request); 
     63        MPI_Wait(&request, &status); 
     64        
     65        MPI_Irecv(recv_quadruple, 4, MPI_INT, remote_leader, tag, peer_comm, &request); 
     66        MPI_Wait(&request, &status); 
     67      } 
     68      else 
     69      { 
     70        MPI_Irecv(recv_quadruple, 4, MPI_INT, remote_leader, tag, peer_comm, &request); 
     71        MPI_Wait(&request, &status); 
     72           
     73        MPI_Isend(send_quadruple, 4, MPI_INT, remote_leader, tag, peer_comm, &request); 
     74        MPI_Wait(&request, &status); 
     75      } 
     76 
     77      remote_ep_size                 = recv_quadruple[0]; 
     78      remote_leader_rank_in_peer     = recv_quadruple[1]; 
     79      remote_leader_rank_in_peer_mpi = recv_quadruple[2]; 
     80      remote_leader_rank_in_world    = recv_quadruple[3]; 
     81#ifdef _showinfo 
     82      printf("peer_rank = %d, packed exchange OK\n", local_leader_rank_in_peer); 
     83#endif 
     84    } 
     85 
     86    MPI_Bcast(send_quadruple, 4, MPI_INT, local_leader, local_comm); 
     87    MPI_Bcast(recv_quadruple, 4, MPI_INT, local_leader, local_comm); 
     88 
     89    if(!is_local_leader) 
     90    { 
     91      local_leader_rank_in_peer     = send_quadruple[1]; 
     92      local_leader_rank_in_peer_mpi = send_quadruple[2]; 
     93      local_leader_rank_in_world    = send_quadruple[3]; 
     94 
     95      remote_ep_size                 = recv_quadruple[0]; 
     96      remote_leader_rank_in_peer     = recv_quadruple[1]; 
     97      remote_leader_rank_in_peer_mpi = recv_quadruple[2]; 
     98      remote_leader_rank_in_world    = recv_quadruple[3]; 
     99    } 
     100 
     101 
     102#ifdef _showinfo 
     103    MPI_Barrier(peer_comm); 
     104    MPI_Barrier(peer_comm); 
    44105    printf("peer_rank = %d, ep_size = %d, remote_ep_size = %d\n", peer_comm->ep_comm_ptr->size_rank_info[0].first, ep_size, remote_ep_size); 
    45106    MPI_Barrier(peer_comm); 
     
    47108#endif 
    48109 
    49     // step 2 : gather ranks in world for both local and remote comm 
     110    /////////////////////////////////////////////////////////////////// 
     111    // step 2 : gather ranks in world for both local and remote comm // 
     112    /////////////////////////////////////////////////////////////////// 
    50113 
    51114    int rank_in_world; 
     
    59122    if(is_local_leader) 
    60123    { 
    61       MPI_Request request[2]; 
    62       MPI_Status status[2]; 
    63       MPI_Isend(ranks_in_world_local,  ep_size,        MPI_INT, remote_leader, tag, peer_comm, &request[0]); 
    64       MPI_Irecv(ranks_in_world_remote, remote_ep_size, MPI_INT, remote_leader, tag, peer_comm, &request[1]); 
    65       MPI_Waitall(2, request, status); 
     124      MPI_Request request; 
     125      MPI_Status status; 
     126 
     127      if(remote_leader > local_leader_rank_in_peer) 
     128      { 
     129        MPI_Isend(ranks_in_world_local,  ep_size, MPI_INT, remote_leader, tag, peer_comm, &request); 
     130        MPI_Wait(&request, &status); 
     131        
     132        MPI_Irecv(ranks_in_world_remote, remote_ep_size, MPI_INT, remote_leader, tag, peer_comm, &request); 
     133        MPI_Wait(&request, &status); 
     134      } 
     135      else 
     136      { 
     137        MPI_Irecv(ranks_in_world_remote, remote_ep_size, MPI_INT, remote_leader, tag, peer_comm, &request); 
     138        MPI_Wait(&request, &status); 
     139           
     140        MPI_Isend(ranks_in_world_local,  ep_size, MPI_INT, remote_leader, tag, peer_comm, &request); 
     141        MPI_Wait(&request, &status); 
     142      } 
     143#ifdef _showinfo 
     144      printf("peer_rank = %d, ranks_in_world exchange OK\n", local_leader_rank_in_peer); 
     145#endif 
    66146    } 
    67147 
     
    136216#endif 
    137217 
    138  
    139     // step 3 : determine the priority and ownership of each ep 
    140  
    141     int local_leader_rank_in_peer; 
    142     int remote_leader_rank_in_peer; 
    143  
    144     if(is_local_leader) MPI_Comm_rank(peer_comm, &local_leader_rank_in_peer); 
    145  
    146     if(is_local_leader) 
    147     { 
    148       MPI_Request request[2]; 
    149       MPI_Status status[2]; 
    150       MPI_Isend(&local_leader_rank_in_peer,  1, MPI_INT, remote_leader, tag, peer_comm, &request[0]); 
    151       MPI_Irecv(&remote_leader_rank_in_peer, 1, MPI_INT, remote_leader, tag, peer_comm, &request[1]); 
    152       MPI_Waitall(2, request, status); 
    153     } 
    154  
    155     MPI_Bcast(&local_leader_rank_in_peer,  1, MPI_INT, local_leader, local_comm); 
    156     MPI_Bcast(&remote_leader_rank_in_peer, 1, MPI_INT, local_leader, local_comm); 
     218    ////////////////////////////////////////////////////////////// 
     219    // step 3 : determine the priority and ownership of each ep // 
     220    ////////////////////////////////////////////////////////////// 
    157221 
    158222    bool priority = local_leader_rank_in_peer > remote_leader_rank_in_peer? true : false; 
    159223 
    160 #ifdef _showinfo 
    161     MPI_Barrier(peer_comm); 
    162     MPI_Barrier(peer_comm); 
    163     printf("peer_rank = %d, priority = %d, local_leader_rank_in_peer = %d, remote_leader_rank_in_peer = %d\n", peer_comm->ep_comm_ptr->size_rank_info[0].first, priority, local_leader_rank_in_peer, remote_leader_rank_in_peer); 
    164     MPI_Barrier(peer_comm); 
    165     MPI_Barrier(peer_comm); 
    166 #endif 
    167  
    168     int local_leader_rank_in_world = ranks_in_world_local[local_leader]; 
    169     int remote_leader_rank_in_world; 
    170  
    171     if(is_local_leader) 
    172     { 
    173       MPI_Request request[2]; 
    174       MPI_Status status[2]; 
    175       MPI_Isend(&local_leader_rank_in_world,  1, MPI_INT, remote_leader, tag, peer_comm, &request[0]); 
    176       MPI_Irecv(&remote_leader_rank_in_world, 1, MPI_INT, remote_leader, tag, peer_comm, &request[1]); 
    177       MPI_Waitall(2, request, status); 
    178     } 
    179  
    180     MPI_Bcast(&remote_leader_rank_in_world, 1, MPI_INT, local_leader, local_comm); 
    181224 
    182225    int ownership; 
     
    196239      } 
    197240    } 
     241 
     242#ifdef _showinfo 
     243    MPI_Barrier(peer_comm); 
     244    MPI_Barrier(peer_comm); 
     245    printf("peer_rank = %d, priority = %d, local_leader_rank_in_peer = %d, remote_leader_rank_in_peer = %d\n", peer_comm->ep_comm_ptr->size_rank_info[0].first, priority, local_leader_rank_in_peer, remote_leader_rank_in_peer); 
     246    MPI_Barrier(peer_comm); 
     247    MPI_Barrier(peer_comm); 
     248#endif 
     249 
    198250     
    199251#ifdef _showinfo 
     
    205257#endif 
    206258 
    207  
    208     // step 4 : extract local_comm and create intercomm 
     259    ////////////////////////////////////////////////////// 
     260    // step 4 : extract local_comm and create intercomm // 
     261    ////////////////////////////////////////////////////// 
    209262 
    210263    bool is_involved = is_local_leader || (!is_local_leader && ep_rank_loc == 0 && rank_in_world != local_leader_rank_in_world); 
     
    268321      ::MPI_Bcast(&local_leader_rank_in_extracted_comm, 1, to_mpi_type(MPI_INT), local_comm->ep_rank_map->at(local_leader).second, to_mpi_comm(local_comm->mpi_comm)); 
    269322 
    270       int local_leader_rank_in_peer_mpi; 
    271       int remote_leader_rank_in_peer_mpi; 
    272  
    273       ::MPI_Comm_rank(to_mpi_comm(peer_comm->mpi_comm), &local_leader_rank_in_peer_mpi); 
    274  
    275       if(is_local_leader) 
    276       { 
    277         MPI_Request request[2]; 
    278         MPI_Status status[2]; 
    279         MPI_Isend(&local_leader_rank_in_peer_mpi,  1, MPI_INT, remote_leader, tag, peer_comm, &request[0]); 
    280         MPI_Irecv(&remote_leader_rank_in_peer_mpi, 1, MPI_INT, remote_leader, tag, peer_comm, &request[1]); 
    281         MPI_Waitall(2, request, status); 
    282       } 
    283  
    284       ::MPI_Bcast(&remote_leader_rank_in_peer_mpi, 1, to_mpi_type(MPI_INT), local_comm->ep_rank_map->at(local_leader).second, to_mpi_comm(local_comm->mpi_comm));       
    285  
    286323 
    287324      if(ownership) 
    288325        ::MPI_Intercomm_create(*extracted_comm, local_leader_rank_in_extracted_comm, to_mpi_comm(peer_comm->mpi_comm), remote_leader_rank_in_peer_mpi, tag, mpi_inter_comm); 
    289326 
    290  
    291       // step 5 :: determine new num_ep 
     327      //////////////////////////////////// 
     328      // step 5 :: determine new num_ep // 
     329      //////////////////////////////////// 
    292330 
    293331      int num_ep_count=0; 
     
    305343      } 
    306344 
    307       //printf("peer_rank = %d, num_ep_count = %d\n", peer_comm->ep_comm_ptr->size_rank_info[0].first, num_ep_count); 
    308  
    309  
    310       // step 6 : create endpoints from extracted_comm  
     345 
     346      /////////////////////////////////////////////////// 
     347      // step 6 : create endpoints from extracted_comm // 
     348      /////////////////////////////////////////////////// 
    311349 
    312350      if(ownership) 
     
    323361          ep_comm[i]->ep_comm_ptr->intercomm->mpi_inter_comm = mpi_inter_comm; 
    324362        } 
    325  
    326         //delete ep_comm[0]->ep_rank_map; 
    327363 
    328364 
     
    397433#endif 
    398434 
    399  
    400     // step 7 : create intercomm_rank_map for local leaders 
     435    ////////////////////////////////////////////////////////// 
     436    // step 7 : create intercomm_rank_map for local leaders // 
     437    ////////////////////////////////////////////////////////// 
    401438     
    402439    int my_quadruple[4]; 
     
    431468    if(is_local_leader) 
    432469    { 
    433       MPI_Request request[2]; 
    434       MPI_Status status[2]; 
    435       MPI_Isend(local_quadruple_list,  4*ep_size,        MPI_INT, remote_leader, tag, peer_comm, &request[0]); 
    436       MPI_Irecv(remote_quadruple_list, 4*remote_ep_size, MPI_INT, remote_leader, tag, peer_comm, &request[1]); 
    437       MPI_Waitall(2, request, status); 
     470      MPI_Request request; 
     471      MPI_Status status; 
     472 
     473      if(remote_leader > local_leader_rank_in_peer) 
     474      { 
     475        MPI_Isend(local_quadruple_list,  4*ep_size, MPI_INT, remote_leader, tag, peer_comm, &request); 
     476        MPI_Wait(&request, &status);         
     477 
     478        MPI_Irecv(remote_quadruple_list, 4*remote_ep_size, MPI_INT, remote_leader, tag, peer_comm, &request); 
     479        MPI_Wait(&request, &status); 
     480      } 
     481      else 
     482      { 
     483        MPI_Irecv(remote_quadruple_list, 4*remote_ep_size, MPI_INT, remote_leader, tag, peer_comm, &request); 
     484        MPI_Wait(&request, &status); 
     485           
     486        MPI_Isend(local_quadruple_list,  4*ep_size, MPI_INT, remote_leader, tag, peer_comm, &request); 
     487        MPI_Wait(&request, &status);        
     488      } 
     489#ifdef _showinfo 
     490      printf("peer_rank = %d, quadruple_list exchange OK\n", local_leader_rank_in_peer); 
     491#endif 
    438492    } 
    439493 
     
    448502    } 
    449503 
    450  
    451     // step 8 : associate intercomm_rank_map to endpoints 
     504    //////////////////////////////////////////////////////// 
     505    // step 8 : associate intercomm_rank_map to endpoints // 
     506    //////////////////////////////////////////////////////// 
    452507 
    453508    int *leader_rank_in_world_local_gathered = new int[(*newintercomm)->ep_comm_ptr->size_rank_info[1].second]; 
     
    467522    if(is_involved) 
    468523    { 
    469       if((*newintercomm)->ep_comm_ptr->size_rank_info[1].first == 0) 
    470       { 
    471         (*newintercomm)->ep_rank_map->clear(); 
    472         delete (*newintercomm)->ep_rank_map; 
    473       } 
    474       (*newintercomm)->ep_rank_map = new EP_RANK_MAP[ep_size]; 
    475       *((*newintercomm)->ep_rank_map) = *(local_comm->ep_rank_map); 
     524      (*newintercomm)->ep_comm_ptr->intercomm->local_rank_map = new EP_RANK_MAP[ep_size]; 
     525      *((*newintercomm)->ep_comm_ptr->intercomm->local_rank_map) = *(local_comm->ep_rank_map); 
    476526    } 
    477527 
     
    491541      } 
    492542      (*newintercomm)->ep_comm_ptr->intercomm->intercomm_rank_map = (*newintercomm)->ep_comm_ptr->comm_list[target]->ep_comm_ptr->intercomm->intercomm_rank_map; 
    493       (*newintercomm)->ep_rank_map = (*newintercomm)->ep_comm_ptr->comm_list[target]->ep_rank_map; 
    494     } 
    495  
    496  
    497     //printf("peer_rank = %d, intercomm_rank_map add = %p\n", peer_comm->ep_comm_ptr->size_rank_info[0].first, (*newintercomm)->ep_comm_ptr->intercomm->intercomm_rank_map); 
    498      
    499  
     543      (*newintercomm)->ep_comm_ptr->intercomm->local_rank_map = (*newintercomm)->ep_comm_ptr->comm_list[target]->ep_comm_ptr->intercomm->local_rank_map; 
     544    } 
     545 
     546    (*newintercomm)->ep_comm_ptr->size_rank_info[0]=local_comm->ep_comm_ptr->size_rank_info[0]; 
     547    (*newintercomm)->ep_comm_ptr->size_rank_info[1]=local_comm->ep_comm_ptr->size_rank_info[1]; 
     548    (*newintercomm)->ep_comm_ptr->size_rank_info[2]=local_comm->ep_comm_ptr->size_rank_info[2]; 
     549     
     550/* 
    500551    if(peer_comm->ep_comm_ptr->size_rank_info[0].first == 5) 
    501552    { 
     
    512563    } 
    513564 
    514     //printf("peer_rank = %d, rank_map add = %p\n", peer_comm->ep_comm_ptr->size_rank_info[0].first, (*newintercomm)->ep_rank_map); 
    515  
    516565 
    517566    if(peer_comm->ep_comm_ptr->size_rank_info[0].first == 5) 
     
    522571      } 
    523572    } 
    524  
    525  
    526     // clean up 
     573*/ 
     574    ////////////// 
     575    // clean up // 
     576    ////////////// 
    527577 
    528578    delete ranks_in_world_local; 
     
    541591  } 
    542592 
    543   int MPI_Intercomm_create_kernel_bkp(MPI_Comm local_comm, int local_leader, MPI_Comm peer_comm, int remote_leader, int tag, MPI_Comm *newintercomm) 
    544   { 
    545     int ep_rank, ep_rank_loc, mpi_rank; 
    546     int ep_size, num_ep, mpi_size; 
    547  
    548     ep_rank = local_comm->ep_comm_ptr->size_rank_info[0].first; 
    549     ep_rank_loc = local_comm->ep_comm_ptr->size_rank_info[1].first; 
    550     mpi_rank = local_comm->ep_comm_ptr->size_rank_info[2].first; 
    551     ep_size = local_comm->ep_comm_ptr->size_rank_info[0].second; 
    552     num_ep = local_comm->ep_comm_ptr->size_rank_info[1].second; 
    553     mpi_size = local_comm->ep_comm_ptr->size_rank_info[2].second; 
    554  
    555  
    556     std::vector<int> rank_info[4];  //! 0->rank_in_world of local_comm,  1->rank_in_local_parent of local_comm 
    557                                     //! 2->rank_in_world of remote_comm, 3->rank_in_local_parent of remote_comm 
    558  
    559     int rank_in_world; 
    560     int rank_in_local_parent; 
    561  
    562     int rank_in_peer_mpi[2]; 
    563  
    564     int local_ep_size = ep_size; 
    565     int remote_ep_size; 
    566  
    567  
    568     ::MPI_Comm local_mpi_comm = to_mpi_comm(local_comm->mpi_comm); 
    569  
    570      
    571     ::MPI_Comm_rank(to_mpi_comm(MPI_COMM_WORLD->mpi_comm), &rank_in_world); 
    572     ::MPI_Comm_rank(local_mpi_comm, &rank_in_local_parent); 
    573      
    574  
    575     bool is_proc_master = false; 
    576     bool is_local_leader = false; 
    577     bool is_final_master = false; 
    578  
    579  
    580     if(ep_rank == local_leader) { is_proc_master = true; is_local_leader = true; is_final_master = true;} 
    581     if(ep_rank_loc == 0 && mpi_rank != local_comm->ep_rank_map->at(local_leader).second) is_proc_master = true; 
    582  
    583  
    584     int size_info[4]; //! used for choose size of rank_info 0-> mpi_size of local_comm, 1-> mpi_size of remote_comm 
    585  
    586     int leader_info[4]; //! 0->world rank of local_leader, 1->world rank of remote leader 
    587  
    588  
    589     std::vector<int> ep_info[2]; //! 0-> num_ep in local_comm, 1->num_ep in remote_comm 
    590  
    591     std::vector<int> new_rank_info[4]; 
    592     std::vector<int> new_ep_info[2]; 
    593  
    594     std::vector<int> offset; 
    595  
    596     if(is_proc_master) 
    597     { 
    598  
    599       size_info[0] = mpi_size; 
    600  
    601       rank_info[0].resize(size_info[0]); 
    602       rank_info[1].resize(size_info[0]); 
    603  
    604  
    605  
    606       ep_info[0].resize(size_info[0]); 
    607  
    608       vector<int> send_buf(6); 
    609       vector<int> recv_buf(3*size_info[0]); 
    610  
    611       send_buf[0] = rank_in_world; 
    612       send_buf[1] = rank_in_local_parent; 
    613       send_buf[2] = num_ep; 
    614  
    615       ::MPI_Allgather(send_buf.data(), 3, to_mpi_type(MPI_INT), recv_buf.data(), 3, to_mpi_type(MPI_INT), local_mpi_comm); 
    616  
    617       for(int i=0; i<size_info[0]; i++) 
    618       { 
    619         rank_info[0][i] = recv_buf[3*i]; 
    620         rank_info[1][i] = recv_buf[3*i+1]; 
    621         ep_info[0][i]   = recv_buf[3*i+2]; 
    622       } 
    623  
    624       if(is_local_leader) 
    625       { 
    626         leader_info[0] = rank_in_world; 
    627         leader_info[1] = remote_leader; 
    628  
    629         ::MPI_Comm_rank(to_mpi_comm(peer_comm->mpi_comm), &rank_in_peer_mpi[0]); 
    630  
    631         send_buf[0] = size_info[0]; 
    632         send_buf[1] = local_ep_size; 
    633         send_buf[2] = rank_in_peer_mpi[0]; 
    634  
    635          
    636          
    637         MPI_Request requests[2]; 
    638         MPI_Status statuses[2]; 
    639          
    640         MPI_Isend(send_buf.data(), 3, MPI_INT, remote_leader, tag, peer_comm, &requests[0]); 
    641         MPI_Irecv(recv_buf.data(), 3, MPI_INT, remote_leader, tag, peer_comm, &requests[1]); 
    642  
    643  
    644         MPI_Waitall(2, requests, statuses); 
    645          
    646         size_info[1] = recv_buf[0]; 
    647         remote_ep_size = recv_buf[1]; 
    648         rank_in_peer_mpi[1] = recv_buf[2]; 
    649  
    650       } 
    651  
    652  
    653  
    654       send_buf[0] = size_info[1]; 
    655       send_buf[1] = leader_info[0]; 
    656       send_buf[2] = leader_info[1]; 
    657       send_buf[3] = rank_in_peer_mpi[0]; 
    658       send_buf[4] = rank_in_peer_mpi[1]; 
    659  
    660       ::MPI_Bcast(send_buf.data(), 5, to_mpi_type(MPI_INT), local_comm->ep_rank_map->at(local_leader).second, local_mpi_comm); 
    661  
    662       size_info[1] = send_buf[0]; 
    663       leader_info[0] = send_buf[1]; 
    664       leader_info[1] = send_buf[2]; 
    665       rank_in_peer_mpi[0] = send_buf[3]; 
    666       rank_in_peer_mpi[1] = send_buf[4]; 
    667  
    668  
    669       rank_info[2].resize(size_info[1]); 
    670       rank_info[3].resize(size_info[1]); 
    671  
    672       ep_info[1].resize(size_info[1]); 
    673  
    674       send_buf.resize(3*size_info[0]); 
    675       recv_buf.resize(3*size_info[1]); 
    676  
    677       if(is_local_leader) 
    678       { 
    679         MPI_Request requests[2]; 
    680         MPI_Status statuses[2]; 
    681  
    682         std::copy ( rank_info[0].data(), rank_info[0].data() + size_info[0], send_buf.begin() ); 
    683         std::copy ( rank_info[1].data(), rank_info[1].data() + size_info[0], send_buf.begin() + size_info[0] ); 
    684         std::copy ( ep_info[0].data(),   ep_info[0].data()   + size_info[0], send_buf.begin() + 2*size_info[0] ); 
    685  
    686         MPI_Isend(send_buf.data(), 3*size_info[0], MPI_INT, remote_leader, tag+1, peer_comm, &requests[0]); 
    687         MPI_Irecv(recv_buf.data(), 3*size_info[1], MPI_INT, remote_leader, tag+1, peer_comm, &requests[1]); 
    688          
    689         MPI_Waitall(2, requests, statuses); 
    690       } 
    691  
    692       ::MPI_Bcast(recv_buf.data(), 3*size_info[1], to_mpi_type(MPI_INT), local_comm->ep_rank_map->at(local_leader).second, local_mpi_comm); 
    693  
    694       std::copy ( recv_buf.data(), recv_buf.data() + size_info[1], rank_info[2].begin() ); 
    695       std::copy ( recv_buf.data() + size_info[1], recv_buf.data() + 2*size_info[1], rank_info[3].begin()  ); 
    696       std::copy ( recv_buf.data() + 2*size_info[1], recv_buf.data() + 3*size_info[1], ep_info[1].begin() ); 
    697  
    698  
    699       offset.resize(size_info[0]); 
    700  
    701       if(leader_info[0]<leader_info[1]) // erase all ranks doubled with remote_comm, except the local leader 
    702       { 
    703  
    704         bool found = false; 
    705         int ep_local; 
    706         int ep_remote; 
    707         for(int i=0; i<size_info[0]; i++) 
    708         { 
    709           int target = rank_info[0][i]; 
    710           found = false; 
    711           for(int j=0; j<size_info[1]; j++) 
    712           { 
    713             if(target == rank_info[2][j]) 
    714             { 
    715               found = true; 
    716               ep_local = ep_info[0][j]; 
    717               ep_remote = ep_info[1][j]; 
    718               break; 
    719             } 
    720           } 
    721           if(found) 
    722           { 
    723  
    724             if(target == leader_info[0]) // the leader is doubled in remote 
    725             { 
    726               new_rank_info[0].push_back(target); 
    727               new_rank_info[1].push_back(rank_info[1][i]); 
    728  
    729               new_ep_info[0].push_back(ep_local + ep_remote); 
    730               offset[i] = 0; 
    731             } 
    732             else 
    733             { 
    734               offset[i] = ep_local; 
    735             } 
    736           } 
    737           else 
    738           { 
    739             new_rank_info[0].push_back(target); 
    740             new_rank_info[1].push_back(rank_info[1][i]); 
    741  
    742             new_ep_info[0].push_back(ep_info[0][i]); 
    743  
    744             offset[i] = 0; 
    745           } 
    746  
    747         } 
    748       } 
    749  
    750       else // erase rank doubled with remote leader 
    751       { 
    752  
    753         bool found = false; 
    754         int ep_local; 
    755         int ep_remote; 
    756         for(int i=0; i<size_info[0]; i++) 
    757         { 
    758           int target = rank_info[0][i]; 
    759           found = false; 
    760           for(int j=0; j<size_info[1]; j++) 
    761           { 
    762  
    763             if(target == rank_info[2][j]) 
    764             { 
    765               found = true; 
    766               ep_local = ep_info[0][j]; 
    767               ep_remote = ep_info[1][j]; 
    768               break; 
    769             } 
    770           } 
    771           if(found) 
    772           { 
    773             if(target != leader_info[1]) 
    774             { 
    775               new_rank_info[0].push_back(target); 
    776               new_rank_info[1].push_back(rank_info[1][i]); 
    777  
    778               new_ep_info[0].push_back(ep_local + ep_remote); 
    779               offset[i] = 0; 
    780             } 
    781             else // found remote leader 
    782             { 
    783               offset[i] = ep_remote; 
    784             } 
    785           } 
    786           else 
    787           { 
    788             new_rank_info[0].push_back(target); 
    789             new_rank_info[1].push_back(rank_info[1][i]); 
    790  
    791             new_ep_info[0].push_back(ep_info[0][i]); 
    792             offset[i] = 0; 
    793           } 
    794         } 
    795       } 
    796  
    797       if(offset[mpi_rank] == 0) 
    798       { 
    799         is_final_master = true; 
    800       } 
    801  
    802  
    803       //! size_info[4]: 2->size of new_ep_info for local, 3->size of new_ep_info for remote 
    804  
    805       if(is_local_leader) 
    806       { 
    807         size_info[2] = new_ep_info[0].size(); 
    808         MPI_Request requests[2]; 
    809         MPI_Status statuses[2]; 
    810         MPI_Isend(&size_info[2], 1, MPI_INT, remote_leader, tag+2, peer_comm, &requests[0]); 
    811         MPI_Irecv(&size_info[3], 1, MPI_INT, remote_leader, tag+2, peer_comm, &requests[1]); 
    812           
    813         MPI_Waitall(2, requests, statuses); 
    814       } 
    815  
    816       ::MPI_Bcast(&size_info[2], 2, to_mpi_type(MPI_INT), local_comm->ep_rank_map->at(local_leader).second, local_mpi_comm); 
    817  
    818       new_rank_info[2].resize(size_info[3]); 
    819       new_rank_info[3].resize(size_info[3]); 
    820       new_ep_info[1].resize(size_info[3]); 
    821  
    822       send_buf.resize(size_info[2]); 
    823       recv_buf.resize(size_info[3]); 
    824  
    825       if(is_local_leader) 
    826       { 
    827         MPI_Request requests[2]; 
    828         MPI_Status statuses[2]; 
    829  
    830         std::copy ( new_rank_info[0].data(), new_rank_info[0].data() + size_info[2], send_buf.begin() ); 
    831         std::copy ( new_rank_info[1].data(), new_rank_info[1].data() + size_info[2], send_buf.begin() + size_info[2] ); 
    832         std::copy ( new_ep_info[0].data(),   new_ep_info[0].data()   + size_info[0], send_buf.begin() + 2*size_info[2] ); 
    833  
    834         MPI_Isend(send_buf.data(), 3*size_info[2], MPI_INT, remote_leader, tag+3, peer_comm, &requests[0]); 
    835         MPI_Irecv(recv_buf.data(), 3*size_info[3], MPI_INT, remote_leader, tag+3, peer_comm, &requests[1]); 
    836          
    837         MPI_Waitall(2, requests, statuses); 
    838       } 
    839  
    840       ::MPI_Bcast(recv_buf.data(),   3*size_info[3], to_mpi_type(MPI_INT), local_comm->ep_rank_map->at(local_leader).second, local_mpi_comm); 
    841  
    842       std::copy ( recv_buf.data(), recv_buf.data() + size_info[3], new_rank_info[2].begin() ); 
    843       std::copy ( recv_buf.data() + size_info[3], recv_buf.data() + 2*size_info[3], new_rank_info[3].begin()  ); 
    844       std::copy ( recv_buf.data() + 2*size_info[3], recv_buf.data() + 3*size_info[3], new_ep_info[1].begin() ); 
    845  
    846     } 
    847  
    848      
    849  
    850     if(is_proc_master) 
    851     { 
    852       //! leader_info[4]: 2-> rank of local leader in new_group generated comm; 
    853                       // 3-> rank of remote leader in new_group generated comm; 
    854       ::MPI_Group local_group; 
    855       ::MPI_Group new_group; 
    856       ::MPI_Comm *new_comm = new ::MPI_Comm; 
    857       ::MPI_Comm *intercomm = new ::MPI_Comm; 
    858  
    859       ::MPI_Comm_group(local_mpi_comm, &local_group); 
    860  
    861       ::MPI_Group_incl(local_group, size_info[2], new_rank_info[1].data(), &new_group); 
    862  
    863       ::MPI_Comm_create(local_mpi_comm, new_group, new_comm); 
    864  
    865  
    866  
    867       if(is_local_leader) 
    868       { 
    869         ::MPI_Comm_rank(*new_comm, &leader_info[2]); 
    870       } 
    871  
    872       ::MPI_Bcast(&leader_info[2], 1, to_mpi_type(MPI_INT), local_comm->ep_rank_map->at(local_leader).second, local_mpi_comm); 
    873  
    874       if(new_comm != static_cast< ::MPI_Comm*>(MPI_COMM_NULL->mpi_comm)) 
    875       { 
    876  
    877         ::MPI_Barrier(*new_comm); 
    878  
    879         ::MPI_Intercomm_create(*new_comm, leader_info[2], to_mpi_comm(peer_comm->mpi_comm), rank_in_peer_mpi[1], tag, intercomm); 
    880  
    881         int id; 
    882  
    883         ::MPI_Comm_rank(*new_comm, &id); 
    884         int my_num_ep = new_ep_info[0][id]; 
    885  
    886         MPI_Comm *ep_intercomm; 
    887         MPI_Info info; 
    888         MPI_Comm_create_endpoints(new_comm, my_num_ep, info, ep_intercomm); 
    889  
    890  
    891         for(int i= 0; i<my_num_ep; i++) 
    892         { 
    893           ep_intercomm[i]->is_intercomm = true; 
    894  
    895           ep_intercomm[i]->ep_comm_ptr->intercomm = new ep_lib::ep_intercomm; 
    896           ep_intercomm[i]->ep_comm_ptr->intercomm->mpi_inter_comm = intercomm; 
    897           ep_intercomm[i]->ep_comm_ptr->comm_label = leader_info[0]; 
    898         } 
    899  
    900  
    901         #pragma omp critical (write_to_tag_list) 
    902         tag_list.push_back(make_pair( make_pair(tag, min(leader_info[0], leader_info[1])) , ep_intercomm)); 
    903         //printf("tag_list size = %lu\n", tag_list.size()); 
    904       } 
    905     } 
    906  
    907     vector<int> bcast_buf(8); 
    908     if(is_local_leader) 
    909     { 
    910       std::copy(size_info, size_info+4, bcast_buf.begin()); 
    911       std::copy(leader_info, leader_info+4, bcast_buf.begin()+4); 
    912     } 
    913  
    914     MPI_Bcast(bcast_buf.data(), 8, MPI_INT, local_leader, local_comm); 
    915  
    916     if(!is_local_leader) 
    917     { 
    918       std::copy(bcast_buf.begin(), bcast_buf.begin()+4, size_info); 
    919       std::copy(bcast_buf.begin()+4, bcast_buf.begin()+8, leader_info); 
    920     } 
    921  
    922     if(!is_local_leader) 
    923     { 
    924       new_rank_info[1].resize(size_info[2]); 
    925       ep_info[1].resize(size_info[1]); 
    926       offset.resize(size_info[0]); 
    927     } 
    928  
    929     bcast_buf.resize(size_info[2]+size_info[1]+size_info[0]+1); 
    930  
    931     if(is_local_leader) 
    932     { 
    933       bcast_buf[0] = remote_ep_size; 
    934       std::copy(new_rank_info[1].data(), new_rank_info[1].data()+size_info[2], bcast_buf.begin()+1); 
    935       std::copy(ep_info[1].data(), ep_info[1].data()+size_info[1], bcast_buf.begin()+size_info[2]+1); 
    936       std::copy(offset.data(), offset.data()+size_info[0], bcast_buf.begin()+size_info[2]+size_info[1]+1); 
    937     } 
    938  
    939     MPI_Bcast(bcast_buf.data(), size_info[2]+size_info[1]+size_info[0]+1, MPI_INT, local_leader, local_comm); 
    940  
    941     if(!is_local_leader) 
    942     { 
    943       remote_ep_size = bcast_buf[0]; 
    944       std::copy(bcast_buf.data()+1, bcast_buf.data()+1+size_info[2], new_rank_info[1].begin()); 
    945       std::copy(bcast_buf.data()+1+size_info[2], bcast_buf.data()+1+size_info[2]+size_info[1], ep_info[1].begin()); 
    946       std::copy(bcast_buf.data()+1+size_info[2]+size_info[1], bcast_buf.data()+1+size_info[2]+size_info[1]+size_info[0], offset.begin()); 
    947     } 
    948  
    949     int my_position = offset[rank_in_local_parent]+ep_rank_loc; 
    950      
    951     MPI_Barrier_local(local_comm); 
    952     #pragma omp flush 
    953  
    954  
    955     #pragma omp critical (read_from_tag_list) 
    956     { 
    957       bool found = false; 
    958       while(!found) 
    959       { 
    960         for(std::list<std::pair < std::pair<int,int>, MPI_Comm* > >::iterator iter = tag_list.begin(); iter!=tag_list.end(); iter++) 
    961         { 
    962           if((*iter).first == make_pair(tag, min(leader_info[0], leader_info[1]))) 
    963           { 
    964             *newintercomm = iter->second[my_position]; 
    965             found = true; 
    966             break; 
    967           } 
    968         } 
    969       } 
    970     } 
    971  
    972     MPI_Barrier(local_comm); 
    973  
    974     if(is_local_leader) 
    975     { 
    976       int local_flag = true; 
    977       int remote_flag = false; 
    978       MPI_Request mpi_requests[2]; 
    979       MPI_Status mpi_statuses[2]; 
    980        
    981       MPI_Isend(&local_flag, 1, MPI_INT, remote_leader, tag, peer_comm, &mpi_requests[0]); 
    982       MPI_Irecv(&remote_flag, 1, MPI_INT, remote_leader, tag, peer_comm, &mpi_requests[1]); 
    983        
    984       MPI_Waitall(2, mpi_requests, mpi_statuses); 
    985     } 
    986  
    987  
    988     MPI_Barrier(local_comm); 
    989  
    990     if(is_proc_master) 
    991     { 
    992       for(std::list<std::pair < std::pair<int,int>, MPI_Comm* > >::iterator iter = tag_list.begin(); iter!=tag_list.end(); iter++) 
    993       { 
    994         if((*iter).first == make_pair(tag, min(leader_info[0], leader_info[1]))) 
    995         { 
    996           tag_list.erase(iter); 
    997           break; 
    998         } 
    999       } 
    1000     } 
    1001  
    1002     int intercomm_ep_rank, intercomm_ep_rank_loc, intercomm_mpi_rank; 
    1003     int intercomm_ep_size, intercomm_num_ep, intercomm_mpi_size; 
    1004  
    1005     intercomm_ep_rank = (*newintercomm)->ep_comm_ptr->size_rank_info[0].first; 
    1006     intercomm_ep_rank_loc = (*newintercomm)->ep_comm_ptr->size_rank_info[1].first; 
    1007     intercomm_mpi_rank = (*newintercomm)->ep_comm_ptr->size_rank_info[2].first; 
    1008     intercomm_ep_size = (*newintercomm)->ep_comm_ptr->size_rank_info[0].second; 
    1009     intercomm_num_ep = (*newintercomm)->ep_comm_ptr->size_rank_info[1].second; 
    1010     intercomm_mpi_size = (*newintercomm)->ep_comm_ptr->size_rank_info[2].second; 
    1011  
    1012     MPI_Bcast(&remote_ep_size, 1, MPI_INT, local_leader, local_comm); 
    1013  
    1014     int my_rank_map_elem[2]; 
    1015  
    1016     my_rank_map_elem[0] = intercomm_ep_rank; 
    1017     my_rank_map_elem[1] = (*newintercomm)->ep_comm_ptr->comm_label; 
    1018  
    1019     vector<pair<int, int> > local_rank_map_array; 
    1020     vector<pair<int, int> > remote_rank_map_array; 
    1021  
    1022  
    1023     (*newintercomm)->ep_comm_ptr->intercomm->local_rank_map = new RANK_MAP; 
    1024     (*newintercomm)->ep_comm_ptr->intercomm->local_rank_map->resize(local_ep_size); 
    1025  
    1026     MPI_Allgather(my_rank_map_elem, 2, MPI_INT,  
    1027       (*newintercomm)->ep_comm_ptr->intercomm->local_rank_map->data(), 2, MPI_INT, local_comm); 
    1028  
    1029     (*newintercomm)->ep_comm_ptr->intercomm->remote_rank_map = new RANK_MAP; 
    1030     (*newintercomm)->ep_comm_ptr->intercomm->remote_rank_map->resize(remote_ep_size); 
    1031  
    1032     (*newintercomm)->ep_comm_ptr->intercomm->size_rank_info[0] = local_comm->ep_comm_ptr->size_rank_info[0]; 
    1033     (*newintercomm)->ep_comm_ptr->intercomm->size_rank_info[1] = local_comm->ep_comm_ptr->size_rank_info[1]; 
    1034     (*newintercomm)->ep_comm_ptr->intercomm->size_rank_info[2] = local_comm->ep_comm_ptr->size_rank_info[2]; 
    1035  
    1036     int local_intercomm_size = intercomm_ep_size; 
    1037     int remote_intercomm_size; 
    1038  
    1039     int new_bcast_root_0 = 0; 
    1040     int new_bcast_root = 0; 
    1041  
    1042  
    1043     if(is_local_leader) 
    1044     { 
    1045       MPI_Request requests[4]; 
    1046       MPI_Status statuses[4]; 
    1047        
    1048       MPI_Isend((*newintercomm)->ep_comm_ptr->intercomm->local_rank_map->data(), 2*local_ep_size, MPI_INT, remote_leader, tag+4, peer_comm, &requests[0]); 
    1049       MPI_Irecv((*newintercomm)->ep_comm_ptr->intercomm->remote_rank_map->data(), 2*remote_ep_size, MPI_INT, remote_leader, tag+4, peer_comm, &requests[1]); 
    1050  
    1051       MPI_Isend(&local_intercomm_size, 1, MPI_INT, remote_leader, tag+5, peer_comm, &requests[2]); 
    1052       MPI_Irecv(&remote_intercomm_size, 1, MPI_INT, remote_leader, tag+5, peer_comm, &requests[3]); 
    1053        
    1054       MPI_Waitall(4, requests, statuses); 
    1055  
    1056       new_bcast_root_0 = intercomm_ep_rank; 
    1057     } 
    1058  
    1059     MPI_Allreduce(&new_bcast_root_0, &new_bcast_root, 1, MPI_INT, MPI_SUM, *newintercomm); 
    1060  
    1061  
    1062     MPI_Bcast((*newintercomm)->ep_comm_ptr->intercomm->remote_rank_map->data(), 2*remote_ep_size, MPI_INT, local_leader, local_comm); 
    1063     MPI_Bcast(&remote_intercomm_size, 1, MPI_INT, new_bcast_root, *newintercomm); 
    1064  
    1065  
    1066     //(*newintercomm)->ep_comm_ptr->intercomm->intercomm_rank_map = new RANK_MAP; 
    1067     //(*newintercomm)->ep_comm_ptr->intercomm->intercomm_rank_map->resize(remote_intercomm_size); 
    1068  
    1069  
    1070  
    1071  
    1072     if(is_local_leader) 
    1073     { 
    1074       MPI_Request requests[2]; 
    1075       MPI_Status statuses[2]; 
    1076        
    1077       std::vector<std::pair<int, std::pair<int, int> > > map2vec((*newintercomm)->ep_rank_map->size()); 
    1078       std::vector<std::pair<int, std::pair<int, int> > > vec2map((*newintercomm)->ep_comm_ptr->intercomm->intercomm_rank_map->size()); 
    1079        
    1080       int ii=0; 
    1081       for(std::map<int, std::pair<int, int> >::iterator it = (*newintercomm)->ep_rank_map->begin(); it != (*newintercomm)->ep_rank_map->end(); it++) 
    1082       { 
    1083         map2vec[ii++] = make_pair(it->first, make_pair(it->second.first, it->second.second)); 
    1084       } 
    1085        
    1086        
    1087       MPI_Isend(map2vec.data(), 3*local_intercomm_size, MPI_INT, remote_leader, tag+6, peer_comm, &requests[0]); 
    1088       MPI_Irecv(vec2map.data(), 3*remote_intercomm_size, MPI_INT, remote_leader, tag+6, peer_comm, &requests[1]); 
    1089        
    1090       
    1091       for(ii=0; ii<vec2map.size(); ii++) 
    1092       { 
    1093         //(*newintercomm)->ep_comm_ptr->intercomm->intercomm_rank_map->at(vec2map[ii].first) = make_pair(vec2map[ii].second.first, vec2map[ii].second.second); 
    1094       } 
    1095        
    1096       MPI_Waitall(2, requests, statuses); 
    1097     } 
    1098  
    1099     //MPI_Bcast((*newintercomm)->ep_comm_ptr->intercomm->intercomm_rank_map->data(), 2*remote_intercomm_size, MPI_INT, new_bcast_root, *newintercomm); 
    1100  
    1101     //(*newintercomm)->ep_comm_ptr->intercomm->local_comm = (local_comm->ep_comm_ptr->comm_list[ep_rank_loc]); 
    1102     (*newintercomm)->ep_comm_ptr->intercomm->intercomm_tag = tag; 
    1103  
    1104 /* 
    1105     for(int i=0; i<local_ep_size; i++) 
    1106     if(local_comm->ep_comm_ptr->comm_label == 0) printf("ep_rank (from EP) = %d, local_rank_map[%d] = (%d,%d)\n", intercomm_ep_rank, i, 
    1107           (*newintercomm)->ep_comm_ptr->intercomm->local_rank_map->at(i).first, (*newintercomm)->ep_comm_ptr->intercomm->local_rank_map->at(i).second); 
    1108  
    1109     for(int i=0; i<remote_ep_size; i++) 
    1110     if(local_comm->ep_comm_ptr->comm_label == 0) printf("ep_rank (from EP) = %d, remote_rank_map[%d] = (%d,%d)\n", intercomm_ep_rank, i, 
    1111           (*newintercomm)->ep_comm_ptr->intercomm->remote_rank_map->at(i).first, (*newintercomm)->ep_comm_ptr->intercomm->remote_rank_map->at(i).second); 
    1112  
    1113     for(int i=0; i<remote_intercomm_size; i++) 
    1114     if(local_comm->ep_comm_ptr->comm_label == 0) printf("ep_rank (from EP) = %d, intercomm_rank_map[%d] = (%d,%d)\n", intercomm_ep_rank, i, 
    1115           (*newintercomm)->ep_comm_ptr->intercomm->intercomm_rank_map->at(i).first, (*newintercomm)->ep_comm_ptr->intercomm->intercomm_rank_map->at(i).second); 
    1116 */ 
    1117  
    1118 //    for(int i=0; i<(*newintercomm)->rank_map->size(); i++) 
    1119 //    if(local_comm->ep_comm_ptr->comm_label != 99) printf("ep_rank = %d, rank_map[%d] = (%d,%d)\n", intercomm_ep_rank, i, 
    1120 //          (*newintercomm)->rank_map->at(i).first, (*newintercomm)->rank_map->at(i).second); 
    1121  
    1122 //    MPI_Comm *test_comm = newintercomm->ep_comm_ptr->intercomm->local_comm; 
    1123 //    int test_rank; 
    1124 //    MPI_Comm_rank(*test_comm, &test_rank); 
    1125 //    printf("=================test_rank = %d\n", test_rank); 
    1126      
    1127      
    1128  
    1129     return MPI_SUCCESS; 
    1130  
    1131   } 
    1132  
    1133  
    1134  
    1135  
    1136   int MPI_Intercomm_create_unique_leader(MPI_Comm local_comm, int local_leader, MPI_Comm peer_comm, int remote_leader, int tag, MPI_Comm *newintercomm) 
    1137   { 
    1138     //! mpi_size of local comm = 1 
    1139     //! same world rank of leaders 
    1140  
    1141     int ep_rank, ep_rank_loc, mpi_rank; 
    1142     int ep_size, num_ep, mpi_size; 
    1143  
    1144     ep_rank = local_comm->ep_comm_ptr->size_rank_info[0].first; 
    1145     ep_rank_loc = local_comm->ep_comm_ptr->size_rank_info[1].first; 
    1146     mpi_rank = local_comm->ep_comm_ptr->size_rank_info[2].first; 
    1147     ep_size = local_comm->ep_comm_ptr->size_rank_info[0].second; 
    1148     num_ep = local_comm->ep_comm_ptr->size_rank_info[1].second; 
    1149     mpi_size = local_comm->ep_comm_ptr->size_rank_info[2].second; 
    1150  
    1151  
    1152  
    1153     std::vector<int> rank_info[4];  //! 0->rank_in_world of local_comm,  1->rank_in_local_parent of local_comm 
    1154                                     //! 2->rank_in_world of remote_comm, 3->rank_in_local_parent of remote_comm 
    1155  
    1156     int rank_in_world; 
    1157  
    1158     int rank_in_peer_mpi[2]; 
    1159  
    1160     ::MPI_Comm_rank(to_mpi_comm(MPI_COMM_WORLD->mpi_comm), &rank_in_world); 
    1161  
    1162  
    1163     int local_num_ep = num_ep; 
    1164     int remote_num_ep; 
    1165     int total_num_ep; 
    1166  
    1167     int leader_rank_in_peer[2]; 
    1168  
    1169     int my_position; 
    1170     int tag_label[2]; 
    1171  
    1172     vector<int> send_buf(4); 
    1173     vector<int> recv_buf(4); 
    1174  
    1175  
    1176     if(ep_rank == local_leader) 
    1177     { 
    1178       MPI_Status status; 
    1179  
    1180  
    1181  
    1182       MPI_Comm_rank(peer_comm, &leader_rank_in_peer[0]); 
    1183  
    1184       send_buf[0] = local_num_ep; 
    1185       send_buf[1] = leader_rank_in_peer[0]; 
    1186  
    1187       MPI_Request req_s, req_r; 
    1188  
    1189       MPI_Isend(send_buf.data(), 2, MPI_INT, remote_leader, tag, peer_comm, &req_s); 
    1190       MPI_Irecv(recv_buf.data(), 2, MPI_INT, remote_leader, tag, peer_comm, &req_r); 
    1191  
    1192  
    1193       MPI_Wait(&req_s, &status); 
    1194       MPI_Wait(&req_r, &status); 
    1195  
    1196       recv_buf[2] = leader_rank_in_peer[0]; 
    1197  
    1198     } 
    1199  
    1200     MPI_Bcast(recv_buf.data(), 3, MPI_INT, local_leader, local_comm); 
    1201  
    1202     remote_num_ep = recv_buf[0]; 
    1203     leader_rank_in_peer[1] = recv_buf[1]; 
    1204     leader_rank_in_peer[0] = recv_buf[2]; 
    1205  
    1206     total_num_ep = local_num_ep + remote_num_ep; 
    1207  
    1208  
    1209     if(leader_rank_in_peer[0] < leader_rank_in_peer[1]) 
    1210     { 
    1211       my_position = ep_rank_loc; 
    1212       //! LEADER create EP 
    1213       if(ep_rank == local_leader) 
    1214       { 
    1215         ::MPI_Comm *mpi_dup = new ::MPI_Comm; 
    1216          
    1217         ::MPI_Comm_dup(to_mpi_comm(local_comm->mpi_comm), mpi_dup); 
    1218  
    1219         MPI_Comm *ep_intercomm; 
    1220         MPI_Info info; 
    1221         MPI_Comm_create_endpoints(mpi_dup, total_num_ep, info, ep_intercomm); 
    1222  
    1223  
    1224         for(int i=0; i<total_num_ep; i++) 
    1225         { 
    1226           ep_intercomm[i]->is_intercomm = true; 
    1227           ep_intercomm[i]->ep_comm_ptr->intercomm = new ep_lib::ep_intercomm; 
    1228           ep_intercomm[i]->ep_comm_ptr->intercomm->mpi_inter_comm = 0; 
    1229  
    1230           ep_intercomm[i]->ep_comm_ptr->comm_label = leader_rank_in_peer[0]; 
    1231         } 
    1232  
    1233         tag_label[0] = TAG++; 
    1234         tag_label[1] = rank_in_world; 
    1235  
    1236         #pragma omp critical (write_to_tag_list) 
    1237         tag_list.push_back(make_pair( make_pair(tag_label[0], tag_label[1]) , ep_intercomm)); 
    1238  
    1239         MPI_Request req_s; 
    1240         MPI_Status sta_s; 
    1241         MPI_Isend(tag_label, 2, MPI_INT, remote_leader, tag, peer_comm, &req_s); 
    1242  
    1243         MPI_Wait(&req_s, &sta_s); 
    1244  
    1245       } 
    1246     } 
    1247     else 
    1248     { 
    1249       //! Wait for EP creation 
    1250       my_position = remote_num_ep + ep_rank_loc; 
    1251       if(ep_rank == local_leader) 
    1252       { 
    1253         MPI_Status status; 
    1254         MPI_Request req_r; 
    1255         MPI_Irecv(tag_label, 2, MPI_INT, remote_leader, tag, peer_comm, &req_r); 
    1256         MPI_Wait(&req_r, &status); 
    1257       } 
    1258     } 
    1259  
    1260     MPI_Bcast(tag_label, 2, MPI_INT, local_leader, local_comm); 
    1261  
    1262  
    1263  
    1264  
    1265     #pragma omp critical (read_from_tag_list) 
    1266     { 
    1267       bool found = false; 
    1268       while(!found) 
    1269       { 
    1270         for(std::list<std::pair < std::pair<int,int>, MPI_Comm* > >::iterator iter = tag_list.begin(); iter!=tag_list.end(); iter++) 
    1271         { 
    1272           if((*iter).first == make_pair(tag_label[0], tag_label[1])) 
    1273           { 
    1274             *newintercomm =  iter->second[my_position]; 
    1275             found = true; 
    1276             // tag_list.erase(iter); 
    1277             break; 
    1278           } 
    1279         } 
    1280       } 
    1281     } 
    1282  
    1283     MPI_Barrier_local(local_comm); 
    1284  
    1285     if(leader_rank_in_peer[0] < leader_rank_in_peer[1]) 
    1286     { 
    1287       for(std::list<std::pair < std::pair<int,int>, MPI_Comm* > >::iterator iter = tag_list.begin(); iter!=tag_list.end(); iter++) 
    1288         { 
    1289           if((*iter).first == make_pair(tag_label[0], tag_label[1])) 
    1290           { 
    1291             tag_list.erase(iter); 
    1292             break; 
    1293           } 
    1294         } 
    1295     } 
    1296  
    1297  
    1298  
    1299     int intercomm_ep_rank, intercomm_ep_rank_loc, intercomm_mpi_rank; 
    1300     int intercomm_ep_size, intercomm_num_ep, intercomm_mpi_size; 
    1301  
    1302     intercomm_ep_rank = (*newintercomm)->ep_comm_ptr->size_rank_info[0].first; 
    1303     intercomm_ep_rank_loc = (*newintercomm)->ep_comm_ptr->size_rank_info[1].first; 
    1304     intercomm_mpi_rank = (*newintercomm)->ep_comm_ptr->size_rank_info[2].first; 
    1305     intercomm_ep_size = (*newintercomm)->ep_comm_ptr->size_rank_info[0].second; 
    1306     intercomm_num_ep = (*newintercomm)->ep_comm_ptr->size_rank_info[1].second; 
    1307     intercomm_mpi_size = (*newintercomm)->ep_comm_ptr->size_rank_info[2].second; 
    1308  
    1309  
    1310  
    1311     (*newintercomm)->ep_comm_ptr->intercomm->local_rank_map  = new RANK_MAP; 
    1312     (*newintercomm)->ep_comm_ptr->intercomm->remote_rank_map = new RANK_MAP; 
    1313     (*newintercomm)->ep_comm_ptr->intercomm->local_rank_map->resize(local_num_ep); 
    1314     (*newintercomm)->ep_comm_ptr->intercomm->remote_rank_map->resize(remote_num_ep); 
    1315  
    1316     (*newintercomm)->ep_comm_ptr->intercomm->size_rank_info[0] = local_comm->ep_comm_ptr->size_rank_info[0]; 
    1317     (*newintercomm)->ep_comm_ptr->intercomm->size_rank_info[1] = local_comm->ep_comm_ptr->size_rank_info[1]; 
    1318     (*newintercomm)->ep_comm_ptr->intercomm->size_rank_info[2] = local_comm->ep_comm_ptr->size_rank_info[2]; 
    1319  
    1320  
    1321  
    1322     int local_rank_map_ele[2]; 
    1323     local_rank_map_ele[0] = intercomm_ep_rank; 
    1324     local_rank_map_ele[1] = (*newintercomm)->ep_comm_ptr->comm_label; 
    1325  
    1326     MPI_Allgather(local_rank_map_ele, 2, MPI_INT,  
    1327       (*newintercomm)->ep_comm_ptr->intercomm->local_rank_map->data(), 2, MPI_INT, local_comm); 
    1328  
    1329     if(ep_rank == local_leader) 
    1330     { 
    1331       MPI_Status status; 
    1332       MPI_Request req_s, req_r; 
    1333  
    1334       MPI_Isend((*newintercomm)->ep_comm_ptr->intercomm->local_rank_map->data(), 2*local_num_ep, MPI_INT, remote_leader, tag, peer_comm, &req_s); 
    1335       MPI_Irecv((*newintercomm)->ep_comm_ptr->intercomm->remote_rank_map->data(), 2*remote_num_ep, MPI_INT, remote_leader, tag, peer_comm, &req_r); 
    1336  
    1337  
    1338       MPI_Wait(&req_s, &status); 
    1339       MPI_Wait(&req_r, &status); 
    1340  
    1341     } 
    1342  
    1343     MPI_Bcast((*newintercomm)->ep_comm_ptr->intercomm->remote_rank_map->data(), 2*remote_num_ep, MPI_INT, local_leader, local_comm); 
    1344     //(*newintercomm)->ep_comm_ptr->intercomm->local_comm = (local_comm->ep_comm_ptr->comm_list[ep_rank_loc]); 
    1345     (*newintercomm)->ep_comm_ptr->intercomm->intercomm_tag = tag; 
    1346  
    1347  
    1348     return MPI_SUCCESS; 
    1349   } 
    1350  
    1351  
     593 
     594 
     595   
    1352596} 
Note: See TracChangeset for help on using the changeset viewer.