source: XIOS/dev/branch_openmp/extern/src_ep_dev/ep_split.cpp @ 1287

Last change on this file since 1287 was 1287, checked in by yushan, 4 years ago

EP updated

File size: 4.3 KB
Line 
1#include "ep_lib.hpp"
2#include <mpi.h>
3#include "ep_declaration.hpp"
4
5using namespace std;
6
7namespace ep_lib
8{
9
10  void vec_simplify(std::vector<int> *inout_vector)
11  {
12    std::vector<int> out_vec;
13    int found=false;
14    for(std::vector<int>::iterator it_in = inout_vector->begin() ; it_in != inout_vector->end(); ++it_in)
15    {
16      for(std::vector<int>::iterator it = out_vec.begin() ; it != out_vec.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_vec.push_back(*it_in);
28      }
29    }
30    inout_vector->swap(out_vec);
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
55    vector<int> all_color(ep_size);
56    vector<int> all_color_loc(num_ep);
57
58    MPI_Gather_local(&color, 1, MPI_INT, all_color_loc.data(), 0, comm);
59    MPI_Bcast_local(all_color_loc.data(), num_ep, MPI_INT, 0, comm);
60
61
62    MPI_Allgather(&color, 1, MPI_INT, all_color.data(), 1, MPI_INT, comm);
63
64    list<int> color_list(all_color.begin(), all_color.end());
65    list<int> color_list_loc(all_color_loc.begin(), all_color_loc.end());
66
67    vec_simplify(&all_color);
68
69    matched_number.resize(all_color.size(), 0);
70    matched_number_loc.resize(all_color.size(), 0);
71
72
73    while(!color_list.empty())
74    {
75      int target_color = color_list.front();
76      for(list<int>::iterator it = color_list.begin(); it != color_list.end(); ++it)
77      {
78        if(*it == target_color)
79        {
80          matched_number[num_color]++;
81        }
82      }
83      for(list<int>::iterator it = color_list_loc.begin(); it != color_list_loc.end(); ++it)
84      {
85        if(*it == target_color)
86        {
87          matched_number_loc[num_color]++;
88        }
89      }
90      color_list.remove(target_color);
91      color_list_loc.remove(target_color);
92      num_color++;
93    }
94
95
96    vector<int> colored_key_loc[num_color];
97    vector<int> key_loc(num_ep);
98
99    MPI_Gather_local(&key, 1, MPI_INT, key_loc.data(), 0, comm);
100    MPI_Bcast_local(key_loc.data(), num_ep, MPI_INT, 0, comm);
101
102    for(int i=0; i<num_ep; i++)
103    {
104      for(int j = 0; j<num_color; j++)
105      {
106        if(all_color_loc[i] == all_color[j])
107        {
108          colored_key_loc[j].push_back(key_loc[i]);
109        }
110      }
111    }
112
113    int new_ep_rank_loc;
114
115    for(int i=0; i<num_color; i++)
116    {
117      if(colored_key_loc[i].size()>1)
118      {
119        std::sort(colored_key_loc[i].begin(), colored_key_loc[i].end());
120      }
121      if(color == all_color[i])
122      {
123        //color_index = i;
124        for(int j=0; j<colored_key_loc[i].size(); j++)
125        {
126          if(key == colored_key_loc[i][j])
127          {
128            new_ep_rank_loc = j;
129            break;
130          }
131        }
132      }
133    }
134
135    ::MPI_Comm split_mpi_comm[num_color];
136
137    for(int j=0; j<num_color; j++)
138    {
139      if(ep_rank_loc == 0)
140      {
141        int master_color = 1;
142        if(matched_number_loc[j] == 0) master_color = MPI_UNDEFINED;
143
144        ::MPI_Comm_split(static_cast< ::MPI_Comm>(comm.mpi_comm), master_color, mpi_rank, &split_mpi_comm[j]);
145       
146        comm.ep_comm_ptr->comm_list->mpi_bridge = split_mpi_comm[j];
147      }
148      MPI_Barrier_local(comm);
149      int num_new_ep = 0;
150
151      if(new_ep_rank_loc == 0 && color == all_color[j])
152      {
153        num_new_ep = matched_number_loc[j];
154        MPI_Info info;
155        MPI_Comm *ep_comm;
156
157        MPI_Comm_create_endpoints(comm.ep_comm_ptr->comm_list->mpi_bridge, num_new_ep, info, ep_comm);
158
159
160        comm.ep_comm_ptr->comm_list->mem_bridge = ep_comm;
161      }
162      MPI_Barrier_local(comm);
163      if(color == all_color[j])
164      {
165        *newcomm = comm.ep_comm_ptr->comm_list->mem_bridge[new_ep_rank_loc];
166        (*newcomm).ep_comm_ptr->comm_label = color;
167      }
168    }
169
170
171
172    return 0;
173  }
174
175}
Note: See TracBrowser for help on using the repository browser.