Loading...
Searching...
No Matches
buffer_copy_kernels.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "grid/grid_types.hpp"
4
6
7/// @brief Communication reduction modes.
9{
10 /// Sums up the node values during receive.
11 SUM,
12
13 /// Stores the min of all received values during receive.
14 MIN,
15
16 /// Stores the max of all received values during receive.
17 MAX,
18};
19
20namespace detail {
21
22/// @brief Helper function to defer to the respective Kokkos::atomic_xxx() reduction function.
23template < typename T >
24KOKKOS_INLINE_FUNCTION void reduction_function( T* ptr, const T& val, const CommunicationReduction reduction_type )
25{
26 if ( reduction_type == CommunicationReduction::SUM )
27 {
28 Kokkos::atomic_add( ptr, val );
29 }
30 else if ( reduction_type == CommunicationReduction::MIN )
31 {
32 Kokkos::atomic_min( ptr, val );
33 }
34 else if ( reduction_type == CommunicationReduction::MAX )
35 {
36 Kokkos::atomic_max( ptr, val );
37 }
38}
39
40} // namespace detail
41
42namespace detail {
43template < typename DataView, bool is_scalar >
44KOKKOS_INLINE_FUNCTION DataView::value_type
45 value( const DataView& data, int local_subdomain_id, int x, int y, int r, int d )
46{
47 if constexpr ( is_scalar )
48 {
49 return data( local_subdomain_id, x, y, r );
50 }
51 else
52 {
53 return data( local_subdomain_id, x, y, r, d );
54 }
55}
56
57template < typename DataView, bool is_scalar >
58KOKKOS_INLINE_FUNCTION DataView::value_type&
59 value_ref( const DataView& data, int local_subdomain_id, int x, int y, int r, int d )
60{
61 if constexpr ( is_scalar )
62 {
63 return data( local_subdomain_id, x, y, r );
64 }
65 else
66 {
67 return data( local_subdomain_id, x, y, r, d );
68 }
69}
70
71KOKKOS_INLINE_FUNCTION
72constexpr int
73 idx( const int loop_idx,
74 const int size,
75 const grid::BoundaryPosition position,
76 const grid::BoundaryDirection direction )
77{
78 if ( position == grid::BoundaryPosition::P0 )
79 {
80 return 0;
81 }
82 else if ( position == grid::BoundaryPosition::P1 )
83 {
84 return size - 1;
85 }
86 else
87 {
88 if ( direction == grid::BoundaryDirection::FORWARD )
89 {
90 return loop_idx;
91 }
92 else
93 {
94 return size - 1 - loop_idx;
95 }
96 }
97}
98
99} // namespace detail
100
101namespace detail_view_constraints {
102
103template <class T>
104struct is_kokkos_view : std::false_type {};
105
106template <class... Args>
107struct is_kokkos_view<Kokkos::View<Args...>> : std::true_type {};
108
109template <class V>
111
112} // namespace detail_view_constraints
113
114
115// ---------------------------
116// Generic 0D copy_to_buffer
117// buffer: rank-1 view of length VecDim
118// ---------------------------
119template < int VecDim, typename BufferView, typename ViewType >
120std::enable_if_t<
123 (std::decay_t<BufferView>::rank == 1)
124>
126 const BufferView& buffer,
127 const ViewType& data,
128 const int local_subdomain_id,
129 const grid::BoundaryVertex boundary_vertex )
130{
131 using ScalarType = typename std::decay_t<BufferView>::value_type;
132
133 // Heuristic: scalar grid data is rank-4 (sd,x,y,r), vector-valued is rank-5 (sd,x,y,r,d)
134 static_assert( std::decay_t<ViewType>::rank == 4 || std::decay_t<ViewType>::rank == 5,
135 "copy_to_buffer expects ViewType rank 4 (scalar) or 5 (vector-valued)." );
136
137 constexpr bool is_scalar = (std::decay_t<ViewType>::rank == 4);
138
139 if ( buffer.extent( 0 ) != VecDim )
140 Kokkos::abort( "The buffer VecDim should match its respective extent. This abort should not happen." );
141
142 const auto boundary_position_x = grid::boundary_position_from_boundary_type_x( boundary_vertex );
143 const auto boundary_position_y = grid::boundary_position_from_boundary_type_y( boundary_vertex );
144 const auto boundary_position_r = grid::boundary_position_from_boundary_type_r( boundary_vertex );
145
146 const auto size_x = data.extent( 1 );
147 const auto size_y = data.extent( 2 );
148 const auto size_r = data.extent( 3 );
149
150 Kokkos::parallel_for(
151 "copy_to_buffer_0D",
152 Kokkos::RangePolicy( 0, buffer.extent( 0 ) ),
153 KOKKOS_LAMBDA( const int d ) {
154 auto x = detail::idx( 0, size_x, boundary_position_x, grid::BoundaryDirection::FORWARD );
155 auto y = detail::idx( 0, size_y, boundary_position_y, grid::BoundaryDirection::FORWARD );
156 auto r = detail::idx( 0, size_r, boundary_position_r, grid::BoundaryDirection::FORWARD );
157 buffer( d ) = detail::value< ViewType, is_scalar >( data, local_subdomain_id, x, y, r, d );
158 } );
159}
160
161
162// ---------------------------
163// Generic 1D copy_to_buffer
164// buffer: rank-2 view of shape (N, VecDim)
165// ---------------------------
166template < int VecDim, typename BufferView, typename ViewType >
167std::enable_if_t<
170 (std::decay_t<BufferView>::rank == 2)
171>
173 const BufferView& buffer,
174 const ViewType& data,
175 const int local_subdomain_id,
176 const grid::BoundaryEdge boundary_edge )
177{
178 using ScalarType = typename std::decay_t<BufferView>::value_type;
179
180 static_assert( std::decay_t<ViewType>::rank == 4 || std::decay_t<ViewType>::rank == 5,
181 "copy_to_buffer expects ViewType rank 4 (scalar) or 5 (vector-valued)." );
182
183 constexpr bool is_scalar = (std::decay_t<ViewType>::rank == 4);
184
185 if ( buffer.extent( 1 ) != VecDim )
186 Kokkos::abort( "The buffer VecDim should match its respective extent. This abort should not happen." );
187
188 const auto boundary_position_x = grid::boundary_position_from_boundary_type_x( boundary_edge );
189 const auto boundary_position_y = grid::boundary_position_from_boundary_type_y( boundary_edge );
190 const auto boundary_position_r = grid::boundary_position_from_boundary_type_r( boundary_edge );
191
192 const auto size_x = data.extent( 1 );
193 const auto size_y = data.extent( 2 );
194 const auto size_r = data.extent( 3 );
195
196 Kokkos::parallel_for(
197 "copy_to_buffer_1D",
198 Kokkos::MDRangePolicy( { 0, 0 }, { buffer.extent( 0 ), buffer.extent( 1 ) } ),
199 KOKKOS_LAMBDA( const int idx, const int d ) {
200 auto x = detail::idx( idx, size_x, boundary_position_x, grid::BoundaryDirection::FORWARD );
201 auto y = detail::idx( idx, size_y, boundary_position_y, grid::BoundaryDirection::FORWARD );
202 auto r = detail::idx( idx, size_r, boundary_position_r, grid::BoundaryDirection::FORWARD );
203 buffer( idx, d ) = detail::value< ViewType, is_scalar >( data, local_subdomain_id, x, y, r, d );
204 } );
205}
206
207
208// ---------------------------
209// Generic 2D copy_to_buffer
210// buffer: rank-3 view of shape (Ni, Nj, VecDim)
211// ---------------------------
212template < int VecDim, typename BufferView, typename ViewType >
213std::enable_if_t<
216 (std::decay_t<BufferView>::rank == 3)
217>
219 const BufferView& buffer,
220 const ViewType& data,
221 const int local_subdomain_id,
222 const grid::BoundaryFace boundary_face )
223{
224 using ScalarType = typename std::decay_t<BufferView>::value_type;
225
226 static_assert( std::decay_t<ViewType>::rank == 4 || std::decay_t<ViewType>::rank == 5,
227 "copy_to_buffer expects ViewType rank 4 (scalar) or 5 (vector-valued)." );
228
229 constexpr bool is_scalar = (std::decay_t<ViewType>::rank == 4);
230
231 if ( buffer.extent( 2 ) != VecDim )
232 Kokkos::abort( "The buffer VecDim should match its respective extent. This abort should not happen." );
233
234 const auto boundary_position_x = grid::boundary_position_from_boundary_type_x( boundary_face );
235 const auto boundary_position_y = grid::boundary_position_from_boundary_type_y( boundary_face );
236 const auto boundary_position_r = grid::boundary_position_from_boundary_type_r( boundary_face );
237
238 const auto size_x = data.extent( 1 );
239 const auto size_y = data.extent( 2 );
240 const auto size_r = data.extent( 3 );
241
242 Kokkos::parallel_for(
243 "copy_to_buffer_2D",
244 Kokkos::MDRangePolicy( { 0, 0, 0 }, { buffer.extent( 0 ), buffer.extent( 1 ), buffer.extent( 2 ) } ),
245 KOKKOS_LAMBDA( const int i, const int j, const int d ) {
246 int x = 0, y = 0, r = 0;
247
248 if ( boundary_position_x != grid::BoundaryPosition::PV )
249 {
250 x = detail::idx( 0, size_x, boundary_position_x, grid::BoundaryDirection::FORWARD );
251 y = detail::idx( i, size_y, boundary_position_y, grid::BoundaryDirection::FORWARD );
252 r = detail::idx( j, size_r, boundary_position_r, grid::BoundaryDirection::FORWARD );
253 }
254 else if ( boundary_position_y != grid::BoundaryPosition::PV )
255 {
256 x = detail::idx( i, size_x, boundary_position_x, grid::BoundaryDirection::FORWARD );
257 y = detail::idx( 0, size_y, boundary_position_y, grid::BoundaryDirection::FORWARD );
258 r = detail::idx( j, size_r, boundary_position_r, grid::BoundaryDirection::FORWARD );
259 }
260 else
261 {
262 x = detail::idx( i, size_x, boundary_position_x, grid::BoundaryDirection::FORWARD );
263 y = detail::idx( j, size_y, boundary_position_y, grid::BoundaryDirection::FORWARD );
264 r = detail::idx( 0, size_r, boundary_position_r, grid::BoundaryDirection::FORWARD );
265 }
266
267 buffer( i, j, d ) = detail::value< ViewType, is_scalar >( data, local_subdomain_id, x, y, r, d );
268 } );
269}
270
271template < typename ScalarType, int VecDim, typename ViewType >
274 const ViewType& data,
275 const int local_subdomain_id,
276 const grid::BoundaryVertex boundary_vertex )
277{
278 static_assert(
279 std::is_same_v< ViewType, grid::Grid4DDataScalar< ScalarType > > ||
280 std::is_same_v< ViewType, grid::Grid4DDataVec< ScalarType, VecDim > > );
281
282 constexpr bool is_scalar = std::is_same_v< ViewType, grid::Grid4DDataScalar< ScalarType > >;
283
284 if ( buffer.extent( 0 ) != VecDim )
285 {
286 Kokkos::abort( "The buffer VecDim should match its respective extent. This abort should not happen." );
287 }
288
289 const auto boundary_position_x = grid::boundary_position_from_boundary_type_x( boundary_vertex );
290 const auto boundary_position_y = grid::boundary_position_from_boundary_type_y( boundary_vertex );
291 const auto boundary_position_r = grid::boundary_position_from_boundary_type_r( boundary_vertex );
292
293 const auto size_x = data.extent( 1 );
294 const auto size_y = data.extent( 2 );
295 const auto size_r = data.extent( 3 );
296
297 Kokkos::parallel_for(
298 "copy_to_buffer_0D", Kokkos::RangePolicy( 0, buffer.extent( 0 ) ), KOKKOS_LAMBDA( const int d ) {
299 auto x = detail::idx( 0, size_x, boundary_position_x, grid::BoundaryDirection::FORWARD );
300 auto y = detail::idx( 0, size_y, boundary_position_y, grid::BoundaryDirection::FORWARD );
301 auto r = detail::idx( 0, size_r, boundary_position_r, grid::BoundaryDirection::FORWARD );
302 buffer( d ) = detail::value< ViewType, is_scalar >( data, local_subdomain_id, x, y, r, d );
303 } );
304}
305
306template < typename ScalarType, int VecDim, typename ViewType >
309 const ViewType& data,
310 const int local_subdomain_id,
311 const grid::BoundaryEdge boundary_edge )
312{
313 static_assert(
314 std::is_same_v< ViewType, grid::Grid4DDataScalar< ScalarType > > ||
315 std::is_same_v< ViewType, grid::Grid4DDataVec< ScalarType, VecDim > > );
316
317 constexpr bool is_scalar = std::is_same_v< ViewType, grid::Grid4DDataScalar< ScalarType > >;
318
319 if ( buffer.extent( 1 ) != VecDim )
320 {
321 Kokkos::abort( "The buffer VecDim should match its respective extent. This abort should not happen." );
322 }
323
324 const auto boundary_position_x = grid::boundary_position_from_boundary_type_x( boundary_edge );
325 const auto boundary_position_y = grid::boundary_position_from_boundary_type_y( boundary_edge );
326 const auto boundary_position_r = grid::boundary_position_from_boundary_type_r( boundary_edge );
327
328 const auto size_x = data.extent( 1 );
329 const auto size_y = data.extent( 2 );
330 const auto size_r = data.extent( 3 );
331
332 Kokkos::parallel_for(
333 "copy_to_buffer_1D",
334 Kokkos::MDRangePolicy( { 0, 0 }, { buffer.extent( 0 ), buffer.extent( 1 ) } ),
335 KOKKOS_LAMBDA( const int idx, const int d ) {
336 auto x = detail::idx( idx, size_x, boundary_position_x, grid::BoundaryDirection::FORWARD );
337 auto y = detail::idx( idx, size_y, boundary_position_y, grid::BoundaryDirection::FORWARD );
338 auto r = detail::idx( idx, size_r, boundary_position_r, grid::BoundaryDirection::FORWARD );
339 buffer( idx, d ) = detail::value< ViewType, is_scalar >( data, local_subdomain_id, x, y, r, d );
340 } );
341}
342
343template < typename ScalarType, int VecDim, typename ViewType >
346 const ViewType& data,
347 const int local_subdomain_id,
348 const grid::BoundaryFace boundary_face )
349{
350 static_assert(
351 std::is_same_v< ViewType, grid::Grid4DDataScalar< ScalarType > > ||
352 std::is_same_v< ViewType, grid::Grid4DDataVec< ScalarType, VecDim > > );
353
354 constexpr bool is_scalar = std::is_same_v< ViewType, grid::Grid4DDataScalar< ScalarType > >;
355
356 if ( buffer.extent( 2 ) != VecDim )
357 {
358 Kokkos::abort( "The buffer VecDim should match its respective extent. This abort should not happen." );
359 }
360
361 const auto boundary_position_x = grid::boundary_position_from_boundary_type_x( boundary_face );
362 const auto boundary_position_y = grid::boundary_position_from_boundary_type_y( boundary_face );
363 const auto boundary_position_r = grid::boundary_position_from_boundary_type_r( boundary_face );
364
365 const auto size_x = data.extent( 1 );
366 const auto size_y = data.extent( 2 );
367 const auto size_r = data.extent( 3 );
368
369 Kokkos::parallel_for(
370 "copy_to_buffer_2D",
371 Kokkos::MDRangePolicy( { 0, 0, 0 }, { buffer.extent( 0 ), buffer.extent( 1 ), buffer.extent( 2 ) } ),
372 KOKKOS_LAMBDA( const int i, const int j, const int d ) {
373 int x = 0;
374 int y = 0;
375 int r = 0;
376
377 if ( boundary_position_x != grid::BoundaryPosition::PV )
378 {
379 x = detail::idx(
380 0 /* can be set to anything */, size_x, boundary_position_x, grid::BoundaryDirection::FORWARD );
381 y = detail::idx( i, size_y, boundary_position_y, grid::BoundaryDirection::FORWARD );
382 r = detail::idx( j, size_r, boundary_position_r, grid::BoundaryDirection::FORWARD );
383 }
384 else if ( boundary_position_y != grid::BoundaryPosition::PV )
385 {
386 x = detail::idx( i, size_x, boundary_position_x, grid::BoundaryDirection::FORWARD );
387 y = detail::idx(
388 0 /* can be set to anything */, size_y, boundary_position_y, grid::BoundaryDirection::FORWARD );
389 r = detail::idx( j, size_r, boundary_position_r, grid::BoundaryDirection::FORWARD );
390 }
391 else
392 {
393 x = detail::idx( i, size_x, boundary_position_x, grid::BoundaryDirection::FORWARD );
394 y = detail::idx( j, size_y, boundary_position_y, grid::BoundaryDirection::FORWARD );
395 r = detail::idx(
396 0 /* can be set to anything */, size_r, boundary_position_r, grid::BoundaryDirection::FORWARD );
397 }
398
399 buffer( i, j, d ) = detail::value< ViewType, is_scalar >( data, local_subdomain_id, x, y, r, d );
400 } );
401}
402
403template < typename ScalarType, int VecDim, typename ViewType >
406 const ViewType& data,
407 const int local_subdomain_id,
408 const grid::BoundaryVertex boundary_vertex,
409 const CommunicationReduction reduction )
410{
411
412 constexpr bool is_scalar = std::is_same_v< ViewType, grid::Grid4DDataScalar< ScalarType > >;
413
414 if ( buffer.extent( 0 ) != VecDim )
415 {
416 Kokkos::abort( "The buffer VecDim should match its respective extent. This abort should not happen." );
417 }
418
419 const auto boundary_position_x = grid::boundary_position_from_boundary_type_x( boundary_vertex );
420 const auto boundary_position_y = grid::boundary_position_from_boundary_type_y( boundary_vertex );
421 const auto boundary_position_r = grid::boundary_position_from_boundary_type_r( boundary_vertex );
422
423 const auto size_x = data.extent( 1 );
424 const auto size_y = data.extent( 2 );
425 const auto size_r = data.extent( 3 );
426
427 Kokkos::parallel_for(
428 "copy_from_buffer_0D", Kokkos::RangePolicy( 0, buffer.extent( 0 ) ), KOKKOS_LAMBDA( const int d ) {
429 auto x = detail::idx( 0, size_x, boundary_position_x, grid::BoundaryDirection::FORWARD );
430 auto y = detail::idx( 0, size_y, boundary_position_y, grid::BoundaryDirection::FORWARD );
431 auto r = detail::idx( 0, size_r, boundary_position_r, grid::BoundaryDirection::FORWARD );
433 &detail::value_ref< ViewType, is_scalar >( data, local_subdomain_id, x, y, r, d ),
434 buffer( d ),
435 reduction );
436 } );
437}
438
439template < typename ScalarType, int VecDim, typename ViewType >
442 const ViewType& data,
443 const int local_subdomain_id,
444 const grid::BoundaryEdge boundary_edge,
445 const grid::BoundaryDirection boundary_direction,
446 const CommunicationReduction reduction )
447{
448 constexpr bool is_scalar = std::is_same_v< ViewType, grid::Grid4DDataScalar< ScalarType > >;
449
450 if ( buffer.extent( 1 ) != VecDim )
451 {
452 Kokkos::abort( "The buffer VecDim should match its respective extent. This abort should not happen." );
453 }
454
455 const auto boundary_position_x = grid::boundary_position_from_boundary_type_x( boundary_edge );
456 const auto boundary_position_y = grid::boundary_position_from_boundary_type_y( boundary_edge );
457 const auto boundary_position_r = grid::boundary_position_from_boundary_type_r( boundary_edge );
458
459 const auto size_x = data.extent( 1 );
460 const auto size_y = data.extent( 2 );
461 const auto size_r = data.extent( 3 );
462
463 Kokkos::parallel_for(
464 "copy_from_buffer_1D",
465 Kokkos::MDRangePolicy( { 0, 0 }, { buffer.extent( 0 ), buffer.extent( 1 ) } ),
466 KOKKOS_LAMBDA( const int idx, const int d ) {
467 auto x = detail::idx( idx, size_x, boundary_position_x, boundary_direction );
468 auto y = detail::idx( idx, size_y, boundary_position_y, boundary_direction );
469 auto r = detail::idx( idx, size_r, boundary_position_r, boundary_direction );
471 &detail::value_ref< ViewType, is_scalar >( data, local_subdomain_id, x, y, r, d ),
472 buffer( idx, d ),
473 reduction );
474 } );
475}
476
477template < typename ScalarType, int VecDim, typename ViewType >
480 const ViewType& data,
481 const int local_subdomain_id,
482 const grid::BoundaryFace boundary_face,
483 const std::tuple< grid::BoundaryDirection, grid::BoundaryDirection > boundary_directions,
484 const CommunicationReduction reduction )
485{
486
487 constexpr bool is_scalar = std::is_same_v< ViewType, grid::Grid4DDataScalar< ScalarType > >;
488
489 if ( buffer.extent( 2 ) != VecDim )
490 {
491 Kokkos::abort( "The buffer VecDim should match its respective extent. This abort should not happen." );
492 }
493
494 const auto boundary_position_x = grid::boundary_position_from_boundary_type_x( boundary_face );
495 const auto boundary_position_y = grid::boundary_position_from_boundary_type_y( boundary_face );
496 const auto boundary_position_r = grid::boundary_position_from_boundary_type_r( boundary_face );
497
498 const auto size_x = data.extent( 1 );
499 const auto size_y = data.extent( 2 );
500 const auto size_r = data.extent( 3 );
501
502 const auto boundary_direction_0 = std::get< 0 >( boundary_directions );
503 const auto boundary_direction_1 = std::get< 1 >( boundary_directions );
504
505 Kokkos::parallel_for(
506 "copy_from_buffer_2D",
507 Kokkos::MDRangePolicy( { 0, 0, 0 }, { buffer.extent( 0 ), buffer.extent( 1 ), buffer.extent( 2 ) } ),
508 KOKKOS_LAMBDA( const int i, const int j, const int d ) {
509 int x = 0;
510 int y = 0;
511 int r = 0;
512
513 if ( boundary_position_x != grid::BoundaryPosition::PV )
514 {
515 x = detail::idx( 0, size_x, boundary_position_x, grid::BoundaryDirection::FORWARD );
516 y = detail::idx( i, size_y, boundary_position_y, boundary_direction_0 );
517 r = detail::idx( j, size_r, boundary_position_r, boundary_direction_1 );
518 }
519 else if ( boundary_position_y != grid::BoundaryPosition::PV )
520 {
521 x = detail::idx( i, size_x, boundary_position_x, boundary_direction_0 );
522 y = detail::idx( 0, size_y, boundary_position_y, grid::BoundaryDirection::FORWARD );
523 r = detail::idx( j, size_r, boundary_position_r, boundary_direction_1 );
524 }
525 else
526 {
527 x = detail::idx( i, size_x, boundary_position_x, boundary_direction_0 );
528 y = detail::idx( j, size_y, boundary_position_y, boundary_direction_1 );
529 r = detail::idx( 0, size_r, boundary_position_r, grid::BoundaryDirection::FORWARD );
530 }
531
533 &detail::value_ref< ViewType, is_scalar >( data, local_subdomain_id, x, y, r, d ),
534 buffer( i, j, d ),
535 reduction );
536 } );
537}
538
539} // namespace terra::communication
constexpr bool is_kokkos_view_v
Definition buffer_copy_kernels.hpp:110
constexpr int idx(const int loop_idx, const int size, const grid::BoundaryPosition position, const grid::BoundaryDirection direction)
Definition buffer_copy_kernels.hpp:73
DataView::value_type value(const DataView &data, int local_subdomain_id, int x, int y, int r, int d)
Definition buffer_copy_kernels.hpp:45
void reduction_function(T *ptr, const T &val, const CommunicationReduction reduction_type)
Helper function to defer to the respective Kokkos::atomic_xxx() reduction function.
Definition buffer_copy_kernels.hpp:24
DataView::value_type & value_ref(const DataView &data, int local_subdomain_id, int x, int y, int r, int d)
Definition buffer_copy_kernels.hpp:59
Definition buffer_copy_kernels.hpp:5
void copy_from_buffer_rotate_and_reduce(const grid::Grid0DDataVec< ScalarType, VecDim > &buffer, const ViewType &data, const int local_subdomain_id, const grid::BoundaryVertex boundary_vertex, const CommunicationReduction reduction)
Definition buffer_copy_kernels.hpp:404
std::enable_if_t< detail_view_constraints::is_kokkos_view_v< BufferView > &&detail_view_constraints::is_kokkos_view_v< ViewType > &&(std::decay_t< BufferView >::rank==1)> copy_to_buffer(const BufferView &buffer, const ViewType &data, const int local_subdomain_id, const grid::BoundaryVertex boundary_vertex)
Definition buffer_copy_kernels.hpp:125
CommunicationReduction
Communication reduction modes.
Definition buffer_copy_kernels.hpp:9
@ MAX
Stores the max of all received values during receive.
@ SUM
Sums up the node values during receive.
@ MIN
Stores the min of all received values during receive.
BoundaryPosition
Enum for encoding the boundary type tuples (in BoundaryVertex, BoundaryEdge, BoundaryFace).
Definition grid_types.hpp:96
BoundaryVertex
Enum for identification of the 8 boundary vertices of a subdomain.
Definition grid_types.hpp:121
BoundaryDirection
Enum for the iteration direction at a boundary.
Definition grid_types.hpp:184
Kokkos::View< ScalarType **[VecDim], Layout > Grid2DDataVec
Definition grid_types.hpp:37
Kokkos::View< ScalarType *[VecDim], Layout > Grid1DDataVec
Definition grid_types.hpp:34
constexpr BoundaryPosition boundary_position_from_boundary_type_y(const BoundaryType &boundary_type)
Definition grid_types.hpp:200
constexpr BoundaryPosition boundary_position_from_boundary_type_r(const BoundaryType &boundary_type)
Definition grid_types.hpp:210
Kokkos::View< ScalarType[VecDim], Layout > Grid0DDataVec
Definition grid_types.hpp:31
BoundaryFace
Enum for identification of the 6 boundary faces of a subdomain.
Definition grid_types.hpp:170
constexpr BoundaryPosition boundary_position_from_boundary_type_x(const BoundaryType &boundary_type)
Definition grid_types.hpp:190
BoundaryEdge
Enum for identification of the 12 boundary edges of a subdomain.
Definition grid_types.hpp:142