23template <
typename T >
28 Kokkos::atomic_add( ptr, val );
32 Kokkos::atomic_min( ptr, val );
36 Kokkos::atomic_max( ptr, val );
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 )
47 if constexpr ( is_scalar )
49 return data( local_subdomain_id, x, y, r );
53 return data( local_subdomain_id, x, y, r, d );
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 )
61 if constexpr ( is_scalar )
63 return data( local_subdomain_id, x, y, r );
67 return data( local_subdomain_id, x, y, r, d );
73 idx(
const int loop_idx,
94 return size - 1 - loop_idx;
101namespace detail_view_constraints {
106template <
class... Args>
119template <
int VecDim,
typename BufferView,
typename ViewType >
123 (std::decay_t<BufferView>::rank == 1)
126 const BufferView& buffer,
127 const ViewType& data,
128 const int local_subdomain_id,
131 using ScalarType =
typename std::decay_t<BufferView>::value_type;
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)." );
137 constexpr bool is_scalar = (std::decay_t<ViewType>::rank == 4);
139 if ( buffer.extent( 0 ) != VecDim )
140 Kokkos::abort(
"The buffer VecDim should match its respective extent. This abort should not happen." );
146 const auto size_x = data.extent( 1 );
147 const auto size_y = data.extent( 2 );
148 const auto size_r = data.extent( 3 );
150 Kokkos::parallel_for(
152 Kokkos::RangePolicy( 0, buffer.extent( 0 ) ),
153 KOKKOS_LAMBDA(
const int d ) {
157 buffer( d ) = detail::value< ViewType, is_scalar >( data, local_subdomain_id, x, y, r, d );
166template <
int VecDim,
typename BufferView,
typename ViewType >
170 (std::decay_t<BufferView>::rank == 2)
173 const BufferView& buffer,
174 const ViewType& data,
175 const int local_subdomain_id,
178 using ScalarType =
typename std::decay_t<BufferView>::value_type;
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)." );
183 constexpr bool is_scalar = (std::decay_t<ViewType>::rank == 4);
185 if ( buffer.extent( 1 ) != VecDim )
186 Kokkos::abort(
"The buffer VecDim should match its respective extent. This abort should not happen." );
192 const auto size_x = data.extent( 1 );
193 const auto size_y = data.extent( 2 );
194 const auto size_r = data.extent( 3 );
196 Kokkos::parallel_for(
198 Kokkos::MDRangePolicy( { 0, 0 }, { buffer.extent( 0 ), buffer.extent( 1 ) } ),
199 KOKKOS_LAMBDA(
const int idx,
const int d ) {
203 buffer( idx, d ) = detail::value< ViewType, is_scalar >( data, local_subdomain_id, x, y, r, d );
212template <
int VecDim,
typename BufferView,
typename ViewType >
216 (std::decay_t<BufferView>::rank == 3)
219 const BufferView& buffer,
220 const ViewType& data,
221 const int local_subdomain_id,
224 using ScalarType =
typename std::decay_t<BufferView>::value_type;
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)." );
229 constexpr bool is_scalar = (std::decay_t<ViewType>::rank == 4);
231 if ( buffer.extent( 2 ) != VecDim )
232 Kokkos::abort(
"The buffer VecDim should match its respective extent. This abort should not happen." );
238 const auto size_x = data.extent( 1 );
239 const auto size_y = data.extent( 2 );
240 const auto size_r = data.extent( 3 );
242 Kokkos::parallel_for(
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;
267 buffer( i, j, d ) = detail::value< ViewType, is_scalar >( data, local_subdomain_id, x, y, r, d );
271template <
typename ScalarType,
int VecDim,
typename ViewType >
274 const ViewType& data,
275 const int local_subdomain_id,
279 std::is_same_v< ViewType, grid::Grid4DDataScalar< ScalarType > > ||
280 std::is_same_v< ViewType, grid::Grid4DDataVec< ScalarType, VecDim > > );
282 constexpr bool is_scalar = std::is_same_v< ViewType, grid::Grid4DDataScalar< ScalarType > >;
284 if ( buffer.extent( 0 ) != VecDim )
286 Kokkos::abort(
"The buffer VecDim should match its respective extent. This abort should not happen." );
293 const auto size_x = data.extent( 1 );
294 const auto size_y = data.extent( 2 );
295 const auto size_r = data.extent( 3 );
297 Kokkos::parallel_for(
298 "copy_to_buffer_0D", Kokkos::RangePolicy( 0, buffer.extent( 0 ) ), KOKKOS_LAMBDA(
const int d ) {
302 buffer( d ) = detail::value< ViewType, is_scalar >( data, local_subdomain_id, x, y, r, d );
306template <
typename ScalarType,
int VecDim,
typename ViewType >
309 const ViewType& data,
310 const int local_subdomain_id,
314 std::is_same_v< ViewType, grid::Grid4DDataScalar< ScalarType > > ||
315 std::is_same_v< ViewType, grid::Grid4DDataVec< ScalarType, VecDim > > );
317 constexpr bool is_scalar = std::is_same_v< ViewType, grid::Grid4DDataScalar< ScalarType > >;
319 if ( buffer.extent( 1 ) != VecDim )
321 Kokkos::abort(
"The buffer VecDim should match its respective extent. This abort should not happen." );
328 const auto size_x = data.extent( 1 );
329 const auto size_y = data.extent( 2 );
330 const auto size_r = data.extent( 3 );
332 Kokkos::parallel_for(
334 Kokkos::MDRangePolicy( { 0, 0 }, { buffer.extent( 0 ), buffer.extent( 1 ) } ),
335 KOKKOS_LAMBDA(
const int idx,
const int d ) {
339 buffer( idx, d ) = detail::value< ViewType, is_scalar >( data, local_subdomain_id, x, y, r, d );
343template <
typename ScalarType,
int VecDim,
typename ViewType >
346 const ViewType& data,
347 const int local_subdomain_id,
351 std::is_same_v< ViewType, grid::Grid4DDataScalar< ScalarType > > ||
352 std::is_same_v< ViewType, grid::Grid4DDataVec< ScalarType, VecDim > > );
354 constexpr bool is_scalar = std::is_same_v< ViewType, grid::Grid4DDataScalar< ScalarType > >;
356 if ( buffer.extent( 2 ) != VecDim )
358 Kokkos::abort(
"The buffer VecDim should match its respective extent. This abort should not happen." );
365 const auto size_x = data.extent( 1 );
366 const auto size_y = data.extent( 2 );
367 const auto size_r = data.extent( 3 );
369 Kokkos::parallel_for(
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 ) {
399 buffer( i, j, d ) = detail::value< ViewType, is_scalar >( data, local_subdomain_id, x, y, r, d );
403template <
typename ScalarType,
int VecDim,
typename ViewType >
406 const ViewType& data,
407 const int local_subdomain_id,
412 constexpr bool is_scalar = std::is_same_v< ViewType, grid::Grid4DDataScalar< ScalarType > >;
414 if ( buffer.extent( 0 ) != VecDim )
416 Kokkos::abort(
"The buffer VecDim should match its respective extent. This abort should not happen." );
423 const auto size_x = data.extent( 1 );
424 const auto size_y = data.extent( 2 );
425 const auto size_r = data.extent( 3 );
427 Kokkos::parallel_for(
428 "copy_from_buffer_0D", Kokkos::RangePolicy( 0, buffer.extent( 0 ) ), KOKKOS_LAMBDA(
const int d ) {
433 &detail::value_ref< ViewType, is_scalar >( data, local_subdomain_id, x, y, r, d ),
439template <
typename ScalarType,
int VecDim,
typename ViewType >
442 const ViewType& data,
443 const int local_subdomain_id,
448 constexpr bool is_scalar = std::is_same_v< ViewType, grid::Grid4DDataScalar< ScalarType > >;
450 if ( buffer.extent( 1 ) != VecDim )
452 Kokkos::abort(
"The buffer VecDim should match its respective extent. This abort should not happen." );
459 const auto size_x = data.extent( 1 );
460 const auto size_y = data.extent( 2 );
461 const auto size_r = data.extent( 3 );
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 ),
477template <
typename ScalarType,
int VecDim,
typename ViewType >
480 const ViewType& data,
481 const int local_subdomain_id,
483 const std::tuple< grid::BoundaryDirection, grid::BoundaryDirection > boundary_directions,
487 constexpr bool is_scalar = std::is_same_v< ViewType, grid::Grid4DDataScalar< ScalarType > >;
489 if ( buffer.extent( 2 ) != VecDim )
491 Kokkos::abort(
"The buffer VecDim should match its respective extent. This abort should not happen." );
498 const auto size_x = data.extent( 1 );
499 const auto size_y = data.extent( 2 );
500 const auto size_r = data.extent( 3 );
502 const auto boundary_direction_0 = std::get< 0 >( boundary_directions );
503 const auto boundary_direction_1 = std::get< 1 >( boundary_directions );
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 ) {
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 );
521 x =
detail::idx( i, size_x, boundary_position_x, boundary_direction_0 );
523 r =
detail::idx( j, size_r, boundary_position_r, boundary_direction_1 );
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 );
533 &detail::value_ref< ViewType, is_scalar >( data, local_subdomain_id, x, y, r, d ),
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
Definition buffer_copy_kernels.hpp:104