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

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

EP update all

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