source: XIOS/dev/branch_openmp/extern/ep_dev/ep_split.cpp @ 1506

Last change on this file since 1506 was 1506, checked in by yushan, 3 years ago

mpi_comm_split respect the norme of MPI: ranking according to the key argument. Key can be the same. In such case, the original ranking is used.

File size: 9.5 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  void vec_simplify(std::vector<int> *inout_vector)
12  {
13    std::vector<int> out_vec;
14    int found=false;
15    for(std::vector<int>::iterator it_in = inout_vector->begin() ; it_in != inout_vector->end(); ++it_in)
16    {
17      for(std::vector<int>::iterator it = out_vec.begin() ; it != out_vec.end(); ++it)
18      {
19        if(*it_in == *it)
20        {
21          found=true;
22          break;
23        }
24        else found=false;
25      }
26      if(found == false)
27      {
28        out_vec.push_back(*it_in);
29      }
30    }
31    inout_vector->swap(out_vec);
32  }
33 
34  void vec_simplify(std::vector<int> *in_vector, std::vector<int> *out_vector)
35  {
36    int found=false;
37    for(std::vector<int>::iterator it_in = in_vector->begin() ; it_in != in_vector->end(); ++it_in)
38    {
39      for(std::vector<int>::iterator it = out_vector->begin() ; it != out_vector->end(); ++it)
40      {
41        if(*it_in == *it)
42        {
43          found=true;
44          break;
45        }
46        else found=false;
47      }
48      if(found == false)
49      {
50        out_vector->push_back(*it_in);
51      }
52    }
53  }
54
55
56
57  int MPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm *newcomm)
58  {
59    int ep_rank, ep_rank_loc, mpi_rank;
60    int ep_size, num_ep, mpi_size;
61
62    ep_rank = comm->ep_comm_ptr->size_rank_info[0].first;
63    ep_rank_loc = comm->ep_comm_ptr->size_rank_info[1].first;
64    mpi_rank = comm->ep_comm_ptr->size_rank_info[2].first;
65    ep_size = comm->ep_comm_ptr->size_rank_info[0].second;
66    num_ep = comm->ep_comm_ptr->size_rank_info[1].second;
67    mpi_size = comm->ep_comm_ptr->size_rank_info[2].second;
68
69    int num_color = 0;
70
71    int color_index;
72
73    vector<int> matched_number;
74    vector<int> matched_number_loc;
75   
76    vector<int> all_color(ep_size);
77    vector<int> all_color_loc(num_ep);
78
79    MPI_Allgather(&color, 1, MPI_INT, all_color.data(), 1, MPI_INT, comm);
80    MPI_Allgather_local(&color, 1, MPI_INT, all_color_loc.data(), comm);
81
82    list<int> color_list(all_color.begin(), all_color.end());
83    list<int> color_list_loc(all_color_loc.begin(), all_color_loc.end());
84
85    vector<int> all_color_simplified;
86    vec_simplify(&all_color, &all_color_simplified);
87    int number_of_color;
88    for(int i=0; i<all_color_simplified.size(); i++)
89    {
90      if(color == all_color_simplified[i])
91      {
92        number_of_color = i;
93        break;
94      }
95    }
96
97    matched_number.resize(all_color_simplified.size(), 0);
98    matched_number_loc.resize(all_color_simplified.size(), 0);
99
100
101    while(!color_list.empty())
102    {
103      int target_color = color_list.front();
104      for(list<int>::iterator it = color_list.begin(); it != color_list.end(); ++it)
105      {
106        if(*it == target_color)
107        {
108          matched_number[num_color]++;
109        }
110      }
111      for(list<int>::iterator it = color_list_loc.begin(); it != color_list_loc.end(); ++it)
112      {
113        if(*it == target_color)
114        {
115          matched_number_loc[num_color]++;
116        }
117      }
118      color_list.remove(target_color);
119      color_list_loc.remove(target_color);
120      num_color++;
121    }
122       
123
124    vector<int> all_key(ep_size);
125    vector<int> all_key_loc(num_ep);
126   
127    vector<int> colored_key[num_color];
128    vector<int> colored_key_loc[num_color];
129   
130
131    MPI_Allgather(&key, 1, MPI_INT, all_key.data(),1, MPI_INT, comm);
132    MPI_Allgather_local(&key, 1, MPI_INT, all_key_loc.data(), comm);
133   
134    vector<int> all_ep_rank(ep_size);
135    vector<int> all_ep_rank_loc(num_ep);
136   
137    vector<int> colored_ep_rank[num_color];
138    vector<int> colored_ep_rank_loc[num_color];
139   
140    MPI_Allgather(&ep_rank, 1, MPI_INT, all_ep_rank.data(),1, MPI_INT, comm);
141    MPI_Allgather_local(&ep_rank, 1, MPI_INT, all_ep_rank_loc.data(), comm);
142
143    for(int i=0; i<num_ep; i++)
144    {
145      for(int j = 0; j<num_color; j++)
146      {
147        if(all_color_loc[i] == all_color_simplified[j])
148        {
149          colored_key_loc[j].push_back(all_key_loc[i]);
150          colored_ep_rank_loc[j].push_back(all_ep_rank_loc[i]);
151        }
152      }
153    }
154   
155    for(int i=0; i<ep_size; i++)
156    {
157      for(int j = 0; j<num_color; j++)
158      {
159        if(all_color[i] == all_color_simplified[j])
160        {
161          colored_key[j].push_back(all_key[i]);
162          colored_ep_rank[j].push_back(all_ep_rank[i]);
163        }
164      }
165    }
166   
167    int my_offset=0;
168    for(int i=0; i<colored_key[number_of_color].size(); i++)
169    {
170      if(key == colored_key[number_of_color][i])
171      {
172        if(ep_rank != colored_ep_rank[number_of_color][i])
173        {
174          my_offset++;
175        }
176        else
177          break;
178      }
179    }
180   
181    int my_offset_loc=0;
182    for(int i=0; i<colored_key_loc[number_of_color].size(); i++)
183    {
184      if(key == colored_key_loc[number_of_color][i])
185      {
186        if(ep_rank != colored_ep_rank_loc[number_of_color][i])
187        {
188          my_offset_loc++;
189        }
190        else
191          break;
192      }
193    }
194   
195   
196   
197    for(int i=0; i<num_color; i++)
198    {
199      std::sort(colored_key[i].begin(), colored_key[i].end());
200      std::sort(colored_key_loc[i].begin(), colored_key_loc[i].end());
201    }
202
203    int new_ep_rank;
204   
205    for(int i=0; i<colored_key[number_of_color].size(); i++)
206    {
207      if(key == colored_key[number_of_color][i])
208      {
209        new_ep_rank = i+my_offset;
210        break;
211      }
212    }
213   
214    int new_ep_rank_loc;
215   
216    for(int i=0; i<colored_key_loc[number_of_color].size(); i++)
217    {
218      if(key == colored_key_loc[number_of_color][i])
219      {
220        new_ep_rank_loc = i+my_offset_loc;
221        break;
222      }
223    }
224   
225
226    ::MPI_Comm **split_mpi_comm;
227    split_mpi_comm = new ::MPI_Comm* [num_color];
228    for(int ii=0; ii<num_color; ii++)
229      split_mpi_comm[ii] = new ::MPI_Comm;
230
231    for(int j=0; j<num_color; j++)
232    {
233      if(ep_rank_loc == 0)
234      {
235        int master_color = 1;
236        if(matched_number_loc[j] == 0) master_color = MPI_UNDEFINED;
237
238        ::MPI_Comm_split(to_mpi_comm(comm->mpi_comm), master_color, mpi_rank, split_mpi_comm[j]);
239       
240        comm->ep_comm_ptr->comm_list[0]->mpi_bridge = split_mpi_comm[j];
241      }
242     
243      MPI_Barrier_local(comm);
244     
245      int num_new_ep = 0;
246
247      if(new_ep_rank_loc == 0 && color == all_color_simplified[j])
248      {
249        num_new_ep = matched_number_loc[j];
250        MPI_Info info;
251        MPI_Comm *ep_comm;
252
253        MPI_Comm_create_endpoints(comm->ep_comm_ptr->comm_list[0]->mpi_bridge, num_new_ep, info, ep_comm);
254
255        comm->ep_comm_ptr->comm_list[0]->mem_bridge = ep_comm;
256       
257        (*ep_comm)->ep_rank_map->clear();
258       
259        memcheck("in MPI_Split ep_rank="<< ep_rank <<" : *ep_comm = "<< *ep_comm);
260      }
261     
262      MPI_Barrier_local(comm);
263     
264      if(color == all_color_simplified[j])
265      {
266        *newcomm = comm->ep_comm_ptr->comm_list[0]->mem_bridge[new_ep_rank_loc];
267        memcheck("in MPI_Split ep_rank="<< ep_rank <<" : *newcomm = "<< *newcomm);
268
269        (*newcomm)->ep_comm_ptr->comm_label = color;
270       
271        (*newcomm)->ep_comm_ptr->size_rank_info[0].first = new_ep_rank;
272        (*newcomm)->ep_comm_ptr->size_rank_info[1].first = new_ep_rank_loc;
273       
274        int my_triple[3];
275        vector<int> my_triple_vector;
276        vector<int> my_triple_vector_recv;
277        my_triple[0] = new_ep_rank;
278        my_triple[1] = new_ep_rank_loc;
279        my_triple[2] = (*newcomm)->ep_comm_ptr->size_rank_info[2].first; // new_mpi_rank
280       
281        int new_ep_size = (*newcomm)->ep_comm_ptr->size_rank_info[0].second;
282        int new_num_ep  = (*newcomm)->ep_comm_ptr->size_rank_info[1].second;
283       
284        int new_mpi_size = (*newcomm)->ep_comm_ptr->size_rank_info[2].second;
285       
286        if(new_ep_rank_loc == 0) my_triple_vector.resize(3*new_ep_size);
287        if(new_ep_rank_loc == 0) my_triple_vector_recv.resize(3*new_ep_size);
288       
289        MPI_Gather_local(my_triple, 3, MPI_INT, my_triple_vector.data(), 0, *newcomm);
290       
291        if(new_ep_rank_loc == 0)
292        {
293          int *recvcounts = new int[new_mpi_size];
294          int *displs = new int[new_mpi_size];
295          int new_num_epx3 = new_num_ep * 3;
296          ::MPI_Allgather(&new_num_epx3, 1, to_mpi_type(MPI_INT), recvcounts, 1, to_mpi_type(MPI_INT), to_mpi_comm((*newcomm)->mpi_comm));
297          displs[0]=0;
298          for(int i=1; i<new_mpi_size; i++)
299            displs[i] = displs[i-1] + recvcounts[i-1];
300             
301          ::MPI_Allgatherv(my_triple_vector.data(), 3*new_num_ep, to_mpi_type(MPI_INT), my_triple_vector_recv.data(), recvcounts, displs, to_mpi_type(MPI_INT), to_mpi_comm((*newcomm)->mpi_comm));
302         
303          for(int i=0; i<new_ep_size; i++)
304          {
305            (*newcomm)->ep_comm_ptr->comm_list[0]->ep_rank_map->insert(std::pair< int, std::pair<int,int> >(my_triple_vector_recv[3*i], my_triple_vector_recv[3*i+1], my_triple_vector_recv[3*i+2]));
306          }
307         
308          (*newcomm)->ep_rank_map = (*newcomm)->ep_comm_ptr->comm_list[0]->ep_rank_map;
309         
310          delete recvcounts;
311          delete displs;
312        } 
313      }
314    }
315
316#ifdef _Memory_check   
317    for(int i=0; i<ep_size; i++)
318    {
319      MPI_Barrier(comm);
320      MPI_Barrier(comm);
321      if(ep_rank==i) 
322      {
323        printf("ep_rank_map for endpoint %d = \n", ep_rank);
324        for(std::map<int, std::pair<int, int> > :: iterator it = (*newcomm)->ep_rank_map->begin(); it != (*newcomm)->ep_rank_map->end(); it++)
325        {
326          printf("\t\t\t %d %d %d\n", it->first, it->second.first, it->second.second);
327        }
328        printf("\n");
329      }
330      MPI_Barrier(comm);
331      MPI_Barrier(comm);
332    }   
333#endif
334   
335    return 0;
336  }
337
338}
Note: See TracBrowser for help on using the repository browser.