source: XIOS/dev/branch_openmp/extern/src_ep_dev/ep_create.cpp @ 1355

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

unify MPI_Comm type

File size: 8.0 KB
Line 
1/*!
2   \file ep_create.cpp
3   \since 2 may 2016
4
5   \brief Definitions of MPI endpoint function: MPI_Comm_create_endpoints
6 */
7
8#include "ep_lib.hpp"
9#include <mpi.h>
10#include "ep_declaration.hpp"
11#include "ep_mpi.hpp"
12
13using namespace std;
14
15namespace ep_lib {
16
17  /*!
18    Dynamic creation of endpoints for each MPI process.
19    The output of this function is an array of communicator handles of length num_ep, where each handle
20    corresponds to a nez local randk in the output communicator.
21    Once created, endpoints behave as MPI processes.
22    \param [in] mpi_comm Parent MPI communicator.
23    \param [in] num_ep Number of endpoints per process.
24    \param [out] info Information of the EP creation.
25    \param [out] out_comm_hdls Handles of EP communicators.
26  */
27  // #ifdef _intelmpi
28  // int MPI_Comm_create_endpoints(int base_comm_ptr, int num_ep, MPI_Info info, MPI_Comm *& out_comm_hdls)
29  // {
30  //   int base_rank;
31  //   int base_size;
32
33  //   ::MPI_Comm mpi_base_comm = static_cast< ::MPI_Comm> (base_comm_ptr);
34
35  //   ::MPI_Comm_size(mpi_base_comm, &base_size);  // ep_lib::mpi_comm_size
36  //   ::MPI_Comm_rank(mpi_base_comm, &base_rank);  // ep_lib::mpi_comm_rank
37                //                                                        // parent_comm can also be endpoints communicators
38
39  //   std::vector<int> recv_num_ep(base_size);
40
41  //   out_comm_hdls = new MPI_Comm[num_ep];
42
43  //   for (int idx = 0; idx < num_ep; ++idx)
44  //   {
45  //     out_comm_hdls[idx].is_ep = true;
46  //     out_comm_hdls[idx].is_intercomm = false;
47  //     out_comm_hdls[idx].ep_comm_ptr = new ep_communicator;
48  //     out_comm_hdls[idx].mpi_comm = base_comm_ptr;
49  //     out_comm_hdls[idx].ep_comm_ptr->comm_list = out_comm_hdls;
50  //     out_comm_hdls[idx].ep_comm_ptr->comm_label = 0;
51  //   }
52
53  //   ::MPI_Allgather(&num_ep, 1, static_cast< ::MPI_Datatype>(MPI_INT), &recv_num_ep[0], 1, static_cast< ::MPI_Datatype>(MPI_INT), mpi_base_comm);
54
55
56  //   int sum = 0;  // representing total ep number of process with smaller rank
57  //   for (int i = 0; i < base_rank; ++i) {sum += recv_num_ep[i]; }
58
59  //   int ep_size = std::accumulate(recv_num_ep.begin(), recv_num_ep.end(), 0);
60
61  //   out_comm_hdls[0].ep_barrier = new OMPbarrier(num_ep);
62
63  //   out_comm_hdls[0].my_buffer = new BUFFER;
64
65  //   out_comm_hdls[0].rank_map = new RANK_MAP;
66  //   out_comm_hdls[0].rank_map->resize(ep_size);
67
68
69  //   for (int i = 1; i < num_ep; i++)
70  //   {
71  //     out_comm_hdls[i].ep_barrier = out_comm_hdls[0].ep_barrier;
72  //     out_comm_hdls[i].my_buffer  = out_comm_hdls[0].my_buffer;
73  //     out_comm_hdls[i].rank_map   = out_comm_hdls[0].rank_map;
74  //   }
75
76
77  //   for (int i = 0; i < num_ep; i++)
78  //   {
79  //     out_comm_hdls[i].ep_comm_ptr->size_rank_info[0] = std::make_pair(sum+i, ep_size);
80  //     out_comm_hdls[i].ep_comm_ptr->size_rank_info[1] = std::make_pair(i, num_ep);
81  //     out_comm_hdls[i].ep_comm_ptr->size_rank_info[2] = std::make_pair(base_rank, base_size);
82
83  //     out_comm_hdls[i].ep_comm_ptr->message_queue = new Message_list;
84  //   }
85
86
87  //   int ind = 0;
88
89  //   for(int i=0; i<base_size; i++)
90  //   {
91  //     for(int j=0; j<recv_num_ep[i]; j++)
92  //     {
93  //       out_comm_hdls[0].rank_map->at(ind) = make_pair(j, i);
94  //       ind++;
95  //     }
96  //   }
97
98
99
100  //   return 0;
101
102  // } //MPI_Comm_create_endpoints
103
104  // #elif _openmpi
105  // int MPI_Comm_create_endpoints(void* base_comm_ptr, int num_ep, MPI_Info info, MPI_Comm *& out_comm_hdls)
106  // {
107
108  //   int base_rank;
109  //   int base_size;
110
111  //   ::MPI_Comm mpi_base_comm = static_cast< ::MPI_Comm> (base_comm_ptr);
112
113  //   ::MPI_Comm_size(mpi_base_comm, &base_size);  // ep_lib::mpi_comm_size
114  //   ::MPI_Comm_rank(mpi_base_comm, &base_rank);  // ep_lib::mpi_comm_rank
115  //                                                // parent_comm can also be endpoints communicators ?
116  //   std::vector<int> recv_num_ep(base_size);
117
118  //   out_comm_hdls = new MPI_Comm[num_ep];
119
120  //   for (int idx = 0; idx < num_ep; ++idx)
121  //   {
122  //     out_comm_hdls[idx].is_ep = true;
123  //     out_comm_hdls[idx].is_intercomm = false;
124  //     out_comm_hdls[idx].ep_comm_ptr = new ep_communicator;
125  //     out_comm_hdls[idx].mpi_comm = base_comm_ptr;
126  //     out_comm_hdls[idx].ep_comm_ptr->comm_list = out_comm_hdls;
127  //     out_comm_hdls[idx].ep_comm_ptr->comm_label = 0;
128  //   }
129
130  //   ::MPI_Allgather(&num_ep, 1, static_cast< ::MPI_Datatype> (MPI_INT),
131  //                  &recv_num_ep[0], 1, static_cast< ::MPI_Datatype> (MPI_INT), mpi_base_comm);
132
133  //   int sum = 0;  // representing total ep number of process with smaller rank
134  //   for (int i = 0; i < base_rank; ++i) {sum += recv_num_ep[i]; }
135
136  //   int ep_size = std::accumulate(recv_num_ep.begin(), recv_num_ep.end(), 0);
137
138  //   out_comm_hdls[0].ep_barrier = new OMPbarrier(num_ep);
139  //   out_comm_hdls[0].my_buffer = new BUFFER;
140
141  //   out_comm_hdls[0].rank_map = new RANK_MAP;
142  //   out_comm_hdls[0].rank_map->resize(ep_size);
143
144
145  //   for (int i = 1; i < num_ep; i++)
146  //   {
147  //     out_comm_hdls[i].ep_barrier = out_comm_hdls[0].ep_barrier;
148  //     out_comm_hdls[i].my_buffer  = out_comm_hdls[0].my_buffer;
149  //     out_comm_hdls[i].rank_map   = out_comm_hdls[0].rank_map;
150  //   }
151
152
153  //   for (int i = 0; i < num_ep; i++)
154  //   {
155  //     out_comm_hdls[i].ep_comm_ptr->size_rank_info[0] = std::make_pair(sum+i, ep_size);
156  //     out_comm_hdls[i].ep_comm_ptr->size_rank_info[1] = std::make_pair(i, num_ep);
157  //     out_comm_hdls[i].ep_comm_ptr->size_rank_info[2] = std::make_pair(base_rank, base_size);
158
159  //     out_comm_hdls[i].ep_comm_ptr->message_queue = new Message_list;
160  //   }
161
162
163  //   int ind = 0;
164
165  //   for(int i=0; i<base_size; i++)
166  //   {
167  //     for(int j=0; j<recv_num_ep[i]; j++)
168  //     {
169  //       out_comm_hdls[0].rank_map->at(ind) = make_pair(j, i);
170  //       ind++;
171  //     }
172  //   }
173
174  //   return 0;
175
176  // } //MPI_Comm_create_endpoints
177
178  // #endif
179 
180 
181  int MPI_Comm_create_endpoints(int* base_comm_ptr, int num_ep, MPI_Info info, MPI_Comm *& out_comm_hdls)
182  {
183
184    int base_rank;
185    int base_size;
186   
187    ::MPI_Comm mpi_base_comm = to_mpi_comm(base_comm_ptr);
188
189    ::MPI_Comm_size(mpi_base_comm, &base_size);  // ep_lib::mpi_comm_size
190    ::MPI_Comm_rank(mpi_base_comm, &base_rank);  // ep_lib::mpi_comm_rank
191                    // parent_comm can also be endpoints communicators
192
193    std::vector<int> recv_num_ep(base_size);
194
195    out_comm_hdls = new MPI_Comm[num_ep];
196
197    for (int idx = 0; idx < num_ep; ++idx)
198    {
199      out_comm_hdls[idx].is_ep = true;
200      out_comm_hdls[idx].is_intercomm = false;
201      out_comm_hdls[idx].ep_comm_ptr = new ep_communicator;     
202      *(out_comm_hdls[idx].mpi_comm) = *base_comm_ptr;
203      out_comm_hdls[idx].ep_comm_ptr->comm_list = out_comm_hdls;
204      out_comm_hdls[idx].ep_comm_ptr->comm_label = 0;
205    }
206
207    ::MPI_Allgather(&num_ep, 1, to_mpi_type(MPI_INT), &recv_num_ep[0], 1, to_mpi_type(MPI_INT), mpi_base_comm);
208
209
210    int sum = 0;  // representing total ep number of process with smaller rank
211    for (int i = 0; i < base_rank; ++i) {sum += recv_num_ep[i]; }
212
213    int ep_size = std::accumulate(recv_num_ep.begin(), recv_num_ep.end(), 0);
214
215    out_comm_hdls[0].ep_barrier = new OMPbarrier(num_ep);
216    out_comm_hdls[0].my_buffer = new BUFFER;
217
218    out_comm_hdls[0].rank_map = new RANK_MAP;
219    out_comm_hdls[0].rank_map->resize(ep_size);
220
221
222    for (int i = 1; i < num_ep; i++)
223    {
224      out_comm_hdls[i].ep_barrier = out_comm_hdls[0].ep_barrier;
225      out_comm_hdls[i].my_buffer  = out_comm_hdls[0].my_buffer;
226      out_comm_hdls[i].rank_map   = out_comm_hdls[0].rank_map;
227    }
228
229
230    for (int i = 0; i < num_ep; i++)
231    {
232      out_comm_hdls[i].ep_comm_ptr->size_rank_info[0] = std::make_pair(sum+i, ep_size);
233      out_comm_hdls[i].ep_comm_ptr->size_rank_info[1] = std::make_pair(i, num_ep);
234      out_comm_hdls[i].ep_comm_ptr->size_rank_info[2] = std::make_pair(base_rank, base_size);
235
236      out_comm_hdls[i].ep_comm_ptr->message_queue = new Message_list;
237    }
238
239
240    int ind = 0;
241
242    for(int i=0; i<base_size; i++)
243    {
244      for(int j=0; j<recv_num_ep[i]; j++)
245      {
246        out_comm_hdls[0].rank_map->at(ind) = make_pair(j, i);
247        ind++;
248      }
249    }
250
251    return 0;
252
253  } //MPI_Comm_create_endpoints
254
255
256} //namespace ep_lib
Note: See TracBrowser for help on using the repository browser.