source: XIOS/dev/branch_yushan_merged/extern/src_ep_dev/ep_create.cpp @ 1134

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

branch merged with trunk r1130

File size: 9.1 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, MPI_INT_STD, &recv_num_ep[0], 1, MPI_INT_STD, 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    out_comm_hdls[0].my_buffer->buf_double = new double[BUFFER_SIZE];
66    out_comm_hdls[0].my_buffer->buf_float  = new float[BUFFER_SIZE];
67    out_comm_hdls[0].my_buffer->buf_int    = new int[BUFFER_SIZE];
68    out_comm_hdls[0].my_buffer->buf_long   = new long[BUFFER_SIZE];
69    out_comm_hdls[0].my_buffer->buf_ulong  = new unsigned long[BUFFER_SIZE];
70    out_comm_hdls[0].my_buffer->buf_char   = new char[BUFFER_SIZE];
71
72    out_comm_hdls[0].rank_map = new RANK_MAP;
73    out_comm_hdls[0].rank_map->resize(ep_size);
74
75
76    for (int i = 1; i < num_ep; i++)
77    {
78      out_comm_hdls[i].ep_barrier = out_comm_hdls[0].ep_barrier;
79      out_comm_hdls[i].my_buffer  = out_comm_hdls[0].my_buffer;
80      out_comm_hdls[i].rank_map   = out_comm_hdls[0].rank_map;
81    }
82
83
84    for (int i = 0; i < num_ep; i++)
85    {
86      out_comm_hdls[i].ep_comm_ptr->size_rank_info[0] = std::make_pair(sum+i, ep_size);
87      out_comm_hdls[i].ep_comm_ptr->size_rank_info[1] = std::make_pair(i, num_ep);
88      out_comm_hdls[i].ep_comm_ptr->size_rank_info[2] = std::make_pair(base_rank, base_size);
89
90      out_comm_hdls[i].ep_comm_ptr->message_queue = new Message_list;
91    }
92
93
94    int ind = 0;
95
96    for(int i=0; i<base_size; i++)
97    {
98      for(int j=0; j<recv_num_ep[i]; j++)
99      {
100        out_comm_hdls[0].rank_map->at(ind) = make_pair(j, i);
101        ind++;
102      }
103    }
104
105    // printf("ep_lib::MPI_Comm_create_endpoints()       OK from int\n");
106
107    return 0;
108
109  } //MPI_Comm_create_endpoints
110
111  #elif _openmpi
112  int MPI_Comm_create_endpoints(void* base_comm_ptr, int num_ep, MPI_Info info, MPI_Comm *& out_comm_hdls)
113  {
114
115    int base_rank;
116    int base_size;
117
118    ::MPI_Comm mpi_base_comm = static_cast< ::MPI_Comm> (base_comm_ptr);
119
120    ::MPI_Comm_size(mpi_base_comm, &base_size);  // ep_lib::mpi_comm_size
121    ::MPI_Comm_rank(mpi_base_comm, &base_rank);  // ep_lib::mpi_comm_rank
122                                                 // parent_comm can also be endpoints communicators ?
123    std::vector<int> recv_num_ep(base_size);
124
125    out_comm_hdls = new MPI_Comm[num_ep];
126
127    for (int idx = 0; idx < num_ep; ++idx)
128    {
129      out_comm_hdls[idx].is_ep = true;
130      out_comm_hdls[idx].is_intercomm = false;
131      out_comm_hdls[idx].ep_comm_ptr = new ep_communicator;
132      out_comm_hdls[idx].mpi_comm = base_comm_ptr;
133      out_comm_hdls[idx].ep_comm_ptr->comm_list = out_comm_hdls;
134      out_comm_hdls[idx].ep_comm_ptr->comm_label = 0;
135    }
136
137    ::MPI_Allgather(&num_ep, 1, MPI_INT_STD, &recv_num_ep[0], 1, MPI_INT_STD, mpi_base_comm);
138
139    int sum = 0;  // representing total ep number of process with smaller rank
140    for (int i = 0; i < base_rank; ++i) {sum += recv_num_ep[i]; }
141
142    int ep_size = std::accumulate(recv_num_ep.begin(), recv_num_ep.end(), 0);
143
144    out_comm_hdls[0].ep_barrier = new OMPbarrier(num_ep);
145
146    out_comm_hdls[0].my_buffer = new BUFFER;
147    out_comm_hdls[0].my_buffer->buf_double = new double[BUFFER_SIZE];
148    out_comm_hdls[0].my_buffer->buf_float  = new float[BUFFER_SIZE];
149    out_comm_hdls[0].my_buffer->buf_int    = new int[BUFFER_SIZE];
150    out_comm_hdls[0].my_buffer->buf_long   = new long[BUFFER_SIZE];
151    out_comm_hdls[0].my_buffer->buf_ulong  = new unsigned long[BUFFER_SIZE];
152    out_comm_hdls[0].my_buffer->buf_char   = new char[BUFFER_SIZE];
153
154    out_comm_hdls[0].rank_map = new RANK_MAP;
155    out_comm_hdls[0].rank_map->resize(ep_size);
156
157
158    for (int i = 1; i < num_ep; i++)
159    {
160      out_comm_hdls[i].ep_barrier = out_comm_hdls[0].ep_barrier;
161      out_comm_hdls[i].my_buffer  = out_comm_hdls[0].my_buffer;
162      out_comm_hdls[i].rank_map   = out_comm_hdls[0].rank_map;
163    }
164
165
166    for (int i = 0; i < num_ep; i++)
167    {
168      out_comm_hdls[i].ep_comm_ptr->size_rank_info[0] = std::make_pair(sum+i, ep_size);
169      out_comm_hdls[i].ep_comm_ptr->size_rank_info[1] = std::make_pair(i, num_ep);
170      out_comm_hdls[i].ep_comm_ptr->size_rank_info[2] = std::make_pair(base_rank, base_size);
171
172      out_comm_hdls[i].ep_comm_ptr->message_queue = new Message_list;
173    }
174
175
176    int ind = 0;
177
178    for(int i=0; i<base_size; i++)
179    {
180      for(int j=0; j<recv_num_ep[i]; j++)
181      {
182        out_comm_hdls[0].rank_map->at(ind) = make_pair(j, i);
183        ind++;
184      }
185    }
186
187    //printf("ep_lib::MPI_Comm_create_endpoints()       OK from void*\n");
188
189    return 0;
190
191  } //MPI_Comm_create_endpoints
192
193  #endif
194 
195 
196  int MPI_Comm_create_endpoints(MPI_Comm base_comm, int num_ep, MPI_Info info, MPI_Comm *& out_comm_hdls)
197  {
198
199    int base_rank;
200    int base_size;
201   
202    assert(!base_comm.is_ep);
203
204    ::MPI_Comm mpi_base_comm = static_cast< ::MPI_Comm> (base_comm.mpi_comm);
205
206    ::MPI_Comm_size(mpi_base_comm, &base_size);  // ep_lib::mpi_comm_size
207    ::MPI_Comm_rank(mpi_base_comm, &base_rank);  // ep_lib::mpi_comm_rank
208                    // parent_comm can also be endpoints communicators
209
210    std::vector<int> recv_num_ep(base_size);
211
212    out_comm_hdls = new MPI_Comm[num_ep];
213
214    for (int idx = 0; idx < num_ep; ++idx)
215    {
216      out_comm_hdls[idx].is_ep = true;
217      out_comm_hdls[idx].is_intercomm = false;
218      out_comm_hdls[idx].ep_comm_ptr = new ep_communicator;
219      out_comm_hdls[idx].mpi_comm = base_comm.mpi_comm;
220      out_comm_hdls[idx].ep_comm_ptr->comm_list = out_comm_hdls;
221      out_comm_hdls[idx].ep_comm_ptr->comm_label = 0;
222    }
223
224    ::MPI_Allgather(&num_ep, 1, MPI_INT_STD, &recv_num_ep[0], 1, MPI_INT_STD, mpi_base_comm);
225
226
227    int sum = 0;  // representing total ep number of process with smaller rank
228    for (int i = 0; i < base_rank; ++i) {sum += recv_num_ep[i]; }
229
230    int ep_size = std::accumulate(recv_num_ep.begin(), recv_num_ep.end(), 0);
231
232    out_comm_hdls[0].ep_barrier = new OMPbarrier(num_ep);
233
234    out_comm_hdls[0].my_buffer = new BUFFER;
235    out_comm_hdls[0].my_buffer->buf_double = new double[BUFFER_SIZE];
236    out_comm_hdls[0].my_buffer->buf_float  = new float[BUFFER_SIZE];
237    out_comm_hdls[0].my_buffer->buf_int    = new int[BUFFER_SIZE];
238    out_comm_hdls[0].my_buffer->buf_long   = new long[BUFFER_SIZE];
239    out_comm_hdls[0].my_buffer->buf_ulong  = new unsigned long[BUFFER_SIZE];
240    out_comm_hdls[0].my_buffer->buf_char   = new char[BUFFER_SIZE];
241
242    out_comm_hdls[0].rank_map = new RANK_MAP;
243    out_comm_hdls[0].rank_map->resize(ep_size);
244
245
246    for (int i = 1; i < num_ep; i++)
247    {
248      out_comm_hdls[i].ep_barrier = out_comm_hdls[0].ep_barrier;
249      out_comm_hdls[i].my_buffer  = out_comm_hdls[0].my_buffer;
250      out_comm_hdls[i].rank_map   = out_comm_hdls[0].rank_map;
251    }
252
253
254    for (int i = 0; i < num_ep; i++)
255    {
256      out_comm_hdls[i].ep_comm_ptr->size_rank_info[0] = std::make_pair(sum+i, ep_size);
257      out_comm_hdls[i].ep_comm_ptr->size_rank_info[1] = std::make_pair(i, num_ep);
258      out_comm_hdls[i].ep_comm_ptr->size_rank_info[2] = std::make_pair(base_rank, base_size);
259
260      out_comm_hdls[i].ep_comm_ptr->message_queue = new Message_list;
261    }
262
263
264    int ind = 0;
265
266    for(int i=0; i<base_size; i++)
267    {
268      for(int j=0; j<recv_num_ep[i]; j++)
269      {
270        out_comm_hdls[0].rank_map->at(ind) = make_pair(j, i);
271        ind++;
272      }
273    }
274
275    // printf("ep_lib::MPI_Comm_create_endpoints()       OK from MPI_Comm\n");
276
277    return 0;
278
279  } //MPI_Comm_create_endpoints
280
281
282} //namespace ep_lib
Note: See TracBrowser for help on using the repository browser.