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

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

save dev. recv_test OK

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