source: XIOS/trunk/extern/src_ep/ep_split.cpp @ 1034

Last change on this file since 1034 was 1034, checked in by yushan, 7 years ago

adding src_ep into extern folder

File size: 4.4 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
48
49
50    int num_color = 0;
51
52    int color_index;
53
54    vector<int> matched_number;
55    vector<int> matched_number_loc;
56
57
58    vector<int> all_color(ep_size);
59    vector<int> all_color_loc(num_ep);
60
61    MPI_Gather_local(&color, 1, MPI_INT, all_color_loc.data(), comm);
62    MPI_Bcast_local(all_color_loc.data(), num_ep, MPI_INT, comm);
63
64
65    MPI_Allgather(&color, 1, MPI_INT, all_color.data(), 1, MPI_INT, comm);
66
67    list<int> color_list(all_color.begin(), all_color.end());
68    list<int> color_list_loc(all_color_loc.begin(), all_color_loc.end());
69
70    vec_simplify(&all_color);
71
72    matched_number.resize(all_color.size(), 0);
73    matched_number_loc.resize(all_color.size(), 0);
74
75
76    while(color_list.size())
77    {
78      int target_color = color_list.front();
79      for(list<int>::iterator it = color_list.begin(); it != color_list.end(); ++it)
80      {
81        if(*it == target_color)
82        {
83          matched_number[num_color]++;
84        }
85      }
86      for(list<int>::iterator it = color_list_loc.begin(); it != color_list_loc.end(); ++it)
87      {
88        if(*it == target_color)
89        {
90          matched_number_loc[num_color]++;
91        }
92      }
93      color_list.remove(target_color);
94      color_list_loc.remove(target_color);
95      num_color++;
96    }
97
98
99    vector<int> colored_key_loc[num_color];
100    vector<int> key_loc(num_ep);
101
102    MPI_Gather_local(&key, 1, MPI_INT, key_loc.data(), comm);
103    MPI_Bcast_local(key_loc.data(), num_ep, MPI_INT, comm);
104
105    for(int i=0; i<num_ep; i++)
106    {
107      for(int j = 0; j<num_color; j++)
108      {
109        if(all_color_loc[i] == all_color[j])
110        {
111          colored_key_loc[j].push_back(key_loc[i]);
112        }
113      }
114    }
115
116    int new_ep_rank_loc;
117
118    for(int i=0; i<num_color; i++)
119    {
120      if(colored_key_loc[i].size()>1)
121      {
122        std::sort(colored_key_loc[i].begin(), colored_key_loc[i].end());
123      }
124      if(color == all_color[i])
125      {
126        color_index = i;
127        for(int j=0; j<colored_key_loc[i].size(); j++)
128        {
129          if(key == colored_key_loc[i][j])
130          {
131            new_ep_rank_loc = j;
132            break;
133          }
134        }
135      }
136    }
137
138    ::MPI_Comm split_mpi_comm[num_color];
139
140    for(int j=0; j<num_color; j++)
141    {
142      if(ep_rank_loc == 0)
143      {
144        int master_color = 1;
145        if(matched_number_loc[j] == 0) master_color = MPI_UNDEFINED;
146        #ifdef _serialized
147        #pragma omp critical (_mpi_call)
148        #endif // _serialized
149        ::MPI_Comm_split(static_cast< ::MPI_Comm>(comm.mpi_comm), master_color, mpi_rank, &split_mpi_comm[j]);
150       
151        comm.ep_comm_ptr->comm_list->mpi_bridge = split_mpi_comm[j];
152      }
153      MPI_Barrier_local(comm);
154      int num_new_ep = 0;
155
156      if(new_ep_rank_loc == 0 && color == all_color[j])
157      {
158        num_new_ep = matched_number_loc[j];
159        MPI_Info info;
160        MPI_Comm *ep_comm;
161
162        MPI_Comm_create_endpoints(comm.ep_comm_ptr->comm_list->mpi_bridge, num_new_ep, info, ep_comm);
163
164
165        comm.ep_comm_ptr->comm_list->mem_bridge = ep_comm;
166      }
167      MPI_Barrier_local(comm);
168      if(color == all_color[j])
169      {
170        *newcomm = comm.ep_comm_ptr->comm_list->mem_bridge[new_ep_rank_loc];
171//        newcomm = &(comm.ep_comm_ptr->comm_list->mem_bridge[new_ep_rank_loc]);
172        (*newcomm).ep_comm_ptr->comm_label = color;
173      }
174    }
175
176
177
178    return 0;
179  }
180
181}
Note: See TracBrowser for help on using the repository browser.