47 #ifndef KOKKOS_LAYOUT_HPP
48 #define KOKKOS_LAYOUT_HPP
51 #include <impl/Kokkos_Traits.hpp>
52 #include <impl/Kokkos_Tags.hpp>
56 enum { ARRAY_LAYOUT_MAX_RANK = 8 };
77 size_t dimension[ ARRAY_LAYOUT_MAX_RANK ];
79 enum { is_extent_constructible =
true };
86 KOKKOS_INLINE_FUNCTION
88 LayoutLeft(
size_t N0 = 0 ,
size_t N1 = 0 ,
size_t N2 = 0 ,
size_t N3 = 0
89 ,
size_t N4 = 0 ,
size_t N5 = 0 ,
size_t N6 = 0 ,
size_t N7 = 0 )
90 : dimension { N0 , N1 , N2 , N3 , N4 , N5 , N6 , N7 } {}
111 size_t dimension[ ARRAY_LAYOUT_MAX_RANK ];
113 enum { is_extent_constructible =
true };
120 KOKKOS_INLINE_FUNCTION
122 LayoutRight(
size_t N0 = 0 ,
size_t N1 = 0 ,
size_t N2 = 0 ,
size_t N3 = 0
123 ,
size_t N4 = 0 ,
size_t N5 = 0 ,
size_t N6 = 0 ,
size_t N7 = 0 )
124 : dimension { N0 , N1 , N2 , N3 , N4 , N5 , N6 , N7 } {}
136 size_t dimension[ ARRAY_LAYOUT_MAX_RANK ] ;
137 size_t stride[ ARRAY_LAYOUT_MAX_RANK ] ;
139 enum { is_extent_constructible =
false };
153 template<
typename iTypeOrder ,
typename iTypeDimen >
154 KOKKOS_INLINE_FUNCTION
static
156 , iTypeOrder
const *
const order
157 , iTypeDimen
const *
const dimen )
161 int check_input = ARRAY_LAYOUT_MAX_RANK < rank ? 0 : int( 1 << rank ) - 1 ;
162 for (
int r = 0 ; r < ARRAY_LAYOUT_MAX_RANK ; ++r ) {
163 tmp.dimension[r] = 0 ;
166 for (
int r = 0 ; r <
rank ; ++r ) {
167 check_input &= ~int( 1 << order[r] );
169 if ( 0 == check_input ) {
171 for (
int r = 0 ; r <
rank ; ++r ) {
172 tmp.stride[ order[r] ] = n ;
173 n *= ( dimen[order[r]] );
174 tmp.dimension[r] = dimen[r];
180 KOKKOS_INLINE_FUNCTION
183 ,
size_t N1 = 0 ,
size_t S1 = 0
184 ,
size_t N2 = 0 ,
size_t S2 = 0
185 ,
size_t N3 = 0 ,
size_t S3 = 0
186 ,
size_t N4 = 0 ,
size_t S4 = 0
187 ,
size_t N5 = 0 ,
size_t S5 = 0
188 ,
size_t N6 = 0 ,
size_t S6 = 0
189 ,
size_t N7 = 0 ,
size_t S7 = 0
191 : dimension { N0 , N1 , N2 , N3 , N4 , N5 , N6 , N7 }
192 , stride { S0 , S1 , S2 , S3 , S4 , S5 , S6 , S7 }
213 template <
unsigned ArgN0 ,
unsigned ArgN1 ,
214 bool IsPowerOfTwo = ( Impl::is_integral_power_of_two(ArgN0) &&
215 Impl::is_integral_power_of_two(ArgN1) )
219 static_assert( Impl::is_integral_power_of_two(ArgN0) &&
220 Impl::is_integral_power_of_two(ArgN1)
221 ,
"LayoutTileLeft must be given power-of-two tile dimensions" );
229 size_t dimension[ ARRAY_LAYOUT_MAX_RANK ] ;
231 enum { is_extent_constructible =
true };
233 LayoutTileLeft( LayoutTileLeft
const & ) = default ;
234 LayoutTileLeft( LayoutTileLeft && ) = default ;
235 LayoutTileLeft & operator = ( LayoutTileLeft
const & ) = default ;
236 LayoutTileLeft & operator = ( LayoutTileLeft && ) = default ;
238 KOKKOS_INLINE_FUNCTION
240 LayoutTileLeft(
size_t argN0 = 0 ,
size_t argN1 = 0 ,
size_t argN2 = 0 ,
size_t argN3 = 0
241 ,
size_t argN4 = 0 ,
size_t argN5 = 0 ,
size_t argN6 = 0 ,
size_t argN7 = 0
243 : dimension { argN0 , argN1 , argN2 , argN3 , argN4 , argN5 , argN6 , argN7 } {}
258 template <
typename LayoutTiledCheck,
class Enable =
void >
259 struct is_layouttiled : std::false_type {};
261 #ifndef KOKKOS_ENABLE_DEPRECATED_CODE
262 template <
typename LayoutTiledCheck >
263 struct is_layouttiled< LayoutTiledCheck, typename std::enable_if<LayoutTiledCheck::is_array_layout_tiled>::type > : std::true_type {};
265 namespace Experimental {
269 template < Kokkos::Iterate OuterP, Kokkos::Iterate InnerP,
270 unsigned ArgN0 ,
unsigned ArgN1 ,
unsigned ArgN2 = 0,
unsigned ArgN3 = 0,
unsigned ArgN4 = 0,
unsigned ArgN5 = 0,
unsigned ArgN6 = 0,
unsigned ArgN7 = 0,
272 ( Impl::is_integral_power_of_two(ArgN0) &&
273 Impl::is_integral_power_of_two(ArgN1) &&
274 (Impl::is_integral_power_of_two(ArgN2) || (ArgN2 == 0) ) &&
275 (Impl::is_integral_power_of_two(ArgN3) || (ArgN3 == 0) ) &&
276 (Impl::is_integral_power_of_two(ArgN4) || (ArgN4 == 0) ) &&
277 (Impl::is_integral_power_of_two(ArgN5) || (ArgN5 == 0) ) &&
278 (Impl::is_integral_power_of_two(ArgN6) || (ArgN6 == 0) ) &&
279 (Impl::is_integral_power_of_two(ArgN7) || (ArgN7 == 0) )
284 static_assert( IsPowerOfTwo
285 ,
"LayoutTiled must be given power-of-two tile dimensions" );
288 static_assert( (Impl::is_integral_power_of_two(ArgN0) ) &&
289 (Impl::is_integral_power_of_two(ArgN1) ) &&
290 (Impl::is_integral_power_of_two(ArgN2) || (ArgN2 == 0) ) &&
291 (Impl::is_integral_power_of_two(ArgN3) || (ArgN3 == 0) ) &&
292 (Impl::is_integral_power_of_two(ArgN4) || (ArgN4 == 0) ) &&
293 (Impl::is_integral_power_of_two(ArgN5) || (ArgN5 == 0) ) &&
294 (Impl::is_integral_power_of_two(ArgN6) || (ArgN6 == 0) ) &&
295 (Impl::is_integral_power_of_two(ArgN7) || (ArgN7 == 0) )
296 ,
"LayoutTiled must be given power-of-two tile dimensions" );
299 typedef LayoutTiled<OuterP, InnerP, ArgN0, ArgN1, ArgN2, ArgN3, ArgN4, ArgN5, ArgN6, ArgN7, IsPowerOfTwo> array_layout ;
300 static constexpr Iterate outer_pattern = OuterP;
301 static constexpr Iterate inner_pattern = InnerP;
312 size_t dimension[ ARRAY_LAYOUT_MAX_RANK ] ;
314 enum { is_extent_constructible =
true };
321 KOKKOS_INLINE_FUNCTION
323 LayoutTiled(
size_t argN0 = 0 ,
size_t argN1 = 0 ,
size_t argN2 = 0 ,
size_t argN3 = 0
324 ,
size_t argN4 = 0 ,
size_t argN5 = 0 ,
size_t argN6 = 0 ,
size_t argN7 = 0
326 : dimension { argN0 , argN1 , argN2 , argN3 , argN4 , argN5 , argN6 , argN7 } {}
334 template <
typename ... Layout >
335 struct layout_iterate_type_selector {
336 static const Kokkos::Iterate outer_iteration_pattern = Kokkos::Iterate::Default ;
337 static const Kokkos::Iterate inner_iteration_pattern = Kokkos::Iterate::Default ;
341 struct layout_iterate_type_selector< Kokkos::LayoutRight > {
342 static const Kokkos::Iterate outer_iteration_pattern = Kokkos::Iterate::Right ;
343 static const Kokkos::Iterate inner_iteration_pattern = Kokkos::Iterate::Right ;
347 struct layout_iterate_type_selector< Kokkos::LayoutLeft > {
348 static const Kokkos::Iterate outer_iteration_pattern = Kokkos::Iterate::Left ;
349 static const Kokkos::Iterate inner_iteration_pattern = Kokkos::Iterate::Left ;
353 struct layout_iterate_type_selector< Kokkos::LayoutStride > {
354 static const Kokkos::Iterate outer_iteration_pattern = Kokkos::Iterate::Default ;
355 static const Kokkos::Iterate inner_iteration_pattern = Kokkos::Iterate::Default ;
358 #ifndef KOKKOS_ENABLE_DEPRECATED_CODE
359 template <
unsigned ArgN0 ,
unsigned ArgN1 ,
unsigned ArgN2 ,
unsigned ArgN3 ,
unsigned ArgN4 ,
unsigned ArgN5 ,
unsigned ArgN6 ,
unsigned ArgN7 >
360 struct layout_iterate_type_selector< Kokkos::Experimental::LayoutTiled<Kokkos::Iterate::Left, Kokkos::Iterate::Left, ArgN0, ArgN1, ArgN2, ArgN3, ArgN4, ArgN5, ArgN6, ArgN7, true> > {
361 static const Kokkos::Iterate outer_iteration_pattern = Kokkos::Iterate::Left ;
362 static const Kokkos::Iterate inner_iteration_pattern = Kokkos::Iterate::Left ;
365 template <
unsigned ArgN0 ,
unsigned ArgN1 ,
unsigned ArgN2 ,
unsigned ArgN3 ,
unsigned ArgN4 ,
unsigned ArgN5 ,
unsigned ArgN6 ,
unsigned ArgN7 >
366 struct layout_iterate_type_selector< Kokkos::Experimental::LayoutTiled<Kokkos::Iterate::Right, Kokkos::Iterate::Left, ArgN0, ArgN1, ArgN2, ArgN3, ArgN4, ArgN5, ArgN6, ArgN7, true> > {
367 static const Kokkos::Iterate outer_iteration_pattern = Kokkos::Iterate::Right ;
368 static const Kokkos::Iterate inner_iteration_pattern = Kokkos::Iterate::Left ;
371 template <
unsigned ArgN0 ,
unsigned ArgN1 ,
unsigned ArgN2 ,
unsigned ArgN3 ,
unsigned ArgN4 ,
unsigned ArgN5 ,
unsigned ArgN6 ,
unsigned ArgN7 >
372 struct layout_iterate_type_selector< Kokkos::Experimental::LayoutTiled<Kokkos::Iterate::Left, Kokkos::Iterate::Right, ArgN0, ArgN1, ArgN2, ArgN3, ArgN4, ArgN5, ArgN6, ArgN7, true> > {
373 static const Kokkos::Iterate outer_iteration_pattern = Kokkos::Iterate::Left ;
374 static const Kokkos::Iterate inner_iteration_pattern = Kokkos::Iterate::Right ;
377 template <
unsigned ArgN0 ,
unsigned ArgN1 ,
unsigned ArgN2 ,
unsigned ArgN3 ,
unsigned ArgN4 ,
unsigned ArgN5 ,
unsigned ArgN6 ,
unsigned ArgN7 >
378 struct layout_iterate_type_selector< Kokkos::Experimental::LayoutTiled<Kokkos::Iterate::Right, Kokkos::Iterate::Right, ArgN0, ArgN1, ArgN2, ArgN3, ArgN4, ArgN5, ArgN6, ArgN7, true> > {
379 static const Kokkos::Iterate outer_iteration_pattern = Kokkos::Iterate::Right ;
380 static const Kokkos::Iterate inner_iteration_pattern = Kokkos::Iterate::Right ;
386 #endif // #ifndef KOKKOS_LAYOUT_HPP
LayoutLeft array_layout
Tag this class as a kokkos array layout.
Memory layout tag indicating left-to-right (Fortran scheme) striding of multi-indices.
Memory layout tag indicated arbitrarily strided multi-index mapping into contiguous memory...
LayoutStride array_layout
Tag this class as a kokkos array layout.
Memory layout tag indicating right-to-left (C or lexigraphical scheme) striding of multi-indices...
static KOKKOS_INLINE_FUNCTION LayoutStride order_dimensions(int const rank, iTypeOrder const *const order, iTypeDimen const *const dimen)
Compute strides from ordered dimensions.
LayoutTileLeft< ArgN0, ArgN1, IsPowerOfTwo > array_layout
Tag this class as a kokkos array layout.
Memory layout tag indicating left-to-right (Fortran scheme) striding of multi-indices by tiles...
KOKKOS_INLINE_FUNCTION constexpr unsigned rank(const View< D, P...> &V)
Temporary free function rank() until rank() is implemented in the View.
LayoutRight array_layout
Tag this class as a kokkos array layout.