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

Last change on this file since 1503 was 1500, checked in by yushan, 6 years ago

save dev

File size: 4.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
35
36  int MPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm *newcomm)
37  {
38    int ep_rank, ep_rank_loc, mpi_rank;
39    int ep_size, num_ep, mpi_size;
40
41    ep_rank = comm->ep_comm_ptr->size_rank_info[0].first;
42    ep_rank_loc = comm->ep_comm_ptr->size_rank_info[1].first;
43    mpi_rank = comm->ep_comm_ptr->size_rank_info[2].first;
44    ep_size = comm->ep_comm_ptr->size_rank_info[0].second;
45    num_ep = comm->ep_comm_ptr->size_rank_info[1].second;
46    mpi_size = comm->ep_comm_ptr->size_rank_info[2].second;
47
48    int num_color = 0;
49
50    int color_index;
51
52    vector<int> matched_number;
53    vector<int> matched_number_loc;
54
55
56    vector<int> all_color(ep_size);
57    vector<int> all_color_loc(num_ep);
58
59    MPI_Gather_local(&color, 1, MPI_INT, all_color_loc.data(), 0, comm);
60    MPI_Bcast_local(all_color_loc.data(), num_ep, MPI_INT, 0, comm);
61
62
63    MPI_Allgather(&color, 1, MPI_INT, all_color.data(), 1, MPI_INT, comm);
64
65    list<int> color_list(all_color.begin(), all_color.end());
66    list<int> color_list_loc(all_color_loc.begin(), all_color_loc.end());
67
68    vec_simplify(&all_color);
69
70    matched_number.resize(all_color.size(), 0);
71    matched_number_loc.resize(all_color.size(), 0);
72
73
74    while(!color_list.empty())
75    {
76      int target_color = color_list.front();
77      for(list<int>::iterator it = color_list.begin(); it != color_list.end(); ++it)
78      {
79        if(*it == target_color)
80        {
81          matched_number[num_color]++;
82        }
83      }
84      for(list<int>::iterator it = color_list_loc.begin(); it != color_list_loc.end(); ++it)
85      {
86        if(*it == target_color)
87        {
88          matched_number_loc[num_color]++;
89        }
90      }
91      color_list.remove(target_color);
92      color_list_loc.remove(target_color);
93      num_color++;
94    }
95
96
97    vector<int> colored_key_loc[num_color];
98    vector<int> key_loc(num_ep);
99
100    MPI_Gather_local(&key, 1, MPI_INT, key_loc.data(), 0, comm);
101    MPI_Bcast_local(key_loc.data(), num_ep, MPI_INT, 0, comm);
102   
103    std::sort(key_loc.begin(), key_loc.end());
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        for(int j=0; j<colored_key_loc[i].size(); j++)
127        {
128          if(key == colored_key_loc[i][j])
129          {
130            new_ep_rank_loc = j;
131            break;
132          }
133        }
134      }
135    }
136
137    ::MPI_Comm **split_mpi_comm;
138    split_mpi_comm = new ::MPI_Comm* [num_color];
139    for(int ii=0; ii<num_color; ii++)
140      split_mpi_comm[ii] = new ::MPI_Comm;
141
142    for(int j=0; j<num_color; j++)
143    {
144      if(ep_rank_loc == 0)
145      {
146        int master_color = 1;
147        if(matched_number_loc[j] == 0) master_color = MPI_UNDEFINED;
148
149        ::MPI_Comm_split(to_mpi_comm(comm->mpi_comm), master_color, mpi_rank, split_mpi_comm[j]);
150       
151        comm->ep_comm_ptr->comm_list[0]->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[0]->mpi_bridge, num_new_ep, info, ep_comm);
163
164
165        comm->ep_comm_ptr->comm_list[0]->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[0]->mem_bridge[new_ep_rank_loc];
171
172        (*newcomm)->ep_comm_ptr->comm_label = color;
173      }
174    }
175
176
177
178
179    return 0;
180  }
181
182}
Note: See TracBrowser for help on using the repository browser.