source: XIOS/dev/branch_yushan_merged/extern/src_ep_dev/ep_intercomm_kernel.cpp @ 1134

Last change on this file since 1134 was 1134, checked in by yushan, 4 years ago

branch merged with trunk r1130

File size: 25.2 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        //printf("tag_list size = %lu\n", tag_list.size());
354      }
355
356
357    }
358
359
360    MPI_Barrier_local(local_comm);
361
362    vector<int> bcast_buf(8);
363    if(is_local_leader)
364    {
365      std::copy(size_info, size_info+4, bcast_buf.begin());
366      std::copy(leader_info, leader_info+4, bcast_buf.begin()+4);
367    }
368
369    MPI_Bcast(bcast_buf.data(), 8, MPI_INT_STD, local_leader, local_comm);
370
371    if(!is_local_leader)
372    {
373      std::copy(bcast_buf.begin(), bcast_buf.begin()+4, size_info);
374      std::copy(bcast_buf.begin()+4, bcast_buf.begin()+8, leader_info);
375    }
376
377    if(!is_local_leader)
378    {
379      new_rank_info[1].resize(size_info[2]);
380      ep_info[1].resize(size_info[1]);
381      offset.resize(size_info[0]);
382    }
383
384    bcast_buf.resize(size_info[2]+size_info[1]+size_info[0]+1);
385
386    if(is_local_leader)
387    {
388      bcast_buf[0] = remote_ep_size;
389      std::copy(new_rank_info[1].data(), new_rank_info[1].data()+size_info[2], bcast_buf.begin()+1);
390      std::copy(ep_info[1].data(), ep_info[1].data()+size_info[1], bcast_buf.begin()+size_info[2]+1);
391      std::copy(offset.data(), offset.data()+size_info[0], bcast_buf.begin()+size_info[2]+size_info[1]+1);
392    }
393
394    MPI_Bcast(bcast_buf.data(), size_info[2]+size_info[1]+size_info[0]+1, MPI_INT_STD, local_leader, local_comm);
395
396    if(!is_local_leader)
397    {
398      remote_ep_size = bcast_buf[0];
399      std::copy(bcast_buf.data()+1, bcast_buf.data()+1+size_info[2], new_rank_info[1].begin());
400      std::copy(bcast_buf.data()+1+size_info[2], bcast_buf.data()+1+size_info[2]+size_info[1], ep_info[1].begin());
401      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());
402    }
403
404    int my_position = offset[rank_in_local_parent]+ep_rank_loc;
405
406
407    MPI_Barrier_local(local_comm);
408    #pragma omp flush
409
410
411    #pragma omp critical (read_from_tag_list)
412    {
413      bool found = false;
414      while(!found)
415      {
416        for(std::list<std::pair < std::pair<int,int>, MPI_Comm* > >::iterator iter = tag_list.begin(); iter!=tag_list.end(); iter++)
417        {
418          if((*iter).first == make_pair(tag, min(leader_info[0], leader_info[1])))
419          {
420            *newintercomm =  iter->second[my_position];
421            found = true;
422            break;
423          }
424        }
425      }
426    }
427
428    MPI_Barrier_local(local_comm);
429    if(is_proc_master)
430    {
431      for(std::list<std::pair < std::pair<int,int>, MPI_Comm* > >::iterator iter = tag_list.begin(); iter!=tag_list.end(); iter++)
432      {
433        if((*iter).first == make_pair(tag, min(leader_info[0], leader_info[1])))
434        {
435          tag_list.erase(iter);
436          break;
437        }
438      }
439    }
440
441    int intercomm_ep_rank, intercomm_ep_rank_loc, intercomm_mpi_rank;
442    int intercomm_ep_size, intercomm_num_ep, intercomm_mpi_size;
443
444    intercomm_ep_rank = newintercomm->ep_comm_ptr->size_rank_info[0].first;
445    intercomm_ep_rank_loc = newintercomm->ep_comm_ptr->size_rank_info[1].first;
446    intercomm_mpi_rank = newintercomm->ep_comm_ptr->size_rank_info[2].first;
447    intercomm_ep_size = newintercomm->ep_comm_ptr->size_rank_info[0].second;
448    intercomm_num_ep = newintercomm->ep_comm_ptr->size_rank_info[1].second;
449    intercomm_mpi_size = newintercomm->ep_comm_ptr->size_rank_info[2].second;
450
451    MPI_Bcast(&remote_ep_size, 1, MPI_INT_STD, local_leader, local_comm);
452
453    int my_rank_map_elem[2];
454
455    my_rank_map_elem[0] = intercomm_ep_rank;
456    my_rank_map_elem[1] = (*newintercomm).ep_comm_ptr->comm_label;
457
458    vector<pair<int, int> > local_rank_map_array;
459    vector<pair<int, int> > remote_rank_map_array;
460
461
462    (*newintercomm).ep_comm_ptr->intercomm->local_rank_map = new RANK_MAP;
463    (*newintercomm).ep_comm_ptr->intercomm->local_rank_map->resize(local_ep_size);
464
465    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);
466
467    (*newintercomm).ep_comm_ptr->intercomm->remote_rank_map = new RANK_MAP;
468    (*newintercomm).ep_comm_ptr->intercomm->remote_rank_map->resize(remote_ep_size);
469
470    (*newintercomm).ep_comm_ptr->intercomm->size_rank_info[0] = local_comm.ep_comm_ptr->size_rank_info[0];
471    (*newintercomm).ep_comm_ptr->intercomm->size_rank_info[1] = local_comm.ep_comm_ptr->size_rank_info[1];
472    (*newintercomm).ep_comm_ptr->intercomm->size_rank_info[2] = local_comm.ep_comm_ptr->size_rank_info[2];
473
474    int local_intercomm_size = intercomm_ep_size;
475    int remote_intercomm_size;
476
477    int new_bcast_root_0 = 0;
478    int new_bcast_root = 0;
479
480
481    if(is_local_leader)
482    {
483      MPI_Status status;
484      MPI_Send((*newintercomm).ep_comm_ptr->intercomm->local_rank_map->data(), 2*local_ep_size, MPI_INT_STD, remote_leader, tag, peer_comm);
485      MPI_Recv((*newintercomm).ep_comm_ptr->intercomm->remote_rank_map->data(), 2*remote_ep_size, MPI_INT_STD, remote_leader, tag, peer_comm, &status);
486
487      MPI_Send(&local_intercomm_size, 1, MPI_INT_STD, remote_leader, tag, peer_comm);
488      MPI_Recv(&remote_intercomm_size, 1, MPI_INT_STD, remote_leader, tag, peer_comm, &status);
489
490      new_bcast_root_0 = intercomm_ep_rank;
491    }
492
493    MPI_Allreduce(&new_bcast_root_0, &new_bcast_root, 1, MPI_INT_STD, MPI_SUM_STD, *newintercomm);
494
495
496    MPI_Bcast((*newintercomm).ep_comm_ptr->intercomm->remote_rank_map->data(), 2*remote_ep_size, MPI_INT_STD, local_leader, local_comm);
497    MPI_Bcast(&remote_intercomm_size, 1, MPI_INT_STD, new_bcast_root, *newintercomm);
498
499
500    (*newintercomm).ep_comm_ptr->intercomm->intercomm_rank_map = new RANK_MAP;
501    (*newintercomm).ep_comm_ptr->intercomm->intercomm_rank_map->resize(remote_intercomm_size);
502
503
504
505
506    if(is_local_leader)
507    {
508      MPI_Status status;
509      MPI_Send((*newintercomm).rank_map->data(), 2*local_intercomm_size, MPI_INT_STD, remote_leader, tag, peer_comm);
510      MPI_Recv((*newintercomm).ep_comm_ptr->intercomm->intercomm_rank_map->data(), 2*remote_intercomm_size, MPI_INT_STD, remote_leader, tag, peer_comm, &status);
511    }
512
513    MPI_Bcast((*newintercomm).ep_comm_ptr->intercomm->intercomm_rank_map->data(), 2*remote_intercomm_size, MPI_INT_STD, new_bcast_root, *newintercomm);
514
515    (*newintercomm).ep_comm_ptr->intercomm->local_comm = &(local_comm.ep_comm_ptr->comm_list[ep_rank_loc]);
516    (*newintercomm).ep_comm_ptr->intercomm->intercomm_tag = tag;
517
518/*
519    for(int i=0; i<local_ep_size; i++)
520    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,
521          (*newintercomm).ep_comm_ptr->intercomm->local_rank_map->at(i).first, (*newintercomm).ep_comm_ptr->intercomm->local_rank_map->at(i).second);
522
523    for(int i=0; i<remote_ep_size; i++)
524    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,
525          (*newintercomm).ep_comm_ptr->intercomm->remote_rank_map->at(i).first, (*newintercomm).ep_comm_ptr->intercomm->remote_rank_map->at(i).second);
526
527    for(int i=0; i<remote_intercomm_size; i++)
528    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,
529          (*newintercomm).ep_comm_ptr->intercomm->intercomm_rank_map->at(i).first, (*newintercomm).ep_comm_ptr->intercomm->intercomm_rank_map->at(i).second);
530*/
531
532//    for(int i=0; i<(*newintercomm).rank_map->size(); i++)
533//    if(local_comm.ep_comm_ptr->comm_label != 99) printf("ep_rank = %d, rank_map[%d] = (%d,%d)\n", intercomm_ep_rank, i,
534//          (*newintercomm).rank_map->at(i).first, (*newintercomm).rank_map->at(i).second);
535
536//    MPI_Comm *test_comm = newintercomm->ep_comm_ptr->intercomm->local_comm;
537//    int test_rank;
538//    MPI_Comm_rank(*test_comm, &test_rank);
539//    printf("=================test_rank = %d\n", test_rank);
540
541    return MPI_SUCCESS;
542
543  }
544
545
546
547
548  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)
549  {
550    //! mpi_size of local comm = 1
551    //! same world rank of leaders
552
553    int ep_rank, ep_rank_loc, mpi_rank;
554    int ep_size, num_ep, mpi_size;
555
556    ep_rank = local_comm.ep_comm_ptr->size_rank_info[0].first;
557    ep_rank_loc = local_comm.ep_comm_ptr->size_rank_info[1].first;
558    mpi_rank = local_comm.ep_comm_ptr->size_rank_info[2].first;
559    ep_size = local_comm.ep_comm_ptr->size_rank_info[0].second;
560    num_ep = local_comm.ep_comm_ptr->size_rank_info[1].second;
561    mpi_size = local_comm.ep_comm_ptr->size_rank_info[2].second;
562
563
564
565    std::vector<int> rank_info[4];  //! 0->rank_in_world of local_comm,  1->rank_in_local_parent of local_comm
566                                    //! 2->rank_in_world of remote_comm, 3->rank_in_local_parent of remote_comm
567
568    int rank_in_world;
569
570    int rank_in_peer_mpi[2];
571
572    ::MPI_Comm_rank(MPI_COMM_WORLD_STD, &rank_in_world);
573
574
575    int local_num_ep = num_ep;
576    int remote_num_ep;
577    int total_num_ep;
578
579    int leader_rank_in_peer[2];
580
581    int my_position;
582    int tag_label[2];
583
584    vector<int> send_buf(4);
585    vector<int> recv_buf(4);
586
587
588    if(ep_rank == local_leader)
589    {
590      MPI_Status status;
591
592
593
594      MPI_Comm_rank(peer_comm, &leader_rank_in_peer[0]);
595
596      send_buf[0] = local_num_ep;
597      send_buf[1] = leader_rank_in_peer[0];
598
599      MPI_Request req_s, req_r;
600
601      MPI_Isend(send_buf.data(), 2, MPI_INT_STD, remote_leader, tag, peer_comm, &req_s);
602      MPI_Irecv(recv_buf.data(), 2, MPI_INT_STD, remote_leader, tag, peer_comm, &req_r);
603
604
605      MPI_Wait(&req_s, &status);
606      MPI_Wait(&req_r, &status);
607
608      recv_buf[2] = leader_rank_in_peer[0];
609
610    }
611
612    MPI_Bcast(recv_buf.data(), 3, MPI_INT_STD, local_leader, local_comm);
613
614    remote_num_ep = recv_buf[0];
615    leader_rank_in_peer[1] = recv_buf[1];
616    leader_rank_in_peer[0] = recv_buf[2];
617
618    total_num_ep = local_num_ep + remote_num_ep;
619
620
621    if(leader_rank_in_peer[0] < leader_rank_in_peer[1])
622    {
623      my_position = ep_rank_loc;
624      //! LEADER create EP
625      if(ep_rank == local_leader)
626      {
627        ::MPI_Comm mpi_dup;
628       
629        ::MPI_Comm_dup(static_cast< ::MPI_Comm>(local_comm.mpi_comm), &mpi_dup);
630
631        MPI_Comm *ep_intercomm;
632        MPI_Info info;
633        MPI_Comm_create_endpoints(mpi_dup, total_num_ep, info, ep_intercomm);
634
635
636        for(int i=0; i<total_num_ep; i++)
637        {
638          ep_intercomm[i].is_intercomm = true;
639          ep_intercomm[i].ep_comm_ptr->intercomm = new ep_lib::ep_intercomm;
640          ep_intercomm[i].ep_comm_ptr->intercomm->mpi_inter_comm = 0;
641
642          ep_intercomm[i].ep_comm_ptr->comm_label = leader_rank_in_peer[0];
643        }
644
645        tag_label[0] = TAG++;
646        tag_label[1] = rank_in_world;
647
648        #pragma omp critical (write_to_tag_list)
649        tag_list.push_back(make_pair( make_pair(tag_label[0], tag_label[1]) , ep_intercomm));
650
651        MPI_Request req_s;
652        MPI_Status sta_s;
653        MPI_Isend(tag_label, 2, MPI_INT_STD, remote_leader, tag, peer_comm, &req_s);
654
655        MPI_Wait(&req_s, &sta_s);
656
657      }
658    }
659    else
660    {
661      //! Wait for EP creation
662      my_position = remote_num_ep + ep_rank_loc;
663      if(ep_rank == local_leader)
664      {
665        MPI_Status status;
666        MPI_Request req_r;
667        MPI_Irecv(tag_label, 2, MPI_INT_STD, remote_leader, tag, peer_comm, &req_r);
668        MPI_Wait(&req_r, &status);
669      }
670    }
671
672    MPI_Bcast(tag_label, 2, MPI_INT_STD, local_leader, local_comm);
673
674
675
676
677    #pragma omp critical (read_from_tag_list)
678    {
679      bool found = false;
680      while(!found)
681      {
682        for(std::list<std::pair < std::pair<int,int>, MPI_Comm* > >::iterator iter = tag_list.begin(); iter!=tag_list.end(); iter++)
683        {
684          if((*iter).first == make_pair(tag_label[0], tag_label[1]))
685          {
686            *newintercomm =  iter->second[my_position];
687            found = true;
688            // tag_list.erase(iter);
689            break;
690          }
691        }
692      }
693    }
694
695    MPI_Barrier_local(local_comm);
696
697    if(leader_rank_in_peer[0] < leader_rank_in_peer[1])
698    {
699      for(std::list<std::pair < std::pair<int,int>, MPI_Comm* > >::iterator iter = tag_list.begin(); iter!=tag_list.end(); iter++)
700        {
701          if((*iter).first == make_pair(tag_label[0], tag_label[1]))
702          {
703            tag_list.erase(iter);
704            break;
705          }
706        }
707    }
708
709
710
711    int intercomm_ep_rank, intercomm_ep_rank_loc, intercomm_mpi_rank;
712    int intercomm_ep_size, intercomm_num_ep, intercomm_mpi_size;
713
714    intercomm_ep_rank = newintercomm->ep_comm_ptr->size_rank_info[0].first;
715    intercomm_ep_rank_loc = newintercomm->ep_comm_ptr->size_rank_info[1].first;
716    intercomm_mpi_rank = newintercomm->ep_comm_ptr->size_rank_info[2].first;
717    intercomm_ep_size = newintercomm->ep_comm_ptr->size_rank_info[0].second;
718    intercomm_num_ep = newintercomm->ep_comm_ptr->size_rank_info[1].second;
719    intercomm_mpi_size = newintercomm->ep_comm_ptr->size_rank_info[2].second;
720
721
722
723    (*newintercomm).ep_comm_ptr->intercomm->local_rank_map  = new RANK_MAP;
724    (*newintercomm).ep_comm_ptr->intercomm->remote_rank_map = new RANK_MAP;
725    (*newintercomm).ep_comm_ptr->intercomm->local_rank_map->resize(local_num_ep);
726    (*newintercomm).ep_comm_ptr->intercomm->remote_rank_map->resize(remote_num_ep);
727
728    (*newintercomm).ep_comm_ptr->intercomm->size_rank_info[0] = local_comm.ep_comm_ptr->size_rank_info[0];
729    (*newintercomm).ep_comm_ptr->intercomm->size_rank_info[1] = local_comm.ep_comm_ptr->size_rank_info[1];
730    (*newintercomm).ep_comm_ptr->intercomm->size_rank_info[2] = local_comm.ep_comm_ptr->size_rank_info[2];
731
732
733
734    int local_rank_map_ele[2];
735    local_rank_map_ele[0] = intercomm_ep_rank;
736    local_rank_map_ele[1] = (*newintercomm).ep_comm_ptr->comm_label;
737
738    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);
739
740    if(ep_rank == local_leader)
741    {
742      MPI_Status status;
743      MPI_Request req_s, req_r;
744
745      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);
746      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);
747
748
749      MPI_Wait(&req_s, &status);
750      MPI_Wait(&req_r, &status);
751
752    }
753
754    MPI_Bcast((*newintercomm).ep_comm_ptr->intercomm->remote_rank_map->data(), 2*remote_num_ep, MPI_INT_STD, local_leader, local_comm);
755    (*newintercomm).ep_comm_ptr->intercomm->local_comm = &(local_comm.ep_comm_ptr->comm_list[ep_rank_loc]);
756    (*newintercomm).ep_comm_ptr->intercomm->intercomm_tag = tag;
757
758
759    return MPI_SUCCESS;
760  }
761
762
763}
Note: See TracBrowser for help on using the repository browser.