source: XIOS/dev/branch_openmp/extern/src_ep_dev/ep_intercomm_world.cpp @ 1355

Last change on this file since 1355 was 1355, checked in by yushan, 6 years ago

unify MPI_Comm type

File size: 35.3 KB
Line 
1#include "ep_lib.hpp"
2#include <mpi.h>
3#include "ep_declaration.hpp"
4#include "ep_mpi.hpp"
5
6using namespace std;
7
8namespace ep_lib
9{
10
11  // #ifdef _openmpi
12
13  // int MPI_Intercomm_create_from_world(MPI_Comm local_comm, int local_leader, void* peer_comm_ptr, int mpi_remote_leader, int tag, MPI_Comm *newintercomm)
14  // {
15
16  //   int ep_rank, ep_rank_loc, mpi_rank;
17  //   int ep_size, num_ep, mpi_size;
18
19  //   ep_rank = local_comm.ep_comm_ptr->size_rank_info[0].first;
20  //   ep_rank_loc = local_comm.ep_comm_ptr->size_rank_info[1].first;
21  //   mpi_rank = local_comm.ep_comm_ptr->size_rank_info[2].first;
22  //   ep_size = local_comm.ep_comm_ptr->size_rank_info[0].second;
23  //   num_ep = local_comm.ep_comm_ptr->size_rank_info[1].second;
24  //   mpi_size = local_comm.ep_comm_ptr->size_rank_info[2].second;
25
26
27  //   std::vector<int> rank_info[4];  //! 0->rank_in_world of local_comm,  1->rank_in_local_parent of local_comm
28  //                                   //! 2->rank_in_world of remote_comm, 3->rank_in_local_parent of remote_comm
29
30  //   int rank_in_world;
31  //   int rank_in_local_parent;
32
33  //   int local_ep_size = ep_size;
34  //   int remote_ep_size;
35
36  //   ::MPI_Comm peer_comm = to_mpi_comm(peer_comm_ptr);
37  //   ::MPI_Comm local_mpi_comm = to_mpi_comm(local_comm.mpi_comm);
38
39  //   ::MPI_Comm_rank(peer_comm, &rank_in_world);
40
41  //   ::MPI_Comm_rank(local_mpi_comm, &rank_in_local_parent);
42
43  //   bool is_proc_master = false;
44  //   bool is_local_leader = false;
45  //   bool is_final_master = false;
46
47
48  //   if(ep_rank == local_leader) { is_proc_master = true; is_local_leader = true; is_final_master = true;}
49  //   if(ep_rank_loc == 0 && mpi_rank != local_comm.rank_map->at(local_leader).second) is_proc_master = true;
50
51
52  //   int size_info[4]; //! used for choose size of rank_info 0-> mpi_size of local_comm, 1-> mpi_size of remote_comm
53
54  //   int leader_info[4]; //! 0->world rank of local_leader, 1->world rank of remote leader
55
56
57  //   std::vector<int> ep_info[2]; //! 0-> num_ep in local_comm, 1->num_ep in remote_comm
58
59  //   std::vector<int> new_rank_info[4];
60  //   std::vector<int> new_ep_info[2];
61
62  //   std::vector<int> offset;
63
64  //   if(is_proc_master)
65  //   {
66
67  //     size_info[0] = mpi_size;
68
69  //     rank_info[0].resize(size_info[0]);
70  //     rank_info[1].resize(size_info[0]);
71
72
73
74  //     ep_info[0].resize(size_info[0]);
75
76  //     vector<int> send_buf(6);
77  //     vector<int> recv_buf(3*size_info[0]);
78
79  //     send_buf[0] = rank_in_world;
80  //     send_buf[1] = rank_in_local_parent;
81  //     send_buf[2] = num_ep;
82
83  //     ::MPI_Allgather(send_buf.data(), 3, to_mpi_type(MPI_INT), recv_buf.data(), 3, to_mpi_type(MPI_INT), local_mpi_comm);
84
85  //     for(int i=0; i<size_info[0]; i++)
86  //     {
87  //       rank_info[0][i] = recv_buf[3*i];
88  //       rank_info[1][i] = recv_buf[3*i+1];
89  //       ep_info[0][i]   = recv_buf[3*i+2];
90  //     }
91
92  //     if(is_local_leader)
93  //     {
94  //       leader_info[0] = rank_in_world;
95  //       leader_info[1] = mpi_remote_leader;
96
97  //       ::MPI_Status mpi_status;
98
99  //       send_buf[0] = size_info[0];
100  //       send_buf[1] = local_ep_size;
101
102  //       ::MPI_Send(send_buf.data(), 2, to_mpi_type(MPI_INT), mpi_remote_leader, tag, peer_comm);
103
104  //       ::MPI_Recv(recv_buf.data(), 2, to_mpi_type(MPI_INT), mpi_remote_leader, tag, peer_comm, &mpi_status);
105
106  //       recv_buf[2] = rank_in_world;
107  //       recv_buf[3] = mpi_remote_leader;
108
109  //     }
110
111  //     ::MPI_Bcast(recv_buf.data(), 4, to_mpi_type(MPI_INT), local_comm.rank_map->at(local_leader).second, local_mpi_comm);
112
113  //     size_info[1] = recv_buf[0];
114  //     remote_ep_size = recv_buf[1];
115  //     leader_info[0] = recv_buf[2];
116  //     leader_info[1] = recv_buf[3];
117
118  //     rank_info[2].resize(size_info[1]);
119  //     rank_info[3].resize(size_info[1]);
120
121  //     ep_info[1].resize(size_info[1]);
122
123  //     send_buf.resize(3*size_info[0]);
124  //     recv_buf.resize(3*size_info[1]);
125
126  //     if(is_local_leader)
127  //     {
128  //       ::MPI_Status mpi_status;
129
130
131  //       std::copy ( rank_info[0].data(), rank_info[0].data() + size_info[0], send_buf.begin() );
132  //       std::copy ( rank_info[1].data(), rank_info[1].data() + size_info[0], send_buf.begin() + size_info[0] );
133  //       std::copy ( ep_info[0].data(),   ep_info[0].data()   + size_info[0], send_buf.begin() + 2*size_info[0] );
134
135  //       ::MPI_Send(send_buf.data(), 3*size_info[0], to_mpi_type(MPI_INT), mpi_remote_leader, tag, peer_comm);
136
137  //       ::MPI_Recv(recv_buf.data(), 3*size_info[1], to_mpi_type(MPI_INT), mpi_remote_leader, tag, peer_comm, &mpi_status);
138
139  //     }
140
141  //     ::MPI_Bcast(recv_buf.data(), 3*size_info[1], to_mpi_type(MPI_INT), local_comm.rank_map->at(local_leader).second, local_mpi_comm);
142
143  //     std::copy ( recv_buf.data(), recv_buf.data() + size_info[1], rank_info[2].begin() );
144  //     std::copy ( recv_buf.data() + size_info[1], recv_buf.data() + 2*size_info[1], rank_info[3].begin()  );
145  //     std::copy ( recv_buf.data() + 2*size_info[1], recv_buf.data() + 3*size_info[1], ep_info[1].begin() );
146
147  //     offset.resize(size_info[0]);
148
149  //     if(leader_info[0]<leader_info[1]) // erase all ranks doubled with remote_comm, except the local leader
150  //     {
151
152  //       bool found = false;
153  //       int ep_tmp;
154  //       int ep_local;
155  //       int ep_remote;
156  //       for(int i=0; i<size_info[0]; i++)
157  //       {
158  //         int target = rank_info[0][i];
159  //         found = false;
160  //         for(int j=0; j<size_info[1]; j++)
161  //         {
162  //           if(target == rank_info[2][j])
163  //           {
164  //             found = true;
165  //             ep_tmp = ep_info[1][j];
166  //             ep_local = ep_info[0][j];
167  //             ep_remote = ep_info[1][j];
168  //             break;
169  //           }
170  //         }
171  //         if(found)
172  //         {
173
174  //           if(target == leader_info[0]) // the leader is doubled in remote
175  //           {
176  //             new_rank_info[0].push_back(target);
177  //             new_rank_info[1].push_back(rank_info[1][i]);
178
179  //             new_ep_info[0].push_back(ep_local + ep_remote);
180  //             offset[i] = 0;
181  //           }
182  //           else
183  //           {
184  //             offset[i] = ep_local;
185  //           }
186  //         }
187  //         else
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_info[0][i]);
193
194  //           offset[i] = 0;
195  //         }
196
197  //       }
198  //     }
199
200  //     else // erase rank doubled with remote leader
201  //     {
202
203  //       bool found = false;
204  //       int ep_tmp;
205  //       int ep_local;
206  //       int ep_remote;
207  //       for(int i=0; i<size_info[0]; i++)
208  //       {
209  //         int target = rank_info[0][i];
210  //         found = false;
211  //         for(int j=0; j<size_info[1]; j++)
212  //         {
213
214  //           if(target == rank_info[2][j])
215  //           {
216  //             found = true;
217  //             ep_tmp = ep_info[1][j];
218  //             ep_local = ep_info[0][j];
219  //             ep_remote = ep_info[1][j];
220  //             break;
221  //           }
222  //         }
223  //         if(found)
224  //         {
225  //           if(target != leader_info[1])
226  //           {
227  //             new_rank_info[0].push_back(target);
228  //             new_rank_info[1].push_back(rank_info[1][i]);
229
230  //             new_ep_info[0].push_back(ep_local + ep_remote);
231  //             offset[i] = 0;
232  //           }
233  //           else // found remote leader
234  //           {
235  //             offset[i] = ep_remote;
236  //           }
237  //         }
238  //         else
239  //         {
240  //           new_rank_info[0].push_back(target);
241  //           new_rank_info[1].push_back(rank_info[1][i]);
242
243  //           new_ep_info[0].push_back(ep_info[0][i]);
244  //           offset[i] = 0;
245  //         }
246  //       }
247  //     }
248
249  //     if(offset[mpi_rank] == 0)
250  //     {
251  //       is_final_master = true;
252  //     }
253
254
255  //     // size_info[4]: 2->size of new_ep_info for local, 3->size of new_ep_info for remote
256
257  //     if(is_local_leader)
258  //     {
259  //       size_info[2] = new_ep_info[0].size();
260  //       ::MPI_Status mpi_status;
261
262  //       ::MPI_Send(&size_info[2], 1, to_mpi_type(MPI_INT), mpi_remote_leader, tag, peer_comm);
263
264  //       ::MPI_Recv(&size_info[3], 1, to_mpi_type(MPI_INT), mpi_remote_leader, tag, peer_comm, &mpi_status);
265  //     }
266
267  //     ::MPI_Bcast(&size_info[2], 2, to_mpi_type(MPI_INT), local_comm.rank_map->at(local_leader).second, local_mpi_comm);
268
269  //     new_rank_info[2].resize(size_info[3]);
270  //     new_rank_info[3].resize(size_info[3]);
271  //     new_ep_info[1].resize(size_info[3]);
272
273  //     send_buf.resize(size_info[2]);
274  //     recv_buf.resize(size_info[3]);
275
276  //     if(is_local_leader)
277  //     {
278  //       ::MPI_Status mpi_status;
279
280  //       std::copy ( new_rank_info[0].data(), new_rank_info[0].data() + size_info[2], send_buf.begin() );
281  //       std::copy ( new_rank_info[1].data(), new_rank_info[1].data() + size_info[2], send_buf.begin() + size_info[2] );
282  //       std::copy ( new_ep_info[0].data(),   new_ep_info[0].data()   + size_info[0], send_buf.begin() + 2*size_info[2] );
283
284  //       ::MPI_Send(send_buf.data(), 3*size_info[2], to_mpi_type(MPI_INT), mpi_remote_leader, tag, peer_comm);
285  //       ::MPI_Recv(recv_buf.data(), 3*size_info[3], to_mpi_type(MPI_INT), mpi_remote_leader, tag, peer_comm, &mpi_status);
286
287  //     }
288
289  //     ::MPI_Bcast(recv_buf.data(),   3*size_info[3], to_mpi_type(MPI_INT), local_comm.rank_map->at(local_leader).second, local_mpi_comm);
290
291  //     std::copy ( recv_buf.data(), recv_buf.data() + size_info[3], new_rank_info[2].begin() );
292  //     std::copy ( recv_buf.data() + size_info[3], recv_buf.data() + 2*size_info[3], new_rank_info[3].begin()  );
293  //     std::copy ( recv_buf.data() + 2*size_info[3], recv_buf.data() + 3*size_info[3], new_ep_info[1].begin() );
294
295  //   }
296
297
298
299  //   if(is_proc_master)
300  //   {
301  //     // leader_info[4]: 2-> rank of local leader in new_group generated comm;
302  //                     // 3-> rank of remote leader in new_group generated comm;
303  //     ::MPI_Group local_group;
304  //     ::MPI_Group new_group;
305  //     ::MPI_Comm *new_comm = new ::MPI_Comm;
306  //     ::MPI_Comm *intercomm = new ::MPI_Comm;
307
308  //     ::MPI_Comm_group(local_mpi_comm, &local_group);
309
310  //     ::MPI_Group_incl(local_group, size_info[2], new_rank_info[1].data(), &new_group);
311
312  //     ::MPI_Comm_create(local_mpi_comm, new_group, new_comm);
313
314
315
316  //     if(is_local_leader)
317  //     {
318  //       ::MPI_Comm_rank(*new_comm, &leader_info[2]);
319  //     }
320
321  //     ::MPI_Bcast(&leader_info[2], 1, to_mpi_type(MPI_INT), local_comm.rank_map->at(local_leader).second, local_mpi_comm);
322
323  //     if(new_comm != static_cast< ::MPI_Comm*>(MPI_COMM_NULL.mpi_comm))
324  //     {
325  //       ::MPI_Barrier(*new_comm);
326
327  //       ::MPI_Intercomm_create(*new_comm, leader_info[2], peer_comm, leader_info[1], tag, intercomm);
328
329  //       int id;
330  //       ::MPI_Comm_rank(*new_comm, &id);
331  //       int my_num_ep = new_ep_info[0][id];
332
333  //       MPI_Comm *ep_intercomm;
334  //       MPI_Info info;
335  //       MPI_Comm_create_endpoints(new_comm, my_num_ep, info, ep_intercomm);
336
337
338
339  //       for(int i= 0; i<my_num_ep; i++)
340  //       {
341  //         ep_intercomm[i].is_intercomm = true;
342
343  //         ep_intercomm[i].ep_comm_ptr->intercomm = new ep_lib::ep_intercomm;
344  //         ep_intercomm[i].ep_comm_ptr->intercomm->mpi_inter_comm = intercomm;
345  //         ep_intercomm[i].ep_comm_ptr->comm_label = leader_info[0];
346  //       }
347
348  //       #pragma omp critical (write_to_tag_list)
349  //       tag_list.push_back(make_pair( make_pair(tag, min(leader_info[0], leader_info[1])) , ep_intercomm));
350  //     }
351
352
353  //   }
354
355
356  //   MPI_Barrier_local(local_comm);
357
358  //   vector<int> bcast_buf(8);
359  //   if(is_local_leader)
360  //   {
361  //     std::copy(size_info, size_info+4, bcast_buf.begin());
362  //     std::copy(leader_info, leader_info+4, bcast_buf.begin()+4);
363  //   }
364
365  //   MPI_Bcast(bcast_buf.data(), 8, MPI_INT, local_leader, local_comm);
366
367  //   if(!is_local_leader)
368  //   {
369  //     std::copy(bcast_buf.begin(), bcast_buf.begin()+4, size_info);
370  //     std::copy(bcast_buf.begin()+4, bcast_buf.begin()+8, leader_info);
371  //   }
372
373  //   if(!is_local_leader)
374  //   {
375  //     new_rank_info[1].resize(size_info[2]);
376  //     ep_info[1].resize(size_info[1]);
377  //     offset.resize(size_info[0]);
378  //   }
379
380  //   bcast_buf.resize(size_info[2]+size_info[1]+size_info[0]+1);
381
382  //   if(is_local_leader)
383  //   {
384  //     bcast_buf[0] = remote_ep_size;
385  //     std::copy(new_rank_info[1].data(), new_rank_info[1].data()+size_info[2], bcast_buf.begin()+1);
386  //     std::copy(ep_info[1].data(), ep_info[1].data()+size_info[1], bcast_buf.begin()+size_info[2]+1);
387  //     std::copy(offset.data(), offset.data()+size_info[0], bcast_buf.begin()+size_info[2]+size_info[1]+1);
388  //   }
389
390  //   MPI_Bcast(bcast_buf.data(), size_info[2]+size_info[1]+size_info[0]+1, MPI_INT, local_leader, local_comm);
391
392  //   if(!is_local_leader)
393  //   {
394  //     remote_ep_size = bcast_buf[0];
395  //     std::copy(bcast_buf.data()+1, bcast_buf.data()+1+size_info[2], new_rank_info[1].begin());
396  //     std::copy(bcast_buf.data()+1+size_info[2], bcast_buf.data()+1+size_info[2]+size_info[1], ep_info[1].begin());
397  //     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());
398  //   }
399
400
401  //   int my_position = offset[rank_in_local_parent]+ep_rank_loc;
402
403
404  //   MPI_Barrier_local(local_comm);
405  //   #pragma omp flush
406
407
408  //   #pragma omp critical (read_from_tag_list)
409  //   {
410  //     bool found = false;
411  //     while(!found)
412  //     {
413  //       for(std::list<std::pair < std::pair<int,int>, MPI_Comm* > >::iterator iter = tag_list.begin(); iter!=tag_list.end(); iter++)
414  //       {
415  //         if((*iter).first == make_pair(tag, min(leader_info[0], leader_info[1])))
416  //         {
417  //           *newintercomm =  iter->second[my_position];
418
419  //           found = true;
420  //           //tag_list.erase(iter);
421  //           break;
422  //         }
423  //       }
424  //     }
425  //   }
426
427  //   MPI_Barrier(local_comm);
428
429  //   if(is_local_leader)
430  //   {
431  //     int local_flag = true;
432  //     int remote_flag = false;
433  //     ::MPI_Status mpi_status;
434     
435  //     ::MPI_Send(&local_flag, 1, to_mpi_type(MPI_INT), mpi_remote_leader, tag, peer_comm);
436
437  //     ::MPI_Recv(&remote_flag, 1, to_mpi_type(MPI_INT), mpi_remote_leader, tag, peer_comm, &mpi_status);
438  //   }
439
440  //   MPI_Barrier(local_comm);
441
442  //   if(is_proc_master)
443  //   {
444  //     for(std::list<std::pair < std::pair<int,int>, MPI_Comm* > >::iterator iter = tag_list.begin(); iter!=tag_list.end(); iter++)
445  //     {
446  //       if((*iter).first == make_pair(tag, min(leader_info[0], leader_info[1])))
447  //       {
448  //         tag_list.erase(iter);
449  //         break;
450  //       }
451  //     }
452  //   }
453
454   
455
456  //   int intercomm_ep_rank, intercomm_ep_rank_loc, intercomm_mpi_rank;
457  //   int intercomm_ep_size, intercomm_num_ep, intercomm_mpi_size;
458
459  //   intercomm_ep_rank = newintercomm->ep_comm_ptr->size_rank_info[0].first;
460  //   intercomm_ep_rank_loc = newintercomm->ep_comm_ptr->size_rank_info[1].first;
461  //   intercomm_mpi_rank = newintercomm->ep_comm_ptr->size_rank_info[2].first;
462  //   intercomm_ep_size = newintercomm->ep_comm_ptr->size_rank_info[0].second;
463  //   intercomm_num_ep = newintercomm->ep_comm_ptr->size_rank_info[1].second;
464  //   intercomm_mpi_size = newintercomm->ep_comm_ptr->size_rank_info[2].second;
465
466  //   MPI_Bcast(&remote_ep_size, 1, MPI_INT, local_leader, local_comm);
467
468  //   int my_rank_map_elem[2];
469
470
471  //   my_rank_map_elem[0] = intercomm_ep_rank;
472
473  //   my_rank_map_elem[1] = (*newintercomm).ep_comm_ptr->comm_label;
474
475  //   vector<pair<int, int> > local_rank_map_array;
476  //   vector<pair<int, int> > remote_rank_map_array;
477
478
479  //   (*newintercomm).ep_comm_ptr->intercomm->local_rank_map = new RANK_MAP;
480  //   (*newintercomm).ep_comm_ptr->intercomm->local_rank_map->resize(local_ep_size);
481
482  //   MPI_Allgather2(my_rank_map_elem, 2, MPI_INT, (*newintercomm).ep_comm_ptr->intercomm->local_rank_map->data(), 2, MPI_INT, local_comm);
483
484  //   (*newintercomm).ep_comm_ptr->intercomm->remote_rank_map = new RANK_MAP;
485  //   (*newintercomm).ep_comm_ptr->intercomm->remote_rank_map->resize(remote_ep_size);
486
487  //   int local_intercomm_size = intercomm_ep_size;
488  //   int remote_intercomm_size;
489
490
491
492
493  //   if(is_local_leader)
494  //   {
495  //     ::MPI_Status status;
496
497  //     ::MPI_Send((*newintercomm).ep_comm_ptr->intercomm->local_rank_map->data(), 2*local_ep_size, to_mpi_type(MPI_INT), mpi_remote_leader, tag, peer_comm);
498
499  //     ::MPI_Recv((*newintercomm).ep_comm_ptr->intercomm->remote_rank_map->data(), 2*remote_ep_size, to_mpi_type(MPI_INT), mpi_remote_leader, tag, peer_comm, &status);
500
501  //     ::MPI_Send(&local_intercomm_size, 1, to_mpi_type(MPI_INT), mpi_remote_leader, tag, peer_comm);
502
503  //     ::MPI_Recv(&remote_intercomm_size, 1, to_mpi_type(MPI_INT), mpi_remote_leader, tag, peer_comm, &status);
504  //   }
505
506  //   MPI_Bcast((*newintercomm).ep_comm_ptr->intercomm->remote_rank_map->data(), 2*remote_ep_size, MPI_INT, local_leader, local_comm);
507  //   MPI_Bcast(&remote_intercomm_size, 1, MPI_INT, 0, *newintercomm);
508
509
510  //   (*newintercomm).ep_comm_ptr->intercomm->intercomm_rank_map = new RANK_MAP;
511  //   (*newintercomm).ep_comm_ptr->intercomm->intercomm_rank_map->resize(remote_intercomm_size);
512
513  //   (*newintercomm).ep_comm_ptr->intercomm->size_rank_info[0] = local_comm.ep_comm_ptr->size_rank_info[0];
514  //   (*newintercomm).ep_comm_ptr->intercomm->size_rank_info[1] = local_comm.ep_comm_ptr->size_rank_info[1];
515  //   (*newintercomm).ep_comm_ptr->intercomm->size_rank_info[2] = local_comm.ep_comm_ptr->size_rank_info[2];
516
517
518  //   if(is_local_leader)
519  //   {
520  //     ::MPI_Status status;
521
522  //     ::MPI_Send((*newintercomm).rank_map->data(), 2*local_intercomm_size, to_mpi_type(MPI_INT), mpi_remote_leader, tag, peer_comm);
523
524  //     ::MPI_Recv((*newintercomm).ep_comm_ptr->intercomm->intercomm_rank_map->data(), 2*remote_intercomm_size, to_mpi_type(MPI_INT), mpi_remote_leader, tag, peer_comm, &status);
525  //   }
526
527  //   MPI_Bcast((*newintercomm).ep_comm_ptr->intercomm->intercomm_rank_map->data(), 2*remote_intercomm_size, to_mpi_type(MPI_INT), 0, *newintercomm);
528
529  //   (*newintercomm).ep_comm_ptr->intercomm->local_comm = &(local_comm.ep_comm_ptr->comm_list[ep_rank_loc]);
530  //   (*newintercomm).ep_comm_ptr->intercomm->intercomm_tag = local_comm.ep_comm_ptr->comm_label;
531
532
533  //   return MPI_SUCCESS;
534
535  // }
536
537
538
539  // #elif _intelmpi
540  int MPI_Intercomm_create_from_world(MPI_Comm local_comm, int local_leader, int* peer_comm_ptr, int mpi_remote_leader, int tag, MPI_Comm *newintercomm)
541  {
542    int ep_rank, ep_rank_loc, mpi_rank;
543    int ep_size, num_ep, mpi_size;
544
545    ep_rank = local_comm.ep_comm_ptr->size_rank_info[0].first;
546    ep_rank_loc = local_comm.ep_comm_ptr->size_rank_info[1].first;
547    mpi_rank = local_comm.ep_comm_ptr->size_rank_info[2].first;
548    ep_size = local_comm.ep_comm_ptr->size_rank_info[0].second;
549    num_ep = local_comm.ep_comm_ptr->size_rank_info[1].second;
550    mpi_size = local_comm.ep_comm_ptr->size_rank_info[2].second;
551
552    std::vector<int> rank_info[4];  //! 0->rank_in_world of local_comm,  1->rank_in_local_parent of local_comm
553                                    //! 2->rank_in_world of remote_comm, 3->rank_in_local_parent of remote_comm
554
555    int rank_in_world;
556    int rank_in_local_parent;
557
558    int local_ep_size = ep_size;
559    int remote_ep_size;
560
561    ::MPI_Comm peer_comm = to_mpi_comm(peer_comm_ptr);
562    ::MPI_Comm local_mpi_comm = to_mpi_comm(local_comm.mpi_comm);
563
564    ::MPI_Comm_rank(peer_comm, &rank_in_world);
565
566    ::MPI_Comm_rank(local_mpi_comm, &rank_in_local_parent);
567
568    bool is_proc_master = false;
569    bool is_local_leader = false;
570    bool is_final_master = false;
571
572
573    if(ep_rank == local_leader) { is_proc_master = true; is_local_leader = true; is_final_master = true;}
574    if(ep_rank_loc == 0 && mpi_rank != local_comm.rank_map->at(local_leader).second) is_proc_master = true;
575
576
577    int size_info[4]; //! used for choose size of rank_info 0-> mpi_size of local_comm, 1-> mpi_size of remote_comm
578
579    int leader_info[4]; //! 0->world rank of local_leader, 1->world rank of remote leader
580
581
582    std::vector<int> ep_info[2]; //! 0-> num_ep in local_comm, 1->num_ep in remote_comm
583
584    std::vector<int> new_rank_info[4];
585    std::vector<int> new_ep_info[2];
586
587    std::vector<int> offset;
588
589    if(is_proc_master)
590    {
591
592      size_info[0] = mpi_size;
593
594      rank_info[0].resize(size_info[0]);
595      rank_info[1].resize(size_info[0]);
596
597      ep_info[0].resize(size_info[0]);
598
599      vector<int> send_buf(6);
600      vector<int> recv_buf(3*size_info[0]);
601
602      send_buf[0] = rank_in_world;
603      send_buf[1] = rank_in_local_parent;
604      send_buf[2] = num_ep;
605
606      ::MPI_Allgather(send_buf.data(), 3, to_mpi_type(MPI_INT), recv_buf.data(), 3, to_mpi_type(MPI_INT), local_mpi_comm);
607
608      for(int i=0; i<size_info[0]; i++)
609      {
610        rank_info[0][i] = recv_buf[3*i];
611        rank_info[1][i] = recv_buf[3*i+1];
612        ep_info[0][i]   = recv_buf[3*i+2];
613      }
614
615
616      if(is_local_leader)
617      {
618        leader_info[0] = rank_in_world;
619        leader_info[1] = mpi_remote_leader;
620
621        ::MPI_Status mpi_status;
622
623        send_buf[0] = size_info[0];
624        send_buf[1] = local_ep_size;
625
626        ::MPI_Send(send_buf.data(), 2, to_mpi_type(MPI_INT), mpi_remote_leader, tag, peer_comm);
627
628        ::MPI_Recv(recv_buf.data(), 2, to_mpi_type(MPI_INT), mpi_remote_leader, tag, peer_comm, &mpi_status);
629
630        recv_buf[2] = rank_in_world;
631        recv_buf[3] = mpi_remote_leader;
632
633      }
634
635      ::MPI_Bcast(recv_buf.data(), 4, to_mpi_type(MPI_INT), local_comm.rank_map->at(local_leader).second, local_mpi_comm);
636
637      size_info[1] = recv_buf[0];
638      remote_ep_size = recv_buf[1];
639      leader_info[0] = recv_buf[2];
640      leader_info[1] = recv_buf[3];
641
642      rank_info[2].resize(size_info[1]);
643      rank_info[3].resize(size_info[1]);
644
645      ep_info[1].resize(size_info[1]);
646
647      send_buf.resize(3*size_info[0]);
648      recv_buf.resize(3*size_info[1]);
649
650      if(is_local_leader)
651      {
652        ::MPI_Status mpi_status;
653
654
655        std::copy ( rank_info[0].data(), rank_info[0].data() + size_info[0], send_buf.begin() );
656        std::copy ( rank_info[1].data(), rank_info[1].data() + size_info[0], send_buf.begin() + size_info[0] );
657        std::copy ( ep_info[0].data(),   ep_info[0].data()   + size_info[0], send_buf.begin() + 2*size_info[0] );
658
659        ::MPI_Send(send_buf.data(), 3*size_info[0], to_mpi_type(MPI_INT), mpi_remote_leader, tag, peer_comm);
660
661        ::MPI_Recv(recv_buf.data(), 3*size_info[1], to_mpi_type(MPI_INT), mpi_remote_leader, tag, peer_comm, &mpi_status);
662
663      }
664
665      ::MPI_Bcast(recv_buf.data(), 3*size_info[1], to_mpi_type(MPI_INT), local_comm.rank_map->at(local_leader).second, local_mpi_comm);
666
667      std::copy ( recv_buf.data(), recv_buf.data() + size_info[1], rank_info[2].begin() );
668      std::copy ( recv_buf.data() + size_info[1], recv_buf.data() + 2*size_info[1], rank_info[3].begin()  );
669      std::copy ( recv_buf.data() + 2*size_info[1], recv_buf.data() + 3*size_info[1], ep_info[1].begin() );
670
671      offset.resize(size_info[0]);
672
673      if(leader_info[0]<leader_info[1]) // erase all ranks doubled with remote_comm, except the local leader
674      {
675
676        bool found = false;
677        int ep_tmp;
678        int ep_local;
679        int ep_remote;
680        for(int i=0; i<size_info[0]; i++)
681        {
682          int target = rank_info[0][i];
683          found = false;
684          for(int j=0; j<size_info[1]; j++)
685          {
686            if(target == rank_info[2][j])
687            {
688              found = true;
689              ep_tmp = ep_info[1][j];
690              ep_local = ep_info[0][j];
691              ep_remote = ep_info[1][j];
692              break;
693            }
694          }
695          if(found)
696          {
697
698            if(target == leader_info[0]) // the leader is doubled in remote
699            {
700              new_rank_info[0].push_back(target);
701              new_rank_info[1].push_back(rank_info[1][i]);
702
703              new_ep_info[0].push_back(ep_local + ep_remote);
704              offset[i] = 0;
705            }
706            else
707            {
708              offset[i] = ep_local;
709            }
710          }
711          else
712          {
713            new_rank_info[0].push_back(target);
714            new_rank_info[1].push_back(rank_info[1][i]);
715
716            new_ep_info[0].push_back(ep_info[0][i]);
717
718            offset[i] = 0;
719          }
720
721        }
722      }
723
724      else // erase rank doubled with remote leader
725      {
726
727        bool found = false;
728        int ep_tmp;
729        int ep_local;
730        int ep_remote;
731        for(int i=0; i<size_info[0]; i++)
732        {
733          int target = rank_info[0][i];
734          found = false;
735          for(int j=0; j<size_info[1]; j++)
736          {
737
738            if(target == rank_info[2][j])
739            {
740              found = true;
741              ep_tmp = ep_info[1][j];
742              ep_local = ep_info[0][j];
743              ep_remote = ep_info[1][j];
744              break;
745            }
746          }
747          if(found)
748          {
749            if(target != leader_info[1])
750            {
751              new_rank_info[0].push_back(target);
752              new_rank_info[1].push_back(rank_info[1][i]);
753
754              new_ep_info[0].push_back(ep_local + ep_remote);
755              offset[i] = 0;
756            }
757            else // found remote leader
758            {
759              offset[i] = ep_remote;
760            }
761          }
762          else
763          {
764            new_rank_info[0].push_back(target);
765            new_rank_info[1].push_back(rank_info[1][i]);
766
767            new_ep_info[0].push_back(ep_info[0][i]);
768            offset[i] = 0;
769          }
770        }
771      }
772
773      if(offset[mpi_rank] == 0)
774      {
775        is_final_master = true;
776      }
777
778
779      // size_info[4]: 2->size of new_ep_info for local, 3->size of new_ep_info for remote
780
781      if(is_local_leader)
782      {
783        size_info[2] = new_ep_info[0].size();
784        ::MPI_Status mpi_status;
785
786        ::MPI_Send(&size_info[2], 1, to_mpi_type(MPI_INT), mpi_remote_leader, tag, peer_comm);
787
788        ::MPI_Recv(&size_info[3], 1, to_mpi_type(MPI_INT), mpi_remote_leader, tag, peer_comm, &mpi_status);
789      }
790
791      ::MPI_Bcast(&size_info[2], 2, to_mpi_type(MPI_INT), local_comm.rank_map->at(local_leader).second, local_mpi_comm);
792
793      new_rank_info[2].resize(size_info[3]);
794      new_rank_info[3].resize(size_info[3]);
795      new_ep_info[1].resize(size_info[3]);
796
797      send_buf.resize(size_info[2]);
798      recv_buf.resize(size_info[3]);
799
800      if(is_local_leader)
801      {
802        ::MPI_Status mpi_status;
803
804        std::copy ( new_rank_info[0].data(), new_rank_info[0].data() + size_info[2], send_buf.begin() );
805        std::copy ( new_rank_info[1].data(), new_rank_info[1].data() + size_info[2], send_buf.begin() + size_info[2] );
806        std::copy ( new_ep_info[0].data(),   new_ep_info[0].data()   + size_info[0], send_buf.begin() + 2*size_info[2] );
807
808        ::MPI_Send(send_buf.data(), 3*size_info[2], to_mpi_type(MPI_INT), mpi_remote_leader, tag, peer_comm);
809
810        ::MPI_Recv(recv_buf.data(), 3*size_info[3], to_mpi_type(MPI_INT), mpi_remote_leader, tag, peer_comm, &mpi_status);
811      }
812
813      ::MPI_Bcast(recv_buf.data(),   3*size_info[3], to_mpi_type(MPI_INT), local_comm.rank_map->at(local_leader).second, local_mpi_comm);
814
815      std::copy ( recv_buf.data(), recv_buf.data() + size_info[3], new_rank_info[2].begin() );
816      std::copy ( recv_buf.data() + size_info[3], recv_buf.data() + 2*size_info[3], new_rank_info[3].begin()  );
817      std::copy ( recv_buf.data() + 2*size_info[3], recv_buf.data() + 3*size_info[3], new_ep_info[1].begin() );
818
819    }
820
821
822
823    if(is_proc_master)
824    {
825      // leader_info[4]: 2-> rank of local leader in new_group generated comm;
826                      // 3-> rank of remote leader in new_group generated comm;
827      ::MPI_Group local_group;
828      ::MPI_Group new_group;
829      ::MPI_Comm *new_comm = new ::MPI_Comm;
830      ::MPI_Comm *intercomm = new ::MPI_Comm;
831
832      ::MPI_Comm_group(local_mpi_comm, &local_group);
833
834      ::MPI_Group_incl(local_group, size_info[2], new_rank_info[1].data(), &new_group);
835
836      ::MPI_Comm_create(local_mpi_comm, new_group, new_comm);
837
838
839
840      if(is_local_leader)
841      {
842        ::MPI_Comm_rank(*new_comm, &leader_info[2]);
843      }
844
845      ::MPI_Bcast(&leader_info[2], 1, to_mpi_type(MPI_INT), local_comm.rank_map->at(local_leader).second, local_mpi_comm);
846
847      if(new_comm != static_cast< ::MPI_Comm* >(MPI_COMM_NULL.mpi_comm))
848      {
849        ::MPI_Barrier(*new_comm);
850
851        ::MPI_Intercomm_create(*new_comm, leader_info[2], peer_comm, leader_info[1], tag, intercomm);
852
853        int id;
854        ::MPI_Comm_rank(*new_comm, &id);
855        int my_num_ep = new_ep_info[0][id];
856
857        MPI_Comm *ep_intercomm;
858        MPI_Info info;
859        MPI_Comm_create_endpoints(new_comm, my_num_ep, info, ep_intercomm);
860
861        for(int i= 0; i<my_num_ep; i++)
862        {
863          ep_intercomm[i].is_intercomm = true;
864
865          ep_intercomm[i].ep_comm_ptr->intercomm = new ep_lib::ep_intercomm;
866          ep_intercomm[i].ep_comm_ptr->intercomm->mpi_inter_comm = intercomm;
867          ep_intercomm[i].ep_comm_ptr->comm_label = leader_info[0];
868        }
869
870
871        #pragma omp critical (write_to_tag_list)
872        tag_list.push_back(make_pair( make_pair(tag, min(leader_info[0], leader_info[1])) , ep_intercomm));
873       
874
875      }
876
877
878    }
879
880
881    vector<int> bcast_buf(8);
882    if(is_local_leader)
883    {
884      std::copy(size_info, size_info+4, bcast_buf.begin());
885      std::copy(leader_info, leader_info+4, bcast_buf.begin()+4);
886    }
887
888
889
890    MPI_Bcast(bcast_buf.data(), 8, MPI_INT, local_leader, local_comm);
891
892
893    if(!is_local_leader)
894    {
895      std::copy(bcast_buf.begin(), bcast_buf.begin()+4, size_info);
896      std::copy(bcast_buf.begin()+4, bcast_buf.begin()+8, leader_info);
897    }
898
899
900
901    if(!is_local_leader)
902    {
903      new_rank_info[1].resize(size_info[2]);
904      ep_info[1].resize(size_info[1]);
905      offset.resize(size_info[0]);
906    }
907
908    bcast_buf.resize(size_info[2]+size_info[1]+size_info[0]+1);
909
910    if(is_local_leader)
911    {
912      bcast_buf[0] = remote_ep_size;
913      std::copy(new_rank_info[1].data(), new_rank_info[1].data()+size_info[2], bcast_buf.begin()+1);
914      std::copy(ep_info[1].data(), ep_info[1].data()+size_info[1], bcast_buf.begin()+size_info[2]+1);
915      std::copy(offset.data(), offset.data()+size_info[0], bcast_buf.begin()+size_info[2]+size_info[1]+1);
916    }
917
918    MPI_Bcast(bcast_buf.data(), size_info[2]+size_info[1]+size_info[0]+1, MPI_INT, local_leader, local_comm);
919
920
921    if(!is_local_leader)
922    {
923      remote_ep_size = bcast_buf[0];
924      std::copy(bcast_buf.data()+1, bcast_buf.data()+1+size_info[2], new_rank_info[1].begin());
925      std::copy(bcast_buf.data()+1+size_info[2], bcast_buf.data()+1+size_info[2]+size_info[1], ep_info[1].begin());
926      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());
927    }
928
929
930    int my_position = offset[rank_in_local_parent]+ep_rank_loc;
931
932
933    #pragma omp critical (read_from_tag_list)
934    {
935      bool found = false;
936      while(!found)
937      {
938        for(std::list<std::pair < std::pair<int,int>, MPI_Comm* > >::iterator iter = tag_list.begin(); iter!=tag_list.end(); iter++)
939        {
940          if((*iter).first == make_pair(tag, min(leader_info[0], leader_info[1])))
941          {
942            *newintercomm =  iter->second[my_position];
943
944            found = true;
945            break;
946          }
947        }
948      }
949    }
950
951    MPI_Barrier(local_comm);
952
953    if(is_local_leader)
954    {
955      int local_flag = true;
956      int remote_flag = false;
957      ::MPI_Status mpi_status;
958     
959      ::MPI_Send(&local_flag, 1, to_mpi_type(MPI_INT), mpi_remote_leader, tag, peer_comm);
960
961      ::MPI_Recv(&remote_flag, 1, to_mpi_type(MPI_INT), mpi_remote_leader, tag, peer_comm, &mpi_status);
962    }
963
964    MPI_Barrier(local_comm);
965
966    if(is_proc_master)
967    {
968      for(std::list<std::pair < std::pair<int,int>, MPI_Comm* > >::iterator iter = tag_list.begin(); iter!=tag_list.end(); iter++)
969      {
970        if((*iter).first == make_pair(tag, min(leader_info[0], leader_info[1])))
971        {
972          tag_list.erase(iter);
973          break;
974        }
975      }
976    }
977
978    int intercomm_ep_rank, intercomm_ep_rank_loc, intercomm_mpi_rank;
979    int intercomm_ep_size, intercomm_num_ep, intercomm_mpi_size;
980
981    intercomm_ep_rank = newintercomm->ep_comm_ptr->size_rank_info[0].first;
982    intercomm_ep_rank_loc = newintercomm->ep_comm_ptr->size_rank_info[1].first;
983    intercomm_mpi_rank = newintercomm->ep_comm_ptr->size_rank_info[2].first;
984    intercomm_ep_size = newintercomm->ep_comm_ptr->size_rank_info[0].second;
985    intercomm_num_ep = newintercomm->ep_comm_ptr->size_rank_info[1].second;
986    intercomm_mpi_size = newintercomm->ep_comm_ptr->size_rank_info[2].second;
987
988
989    MPI_Bcast(&remote_ep_size, 1, MPI_INT, local_leader, local_comm);
990
991    int my_rank_map_elem[2];
992
993
994    my_rank_map_elem[0] = intercomm_ep_rank;
995
996    my_rank_map_elem[1] = (*newintercomm).ep_comm_ptr->comm_label;
997
998    vector<pair<int, int> > local_rank_map_array;
999    vector<pair<int, int> > remote_rank_map_array;
1000
1001
1002    (*newintercomm).ep_comm_ptr->intercomm->local_rank_map = new RANK_MAP;
1003    (*newintercomm).ep_comm_ptr->intercomm->local_rank_map->resize(local_ep_size);
1004
1005    MPI_Allgather(my_rank_map_elem, 2, MPI_INT, (*newintercomm).ep_comm_ptr->intercomm->local_rank_map->data(), 2, MPI_INT, local_comm);
1006   
1007    (*newintercomm).ep_comm_ptr->intercomm->remote_rank_map = new RANK_MAP;
1008    (*newintercomm).ep_comm_ptr->intercomm->remote_rank_map->resize(remote_ep_size);
1009
1010    int local_intercomm_size = intercomm_ep_size;
1011    int remote_intercomm_size;
1012
1013
1014    if(is_local_leader)
1015    {
1016      ::MPI_Status status;
1017
1018      ::MPI_Send((*newintercomm).ep_comm_ptr->intercomm->local_rank_map->data(), 2*local_ep_size, to_mpi_type(MPI_INT), mpi_remote_leader, tag, peer_comm);
1019
1020      ::MPI_Recv((*newintercomm).ep_comm_ptr->intercomm->remote_rank_map->data(), 2*remote_ep_size, to_mpi_type(MPI_INT), mpi_remote_leader, tag, peer_comm, &status);
1021
1022      ::MPI_Send(&local_intercomm_size, 1, to_mpi_type(MPI_INT), mpi_remote_leader, tag, peer_comm);
1023
1024      ::MPI_Recv(&remote_intercomm_size, 1, to_mpi_type(MPI_INT), mpi_remote_leader, tag, peer_comm, &status);
1025    }
1026
1027    MPI_Bcast((*newintercomm).ep_comm_ptr->intercomm->remote_rank_map->data(), 2*remote_ep_size, MPI_INT, local_leader, local_comm);
1028    MPI_Bcast(&remote_intercomm_size, 1, MPI_INT, 0, *newintercomm);
1029
1030
1031    (*newintercomm).ep_comm_ptr->intercomm->intercomm_rank_map = new RANK_MAP;
1032    (*newintercomm).ep_comm_ptr->intercomm->intercomm_rank_map->resize(remote_intercomm_size);
1033
1034    (*newintercomm).ep_comm_ptr->intercomm->size_rank_info[0] = local_comm.ep_comm_ptr->size_rank_info[0];
1035    (*newintercomm).ep_comm_ptr->intercomm->size_rank_info[1] = local_comm.ep_comm_ptr->size_rank_info[1];
1036    (*newintercomm).ep_comm_ptr->intercomm->size_rank_info[2] = local_comm.ep_comm_ptr->size_rank_info[2];
1037
1038
1039    if(is_local_leader)
1040    {
1041      ::MPI_Status status;
1042
1043      ::MPI_Send((*newintercomm).rank_map->data(), 2*local_intercomm_size, to_mpi_type(MPI_INT), mpi_remote_leader, tag, peer_comm);
1044
1045      ::MPI_Recv((*newintercomm).ep_comm_ptr->intercomm->intercomm_rank_map->data(), 2*remote_intercomm_size, to_mpi_type(MPI_INT), mpi_remote_leader, tag, peer_comm, &status);
1046    }
1047
1048    MPI_Bcast((*newintercomm).ep_comm_ptr->intercomm->intercomm_rank_map->data(), 2*remote_intercomm_size, MPI_INT, 0, *newintercomm);
1049
1050    (*newintercomm).ep_comm_ptr->intercomm->local_comm = &(local_comm.ep_comm_ptr->comm_list[ep_rank_loc]);
1051    (*newintercomm).ep_comm_ptr->intercomm->intercomm_tag = local_comm.ep_comm_ptr->comm_label;
1052
1053    return MPI_SUCCESS;
1054
1055  }
1056
1057  // #endif
1058
1059}
1060
Note: See TracBrowser for help on using the repository browser.