source: XIOS/dev/dev_trunk_omp/extern/src_ep_dev/ep_split.cpp @ 1605

Last change on this file since 1605 was 1605, checked in by yushan, 5 years ago

branch_openmp merged and tested with trunk r1597

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