Cabana 0.8.0-dev
 
Loading...
Searching...
No Matches
Cabana_Slice.hpp
Go to the documentation of this file.
1/****************************************************************************
2 * Copyright (c) 2018-2023 by the Cabana authors *
3 * All rights reserved. *
4 * *
5 * This file is part of the Cabana library. Cabana is distributed under a *
6 * BSD 3-clause license. For the licensing terms see the LICENSE file in *
7 * the top-level directory. *
8 * *
9 * SPDX-License-Identifier: BSD-3-Clause *
10 ****************************************************************************/
11
16#ifndef CABANA_SLICE_HPP
17#define CABANA_SLICE_HPP
18
19#include <Cabana_Types.hpp>
20#include <Cabana_Utils.hpp>
21#include <impl/Cabana_Index.hpp>
22#include <impl/Cabana_TypeTraits.hpp>
23
24#include <Kokkos_Core.hpp>
25
26#include <cstdlib>
27#include <string>
28#include <type_traits>
29
30//---------------------------------------------------------------------------//
31namespace Kokkos
32{
33//---------------------------------------------------------------------------//
35template <int SOASTRIDE, int VLEN, int DIM0 = 0, int DIM1 = 0, int DIM2 = 0,
36 int DIM3 = 0, int DIM4 = 0, int DIM5 = 0>
38{
42 enum
43 {
44 is_extent_constructible = true
45 };
46
48 static constexpr int Stride = SOASTRIDE;
50 static constexpr int VectorLength = VLEN;
52 static constexpr int D0 = DIM0;
54 static constexpr int D1 = DIM1;
56 static constexpr int D2 = DIM2;
58 static constexpr int D3 = DIM3;
60 static constexpr int D4 = DIM4;
62 static constexpr int D5 = DIM5;
63
65 size_t dimension[ARRAY_LAYOUT_MAX_RANK];
66
75
77 KOKKOS_INLINE_FUNCTION
78 explicit constexpr LayoutCabanaSlice( size_t num_soa = 0,
79 size_t vector_length = VectorLength,
80 size_t d0 = D0, size_t d1 = D1,
81 size_t d2 = D2, size_t d3 = D3,
82 size_t d4 = D4, size_t d5 = D5 )
83 : dimension{ num_soa, vector_length, d0, d1, d2, d3, d4, d5 }
84 {
85 }
86};
87
88//---------------------------------------------------------------------------//
89namespace Impl
90{
92
93//---------------------------------------------------------------------------//
94// View offset of LayoutCabanaSlice.
95template <class Dimension, int... LayoutDims>
96struct ViewOffset<Dimension, Kokkos::LayoutCabanaSlice<LayoutDims...>, void>
97{
98 public:
99 using is_mapping_plugin = std::true_type;
100 using is_regular = std::true_type;
101
102 typedef size_t size_type;
103 typedef Dimension dimension_type;
104 typedef Kokkos::LayoutCabanaSlice<LayoutDims...> array_layout;
105
106 static constexpr int Stride = array_layout::Stride;
107 static constexpr int VectorLength = array_layout::VectorLength;
108 static constexpr int D0 = array_layout::D0;
109 static constexpr int D1 = array_layout::D1;
110 static constexpr int D2 = array_layout::D2;
111 static constexpr int D3 = array_layout::D3;
112 static constexpr int D4 = array_layout::D4;
113 static constexpr int D5 = array_layout::D5;
114
115 dimension_type m_dim;
116
117 //----------------------------------------
118
119 // rank 1
120 template <typename S>
121 KOKKOS_INLINE_FUNCTION constexpr size_type operator()( S const& s ) const
122 {
123 return Stride * s;
124 }
125
126 // rank 2
127 template <typename S, typename A>
128 KOKKOS_INLINE_FUNCTION constexpr size_type operator()( S const& s,
129 A const& a ) const
130 {
131 return Stride * s + a;
132 }
133
134 // rank 3
135 template <typename S, typename A, typename I0>
136 KOKKOS_INLINE_FUNCTION constexpr size_type
137 operator()( S const& s, A const& a, I0 const& i0 ) const
138 {
139 return Stride * s + a + VectorLength * i0;
140 }
141
142 // rank 4
143 template <typename S, typename A, typename I0, typename I1>
144 KOKKOS_INLINE_FUNCTION constexpr size_type
145 operator()( S const& s, A const& a, I0 const& i0, I1 const& i1 ) const
146 {
147 return Stride * s + a + VectorLength * ( i1 + D1 * i0 );
148 }
149
150 // rank 5
151 template <typename S, typename A, typename I0, typename I1, typename I2>
152 KOKKOS_INLINE_FUNCTION constexpr size_type
153 operator()( S const& s, A const& a, I0 const& i0, I1 const& i1,
154 I2 const& i2 ) const
155 {
156 return Stride * s + a + VectorLength * ( i2 + D2 * ( i1 + D1 * i0 ) );
157 }
158
159 // rank 6
160 template <typename S, typename A, typename I0, typename I1, typename I2,
161 typename I3>
162 KOKKOS_INLINE_FUNCTION constexpr size_type
163 operator()( S const& s, A const& a, I0 const& i0, I1 const& i1,
164 I2 const& i2, I3 const& i3 ) const
165 {
166 return Stride * s + a +
167 VectorLength * ( i3 + D3 * i2 + D2 * ( i1 + D1 * i0 ) );
168 }
169
170 // rank 7
171 template <typename S, typename A, typename I0, typename I1, typename I2,
172 typename I3, typename I4>
173 KOKKOS_INLINE_FUNCTION constexpr size_type
174 operator()( S const& s, A const& a, I0 const& i0, I1 const& i1,
175 I2 const& i2, I3 const& i3, I4 const& i4 ) const
176 {
177 return Stride * s + a +
178 VectorLength *
179 ( i4 + D4 * ( i3 + D3 * i2 + D2 * ( i1 + D1 * i0 ) ) );
180 }
181
182 // rank 8
183 template <typename S, typename A, typename I0, typename I1, typename I2,
184 typename I3, typename I4, typename I5>
185 KOKKOS_INLINE_FUNCTION constexpr size_type
186 operator()( S const& s, A const& a, I0 const& i0, I1 const& i1,
187 I2 const& i2, I3 const& i3, I4 const& i4, I5 const& i5 ) const
188 {
189 return Stride * s + a +
190 VectorLength *
191 ( i5 + D5 * ( i4 + D4 * ( i3 + D3 * i2 +
192 D2 * ( i1 + D1 * i0 ) ) ) );
193 }
194
195 //----------------------------------------
196
197 KOKKOS_INLINE_FUNCTION
198 constexpr array_layout layout() const { return array_layout( m_dim.N0 ); }
199
200 KOKKOS_INLINE_FUNCTION constexpr size_type dimension_0() const
201 {
202 return m_dim.N0;
203 }
204 KOKKOS_INLINE_FUNCTION constexpr size_type dimension_1() const
205 {
206 return m_dim.N1;
207 }
208 KOKKOS_INLINE_FUNCTION constexpr size_type dimension_2() const
209 {
210 return m_dim.N2;
211 }
212 KOKKOS_INLINE_FUNCTION constexpr size_type dimension_3() const
213 {
214 return m_dim.N3;
215 }
216 KOKKOS_INLINE_FUNCTION constexpr size_type dimension_4() const
217 {
218 return m_dim.N4;
219 }
220 KOKKOS_INLINE_FUNCTION constexpr size_type dimension_5() const
221 {
222 return m_dim.N5;
223 }
224 KOKKOS_INLINE_FUNCTION constexpr size_type dimension_6() const
225 {
226 return m_dim.N6;
227 }
228 KOKKOS_INLINE_FUNCTION constexpr size_type dimension_7() const
229 {
230 return m_dim.N7;
231 }
232
233 /* Cardinality of the domain index space */
234 KOKKOS_INLINE_FUNCTION
235 constexpr size_type size() const
236 {
237 return m_dim.N0 * m_dim.N1 * m_dim.N2 * m_dim.N3 * m_dim.N4 * m_dim.N5 *
238 m_dim.N6 * m_dim.N7;
239 }
240
241 /* Span of the range space, largest stride * dimension */
242 KOKKOS_INLINE_FUNCTION
243 constexpr size_type span() const { return m_dim.N0 * Stride; }
244
245 KOKKOS_INLINE_FUNCTION constexpr bool span_is_contiguous() const
246 {
247 return span() == size();
248 }
249
250 /* Strides of dimensions */
251 KOKKOS_INLINE_FUNCTION constexpr size_type stride_0() const
252 {
253 return Stride;
254 }
255
256 KOKKOS_INLINE_FUNCTION constexpr size_type stride_1() const { return 1; }
257
258 KOKKOS_INLINE_FUNCTION constexpr size_type stride_2() const
259 {
260 return m_dim.N7 * m_dim.N6 * m_dim.N5 * m_dim.N4 * m_dim.N3 *
261 VectorLength;
262 }
263
264 KOKKOS_INLINE_FUNCTION constexpr size_type stride_3() const
265 {
266 return m_dim.N7 * m_dim.N6 * m_dim.N5 * m_dim.N4 * VectorLength;
267 }
268
269 KOKKOS_INLINE_FUNCTION constexpr size_type stride_4() const
270 {
271 return m_dim.N7 * m_dim.N6 * m_dim.N5 * VectorLength;
272 }
273
274 KOKKOS_INLINE_FUNCTION constexpr size_type stride_5() const
275 {
276 return m_dim.N7 * m_dim.N6 * VectorLength;
277 }
278
279 KOKKOS_INLINE_FUNCTION constexpr size_type stride_6() const
280 {
281 return m_dim.N7 * VectorLength;
282 }
283
284 KOKKOS_INLINE_FUNCTION constexpr size_type stride_7() const
285 {
286 return VectorLength;
287 }
288
289 // Stride with [ rank ] value is the total length
290 template <typename iType>
291 KOKKOS_INLINE_FUNCTION void stride( iType* const s ) const
292 {
293 if ( 0 < dimension_type::rank )
294 {
295 s[0] = stride_0();
296 }
297 if ( 1 < dimension_type::rank )
298 {
299 s[1] = stride_1();
300 }
301 if ( 2 < dimension_type::rank )
302 {
303 s[2] = stride_2();
304 }
305 if ( 3 < dimension_type::rank )
306 {
307 s[3] = stride_3();
308 }
309 if ( 4 < dimension_type::rank )
310 {
311 s[4] = stride_4();
312 }
313 if ( 5 < dimension_type::rank )
314 {
315 s[5] = stride_5();
316 }
317 if ( 6 < dimension_type::rank )
318 {
319 s[6] = stride_6();
320 }
321 if ( 7 < dimension_type::rank )
322 {
323 s[7] = stride_7();
324 }
325 s[dimension_type::rank] = span();
326 }
327
328 //----------------------------------------
329
330 ViewOffset() = default;
331 ViewOffset( const ViewOffset& ) = default;
332 ViewOffset& operator=( const ViewOffset& ) = default;
333
334 KOKKOS_INLINE_FUNCTION
335 constexpr ViewOffset( std::integral_constant<unsigned, 0> const&,
336 Kokkos::LayoutCabanaSlice<LayoutDims...> const& rhs )
337 : m_dim( rhs.dimension[0], rhs.dimension[1], rhs.dimension[2],
338 rhs.dimension[3], rhs.dimension[4], rhs.dimension[5],
339 rhs.dimension[6], rhs.dimension[7] )
340 {
341 }
342
343 template <class DimRHS, class LayoutRHS>
344 KOKKOS_INLINE_FUNCTION constexpr ViewOffset(
345 const ViewOffset<DimRHS, LayoutRHS, void>& rhs )
346 : m_dim( rhs.m_dim.N0, rhs.m_dim.N1, rhs.m_dim.N2, rhs.m_dim.N3,
347 rhs.m_dim.N4, rhs.m_dim.N5, rhs.m_dim.N6, rhs.m_dim.N7 )
348 {
349 static_assert( int( DimRHS::rank ) == int( dimension_type::rank ),
350 "ViewOffset assignment requires equal rank" );
351 }
352
353 //----------------------------------------
354 // Subview construction
355
356 template <class DimRHS, class LayoutRHS>
357 KOKKOS_INLINE_FUNCTION constexpr ViewOffset(
358 const ViewOffset<DimRHS, LayoutRHS, void>&,
359 const SubviewExtents<DimRHS::rank, dimension_type::rank>& sub )
360 : m_dim( sub.range_extent( 0 ), sub.range_extent( 1 ),
361 sub.range_extent( 2 ), sub.range_extent( 3 ),
362 sub.range_extent( 4 ), sub.range_extent( 5 ),
363 sub.range_extent( 6 ), sub.range_extent( 7 ) )
364 {
365 }
366};
367
368//---------------------------------------------------------------------------//
369
371} // namespace Impl
372
373} // end namespace Kokkos
374
375//---------------------------------------------------------------------------//
376namespace Cabana
377{
378namespace Impl
379{
381
382//---------------------------------------------------------------------------//
383// Given a tuple member type T of the given rank get the Kokkos view
384// data layout parameters. The tuple index effectively introduces 2 new
385// dimensions to the problem on top of the member dimensions - one for the
386// struct index and one for the vector index.
387template <typename T, std::size_t Rank, int VectorLength, int Stride>
388struct KokkosDataTypeImpl;
389
390// Rank-0
391template <typename T, int VectorLength, int Stride>
392struct KokkosDataTypeImpl<T, 0, VectorLength, Stride>
393{
394 using value_type = typename std::remove_all_extents<T>::type;
395 using data_type = value_type* [VectorLength];
396 using cabana_layout = Kokkos::LayoutCabanaSlice<Stride, VectorLength>;
397
398 inline static cabana_layout createLayout( const std::size_t num_soa )
399 {
400 return cabana_layout( num_soa );
401 }
402};
403
404// Rank-1
405template <typename T, int VectorLength, int Stride>
406struct KokkosDataTypeImpl<T, 1, VectorLength, Stride>
407{
408 using value_type = typename std::remove_all_extents<T>::type;
409 static constexpr std::size_t D0 = std::extent<T, 0>::value;
410 using data_type = value_type* [VectorLength][D0];
411 using cabana_layout = Kokkos::LayoutCabanaSlice<Stride, VectorLength, D0>;
412
413 inline static cabana_layout createLayout( const std::size_t num_soa )
414 {
415 return cabana_layout( num_soa );
416 }
417};
418
419// Rank-2
420template <typename T, int VectorLength, int Stride>
421struct KokkosDataTypeImpl<T, 2, VectorLength, Stride>
422{
423 using value_type = typename std::remove_all_extents<T>::type;
424 static constexpr std::size_t D0 = std::extent<T, 0>::value;
425 static constexpr std::size_t D1 = std::extent<T, 1>::value;
426 using data_type = value_type* [VectorLength][D0][D1];
427 using cabana_layout =
428 Kokkos::LayoutCabanaSlice<Stride, VectorLength, D0, D1>;
429
430 inline static cabana_layout createLayout( const std::size_t num_soa )
431 {
432 return cabana_layout( num_soa );
433 }
434};
435
436// Rank-3
437template <typename T, int VectorLength, int Stride>
438struct KokkosDataTypeImpl<T, 3, VectorLength, Stride>
439{
440 using value_type = typename std::remove_all_extents<T>::type;
441 static constexpr std::size_t D0 = std::extent<T, 0>::value;
442 static constexpr std::size_t D1 = std::extent<T, 1>::value;
443 static constexpr std::size_t D2 = std::extent<T, 2>::value;
444 using data_type = value_type* [VectorLength][D0][D1][D2];
445 using cabana_layout =
446 Kokkos::LayoutCabanaSlice<Stride, VectorLength, D0, D1, D2>;
447
448 inline static cabana_layout createLayout( const std::size_t num_soa )
449 {
450 return cabana_layout( num_soa );
451 }
452};
453
454// Data type specialization.
455template <typename T, int VectorLength, int Stride>
456struct KokkosDataType
457{
458 using kokkos_data_type =
459 KokkosDataTypeImpl<T, std::rank<T>::value, VectorLength, Stride>;
460 using data_type = typename kokkos_data_type::data_type;
461 using cabana_layout = typename kokkos_data_type::cabana_layout;
462
463 inline static cabana_layout createLayout( const std::size_t num_soa )
464 {
465 return kokkos_data_type::createLayout( num_soa );
466 }
467};
468
469//---------------------------------------------------------------------------//
470// Kokkos view wrapper for tuple members
471template <typename T, int VectorLength, int Stride,
472 typename std::enable_if<
473 Impl::IsVectorLengthValid<VectorLength>::value, int>::type = 0>
474struct KokkosViewWrapper
475{
476 using data_type =
477 typename KokkosDataType<T, VectorLength, Stride>::data_type;
478
479 using cabana_layout =
480 typename KokkosDataType<T, VectorLength, Stride>::cabana_layout;
481
482 inline static cabana_layout createLayout( const std::size_t num_soa )
483 {
484 return KokkosDataType<T, VectorLength, Stride>::createLayout( num_soa );
485 }
486};
487
488//---------------------------------------------------------------------------//
489
491} // end namespace Impl
492
493//---------------------------------------------------------------------------//
498//---------------------------------------------------------------------------//
499template <typename DataType, typename MemorySpace, typename MemoryAccessType,
500 int VectorLength, int Stride>
501class Slice
502{
503 public:
504 // Ensure the vector length is valid.
505 static_assert( Impl::IsVectorLengthValid<VectorLength>::value,
506 "Vector length must be valid" );
507
511
513 using memory_space = MemorySpace;
514 static_assert( Kokkos::is_memory_space<MemorySpace>() );
515
517 using execution_space = typename memory_space::execution_space;
518
520 "Slice memory access type must be a Cabana access type" );
522 using memory_access_type = MemoryAccessType;
523
525 static constexpr int vector_length = VectorLength;
526
528 static constexpr int soa_stride = Stride;
529
531 using size_type = typename memory_space::size_type;
532
535
537 static constexpr std::size_t max_supported_rank = 3;
538
540 static constexpr std::size_t max_label_length = 128;
541
544 Impl::KokkosViewWrapper<DataType, vector_length, soa_stride>;
545
548 Kokkos::View<typename view_wrapper::data_type,
549 typename view_wrapper::cabana_layout, MemorySpace,
550 typename MemoryAccessType::kokkos_memory_traits>;
551
553 using reference_type = typename kokkos_view::reference_type;
555 using value_type = typename kokkos_view::value_type;
557 using pointer_type = typename kokkos_view::pointer_type;
559 using view_layout = typename kokkos_view::array_layout;
560
570
571 // Declare slices of different memory access types to be friends.
572 friend class Slice<DataType, MemorySpace, DefaultAccessMemory, VectorLength,
573 Stride>;
574 friend class Slice<DataType, MemorySpace, AtomicAccessMemory, VectorLength,
575 Stride>;
576 friend class Slice<DataType, MemorySpace, RandomAccessMemory, VectorLength,
577 Stride>;
578
579 // Equivalent Kokkos view rank. This rank assumes that the struct and
580 // array dimension are merged. For the true rank of the raw AoSoA data use
581 // the rank() function below which will account for the extra dimension
582 // from separate struct and array indices. This enumeration is for
583 // compatibility with Kokkos views.
584 enum
585 {
586 rank = std::rank<DataType>::value + 1
587 };
588
589 public:
594 : _size( 0 )
595 {
596 }
597
606 const size_type num_soa, const std::string& label = "" )
607 : _view( data, view_wrapper::createLayout( num_soa ) )
608 , _size( size )
609 {
610 std::strcpy( _label, label.c_str() );
611 }
612
620 template <class MAT>
622 : _view( rhs._view )
623 , _size( rhs._size )
624 {
625 std::strcpy( _label, rhs._label );
626 }
627
637 template <class MAT>
640 {
641 _view = rhs._view;
642 _size = rhs._size;
643 std::strcpy( _label, rhs._label );
644 return *this;
645 }
646
652 std::string label() const { return std::string( _label ); }
653
658 KOKKOS_INLINE_FUNCTION
659 size_type size() const { return _size; }
660
665 KOKKOS_INLINE_FUNCTION
666 size_type numSoA() const { return _view.extent( 0 ); }
667
673 KOKKOS_INLINE_FUNCTION
675 {
676 // Check if this is not the last struct index.
677 // If it isn't, the data array is guaranteed to be full.
678 if ( static_cast<size_type>( s ) < _view.extent( 0 ) - 1 )
679 {
680 return vector_length;
681 }
682 else
683 {
684 // This is the last struct index, which may be partially full.
685 // We calculate the remainder to see how many elements it holds.
686 const size_type rem = _size % vector_length;
687 // If rem is 0 and size is positive, the last chunk is full.
688 // Otherwise, the remainder is the correct size (e.g., for _size=0).
689 return ( rem == 0 && _size > 0 ) ? vector_length : rem;
690 }
691 }
692
693 // ------------
694 // 2-D accessor
695
697 template <typename U = DataType>
698 KOKKOS_FORCEINLINE_FUNCTION
699 typename std::enable_if<( 0 == std::rank<U>::value &&
700 std::is_same<U, DataType>::value ),
701 reference_type>::type
702 access( const size_type s, const size_type a ) const
703 {
704 return _view( s, a );
705 }
706
708 template <typename U = DataType>
709 KOKKOS_FORCEINLINE_FUNCTION
710 typename std::enable_if<( 1 == std::rank<U>::value &&
711 std::is_same<U, DataType>::value ),
712 reference_type>::type
713 access( const size_type s, const size_type a, const size_type d0 ) const
714 {
715 return _view( s, a, d0 );
716 }
717
719 template <typename U = DataType>
720 KOKKOS_FORCEINLINE_FUNCTION
721 typename std::enable_if<( 2 == std::rank<U>::value &&
722 std::is_same<U, DataType>::value ),
723 reference_type>::type
724 access( const size_type s, const size_type a, const size_type d0,
725 const size_type d1 ) const
726 {
727 return _view( s, a, d0, d1 );
728 }
729
731 template <typename U = DataType>
732 KOKKOS_FORCEINLINE_FUNCTION
733 typename std::enable_if<( 3 == std::rank<U>::value &&
734 std::is_same<U, DataType>::value ),
735 reference_type>::type
736 access( const size_type s, const size_type a, const size_type d0,
737 const size_type d1, const size_type d2 ) const
738 {
739 return _view( s, a, d0, d1, d2 );
740 }
741
742 // ------------
743 // 1-D accessor
744
746 template <typename U = DataType>
747 KOKKOS_FORCEINLINE_FUNCTION
748 typename std::enable_if<( 0 == std::rank<U>::value &&
749 std::is_same<U, DataType>::value ),
750 reference_type>::type
751 operator()( const size_type i ) const
752 {
753 return access( index_type::s( i ), index_type::a( i ) );
754 }
755
757 template <typename U = DataType>
758 KOKKOS_FORCEINLINE_FUNCTION
759 typename std::enable_if<( 1 == std::rank<U>::value &&
760 std::is_same<U, DataType>::value ),
761 reference_type>::type
762 operator()( const size_type i, const size_type d0 ) const
763 {
764 return access( index_type::s( i ), index_type::a( i ), d0 );
765 }
766
768 template <typename U = DataType>
769 KOKKOS_FORCEINLINE_FUNCTION
770 typename std::enable_if<( 2 == std::rank<U>::value &&
771 std::is_same<U, DataType>::value ),
772 reference_type>::type
773 operator()( const size_type i, const size_type d0,
774 const size_type d1 ) const
775 {
776 return access( index_type::s( i ), index_type::a( i ), d0, d1 );
777 }
778
780 template <typename U = DataType>
781 KOKKOS_FORCEINLINE_FUNCTION
782 typename std::enable_if<( 3 == std::rank<U>::value &&
783 std::is_same<U, DataType>::value ),
784 reference_type>::type
785 operator()( const size_type i, const size_type d0, const size_type d1,
786 const size_type d2 ) const
787 {
788 return access( index_type::s( i ), index_type::a( i ), d0, d1, d2 );
789 }
790
791 // -------------------------------
792 // Raw data access.
793
798 KOKKOS_INLINE_FUNCTION
799 pointer_type data() const { return _view.data(); }
800
807 KOKKOS_INLINE_FUNCTION
808 constexpr size_type viewRank() const { return _view.rank; }
809
817 KOKKOS_INLINE_FUNCTION
818 size_type extent( const size_type d ) const { return _view.extent( d ); }
819
826 KOKKOS_INLINE_FUNCTION
827 size_type stride( const size_type d ) const { return _view.stride( d ); }
828
832 KOKKOS_INLINE_FUNCTION
833 kokkos_view view() const { return _view; }
834
835 private:
836 // The data view. This view is unmanaged and has access traits specified
837 // by the template parameters of this class.
838 kokkos_view _view;
839
840 // Number of tuples in the slice.
841 size_type _size;
842
843 // Slice label.
844 char _label[max_label_length];
845};
846
847//---------------------------------------------------------------------------//
849template <typename>
850struct is_slice_impl : public std::false_type
851{
852};
853
854// True only if the type is a member slice *AND* the member slice is templated
855// on an AoSoA type.
856template <typename DataType, typename MemorySpace, typename MemoryAccessType,
857 int VectorLength, int Stride>
858struct is_slice_impl<
859 Slice<DataType, MemorySpace, MemoryAccessType, VectorLength, Stride>>
860 : public std::true_type
861{
862};
864
866template <class T>
867struct is_slice : public is_slice_impl<typename std::remove_cv<T>::type>::type
868{
869};
870
871//---------------------------------------------------------------------------//
872// Copy to View.
873//---------------------------------------------------------------------------//
874
876template <class ExecutionSpace, class ViewType, class SliceType>
878 ExecutionSpace exec_space, ViewType& view, const SliceType& slice,
879 const std::size_t begin, const std::size_t end,
880 typename std::enable_if<
881 2 == SliceType::kokkos_view::traits::dimension::rank, int*>::type = 0 )
882{
883 Kokkos::parallel_for(
884 "Cabana::copySliceToView::Rank0",
885 Kokkos::RangePolicy<ExecutionSpace>( exec_space, begin, end ),
886 KOKKOS_LAMBDA( const int i ) { view( i - begin ) = slice( i ); } );
887}
888
890template <class ExecutionSpace, class ViewType, class SliceType>
892 ExecutionSpace exec_space, ViewType& view, const SliceType& slice,
893 const std::size_t begin, const std::size_t end,
894 typename std::enable_if<
895 3 == SliceType::kokkos_view::traits::dimension::rank, int*>::type = 0 )
896{
897 Kokkos::parallel_for(
898 "Cabana::copySliceToView::Rank1",
899 Kokkos::RangePolicy<ExecutionSpace>( exec_space, begin, end ),
900 KOKKOS_LAMBDA( const int i ) {
901 for ( std::size_t d0 = 0; d0 < slice.extent( 2 ); ++d0 )
902 view( i - begin, d0 ) = slice( i, d0 );
903 } );
904}
905
907template <class ExecutionSpace, class ViewType, class SliceType>
909 ExecutionSpace exec_space, ViewType& view, const SliceType& slice,
910 const std::size_t begin, const std::size_t end,
911 typename std::enable_if<
912 4 == SliceType::kokkos_view::traits::dimension::rank, int*>::type = 0 )
913{
914 Kokkos::parallel_for(
915 "Cabana::copySliceToView::Rank2",
916 Kokkos::RangePolicy<ExecutionSpace>( exec_space, begin, end ),
917 KOKKOS_LAMBDA( const int i ) {
918 for ( std::size_t d0 = 0; d0 < slice.extent( 2 ); ++d0 )
919 for ( std::size_t d1 = 0; d1 < slice.extent( 3 ); ++d1 )
920 view( i - begin, d0, d1 ) = slice( i, d0, d1 );
921 } );
922}
923
925template <class ViewType, class SliceType>
926void copySliceToView( ViewType& view, const SliceType& slice,
927 const std::size_t begin, const std::size_t end )
928{
929 using exec_space = typename SliceType::execution_space;
930 copySliceToView( exec_space{}, view, slice, begin, end );
931}
932
933//---------------------------------------------------------------------------//
934// Copy from View.
935//---------------------------------------------------------------------------//
936
938template <class ExecutionSpace, class SliceType, class ViewType>
940 ExecutionSpace exec_space, SliceType& slice, const ViewType& view,
941 const std::size_t begin, const std::size_t end,
942 typename std::enable_if<
943 2 == SliceType::kokkos_view::traits::dimension::rank, int*>::type = 0 )
944{
945 Kokkos::parallel_for(
946 "Cabana::copyViewToSlice::Rank0",
947 Kokkos::RangePolicy<ExecutionSpace>( exec_space, begin, end ),
948 KOKKOS_LAMBDA( const int i ) { slice( i - begin ) = view( i ); } );
949}
950
952template <class ExecutionSpace, class SliceType, class ViewType>
954 ExecutionSpace exec_space, SliceType& slice, const ViewType& view,
955 const std::size_t begin, const std::size_t end,
956 typename std::enable_if<
957 3 == SliceType::kokkos_view::traits::dimension::rank, int*>::type = 0 )
958{
959 Kokkos::parallel_for(
960 "Cabana::copyViewToSlice::Rank1",
961 Kokkos::RangePolicy<ExecutionSpace>( exec_space, begin, end ),
962 KOKKOS_LAMBDA( const int i ) {
963 for ( std::size_t d0 = 0; d0 < slice.extent( 2 ); ++d0 )
964 slice( i - begin, d0 ) = view( i, d0 );
965 } );
966}
967
969template <class ExecutionSpace, class SliceType, class ViewType>
971 ExecutionSpace exec_space, SliceType& slice, const ViewType& view,
972 const std::size_t begin, const std::size_t end,
973 typename std::enable_if<
974 4 == SliceType::kokkos_view::traits::dimension::rank, int*>::type = 0 )
975{
976 Kokkos::parallel_for(
977 "Cabana::copyViewToSlice::Rank2",
978 Kokkos::RangePolicy<ExecutionSpace>( exec_space, begin, end ),
979 KOKKOS_LAMBDA( const int i ) {
980 for ( std::size_t d0 = 0; d0 < slice.extent( 2 ); ++d0 )
981 for ( std::size_t d1 = 0; d1 < slice.extent( 3 ); ++d1 )
982 slice( i - begin, d0, d1 ) = view( i, d0, d1 );
983 } );
984}
985
987template <class ViewType, class SliceType>
988void copyViewToSlice( SliceType& slice, const ViewType& view,
989 const std::size_t begin, const std::size_t end )
990{
991 using exec_space = typename SliceType::execution_space;
992 copyViewToSlice( exec_space{}, slice, view, begin, end );
993}
994
996template <class SliceType>
998 [[maybe_unused]] SliceType slice, [[maybe_unused]] const std::size_t size,
999 typename std::enable_if<is_slice<SliceType>::value, int>::type* = 0 )
1000{
1001 // Allow unused for release builds.
1002 assert( slice.size() == size );
1003}
1004
1006template <class ViewType>
1008 [[maybe_unused]] ViewType view, [[maybe_unused]] const std::size_t size,
1009 typename std::enable_if<Kokkos::is_view<ViewType>::value, int>::type* = 0 )
1010{
1011 // Allow unused for release builds.
1012 assert( view.extent( 0 ) == size );
1013}
1014
1015//---------------------------------------------------------------------------//
1016
1018template <class SliceType>
1019auto size( SliceType slice,
1020 typename std::enable_if<is_slice<SliceType>::value, int>::type* = 0 )
1021{
1022 return slice.size();
1023}
1024
1026template <class ViewType>
1027auto size(
1028 ViewType view,
1029 typename std::enable_if<Kokkos::is_view<ViewType>::value, int>::type* = 0 )
1030{
1031 return view.extent( 0 );
1032}
1033
1034} // end namespace Cabana
1035
1036//---------------------------------------------------------------------------//
1037
1038#endif // end CABANA_SLICE_HPP
AoSoA indexing.
Memory access type checking.
Cabana utilities.
Class for converting between 1d and 2d aosoa indices.
Definition Cabana_Index.hpp:38
static KOKKOS_FORCEINLINE_FUNCTION constexpr std::size_t a(const std::size_t i)
Definition Cabana_Index.hpp:77
static KOKKOS_FORCEINLINE_FUNCTION constexpr std::size_t s(const std::size_t i)
Definition Cabana_Index.hpp:62
A slice of an array-of-structs-of-arrays with data access to a single multidimensional member.
Definition Cabana_Slice.hpp:502
KOKKOS_FORCEINLINE_FUNCTION std::enable_if<(3==std::rank< U >::value &&std::is_same< U, DataType >::value), reference_type >::type access(const size_type s, const size_type a, const size_type d0, const size_type d1, const size_type d2) const
2d access for Rank 3
Definition Cabana_Slice.hpp:736
Slice & operator=(const Slice< DataType, MemorySpace, MAT, VectorLength, Stride > &rhs)
Assignment operator for different memory spaces for assigning new memory access traits to the view.
Definition Cabana_Slice.hpp:638
Slice< member_data_type< M >, memory_space, RandomAccessMemory, VectorLength, Stride > random_access_slice
Definition Cabana_Slice.hpp:568
KOKKOS_FORCEINLINE_FUNCTION std::enable_if<(0==std::rank< U >::value &&std::is_same< U, DataType >::value), reference_type >::type access(const size_type s, const size_type a) const
2d access for Rank 0
Definition Cabana_Slice.hpp:702
KOKKOS_INLINE_FUNCTION size_type stride(const size_type d) const
Get the stride of a given raw slice dimension. This includes the struct dimension,...
Definition Cabana_Slice.hpp:827
Slice(const pointer_type data, const size_type size, const size_type num_soa, const std::string &label="")
Constructor.
Definition Cabana_Slice.hpp:605
KOKKOS_INLINE_FUNCTION size_type arraySize(const size_type s) const
Get the size of the data array at a given struct member index.
Definition Cabana_Slice.hpp:674
KOKKOS_INLINE_FUNCTION constexpr size_type viewRank() const
Get the rank of the raw data for this slice. This includes the struct dimension, array dimension,...
Definition Cabana_Slice.hpp:808
KOKKOS_FORCEINLINE_FUNCTION std::enable_if<(1==std::rank< U >::value &&std::is_same< U, DataType >::value), reference_type >::type access(const size_type s, const size_type a, const size_type d0) const
2d access for Rank 1
Definition Cabana_Slice.hpp:713
Slice< member_data_type< M >, memory_space, DefaultAccessMemory, VectorLength, Stride > default_access_slice
Definition Cabana_Slice.hpp:562
Slice< member_data_type< M >, memory_space, AtomicAccessMemory, VectorLength, Stride > atomic_access_slice
Definition Cabana_Slice.hpp:565
Slice()
Default constructor.
Definition Cabana_Slice.hpp:593
Slice(const Slice< DataType, MemorySpace, MAT, VectorLength, Stride > &rhs)
Shallow copy constructor for different memory spaces for assigning new memory access traits to the vi...
Definition Cabana_Slice.hpp:621
KOKKOS_FORCEINLINE_FUNCTION std::enable_if<(2==std::rank< U >::value &&std::is_same< U, DataType >::value), reference_type >::type access(const size_type s, const size_type a, const size_type d0, const size_type d1) const
2d access for Rank 2
Definition Cabana_Slice.hpp:724
KOKKOS_INLINE_FUNCTION size_type extent(const size_type d) const
Get the extent of a given raw slice data dimension. This includes the struct dimension,...
Definition Cabana_Slice.hpp:818
KOKKOS_INLINE_FUNCTION kokkos_view view() const
Get the underlying Kokkos View managing the slice data.
Definition Cabana_Slice.hpp:833
KOKKOS_INLINE_FUNCTION size_type numSoA() const
Get the number of structs-of-arrays in the container.
Definition Cabana_Slice.hpp:666
Slice< member_data_type< M >, memory_space, DefaultAccessMemory, VectorLength, Stride > slice_type
Definition Cabana_Slice.hpp:509
Kokkos::View< typename view_wrapper::data_type, typename view_wrapper::cabana_layout, memory_space, typename DefaultAccessMemory::kokkos_memory_traits > kokkos_view
Definition Cabana_Slice.hpp:547
Impl::KokkosViewWrapper< member_data_type< M >, vector_length, soa_stride > view_wrapper
Definition Cabana_Slice.hpp:543
Core: particle data structures and algorithms.
Definition Cabana_AoSoA.hpp:36
auto size(SliceType slice, typename std::enable_if< is_slice< SliceType >::value, int >::type *=0)
Check slice size (differs from Kokkos View).
Definition Cabana_Slice.hpp:1019
void copyViewToSlice(ExecutionSpace exec_space, SliceType &slice, const ViewType &view, const std::size_t begin, const std::size_t end, typename std::enable_if< 2==SliceType::kokkos_view::traits::dimension::rank, int * >::type=0)
Copy from View to slice. Rank-0.
Definition Cabana_Slice.hpp:939
void copySliceToView(ExecutionSpace exec_space, ViewType &view, const SliceType &slice, const std::size_t begin, const std::size_t end, typename std::enable_if< 2==SliceType::kokkos_view::traits::dimension::rank, int * >::type=0)
Copy from slice to View. Rank-0.
Definition Cabana_Slice.hpp:877
AoSoA_t::template member_slice_type< M > slice(const AoSoA_t &aosoa, const std::string &slice_label="")
Create a slice from an AoSoA.
Definition Cabana_AoSoA.hpp:77
void checkSize(SliceType slice, const std::size_t size, typename std::enable_if< is_slice< SliceType >::value, int >::type *=0)
Check slice size (differs from Kokkos View).
Definition Cabana_Slice.hpp:997
Atomic memory access. All reads and writes are atomic.
Definition Cabana_Types.hpp:70
Definition Cabana_Types.hpp:37
Random access memory. Read-only and const with limited spatial locality.
Definition Cabana_Types.hpp:54
Memory access type checker.
Definition Cabana_Types.hpp:31
Slice static type checker.
Definition Cabana_Slice.hpp:868
Cabana Slice layout.
Definition Cabana_Slice.hpp:38
LayoutCabanaSlice & operator=(LayoutCabanaSlice const &)=default
Const assignment operator.
static constexpr int Stride
Slice SoA stride.
Definition Cabana_Slice.hpp:48
static constexpr int D0
Slice zeroth dimension size.
Definition Cabana_Slice.hpp:52
static constexpr int D4
Slice fourth dimension size.
Definition Cabana_Slice.hpp:60
LayoutCabanaSlice array_layout
Slice array layout.
Definition Cabana_Slice.hpp:40
static constexpr int D5
Slice fifth dimension size.
Definition Cabana_Slice.hpp:62
LayoutCabanaSlice(LayoutCabanaSlice &&)=default
Copy constructor.
static constexpr int D2
Slice second dimension size.
Definition Cabana_Slice.hpp:56
size_t dimension[ARRAY_LAYOUT_MAX_RANK]
Slice dimension.
Definition Cabana_Slice.hpp:65
LayoutCabanaSlice(LayoutCabanaSlice const &)=default
Const copy constructor.
LayoutCabanaSlice & operator=(LayoutCabanaSlice &&)=default
Assignment operator.
static constexpr int VectorLength
Slice vectorlength.
Definition Cabana_Slice.hpp:50
static constexpr int D1
Slice first dimension size.
Definition Cabana_Slice.hpp:54
static constexpr int D3
Slice third dimension size.
Definition Cabana_Slice.hpp:58
KOKKOS_INLINE_FUNCTION constexpr LayoutCabanaSlice(size_t num_soa=0, size_t vector_length=VectorLength, size_t d0=D0, size_t d1=D1, size_t d2=D2, size_t d3=D3, size_t d4=D4, size_t d5=D5)
Constructor.
Definition Cabana_Slice.hpp:78