MoCSI API Reference
Loading...
Searching...
No Matches
MpiCommunicationPatterns.h
Go to the documentation of this file.
1#ifndef MPI_COMMUNICATION_PATTERNS_H
2#define MPI_COMMUNICATION_PATTERNS_H
3
4#ifdef MPI_PRESENT
5#include <mpi.h>
6
7#include <climits>
8#include <string>
9#include <valarray>
10#include <vector>
11
12#include "IniParser.h"
13#include "SimulationClassBase.h"
14
22template <typename T>
24
25template <>
27{
28 return MPI_DOUBLE;
29}
30template <>
32{
33 return MPI_FLOAT;
34}
35template <>
37{
38 return MPI_INT;
39}
40template <>
42{
43 return MPI_LONG;
44}
45
57template <typename T>
58void commPatternAllDataToAll(std::valarray<T>& global_array, const std::valarray<T>& local_array,
59 const SimulationClassBase<T>* sim)
60{
61 static_assert(std::is_same<T, double>::value || std::is_same<T, float>::value
62 || std::is_same<T, int>::value || std::is_same<T, long>::value,
63 "commPatternAllDataToAll: unsupported T; extend mpi_type_of<T>()");
64
66
67 // quick sanity
68 if (global_array.size() == 0 || local_array.size() == 0)
69 return;
70
72 // This call gathers all temperatures in all arrays within the two sub-communicators.
73 // Within each, the size of all temperature fields are equivalent, so the scalable operations
74 // can be used.
75 int split_id;
76 try
77 {
78 if (global_array.size()
79 == sim->m_simulation_config.getIntParameters("global_number_of_facets"))
80 {
81 split_id =
82 static_cast<int>(sim->global_array_split
83 / sim->m_simulation_config.getIntParameters("numerical_layers"));
84 }
85 else
86 {
87 split_id = sim->global_array_split;
88 }
89 }
90 catch (const BadInput& e)
91 {
92 std::cerr << static_cast<std::string>("[MpiCommunicationPatterns]: ")
93 << static_cast<std::string>(e.what()) << '\n';
94 throw BadInput(static_cast<std::string>("[MpiCommunicationPatterns]: ")
95 + static_cast<std::string>(e.what()));
96 }
97
99 {
100 std::cerr << "[MpiCommunicationPatterns]: split_id out of bounds.\n";
101 throw std::runtime_error(
102 static_cast<std::string>("[MpiCommunicationPatterns]: split_id out of bounds."));
103 }
104
105 // Safe check size and cast to int. Not needed for global_array_split as if that is > MAX_INT,
106 // so is global_array.size().
107 auto check_and_cast = [](std::size_t s) -> int
108 {
109 if (s > static_cast<std::size_t>(INT_MAX))
110 {
111 std::cerr << "[MpiCommunicationPatterns]: count > INT_MAX\n";
112 throw std::overflow_error("[MpiCommunicationPatterns]: count > INT_MAX.");
113 }
114 return static_cast<int>(s);
115 };
118 if (sim->my_color == 0)
119 {
120 // Color 0 gathers in the first part of the array.
122 sim->sub_comm);
123 }
124 else
125 {
126 // While color 1 gathers in the second part.
128 dtype, sim->sub_comm);
129 }
130
131 // Skip final comm pattern that only needs to be used, when sub- and intercomms are established.
132 if (sim->other_color_exists == 0)
133 {
134 return;
135 }
136
137 // This code exchanges the two parts of the array to the other group. The remote leader sends
138 // the data of the one sub-comm to each process in the other sub-comm.
139 // The operation is performed non-blocking for both sub-comms via the inter-comm.
140 if (sim->my_color == 0 && sim->my_sub_rank == 0)
141 {
142 MPI_Ibcast(&global_array[0], split_id, dtype, MPI_ROOT, sim->inter_comm,
143 &request_handles[0]);
144 }
145 else if (sim->my_color == 0)
146 {
147 MPI_Ibcast(&global_array[0], split_id, dtype, MPI_PROC_NULL, sim->inter_comm,
148 &request_handles[0]);
149 }
150 else
151 {
152 MPI_Ibcast(&global_array[0], split_id, dtype, 0, sim->inter_comm, &request_handles[0]);
153 }
154
156
157 if (sim->my_color == 1 && sim->my_sub_rank == 0)
158 {
160 &request_handles[1]);
161 }
162 else if (sim->my_color == 1)
163 {
165 &request_handles[1]);
166 }
167 else
168 {
169 MPI_Ibcast(&global_array[split_id], lower_array_size, dtype, 0, sim->inter_comm,
170 &request_handles[1]);
171 }
172
174}
175
189template <typename T>
190void commPatternAllDataToAllInPlace(std::valarray<T>& global_array, int data_count,
191 const SimulationClassBase<T>* sim)
192{
193 static_assert(std::is_same<T, double>::value || std::is_same<T, float>::value
194 || std::is_same<T, int>::value || std::is_same<T, long>::value,
195 "commPatternAllDataToAll: unsupported T; extend mpi_type_of<T>()");
196
198
199 // quick sanity
200 if (global_array.size() == 0)
201 return;
202
204 // This call gathers all temperatures in all arrays within the two sub-communicators.
205 // Within each, the size of all temperature fields are equivalent, so the scalable operations
206 // can be used.
207 int split_id;
208 try
209 {
210 if (global_array.size()
211 == sim->m_simulation_config.getIntParameters("global_number_of_facets"))
212 {
213 split_id =
214 static_cast<int>(sim->global_array_split
215 / sim->m_simulation_config.getIntParameters("numerical_layers"));
216 }
217 else
218 {
219 split_id = sim->global_array_split;
220 }
221 }
222 catch (const BadInput& e)
223 {
224 std::cerr << static_cast<std::string>("[MpiCommunicationPatterns]: ")
225 << static_cast<std::string>(e.what()) << '\n';
226 throw BadInput(static_cast<std::string>("[MpiCommunicationPatterns]: ")
227 + static_cast<std::string>(e.what()));
228 }
229
231 {
232 std::cerr << "[MpiCommunicationPatterns]: split_id out of bounds.\n";
233 throw std::runtime_error(
234 static_cast<std::string>("[MpiCommunicationPatterns]: split_id out of bounds."));
235 }
236
237 if (sim->my_color == 0)
238 {
239 // Color 0 gathers in the first part of the array.
241 sim->sub_comm);
242 }
243 else
244 {
245 // While color 1 gathers in the second part.
247 MPI_DOUBLE, sim->sub_comm);
248 }
249
250 // Skip final comm pattern that only needs to be used, when sub- and intercomms are established.
251 if (sim->other_color_exists == 0)
252 {
253 return;
254 }
255
256 // This code exchanges the two parts of the array to the other group. The remote leader sends
257 // the data of the one sub-comm to each process in the other sub-comm.
258 // The operation is performed non-blocking for both sub-comms via the inter-comm.
259 if (sim->my_color == 0 && sim->my_sub_rank == 0)
260 {
261 MPI_Ibcast(&global_array[0], split_id, MPI_DOUBLE, MPI_ROOT, sim->inter_comm,
262 &request_handles[0]);
263 }
264 else if (sim->my_color == 0)
265 {
267 &request_handles[0]);
268 }
269 else
270 {
271 MPI_Ibcast(&global_array[0], split_id, MPI_DOUBLE, 0, sim->inter_comm, &request_handles[0]);
272 }
273
274 auto check_and_cast = [](std::size_t s) -> int
275 {
276 if (s > static_cast<std::size_t>(INT_MAX))
277 {
278 std::cerr << "[MpiCommunicationPatterns]: count > INT_MAX\n";
279 throw std::overflow_error("[MpiCommunicationPatterns]: count > INT_MAX.");
280 }
281 return static_cast<int>(s);
282 };
284
285 if (sim->my_color == 1 && sim->my_sub_rank == 0)
286 {
288 &request_handles[1]);
289 }
290 else if (sim->my_color == 1)
291 {
293 sim->inter_comm, &request_handles[1]);
294 }
295 else
296 {
298 &request_handles[1]);
299 }
300
302}
303
317template <typename T>
319 const SimulationClassBase<T>* sim)
320{
321 static_assert(std::is_same<T, double>::value || std::is_same<T, float>::value
322 || std::is_same<T, int>::value || std::is_same<T, long>::value,
323 "commPatternAllDataToAll: unsupported T; extend mpi_type_of<T>()");
324
326
327 // quick sanity
328 if (global_array.size() == 0)
329 return;
330
332 // This call gathers all temperatures in all arrays within the two sub-communicators.
333 // Within each, the size of all temperature fields are equivalent, so the scalable operations
334 // can be used.
335 int split_id;
336 try
337 {
338 if (global_array.size()
339 == sim->m_simulation_config.getIntParameters("global_number_of_facets"))
340 {
341 split_id =
342 static_cast<int>(sim->global_array_split
343 / sim->m_simulation_config.getIntParameters("numerical_layers"));
344 }
345 else
346 {
347 split_id = sim->global_array_split;
348 }
349 }
350 catch (const BadInput& e)
351 {
352 std::cerr << static_cast<std::string>("[MpiCommunicationPatterns]: ")
353 << static_cast<std::string>(e.what()) << '\n';
354 throw BadInput(static_cast<std::string>("[MpiCommunicationPatterns]: ")
355 + static_cast<std::string>(e.what()));
356 }
357
359 {
360 std::cerr << "[MpiCommunicationPatterns]: split_id out of bounds.\n";
361 throw std::runtime_error(
362 static_cast<std::string>("[MpiCommunicationPatterns]: split_id out of bounds."));
363 }
364
365 if (sim->my_color == 0)
366 {
367 // Color 0 gathers in the first part of the array.
369 sim->sub_comm);
370 }
371 else
372 {
373 // While color 1 gathers in the second part.
375 MPI_DOUBLE, sim->sub_comm);
376 }
377
378 // Skip final comm pattern that only needs to be used, when sub- and intercomms are established.
379 if (sim->other_color_exists == 0)
380 {
381 return;
382 }
383
384 // This code exchanges the two parts of the array to the other group. The remote leader sends
385 // the data of the one sub-comm to each process in the other sub-comm.
386 // The operation is performed non-blocking for both sub-comms via the inter-comm.
387 if (sim->my_color == 0 && sim->my_sub_rank == 0)
388 {
389 MPI_Ibcast(&global_array[0], split_id, MPI_DOUBLE, MPI_ROOT, sim->inter_comm,
390 &request_handles[0]);
391 }
392 else if (sim->my_color == 0)
393 {
395 &request_handles[0]);
396 }
397 else
398 {
399 MPI_Ibcast(&global_array[0], split_id, MPI_DOUBLE, 0, sim->inter_comm, &request_handles[0]);
400 }
401
402 auto check_and_cast = [](std::size_t s) -> int
403 {
404 if (s > static_cast<std::size_t>(INT_MAX))
405 {
406 std::cerr << "[MpiCommunicationPatterns]: count > INT_MAX\n";
407 throw std::overflow_error("[MpiCommunicationPatterns]: count > INT_MAX.");
408 }
409 return static_cast<int>(s);
410 };
412
413 if (sim->my_color == 1 && sim->my_sub_rank == 0)
414 {
416 &request_handles[1]);
417 }
418 else if (sim->my_color == 1)
419 {
421 sim->inter_comm, &request_handles[1]);
422 }
423 else
424 {
426 &request_handles[1]);
427 }
428
430}
431
432#endif // MPI_PRESENT
433
434#endif // MPI_COMMUNICATION_PATTERNS_H
This error class inherits from std::exception and marks faulty parameter or CL inputs....
Definition IniParser.h:71
Concrete implementation of a matrix class representing a Compressed Sparse Rows (CSR) matrix....
Definition CsrMatrix.h:37
std::pair< int, int > size() const
Function that returns the size of the matrix as a pair in (rows, columns) format.
Definition GenericMatrix.h:120