source: XIOS/dev/branch_openmp/extern/ep_dev/ep_merge.cpp @ 1518

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

optimisation partially finished. To do : special case for intercomm_create and intercomm_merge

File size: 10.9 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
8
9namespace ep_lib {
10
11  int MPI_Intercomm_merge_unique_leader(MPI_Comm inter_comm, bool high, MPI_Comm *newintracomm)
12  {
13    Debug("intercomm_merge with unique leader\n");
14
15
16
17    int ep_rank, ep_rank_loc, mpi_rank;
18    int ep_size, num_ep, mpi_size;
19
20    ep_rank = inter_comm->ep_comm_ptr->size_rank_info[0].first;
21    ep_rank_loc = inter_comm->ep_comm_ptr->size_rank_info[1].first;
22    mpi_rank = inter_comm->ep_comm_ptr->size_rank_info[2].first;
23    ep_size = inter_comm->ep_comm_ptr->size_rank_info[0].second;
24    num_ep = inter_comm->ep_comm_ptr->size_rank_info[1].second;
25    mpi_size = inter_comm->ep_comm_ptr->size_rank_info[2].second;
26
27    int local_high = high;
28    int remote_high;
29
30    int remote_ep_size = inter_comm->ep_comm_ptr->intercomm->remote_rank_map->size();
31
32    int local_ep_rank, local_ep_rank_loc, local_mpi_rank;
33    int local_ep_size, local_num_ep, local_mpi_size;
34
35    //local_ep_rank = inter_comm->ep_comm_ptr->intercomm->local_comm->ep_comm_ptr->size_rank_info[0].first;
36    //local_ep_rank_loc = inter_comm->ep_comm_ptr->intercomm->local_comm->ep_comm_ptr->size_rank_info[1].first;
37    //local_mpi_rank = inter_comm->ep_comm_ptr->intercomm->local_comm->ep_comm_ptr->size_rank_info[2].first;
38    //local_ep_size = inter_comm->ep_comm_ptr->intercomm->local_comm->ep_comm_ptr->size_rank_info[0].second;
39    //local_num_ep = inter_comm->ep_comm_ptr->intercomm->local_comm->ep_comm_ptr->size_rank_info[1].second;
40    //local_mpi_size = inter_comm->ep_comm_ptr->intercomm->local_comm->ep_comm_ptr->size_rank_info[2].second;
41
42
43    if(local_ep_rank == 0)
44    {
45      MPI_Status status[2];
46      MPI_Request request[2];
47      MPI_Isend(&local_high, 1, MPI_INT, 0, inter_comm->ep_comm_ptr->intercomm->intercomm_tag, inter_comm, &request[0]);
48      MPI_Irecv(&remote_high, 1, MPI_INT, 0, inter_comm->ep_comm_ptr->intercomm->intercomm_tag, inter_comm, &request[1]);
49
50      MPI_Waitall(2, request, status);
51    }
52
53
54    //MPI_Bcast(&remote_high, 1, MPI_INT, 0, inter_comm->ep_comm_ptr->intercomm->local_comm);
55
56
57
58    MPI_Comm_dup(inter_comm, newintracomm);
59
60    int my_ep_rank = local_high<remote_high? local_ep_rank: local_ep_rank+remote_ep_size;
61
62
63    int intra_ep_rank, intra_ep_rank_loc, intra_mpi_rank;
64    int intra_ep_size, intra_num_ep, intra_mpi_size;
65
66    intra_ep_rank = (*newintracomm)->ep_comm_ptr->size_rank_info[0].first;
67    intra_ep_rank_loc = (*newintracomm)->ep_comm_ptr->size_rank_info[1].first;
68    intra_mpi_rank = (*newintracomm)->ep_comm_ptr->size_rank_info[2].first;
69    intra_ep_size = (*newintracomm)->ep_comm_ptr->size_rank_info[0].second;
70    intra_num_ep = (*newintracomm)->ep_comm_ptr->size_rank_info[1].second;
71    intra_mpi_size = (*newintracomm)->ep_comm_ptr->size_rank_info[2].second;
72
73
74    MPI_Barrier_local(*newintracomm);
75
76
77    int *reorder;
78    if(intra_ep_rank_loc == 0)
79    {
80      reorder = new int[intra_ep_size];
81    }
82
83
84    MPI_Gather(&my_ep_rank, 1, MPI_INT, reorder, 1, MPI_INT, 0, *newintracomm);
85    if(intra_ep_rank_loc == 0)
86    {
87      ::MPI_Bcast(reorder, intra_ep_size, to_mpi_type(MPI_INT), 0, to_mpi_comm((*newintracomm)->mpi_comm));
88
89      vector< pair<int, int> > tmp_rank_map(intra_ep_size);
90
91
92      for(int i=0; i<intra_ep_size; i++)
93      {
94        tmp_rank_map[reorder[i]] = (*newintracomm)->ep_rank_map->at(i) ;
95      }
96
97      //(*newintracomm)->rank_map->swap(tmp_rank_map);
98      (*newintracomm)->ep_rank_map->clear();
99      for(int i=0; i<tmp_rank_map.size(); i++)
100      {
101        (*newintracomm)->ep_rank_map->insert(std::pair< int, std::pair<int,int> >(i, tmp_rank_map[i].first, tmp_rank_map[i].second));
102      }
103     
104
105      tmp_rank_map.clear();
106    }
107
108    MPI_Barrier_local(*newintracomm);
109
110    (*newintracomm)->ep_comm_ptr->size_rank_info[0].first = my_ep_rank;
111
112    if(intra_ep_rank_loc == 0)
113    {
114      delete[] reorder;
115    }
116
117    return MPI_SUCCESS;
118  }
119
120
121
122
123
124  int MPI_Intercomm_merge(MPI_Comm inter_comm, bool high, MPI_Comm *newintracomm)
125  {
126   
127
128    assert(inter_comm->is_intercomm);
129
130    // determine if only one MPI proc
131
132        // to be completed ......
133
134    // multiple MPI proc and high differs
135
136    int newcomm_ep_rank = inter_comm->ep_comm_ptr->intercomm->size_rank_info[0].first;
137    int newcomm_ep_rank_loc = inter_comm->ep_comm_ptr->intercomm->size_rank_info[1].first;
138    int newcomm_num_ep = inter_comm->ep_comm_ptr->intercomm->size_rank_info[1].second;
139
140    int ep_rank = inter_comm->ep_comm_ptr->size_rank_info[0].first;
141    int ep_rank_loc = inter_comm->ep_comm_ptr->size_rank_info[1].first;
142    int num_ep = inter_comm->ep_comm_ptr->size_rank_info[1].second;
143
144    if(newcomm_ep_rank_loc == 0)
145    {
146      ::MPI_Comm *mpi_intracomm = new ::MPI_Comm;
147      ::MPI_Intercomm_merge(to_mpi_comm(inter_comm->ep_comm_ptr->intercomm->mpi_inter_comm), high, mpi_intracomm);
148     
149      MPI_Info info;
150      MPI_Comm *ep_comm;
151      MPI_Comm_create_endpoints(mpi_intracomm, newcomm_num_ep, info, ep_comm);
152
153      inter_comm->ep_comm_ptr->comm_list[0]->mem_bridge = ep_comm;
154    }
155
156    MPI_Barrier_local(inter_comm);
157
158    int remote_num_ep = newcomm_num_ep - num_ep;
159
160    *newintracomm = inter_comm->ep_comm_ptr->comm_list[0]->mem_bridge[high? remote_num_ep+ep_rank_loc : ep_rank_loc];
161
162    int ep_size = inter_comm->ep_comm_ptr->size_rank_info[0].second;
163    int remote_ep_size = inter_comm->ep_comm_ptr->intercomm->intercomm_rank_map->size();
164
165    //printf("ep_size = %d, remote_ep_size = %d\n", ep_size, remote_ep_size);
166
167    (*newintracomm)->ep_comm_ptr->size_rank_info[0].first = high? remote_ep_size+ep_rank : ep_rank;
168
169    int my_triple[3];
170    my_triple[0] = (*newintracomm)->ep_comm_ptr->size_rank_info[0].first;
171    my_triple[1] = (*newintracomm)->ep_comm_ptr->size_rank_info[1].first;
172    my_triple[2] = (*newintracomm)->ep_comm_ptr->size_rank_info[2].first;
173
174    int *my_triple_list = new int[3 * (*newintracomm)->ep_comm_ptr->size_rank_info[0].second];
175
176
177    MPI_Allgather(my_triple, 3, MPI_INT, my_triple_list, 3, MPI_INT, *newintracomm);
178
179    if((*newintracomm)->ep_comm_ptr->size_rank_info[1].first == 0)
180    {
181      (*newintracomm)->ep_rank_map->clear();
182      for(int i=0; i<(*newintracomm)->ep_comm_ptr->size_rank_info[0].second; i++)
183      {
184        (*newintracomm)->ep_rank_map->insert(std::pair< int, std::pair<int,int> >(my_triple_list[3*i], my_triple_list[3*i+1], my_triple_list[3*i+2]));
185      }
186    }
187
188#ifdef _showinfo
189    MPI_Barrier_local(inter_comm);
190    if((*newintracomm)->ep_comm_ptr->size_rank_info[0].first == 15)
191    {
192      for(std::map<int, std::pair<int, int> >::iterator it = (*newintracomm)->ep_rank_map->begin(); it != (*newintracomm)->ep_rank_map->end(); it++)
193      {
194        printf("(%d  %d  %d)\n", it->first, it->second.first, it->second.second);
195      }
196    }
197#endif
198   
199    delete my_triple_list;
200 
201
202    return 0;
203
204
205
206    Debug("intercomm_merge kernel\n");
207
208    //int ep_rank_loc;
209    //int num_ep;
210
211    ep_rank_loc = inter_comm->ep_comm_ptr->size_rank_info[1].first;
212    num_ep = inter_comm->ep_comm_ptr->size_rank_info[1].second;
213
214
215
216    //int remote_ep_size = inter_comm->ep_comm_ptr->intercomm->remote_rank_map->size();
217
218
219    MPI_Barrier(inter_comm);
220
221
222    ::MPI_Comm *mpi_intracomm = new ::MPI_Comm;
223    MPI_Comm *ep_intracomm;
224
225    if(ep_rank_loc == 0)
226    {
227
228      ::MPI_Comm mpi_comm = to_mpi_comm(inter_comm->ep_comm_ptr->intercomm->mpi_inter_comm);
229
230      ::MPI_Intercomm_merge(mpi_comm, high, mpi_intracomm);
231      MPI_Info info;
232      MPI_Comm_create_endpoints(mpi_intracomm, num_ep, info, ep_intracomm);
233
234      inter_comm->ep_comm_ptr->comm_list[0]->mem_bridge = ep_intracomm;
235
236    }
237
238    MPI_Barrier_local(inter_comm);
239
240    int inter_rank;
241    MPI_Comm_rank(inter_comm, &inter_rank);
242   
243    int my_ep_rank = high? inter_rank+remote_ep_size : inter_rank;
244    int my_ep_rank_loc;// = inter_comm->ep_comm_ptr->intercomm->local_comm->ep_comm_ptr->size_rank_info[1].first;
245    int my_num_ep_loc;// = inter_comm->ep_comm_ptr->intercomm->local_comm->ep_comm_ptr->size_rank_info[1].second;
246    int my_num_ep_total = inter_comm->ep_comm_ptr->comm_list[0]->mem_bridge[0]->ep_comm_ptr->size_rank_info[1].second;
247    int my_ep_size = inter_comm->ep_comm_ptr->comm_list[0]->mem_bridge[0]->ep_comm_ptr->size_rank_info[0].second;
248
249    int tmp_intra_ep_rank_loc = high?my_ep_rank_loc+my_num_ep_total-my_num_ep_loc: my_ep_rank_loc;
250
251
252    *newintracomm = inter_comm->ep_comm_ptr->comm_list[0]->mem_bridge[tmp_intra_ep_rank_loc];
253
254    int newintracomm_ep_rank = (*newintracomm)->ep_comm_ptr->size_rank_info[0].first;
255    int newintracomm_ep_rank_loc = (*newintracomm)->ep_comm_ptr->size_rank_info[1].first;
256    int newintracomm_mpi_rank = (*newintracomm)->ep_comm_ptr->size_rank_info[2].first;
257    int newintracomm_ep_size = (*newintracomm)->ep_comm_ptr->size_rank_info[0].second;
258    int newintracomm_num_ep = (*newintracomm)->ep_comm_ptr->size_rank_info[1].second;
259    int newintracomm_mpi_size = (*newintracomm)->ep_comm_ptr->size_rank_info[2].second;
260
261
262    int buf[3];
263    buf[0] = my_ep_rank;
264    buf[1] = tmp_intra_ep_rank_loc;
265    buf[2] = (*newintracomm)->ep_comm_ptr->size_rank_info[2].first;
266
267    // printf("my_ep_rank = %d, tmp_intra_ep_rank_loc = %d, mpi_rank = %d\n", my_ep_rank, tmp_intra_ep_rank_loc, newintracomm->ep_comm_ptr->size_rank_info[2].first);
268
269    int *rankmap_buf;
270    rankmap_buf = new int [3*my_ep_size];
271
272    MPI_Allgather(buf, 3, MPI_INT, rankmap_buf, 3, MPI_INT, *newintracomm);
273
274   
275    // printf(" ID = %d : rankmap_buf = (%d %d %d), (%d %d %d), (%d %d %d), (%d %d %d), (%d %d %d), (%d %d %d), (%d %d %d), (%d %d %d), (%d %d %d), (%d %d %d), (%d %d %d), (%d %d %d), (%d %d %d), (%d %d %d), (%d %d %d), (%d %d %d)\n", newintracomm_ep_rank,
276    //                     rankmap_buf[0], rankmap_buf[1], rankmap_buf[2], rankmap_buf[3], rankmap_buf[4], rankmap_buf[5], rankmap_buf[6], rankmap_buf[7], rankmap_buf[8], rankmap_buf[9],
277    //                     rankmap_buf[10], rankmap_buf[11], rankmap_buf[12], rankmap_buf[13], rankmap_buf[14], rankmap_buf[15], rankmap_buf[16], rankmap_buf[17], rankmap_buf[18], rankmap_buf[19],
278    //                     rankmap_buf[20], rankmap_buf[21], rankmap_buf[22], rankmap_buf[23], rankmap_buf[24], rankmap_buf[25], rankmap_buf[26], rankmap_buf[27], rankmap_buf[28], rankmap_buf[29],
279    //                     rankmap_buf[30], rankmap_buf[31], rankmap_buf[32], rankmap_buf[33], rankmap_buf[34], rankmap_buf[35], rankmap_buf[36], rankmap_buf[37], rankmap_buf[38], rankmap_buf[39],
280    //                     rankmap_buf[40], rankmap_buf[41], rankmap_buf[42], rankmap_buf[43], rankmap_buf[44], rankmap_buf[45], rankmap_buf[46], rankmap_buf[47]);
281
282
283    for(int i=0; i<newintracomm_ep_size; i++)
284    {
285      (*newintracomm)->ep_rank_map->at(rankmap_buf[3*i]).first  = rankmap_buf[3*i+1];
286      (*newintracomm)->ep_rank_map->at(rankmap_buf[3*i]).second = rankmap_buf[3*i+2];
287    }
288
289
290    (*newintracomm)->ep_comm_ptr->size_rank_info[0].first = my_ep_rank;
291    (*newintracomm)->ep_comm_ptr->size_rank_info[1].first = tmp_intra_ep_rank_loc;
292   
293
294    delete[] rankmap_buf;
295
296   
297    return MPI_SUCCESS;
298
299  }
300
301
302}
Note: See TracBrowser for help on using the repository browser.