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 <string>
8#include <valarray>
9#include <vector>
10
11#include "IniParser.h"
12#include "SimulationClassBase.h"
13
21template <typename T>
23
24template <>
26{
27 return MPI_DOUBLE;
28}
29template <>
31{
32 return MPI_FLOAT;
33}
34template <>
36{
37 return MPI_INT;
38}
39template <>
41{
42 return MPI_LONG;
43}
44
56template <typename T>
57void commPatternAllDataToAll(std::valarray<T>& global_array, const std::valarray<T>& local_array,
58 const SimulationClassBase<T>* sim)
59{
60 static_assert(std::is_same<T, double>::value || std::is_same<T, float>::value
61 || std::is_same<T, int>::value || std::is_same<T, long>::value,
62 "commPatternAllDataToAll: unsupported T; extend mpi_type_of<T>()");
63
65
66 // quick sanity
67 if (global_array.size() == 0 || local_array.size() == 0)
68 return;
69
71 // This call gathers all temperatures in all arrays within the two sub-communicators.
72 // Within each, the size of all temperature fields are equivalent, so the scalable operations
73 // can be used.
74 int split_id;
75 try
76 {
77 if (global_array.size()
78 == sim->m_simulation_config.getIntParameters("global_number_of_facets"))
79 {
80 split_id =
81 static_cast<int>(sim->global_array_split
82 / sim->m_simulation_config.getIntParameters("numerical_layers"));
83 }
84 else
85 {
86 split_id = sim->global_array_split;
87 }
88 }
89 catch (const BadInput& e)
90 {
91 std::cerr << static_cast<std::string>("[MpiCommunicationPatterns]: ")
92 << static_cast<std::string>(e.what()) << '\n';
93 throw BadInput(static_cast<std::string>("[MpiCommunicationPatterns]: ")
94 + static_cast<std::string>(e.what()));
95 }
96
98 {
99 std::cerr << "[MpiCommunicationPatterns]: split_id out of bounds.\n";
100 throw std::runtime_error(
101 static_cast<std::string>("[MpiCommunicationPatterns]: split_id out of bounds."));
102 }
103
104 // Safe check size and cast to int. Not needed for global_array_split as if that is > MAX_INT,
105 // so is global_array.size().
106 auto check_and_cast = [](std::size_t s) -> int
107 {
108 if (s > static_cast<std::size_t>(INT_MAX))
109 {
110 std::cerr << "[MpiCommunicationPatterns]: count > INT_MAX\n";
111 throw std::overflow_error("[MpiCommunicationPatterns]: count > INT_MAX.");
112 }
113 return static_cast<int>(s);
114 };
117 if (sim->my_color == 0)
118 {
119 // Color 0 gathers in the first part of the array.
121 sim->sub_comm);
122 }
123 else
124 {
125 // While color 1 gathers in the second part.
127 dtype, sim->sub_comm);
128 }
129
130 // Skip final comm pattern that only needs to be used, when sub- and intercomms are established.
131 if (sim->other_color_exists == 0)
132 {
133 return;
134 }
135
136 // This code exchanges the two parts of the array to the other group. The remote leader sends
137 // the data of the one sub-comm to each process in the other sub-comm.
138 // The operation is performed non-blocking for both sub-comms via the inter-comm.
139 if (sim->my_color == 0 && sim->my_sub_rank == 0)
140 {
141 MPI_Ibcast(&global_array[0], split_id, dtype, MPI_ROOT, sim->inter_comm,
142 &request_handles[0]);
143 }
144 else if (sim->my_color == 0)
145 {
146 MPI_Ibcast(&global_array[0], split_id, dtype, MPI_PROC_NULL, sim->inter_comm,
147 &request_handles[0]);
148 }
149 else
150 {
151 MPI_Ibcast(&global_array[0], split_id, dtype, 0, sim->inter_comm, &request_handles[0]);
152 }
153
155
156 if (sim->my_color == 1 && sim->my_sub_rank == 0)
157 {
159 &request_handles[1]);
160 }
161 else if (sim->my_color == 1)
162 {
164 &request_handles[1]);
165 }
166 else
167 {
168 MPI_Ibcast(&global_array[split_id], lower_array_size, dtype, 0, sim->inter_comm,
169 &request_handles[1]);
170 }
171
173}
174
188template <typename T>
189void commPatternAllDataToAllInPlace(std::valarray<T>& global_array, int data_count,
190 const SimulationClassBase<T>* sim)
191{
192 static_assert(std::is_same<T, double>::value || std::is_same<T, float>::value
193 || std::is_same<T, int>::value || std::is_same<T, long>::value,
194 "commPatternAllDataToAll: unsupported T; extend mpi_type_of<T>()");
195
197
198 // quick sanity
199 if (global_array.size() == 0)
200 return;
201
203 // This call gathers all temperatures in all arrays within the two sub-communicators.
204 // Within each, the size of all temperature fields are equivalent, so the scalable operations
205 // can be used.
206 int split_id;
207 try
208 {
209 if (global_array.size()
210 == sim->m_simulation_config.getIntParameters("global_number_of_facets"))
211 {
212 split_id =
213 static_cast<int>(sim->global_array_split
214 / sim->m_simulation_config.getIntParameters("numerical_layers"));
215 }
216 else
217 {
218 split_id = sim->global_array_split;
219 }
220 }
221 catch (const BadInput& e)
222 {
223 std::cerr << static_cast<std::string>("[MpiCommunicationPatterns]: ")
224 << static_cast<std::string>(e.what()) << '\n';
225 throw BadInput(static_cast<std::string>("[MpiCommunicationPatterns]: ")
226 + static_cast<std::string>(e.what()));
227 }
228
230 {
231 std::cerr << "[MpiCommunicationPatterns]: split_id out of bounds.\n";
232 throw std::runtime_error(
233 static_cast<std::string>("[MpiCommunicationPatterns]: split_id out of bounds."));
234 }
235
236 if (sim->my_color == 0)
237 {
238 // Color 0 gathers in the first part of the array.
240 sim->sub_comm);
241 }
242 else
243 {
244 // While color 1 gathers in the second part.
246 MPI_DOUBLE, sim->sub_comm);
247 }
248
249 // Skip final comm pattern that only needs to be used, when sub- and intercomms are established.
250 if (sim->other_color_exists == 0)
251 {
252 return;
253 }
254
255 // This code exchanges the two parts of the array to the other group. The remote leader sends
256 // the data of the one sub-comm to each process in the other sub-comm.
257 // The operation is performed non-blocking for both sub-comms via the inter-comm.
258 if (sim->my_color == 0 && sim->my_sub_rank == 0)
259 {
260 MPI_Ibcast(&global_array[0], split_id, MPI_DOUBLE, MPI_ROOT, sim->inter_comm,
261 &request_handles[0]);
262 }
263 else if (sim->my_color == 0)
264 {
266 &request_handles[0]);
267 }
268 else
269 {
270 MPI_Ibcast(&global_array[0], split_id, MPI_DOUBLE, 0, sim->inter_comm, &request_handles[0]);
271 }
272
273 auto check_and_cast = [](std::size_t s) -> int
274 {
275 if (s > static_cast<std::size_t>(INT_MAX))
276 {
277 std::cerr << "[MpiCommunicationPatterns]: count > INT_MAX\n";
278 throw std::overflow_error("[MpiCommunicationPatterns]: count > INT_MAX.");
279 }
280 return static_cast<int>(s);
281 };
283
284 if (sim->my_color == 1 && sim->my_sub_rank == 0)
285 {
287 &request_handles[1]);
288 }
289 else if (sim->my_color == 1)
290 {
292 sim->inter_comm, &request_handles[1]);
293 }
294 else
295 {
297 &request_handles[1]);
298 }
299
301}
302
316template <typename T>
318 const SimulationClassBase<T>* sim)
319{
320 static_assert(std::is_same<T, double>::value || std::is_same<T, float>::value
321 || std::is_same<T, int>::value || std::is_same<T, long>::value,
322 "commPatternAllDataToAll: unsupported T; extend mpi_type_of<T>()");
323
325
326 // quick sanity
327 if (global_array.size() == 0)
328 return;
329
331 // This call gathers all temperatures in all arrays within the two sub-communicators.
332 // Within each, the size of all temperature fields are equivalent, so the scalable operations
333 // can be used.
334 int split_id;
335 try
336 {
337 if (global_array.size()
338 == sim->m_simulation_config.getIntParameters("global_number_of_facets"))
339 {
340 split_id =
341 static_cast<int>(sim->global_array_split
342 / sim->m_simulation_config.getIntParameters("numerical_layers"));
343 }
344 else
345 {
346 split_id = sim->global_array_split;
347 }
348 }
349 catch (const BadInput& e)
350 {
351 std::cerr << static_cast<std::string>("[MpiCommunicationPatterns]: ")
352 << static_cast<std::string>(e.what()) << '\n';
353 throw BadInput(static_cast<std::string>("[MpiCommunicationPatterns]: ")
354 + static_cast<std::string>(e.what()));
355 }
356
358 {
359 std::cerr << "[MpiCommunicationPatterns]: split_id out of bounds.\n";
360 throw std::runtime_error(
361 static_cast<std::string>("[MpiCommunicationPatterns]: split_id out of bounds."));
362 }
363
364 if (sim->my_color == 0)
365 {
366 // Color 0 gathers in the first part of the array.
368 sim->sub_comm);
369 }
370 else
371 {
372 // While color 1 gathers in the second part.
374 MPI_DOUBLE, sim->sub_comm);
375 }
376
377 // Skip final comm pattern that only needs to be used, when sub- and intercomms are established.
378 if (sim->other_color_exists == 0)
379 {
380 return;
381 }
382
383 // This code exchanges the two parts of the array to the other group. The remote leader sends
384 // the data of the one sub-comm to each process in the other sub-comm.
385 // The operation is performed non-blocking for both sub-comms via the inter-comm.
386 if (sim->my_color == 0 && sim->my_sub_rank == 0)
387 {
388 MPI_Ibcast(&global_array[0], split_id, MPI_DOUBLE, MPI_ROOT, sim->inter_comm,
389 &request_handles[0]);
390 }
391 else if (sim->my_color == 0)
392 {
394 &request_handles[0]);
395 }
396 else
397 {
398 MPI_Ibcast(&global_array[0], split_id, MPI_DOUBLE, 0, sim->inter_comm, &request_handles[0]);
399 }
400
401 auto check_and_cast = [](std::size_t s) -> int
402 {
403 if (s > static_cast<std::size_t>(INT_MAX))
404 {
405 std::cerr << "[MpiCommunicationPatterns]: count > INT_MAX\n";
406 throw std::overflow_error("[MpiCommunicationPatterns]: count > INT_MAX.");
407 }
408 return static_cast<int>(s);
409 };
411
412 if (sim->my_color == 1 && sim->my_sub_rank == 0)
413 {
415 &request_handles[1]);
416 }
417 else if (sim->my_color == 1)
418 {
420 sim->inter_comm, &request_handles[1]);
421 }
422 else
423 {
425 &request_handles[1]);
426 }
427
429}
430
431#endif // MPI_PRESENT
432
433#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