source: XIOS/dev/branch_yushan/extern/src_ep_dev/ep_intercomm_kernel.cpp @ 1063

Last change on this file since 1063 was 1053, checked in by yushan, 7 years ago

ep_lib namespace specified when netcdf involved

File size: 24.3 KB
Line 
1#include "ep_lib.hpp"
2#include <mpi.h>
3#include "ep_declaration.hpp"
4
5using namespace std;
6
7
8namespace ep_lib
9{
10  int MPI_Intercomm_create_kernel(MPI_Comm local_comm, int local_leader, MPI_Comm peer_comm, int remote_leader, int tag, MPI_Comm *newintercomm)
11  {
12
13    int ep_rank, ep_rank_loc, mpi_rank;
14    int ep_size, num_ep, mpi_size;
15
16    ep_rank = local_comm.ep_comm_ptr->size_rank_info[0].first;
17    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    std::vector<int> rank_info[4];  //! 0->rank_in_world of local_comm,  1->rank_in_local_parent of local_comm
24                                    //! 2->rank_in_world of remote_comm, 3->rank_in_local_parent of remote_comm
25
26    int rank_in_world;
27    int rank_in_local_parent;
28
29    int rank_in_peer_mpi[2];
30
31    int local_ep_size = ep_size;
32    int remote_ep_size;
33
34
35    ::MPI_Comm local_mpi_comm = static_cast< ::MPI_Comm>(local_comm.mpi_comm);
36
37   
38    ::MPI_Comm_rank(MPI_COMM_WORLD_STD, &rank_in_world);
39    ::MPI_Comm_rank(static_cast< ::MPI_Comm>(local_comm.mpi_comm), &rank_in_local_parent);
40   
41
42    bool is_proc_master = false;
43    bool is_local_leader = false;
44    bool is_final_master = false;
45
46
47    if(ep_rank == local_leader) { is_proc_master = true; is_local_leader = true; is_final_master = true;}
48    if(ep_rank_loc == 0 && mpi_rank != local_comm.rank_map->at(local_leader).second) is_proc_master = true;
49
50
51    int size_info[4]; //! used for choose size of rank_info 0-> mpi_size of local_comm, 1-> mpi_size of remote_comm
52
53    int leader_info[4]; //! 0->world rank of local_leader, 1->world rank of remote leader
54
55
56    std::vector<int> ep_info[2]; //! 0-> num_ep in local_comm, 1->num_ep in remote_comm
57
58    std::vector<int> new_rank_info[4];
59    std::vector<int> new_ep_info[2];
60
61    std::vector<int> offset;
62
63    if(is_proc_master)
64    {
65
66      size_info[0] = mpi_size;
67
68      rank_info[0].resize(size_info[0]);
69      rank_info[1].resize(size_info[0]);
70
71
72
73      ep_info[0].resize(size_info[0]);
74
75      vector<int> send_buf(6);
76      vector<int> recv_buf(3*size_info[0]);
77
78      send_buf[0] = rank_in_world;
79      send_buf[1] = rank_in_local_parent;
80      send_buf[2] = num_ep;
81
82      ::MPI_Allgather(send_buf.data(), 3, MPI_INT_STD, recv_buf.data(), 3, MPI_INT_STD, local_mpi_comm);
83
84      for(int i=0; i<size_info[0]; i++)
85      {
86        rank_info[0][i] = recv_buf[3*i];
87        rank_info[1][i] = recv_buf[3*i+1];
88        ep_info[0][i]   = recv_buf[3*i+2];
89      }
90
91      if(is_local_leader)
92      {
93        leader_info[0] = rank_in_world;
94        leader_info[1] = remote_leader;
95
96        ::MPI_Comm_rank(static_cast< ::MPI_Comm>(peer_comm.mpi_comm), &rank_in_peer_mpi[0]);
97
98        MPI_Status status;
99
100        send_buf[0] = size_info[0];
101        send_buf[1] = local_ep_size;
102        send_buf[2] = rank_in_peer_mpi[0];
103
104        MPI_Send(send_buf.data(), 3, MPI_INT_STD, remote_leader, tag, peer_comm);
105        MPI_Recv(recv_buf.data(), 3, MPI_INT_STD, remote_leader, tag, peer_comm, &status);
106
107        size_info[1] = recv_buf[0];
108        remote_ep_size = recv_buf[1];
109        rank_in_peer_mpi[1] = recv_buf[2];
110
111      }
112
113      send_buf[0] = size_info[1];
114      send_buf[1] = leader_info[0];
115      send_buf[2] = leader_info[1];
116      send_buf[3] = rank_in_peer_mpi[0];
117      send_buf[4] = rank_in_peer_mpi[1];
118
119      ::MPI_Bcast(send_buf.data(), 5, MPI_INT_STD, local_comm.rank_map->at(local_leader).second, local_mpi_comm);
120
121      size_info[1] = send_buf[0];
122      leader_info[0] = send_buf[1];
123      leader_info[1] = send_buf[2];
124      rank_in_peer_mpi[0] = send_buf[3];
125      rank_in_peer_mpi[1] = send_buf[4];
126
127
128      rank_info[2].resize(size_info[1]);
129      rank_info[3].resize(size_info[1]);
130
131      ep_info[1].resize(size_info[1]);
132
133      send_buf.resize(3*size_info[0]);
134      recv_buf.resize(3*size_info[1]);
135
136      if(is_local_leader)
137      {
138        MPI_Status status;
139
140        std::copy ( rank_info[0].data(), rank_info[0].data() + size_info[0], send_buf.begin() );
141        std::copy ( rank_info[1].data(), rank_info[1].data() + size_info[0], send_buf.begin() + size_info[0] );
142        std::copy ( ep_info[0].data(),   ep_info[0].data()   + size_info[0], send_buf.begin() + 2*size_info[0] );
143
144        MPI_Send(send_buf.data(), 3*size_info[0], MPI_INT_STD, remote_leader, tag, peer_comm);
145        MPI_Recv(recv_buf.data(), 3*size_info[1], MPI_INT_STD, remote_leader, tag, peer_comm, &status);
146      }
147
148      ::MPI_Bcast(recv_buf.data(), 3*size_info[1], MPI_INT_STD, local_comm.rank_map->at(local_leader).second, local_mpi_comm);
149
150      std::copy ( recv_buf.data(), recv_buf.data() + size_info[1], rank_info[2].begin() );
151      std::copy ( recv_buf.data() + size_info[1], recv_buf.data() + 2*size_info[1], rank_info[3].begin()  );
152      std::copy ( recv_buf.data() + 2*size_info[1], recv_buf.data() + 3*size_info[1], ep_info[1].begin() );
153
154
155      offset.resize(size_info[0]);
156
157      if(leader_info[0]<leader_info[1]) // erase all ranks doubled with remote_comm, except the local leader
158      {
159
160        bool found = false;
161        int ep_local;
162        int ep_remote;
163        for(int i=0; i<size_info[0]; i++)
164        {
165          int target = rank_info[0][i];
166          found = false;
167          for(int j=0; j<size_info[1]; j++)
168          {
169            if(target == rank_info[2][j])
170            {
171              found = true;
172              ep_local = ep_info[0][j];
173              ep_remote = ep_info[1][j];
174              break;
175            }
176          }
177          if(found)
178          {
179
180            if(target == leader_info[0]) // the leader is doubled in remote
181            {
182              new_rank_info[0].push_back(target);
183              new_rank_info[1].push_back(rank_info[1][i]);
184
185              new_ep_info[0].push_back(ep_local + ep_remote);
186              offset[i] = 0;
187            }
188            else
189            {
190              offset[i] = ep_local;
191            }
192          }
193          else
194          {
195            new_rank_info[0].push_back(target);
196            new_rank_info[1].push_back(rank_info[1][i]);
197
198            new_ep_info[0].push_back(ep_info[0][i]);
199
200            offset[i] = 0;
201          }
202
203        }
204      }
205
206      else // erase rank doubled with remote leader
207      {
208
209        bool found = false;
210        int ep_local;
211        int ep_remote;
212        for(int i=0; i<size_info[0]; i++)
213        {
214          int target = rank_info[0][i];
215          found = false;
216          for(int j=0; j<size_info[1]; j++)
217          {
218
219            if(target == rank_info[2][j])
220            {
221              found = true;
222              ep_local = ep_info[0][j];
223              ep_remote = ep_info[1][j];
224              break;
225            }
226          }
227          if(found)
228          {
229            if(target != leader_info[1])
230            {
231              new_rank_info[0].push_back(target);
232              new_rank_info[1].push_back(rank_info[1][i]);
233
234              new_ep_info[0].push_back(ep_local + ep_remote);
235              offset[i] = 0;
236            }
237            else // found remote leader
238            {
239              offset[i] = ep_remote;
240            }
241          }
242          else
243          {
244            new_rank_info[0].push_back(target);
245            new_rank_info[1].push_back(rank_info[1][i]);
246
247            new_ep_info[0].push_back(ep_info[0][i]);
248            offset[i] = 0;
249          }
250        }
251      }
252
253      if(offset[mpi_rank] == 0)
254      {
255        is_final_master = true;
256      }
257
258
259      //! size_info[4]: 2->size of new_ep_info for local, 3->size of new_ep_info for remote
260
261      if(is_local_leader)
262      {
263        size_info[2] = new_ep_info[0].size();
264        MPI_Status status;
265        MPI_Send(&size_info[2], 1, MPI_INT_STD, remote_leader, tag, peer_comm);
266        MPI_Recv(&size_info[3], 1, MPI_INT_STD, remote_leader, tag, peer_comm, &status);
267      }
268
269      ::MPI_Bcast(&size_info[2], 2, MPI_INT_STD, local_comm.rank_map->at(local_leader).second, local_mpi_comm);
270
271      new_rank_info[2].resize(size_info[3]);
272      new_rank_info[3].resize(size_info[3]);
273      new_ep_info[1].resize(size_info[3]);
274
275      send_buf.resize(size_info[2]);
276      recv_buf.resize(size_info[3]);
277
278      if(is_local_leader)
279      {
280        MPI_Status status;
281
282        std::copy ( new_rank_info[0].data(), new_rank_info[0].data() + size_info[2], send_buf.begin() );
283        std::copy ( new_rank_info[1].data(), new_rank_info[1].data() + size_info[2], send_buf.begin() + size_info[2] );
284        std::copy ( new_ep_info[0].data(),   new_ep_info[0].data()   + size_info[0], send_buf.begin() + 2*size_info[2] );
285
286        MPI_Send(send_buf.data(), 3*size_info[2], MPI_INT_STD, remote_leader, tag, peer_comm);
287        MPI_Recv(recv_buf.data(), 3*size_info[3], MPI_INT_STD, remote_leader, tag, peer_comm, &status);
288      }
289
290      ::MPI_Bcast(recv_buf.data(),   3*size_info[3], MPI_INT_STD, local_comm.rank_map->at(local_leader).second, local_mpi_comm);
291
292      std::copy ( recv_buf.data(), recv_buf.data() + size_info[3], new_rank_info[2].begin() );
293      std::copy ( recv_buf.data() + size_info[3], recv_buf.data() + 2*size_info[3], new_rank_info[3].begin()  );
294      std::copy ( recv_buf.data() + 2*size_info[3], recv_buf.data() + 3*size_info[3], new_ep_info[1].begin() );
295
296    }
297
298
299
300    if(is_proc_master)
301    {
302      //! leader_info[4]: 2-> rank of local leader in new_group generated comm;
303                      // 3-> rank of remote leader in new_group generated comm;
304      ::MPI_Group local_group;
305      ::MPI_Group new_group;
306      ::MPI_Comm new_comm;
307      ::MPI_Comm intercomm;
308
309      ::MPI_Comm_group(local_mpi_comm, &local_group);
310
311      ::MPI_Group_incl(local_group, size_info[2], new_rank_info[1].data(), &new_group);
312
313      ::MPI_Comm_create(local_mpi_comm, new_group, &new_comm);
314
315
316
317      if(is_local_leader)
318      {
319        ::MPI_Comm_rank(new_comm, &leader_info[2]);
320      }
321
322      ::MPI_Bcast(&leader_info[2], 1, MPI_INT_STD, local_comm.rank_map->at(local_leader).second, local_mpi_comm);
323
324      if(new_comm != MPI_COMM_NULL_STD)
325      {
326
327        ::MPI_Barrier(new_comm);
328
329        ::MPI_Intercomm_create(new_comm, leader_info[2], static_cast< ::MPI_Comm>(peer_comm.mpi_comm), rank_in_peer_mpi[1], tag, &intercomm);
330
331        int id;
332
333        ::MPI_Comm_rank(new_comm, &id);
334        int my_num_ep = new_ep_info[0][id];
335
336        MPI_Comm *ep_intercomm;
337        MPI_Info info;
338        MPI_Comm_create_endpoints(new_comm, my_num_ep, info, ep_intercomm);
339
340
341        for(int i= 0; i<my_num_ep; i++)
342        {
343          ep_intercomm[i].is_intercomm = true;
344
345          ep_intercomm[i].ep_comm_ptr->intercomm = new ep_lib::ep_intercomm;
346          ep_intercomm[i].ep_comm_ptr->intercomm->mpi_inter_comm = intercomm;
347          ep_intercomm[i].ep_comm_ptr->comm_label = leader_info[0];
348        }
349
350
351        #pragma omp critical (write_to_tag_list)
352        tag_list.push_back(make_pair( make_pair(tag, min(leader_info[0], leader_info[1])) , ep_intercomm));
353      }
354
355
356    }
357
358
359    MPI_Barrier_local(local_comm);
360
361    vector<int> bcast_buf(8);
362    if(is_local_leader)
363    {
364      std::copy(size_info, size_info+4, bcast_buf.begin());
365      std::copy(leader_info, leader_info+4, bcast_buf.begin()+4);
366    }
367
368    MPI_Bcast(bcast_buf.data(), 8, MPI_INT_STD, local_leader, local_comm);
369
370    if(!is_local_leader)
371    {
372      std::copy(bcast_buf.begin(), bcast_buf.begin()+4, size_info);
373      std::copy(bcast_buf.begin()+4, bcast_buf.begin()+8, leader_info);
374    }
375
376    if(!is_local_leader)
377    {
378      new_rank_info[1].resize(size_info[2]);
379      ep_info[1].resize(size_info[1]);
380      offset.resize(size_info[0]);
381    }
382
383    bcast_buf.resize(size_info[2]+size_info[1]+size_info[0]+1);
384
385    if(is_local_leader)
386    {
387      bcast_buf[0] = remote_ep_size;
388      std::copy(new_rank_info[1].data(), new_rank_info[1].data()+size_info[2], bcast_buf.begin()+1);
389      std::copy(ep_info[1].data(), ep_info[1].data()+size_info[1], bcast_buf.begin()+size_info[2]+1);
390      std::copy(offset.data(), offset.data()+size_info[0], bcast_buf.begin()+size_info[2]+size_info[1]+1);
391    }
392
393    MPI_Bcast(bcast_buf.data(), size_info[2]+size_info[1]+size_info[0]+1, MPI_INT_STD, local_leader, local_comm);
394
395    if(!is_local_leader)
396    {
397      remote_ep_size = bcast_buf[0];
398      std::copy(bcast_buf.data()+1, bcast_buf.data()+1+size_info[2], new_rank_info[1].begin());
399      std::copy(bcast_buf.data()+1+size_info[2], bcast_buf.data()+1+size_info[2]+size_info[1], ep_info[1].begin());
400      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());
401    }
402
403    int my_position = offset[rank_in_local_parent]+ep_rank_loc;
404
405
406    MPI_Barrier_local(local_comm);
407    #pragma omp flush
408
409
410    #pragma omp critical (read_from_tag_list)
411    {
412      bool found = false;
413      while(!found)
414      {
415        for(std::list<std::pair < std::pair<int,int>, MPI_Comm* > >::iterator iter = tag_list.begin(); iter!=tag_list.end(); iter++)
416        {
417          if((*iter).first == make_pair(tag, min(leader_info[0], leader_info[1])))
418          {
419            *newintercomm =  iter->second[my_position];
420            found = true;
421            break;
422          }
423        }
424      }
425    }
426
427    MPI_Barrier_local(local_comm);
428
429    int intercomm_ep_rank, intercomm_ep_rank_loc, intercomm_mpi_rank;
430    int intercomm_ep_size, intercomm_num_ep, intercomm_mpi_size;
431
432    intercomm_ep_rank = newintercomm->ep_comm_ptr->size_rank_info[0].first;
433    intercomm_ep_rank_loc = newintercomm->ep_comm_ptr->size_rank_info[1].first;
434    intercomm_mpi_rank = newintercomm->ep_comm_ptr->size_rank_info[2].first;
435    intercomm_ep_size = newintercomm->ep_comm_ptr->size_rank_info[0].second;
436    intercomm_num_ep = newintercomm->ep_comm_ptr->size_rank_info[1].second;
437    intercomm_mpi_size = newintercomm->ep_comm_ptr->size_rank_info[2].second;
438
439    MPI_Bcast(&remote_ep_size, 1, MPI_INT_STD, local_leader, local_comm);
440
441    int my_rank_map_elem[2];
442
443    my_rank_map_elem[0] = intercomm_ep_rank;
444    my_rank_map_elem[1] = (*newintercomm).ep_comm_ptr->comm_label;
445
446    vector<pair<int, int> > local_rank_map_array;
447    vector<pair<int, int> > remote_rank_map_array;
448
449
450    (*newintercomm).ep_comm_ptr->intercomm->local_rank_map = new RANK_MAP;
451    (*newintercomm).ep_comm_ptr->intercomm->local_rank_map->resize(local_ep_size);
452
453    MPI_Allgather(my_rank_map_elem, 2, MPI_INT_STD, (*newintercomm).ep_comm_ptr->intercomm->local_rank_map->data(), 2, MPI_INT_STD, local_comm);
454
455    (*newintercomm).ep_comm_ptr->intercomm->remote_rank_map = new RANK_MAP;
456    (*newintercomm).ep_comm_ptr->intercomm->remote_rank_map->resize(remote_ep_size);
457
458    (*newintercomm).ep_comm_ptr->intercomm->size_rank_info[0] = local_comm.ep_comm_ptr->size_rank_info[0];
459    (*newintercomm).ep_comm_ptr->intercomm->size_rank_info[1] = local_comm.ep_comm_ptr->size_rank_info[1];
460    (*newintercomm).ep_comm_ptr->intercomm->size_rank_info[2] = local_comm.ep_comm_ptr->size_rank_info[2];
461
462    int local_intercomm_size = intercomm_ep_size;
463    int remote_intercomm_size;
464
465    int new_bcast_root_0 = 0;
466    int new_bcast_root = 0;
467
468
469    if(is_local_leader)
470    {
471      MPI_Status status;
472      MPI_Send((*newintercomm).ep_comm_ptr->intercomm->local_rank_map->data(), 2*local_ep_size, MPI_INT_STD, remote_leader, tag, peer_comm);
473      MPI_Recv((*newintercomm).ep_comm_ptr->intercomm->remote_rank_map->data(), 2*remote_ep_size, MPI_INT_STD, remote_leader, tag, peer_comm, &status);
474
475      MPI_Send(&local_intercomm_size, 1, MPI_INT_STD, remote_leader, tag, peer_comm);
476      MPI_Recv(&remote_intercomm_size, 1, MPI_INT_STD, remote_leader, tag, peer_comm, &status);
477
478      new_bcast_root_0 = intercomm_ep_rank;
479    }
480
481    MPI_Allreduce(&new_bcast_root_0, &new_bcast_root, 1, MPI_INT_STD, MPI_SUM_STD, *newintercomm);
482
483
484    MPI_Bcast((*newintercomm).ep_comm_ptr->intercomm->remote_rank_map->data(), 2*remote_ep_size, MPI_INT_STD, local_leader, local_comm);
485    MPI_Bcast(&remote_intercomm_size, 1, MPI_INT_STD, new_bcast_root, *newintercomm);
486
487
488    (*newintercomm).ep_comm_ptr->intercomm->intercomm_rank_map = new RANK_MAP;
489    (*newintercomm).ep_comm_ptr->intercomm->intercomm_rank_map->resize(remote_intercomm_size);
490
491
492
493
494    if(is_local_leader)
495    {
496      MPI_Status status;
497      MPI_Send((*newintercomm).rank_map->data(), 2*local_intercomm_size, MPI_INT_STD, remote_leader, tag, peer_comm);
498      MPI_Recv((*newintercomm).ep_comm_ptr->intercomm->intercomm_rank_map->data(), 2*remote_intercomm_size, MPI_INT_STD, remote_leader, tag, peer_comm, &status);
499    }
500
501    MPI_Bcast((*newintercomm).ep_comm_ptr->intercomm->intercomm_rank_map->data(), 2*remote_intercomm_size, MPI_INT_STD, new_bcast_root, *newintercomm);
502
503    (*newintercomm).ep_comm_ptr->intercomm->local_comm = &(local_comm.ep_comm_ptr->comm_list[ep_rank_loc]);
504    (*newintercomm).ep_comm_ptr->intercomm->intercomm_tag = tag;
505
506/*
507    for(int i=0; i<local_ep_size; i++)
508    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,
509          (*newintercomm).ep_comm_ptr->intercomm->local_rank_map->at(i).first, (*newintercomm).ep_comm_ptr->intercomm->local_rank_map->at(i).second);
510
511    for(int i=0; i<remote_ep_size; i++)
512    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,
513          (*newintercomm).ep_comm_ptr->intercomm->remote_rank_map->at(i).first, (*newintercomm).ep_comm_ptr->intercomm->remote_rank_map->at(i).second);
514
515    for(int i=0; i<remote_intercomm_size; i++)
516    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,
517          (*newintercomm).ep_comm_ptr->intercomm->intercomm_rank_map->at(i).first, (*newintercomm).ep_comm_ptr->intercomm->intercomm_rank_map->at(i).second);
518*/
519
520//    for(int i=0; i<(*newintercomm).rank_map->size(); i++)
521//    if(local_comm.ep_comm_ptr->comm_label != 99) printf("ep_rank = %d, rank_map[%d] = (%d,%d)\n", intercomm_ep_rank, i,
522//          (*newintercomm).rank_map->at(i).first, (*newintercomm).rank_map->at(i).second);
523
524//    MPI_Comm *test_comm = newintercomm->ep_comm_ptr->intercomm->local_comm;
525//    int test_rank;
526//    MPI_Comm_rank(*test_comm, &test_rank);
527//    printf("=================test_rank = %d\n", test_rank);
528
529    return MPI_SUCCESS;
530
531  }
532
533
534
535
536  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)
537  {
538    //! mpi_size of local comm = 1
539    //! same world rank of leaders
540
541    int ep_rank, ep_rank_loc, mpi_rank;
542    int ep_size, num_ep, mpi_size;
543
544    ep_rank = local_comm.ep_comm_ptr->size_rank_info[0].first;
545    ep_rank_loc = local_comm.ep_comm_ptr->size_rank_info[1].first;
546    mpi_rank = local_comm.ep_comm_ptr->size_rank_info[2].first;
547    ep_size = local_comm.ep_comm_ptr->size_rank_info[0].second;
548    num_ep = local_comm.ep_comm_ptr->size_rank_info[1].second;
549    mpi_size = local_comm.ep_comm_ptr->size_rank_info[2].second;
550
551
552
553    std::vector<int> rank_info[4];  //! 0->rank_in_world of local_comm,  1->rank_in_local_parent of local_comm
554                                    //! 2->rank_in_world of remote_comm, 3->rank_in_local_parent of remote_comm
555
556    int rank_in_world;
557
558    int rank_in_peer_mpi[2];
559
560    ::MPI_Comm_rank(MPI_COMM_WORLD_STD, &rank_in_world);
561
562
563    int local_num_ep = num_ep;
564    int remote_num_ep;
565    int total_num_ep;
566
567    int leader_rank_in_peer[2];
568
569    int my_position;
570    int tag_label[2];
571
572    vector<int> send_buf(4);
573    vector<int> recv_buf(4);
574
575
576    if(ep_rank == local_leader)
577    {
578      MPI_Status status;
579
580
581
582      MPI_Comm_rank(peer_comm, &leader_rank_in_peer[0]);
583
584      send_buf[0] = local_num_ep;
585      send_buf[1] = leader_rank_in_peer[0];
586
587      MPI_Request req_s, req_r;
588
589      MPI_Isend(send_buf.data(), 2, MPI_INT_STD, remote_leader, tag, peer_comm, &req_s);
590      MPI_Irecv(recv_buf.data(), 2, MPI_INT_STD, remote_leader, tag, peer_comm, &req_r);
591
592
593      MPI_Wait(&req_s, &status);
594      MPI_Wait(&req_r, &status);
595
596      recv_buf[2] = leader_rank_in_peer[0];
597
598    }
599
600    MPI_Bcast(recv_buf.data(), 3, MPI_INT_STD, local_leader, local_comm);
601
602    remote_num_ep = recv_buf[0];
603    leader_rank_in_peer[1] = recv_buf[1];
604    leader_rank_in_peer[0] = recv_buf[2];
605
606    total_num_ep = local_num_ep + remote_num_ep;
607
608
609    if(leader_rank_in_peer[0] < leader_rank_in_peer[1])
610    {
611      my_position = ep_rank_loc;
612      //! LEADER create EP
613      if(ep_rank == local_leader)
614      {
615        ::MPI_Comm mpi_dup;
616       
617        ::MPI_Comm_dup(static_cast< ::MPI_Comm>(local_comm.mpi_comm), &mpi_dup);
618
619        MPI_Comm *ep_intercomm;
620        MPI_Info info;
621        MPI_Comm_create_endpoints(mpi_dup, total_num_ep, info, ep_intercomm);
622
623
624        for(int i=0; i<total_num_ep; i++)
625        {
626          ep_intercomm[i].is_intercomm = true;
627          ep_intercomm[i].ep_comm_ptr->intercomm = new ep_lib::ep_intercomm;
628          ep_intercomm[i].ep_comm_ptr->intercomm->mpi_inter_comm = 0;
629
630          ep_intercomm[i].ep_comm_ptr->comm_label = leader_rank_in_peer[0];
631        }
632
633        tag_label[0] = TAG++;
634        tag_label[1] = rank_in_world;
635
636        #pragma omp critical (write_to_tag_list)
637        tag_list.push_back(make_pair( make_pair(tag_label[0], tag_label[1]) , ep_intercomm));
638
639        MPI_Request req_s;
640        MPI_Status sta_s;
641        MPI_Isend(tag_label, 2, MPI_INT_STD, remote_leader, tag, peer_comm, &req_s);
642
643        MPI_Wait(&req_s, &sta_s);
644
645      }
646    }
647    else
648    {
649      //! Wait for EP creation
650      my_position = remote_num_ep + ep_rank_loc;
651      if(ep_rank == local_leader)
652      {
653        MPI_Status status;
654        MPI_Request req_r;
655        MPI_Irecv(tag_label, 2, MPI_INT_STD, remote_leader, tag, peer_comm, &req_r);
656        MPI_Wait(&req_r, &status);
657      }
658    }
659
660    MPI_Bcast(tag_label, 2, MPI_INT_STD, local_leader, local_comm);
661
662
663
664
665    #pragma omp critical (read_from_tag_list)
666    {
667      bool found = false;
668      while(!found)
669      {
670        for(std::list<std::pair < std::pair<int,int>, MPI_Comm* > >::iterator iter = tag_list.begin(); iter!=tag_list.end(); iter++)
671        {
672          if((*iter).first == make_pair(tag_label[0], tag_label[1]))
673          {
674            *newintercomm =  iter->second[my_position];
675            found = true;
676            break;
677          }
678        }
679      }
680    }
681
682
683
684    int intercomm_ep_rank, intercomm_ep_rank_loc, intercomm_mpi_rank;
685    int intercomm_ep_size, intercomm_num_ep, intercomm_mpi_size;
686
687    intercomm_ep_rank = newintercomm->ep_comm_ptr->size_rank_info[0].first;
688    intercomm_ep_rank_loc = newintercomm->ep_comm_ptr->size_rank_info[1].first;
689    intercomm_mpi_rank = newintercomm->ep_comm_ptr->size_rank_info[2].first;
690    intercomm_ep_size = newintercomm->ep_comm_ptr->size_rank_info[0].second;
691    intercomm_num_ep = newintercomm->ep_comm_ptr->size_rank_info[1].second;
692    intercomm_mpi_size = newintercomm->ep_comm_ptr->size_rank_info[2].second;
693
694
695
696    (*newintercomm).ep_comm_ptr->intercomm->local_rank_map  = new RANK_MAP;
697    (*newintercomm).ep_comm_ptr->intercomm->remote_rank_map = new RANK_MAP;
698    (*newintercomm).ep_comm_ptr->intercomm->local_rank_map->resize(local_num_ep);
699    (*newintercomm).ep_comm_ptr->intercomm->remote_rank_map->resize(remote_num_ep);
700
701    (*newintercomm).ep_comm_ptr->intercomm->size_rank_info[0] = local_comm.ep_comm_ptr->size_rank_info[0];
702    (*newintercomm).ep_comm_ptr->intercomm->size_rank_info[1] = local_comm.ep_comm_ptr->size_rank_info[1];
703    (*newintercomm).ep_comm_ptr->intercomm->size_rank_info[2] = local_comm.ep_comm_ptr->size_rank_info[2];
704
705
706
707    int local_rank_map_ele[2];
708    local_rank_map_ele[0] = intercomm_ep_rank;
709    local_rank_map_ele[1] = (*newintercomm).ep_comm_ptr->comm_label;
710
711    MPI_Allgather(local_rank_map_ele, 2, MPI_INT_STD, (*newintercomm).ep_comm_ptr->intercomm->local_rank_map->data(), 2, MPI_INT_STD, local_comm);
712
713    if(ep_rank == local_leader)
714    {
715      MPI_Status status;
716      MPI_Request req_s, req_r;
717
718      MPI_Isend((*newintercomm).ep_comm_ptr->intercomm->local_rank_map->data(), 2*local_num_ep, MPI_INT_STD, remote_leader, tag, peer_comm, &req_s);
719      MPI_Irecv((*newintercomm).ep_comm_ptr->intercomm->remote_rank_map->data(), 2*remote_num_ep, MPI_INT_STD, remote_leader, tag, peer_comm, &req_r);
720
721
722      MPI_Wait(&req_s, &status);
723      MPI_Wait(&req_r, &status);
724
725    }
726
727    MPI_Bcast((*newintercomm).ep_comm_ptr->intercomm->remote_rank_map->data(), 2*remote_num_ep, MPI_INT_STD, local_leader, local_comm);
728    (*newintercomm).ep_comm_ptr->intercomm->local_comm = &(local_comm.ep_comm_ptr->comm_list[ep_rank_loc]);
729    (*newintercomm).ep_comm_ptr->intercomm->intercomm_tag = tag;
730
731
732    return MPI_SUCCESS;
733  }
734
735
736}
Note: See TracBrowser for help on using the repository browser.