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

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

branch merged with trunk @1645. arch file (ep&mpi) added for ADA

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