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 "SimulationClassBase.h"
12
20template <typename T>
22
23template <>
25{
26 return MPI_DOUBLE;
27}
28template <>
30{
31 return MPI_FLOAT;
32}
33template <>
35{
36 return MPI_INT;
37}
38template <>
40{
41 return MPI_LONG;
42}
43
55template <typename T>
56void commPatternAllDataToAll(std::valarray<T>& global_array, const std::valarray<T>& local_array,
57 const SimulationClassBase<T>* sim)
58{
59 static_assert(std::is_same<T, double>::value || std::is_same<T, float>::value
60 || std::is_same<T, int>::value || std::is_same<T, long>::value,
61 "commPatternAllDataToAll: unsupported T; extend mpi_type_of<T>()");
62
64
65 // quick sanity
66 if (global_array.size() == 0 || local_array.size() == 0)
67 return;
68
70 // This call gathers all temperatures in all arrays within the two sub-communicators.
71 // Within each, the size of all temperature fields are equivalent, so the scalable operations
72 // can be used.
73 int split_id;
74 if (global_array.size() == sim->m_simulation_config.getIntParameters("global_number_of_facets"))
75 {
76 split_id =
77 static_cast<int>(sim->global_array_split
78 / sim->m_simulation_config.getIntParameters("numerical_layers"));
79 }
80 else
81 {
82 split_id = sim->global_array_split;
83 }
84
86 throw std::runtime_error("split_id out of bounds");
87
88 // Safe check size and cast to int. Not needed for global_array_split as if that is > MAX_INT,
89 // so is global_array.size().
90 auto check_and_cast = [](std::size_t s) -> int
91 {
92 if (s > static_cast<std::size_t>(INT_MAX))
93 throw std::overflow_error("count > INT_MAX");
94 return static_cast<int>(s);
95 };
98 if (sim->my_color == 0)
99 {
100 // Color 0 gathers in the first part of the array.
102 sim->sub_comm);
103 }
104 else
105 {
106 // While color 1 gathers in the second part.
108 dtype, sim->sub_comm);
109 }
110
111 // Skip final comm pattern that only needs to be used, when sub- and intercomms are established.
112 if (sim->other_color_exists == 0)
113 {
114 return;
115 }
116
117 // This code exchanges the two parts of the array to the other group. The remote leader sends
118 // the data of the one sub-comm to each process in the other sub-comm.
119 // The operation is performed non-blocking for both sub-comms via the inter-comm.
120 if (sim->my_color == 0 && sim->my_sub_rank == 0)
121 {
122 MPI_Ibcast(&global_array[0], split_id, dtype, MPI_ROOT, sim->inter_comm,
123 &request_handles[0]);
124 }
125 else if (sim->my_color == 0)
126 {
127 MPI_Ibcast(&global_array[0], split_id, dtype, MPI_PROC_NULL, sim->inter_comm,
128 &request_handles[0]);
129 }
130 else
131 {
132 MPI_Ibcast(&global_array[0], split_id, dtype, 0, sim->inter_comm, &request_handles[0]);
133 }
134
136
137 if (sim->my_color == 1 && sim->my_sub_rank == 0)
138 {
140 &request_handles[1]);
141 }
142 else if (sim->my_color == 1)
143 {
145 &request_handles[1]);
146 }
147 else
148 {
149 MPI_Ibcast(&global_array[split_id], lower_array_size, dtype, 0, sim->inter_comm,
150 &request_handles[1]);
151 }
152
154}
155
169template <typename T>
170void commPatternAllDataToAllInPlace(std::valarray<T>& global_array, int data_count,
171 const SimulationClassBase<T>* sim)
172{
173 static_assert(std::is_same<T, double>::value || std::is_same<T, float>::value
174 || std::is_same<T, int>::value || std::is_same<T, long>::value,
175 "commPatternAllDataToAll: unsupported T; extend mpi_type_of<T>()");
176
178
179 // quick sanity
180 if (global_array.size() == 0)
181 return;
182
184 // This call gathers all temperatures in all arrays within the two sub-communicators.
185 // Within each, the size of all temperature fields are equivalent, so the scalable operations
186 // can be used.
187 int split_id;
188 if (global_array.size() == sim->m_simulation_config.getIntParameters("global_number_of_facets"))
189 {
190 split_id =
191 static_cast<int>(sim->global_array_split
192 / sim->m_simulation_config.getIntParameters("numerical_layers"));
193 }
194 else
195 {
196 split_id = sim->global_array_split;
197 }
198
200 throw std::runtime_error("split_id out of bounds");
201
202 if (sim->my_color == 0)
203 {
204 // Color 0 gathers in the first part of the array.
206 sim->sub_comm);
207 }
208 else
209 {
210 // While color 1 gathers in the second part.
212 MPI_DOUBLE, sim->sub_comm);
213 }
214
215 // Skip final comm pattern that only needs to be used, when sub- and intercomms are established.
216 if (sim->other_color_exists == 0)
217 {
218 return;
219 }
220
221 // This code exchanges the two parts of the array to the other group. The remote leader sends
222 // the data of the one sub-comm to each process in the other sub-comm.
223 // The operation is performed non-blocking for both sub-comms via the inter-comm.
224 if (sim->my_color == 0 && sim->my_sub_rank == 0)
225 {
226 MPI_Ibcast(&global_array[0], split_id, MPI_DOUBLE, MPI_ROOT, sim->inter_comm,
227 &request_handles[0]);
228 }
229 else if (sim->my_color == 0)
230 {
232 &request_handles[0]);
233 }
234 else
235 {
236 MPI_Ibcast(&global_array[0], split_id, MPI_DOUBLE, 0, sim->inter_comm, &request_handles[0]);
237 }
238
239 auto check_and_cast = [](std::size_t s) -> int
240 {
241 if (s > static_cast<std::size_t>(INT_MAX))
242 throw std::overflow_error("count > INT_MAX");
243 return static_cast<int>(s);
244 };
246
247 if (sim->my_color == 1 && sim->my_sub_rank == 0)
248 {
250 &request_handles[1]);
251 }
252 else if (sim->my_color == 1)
253 {
255 sim->inter_comm, &request_handles[1]);
256 }
257 else
258 {
260 &request_handles[1]);
261 }
262
264}
265
279template <typename T>
281 const SimulationClassBase<T>* sim)
282{
283 static_assert(std::is_same<T, double>::value || std::is_same<T, float>::value
284 || std::is_same<T, int>::value || std::is_same<T, long>::value,
285 "commPatternAllDataToAll: unsupported T; extend mpi_type_of<T>()");
286
288
289 // quick sanity
290 if (global_array.size() == 0)
291 return;
292
294 // This call gathers all temperatures in all arrays within the two sub-communicators.
295 // Within each, the size of all temperature fields are equivalent, so the scalable operations
296 // can be used.
297 int split_id;
298 if (global_array.size() == sim->m_simulation_config.getIntParameters("global_number_of_facets"))
299 {
300 split_id =
301 static_cast<int>(sim->global_array_split
302 / sim->m_simulation_config.getIntParameters("numerical_layers"));
303 }
304 else
305 {
306 split_id = sim->global_array_split;
307 }
308
310 throw std::runtime_error("split_id out of bounds");
311
312 if (sim->my_color == 0)
313 {
314 // Color 0 gathers in the first part of the array.
316 sim->sub_comm);
317 }
318 else
319 {
320 // While color 1 gathers in the second part.
322 MPI_DOUBLE, sim->sub_comm);
323 }
324
325 // Skip final comm pattern that only needs to be used, when sub- and intercomms are established.
326 if (sim->other_color_exists == 0)
327 {
328 return;
329 }
330
331 // This code exchanges the two parts of the array to the other group. The remote leader sends
332 // the data of the one sub-comm to each process in the other sub-comm.
333 // The operation is performed non-blocking for both sub-comms via the inter-comm.
334 if (sim->my_color == 0 && sim->my_sub_rank == 0)
335 {
336 MPI_Ibcast(&global_array[0], split_id, MPI_DOUBLE, MPI_ROOT, sim->inter_comm,
337 &request_handles[0]);
338 }
339 else if (sim->my_color == 0)
340 {
342 &request_handles[0]);
343 }
344 else
345 {
346 MPI_Ibcast(&global_array[0], split_id, MPI_DOUBLE, 0, sim->inter_comm, &request_handles[0]);
347 }
348
349 auto check_and_cast = [](std::size_t s) -> int
350 {
351 if (s > static_cast<std::size_t>(INT_MAX))
352 throw std::overflow_error("count > INT_MAX");
353 return static_cast<int>(s);
354 };
356
357 if (sim->my_color == 1 && sim->my_sub_rank == 0)
358 {
360 &request_handles[1]);
361 }
362 else if (sim->my_color == 1)
363 {
365 sim->inter_comm, &request_handles[1]);
366 }
367 else
368 {
370 &request_handles[1]);
371 }
372
374}
375
376#endif // MPI_PRESENT
377
378#endif // MPI_COMMUNICATION_PATTERNS_H
Concrete implementation of a matrix class representing a Compressed Sparse Rows (CSR) matrix....
Definition CsrMatrix.h:35
std::pair< int, int > size() const
Function that returns the size of the matrix as a pair in (rows, columns) format.
Definition GenericMatrix.h:118