48 #ifndef KOKKOS_LAYOUT_HPP
49 #define KOKKOS_LAYOUT_HPP
52 #include <impl/Kokkos_Traits.hpp>
53 #include <impl/Kokkos_Tags.hpp>
57 enum { ARRAY_LAYOUT_MAX_RANK = 8 };
78 size_t dimension[ARRAY_LAYOUT_MAX_RANK];
80 enum { is_extent_constructible =
true };
87 KOKKOS_INLINE_FUNCTION
88 explicit constexpr
LayoutLeft(
size_t N0 = 0,
size_t N1 = 0,
size_t N2 = 0,
89 size_t N3 = 0,
size_t N4 = 0,
size_t N5 = 0,
90 size_t N6 = 0,
size_t N7 = 0)
91 : dimension{N0, N1, N2, N3, N4, N5, N6, N7} {}
112 size_t dimension[ARRAY_LAYOUT_MAX_RANK];
114 enum { is_extent_constructible =
true };
121 KOKKOS_INLINE_FUNCTION
122 explicit constexpr
LayoutRight(
size_t N0 = 0,
size_t N1 = 0,
size_t N2 = 0,
123 size_t N3 = 0,
size_t N4 = 0,
size_t N5 = 0,
124 size_t N6 = 0,
size_t N7 = 0)
125 : 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>
155 int const rank, iTypeOrder
const*
const order,
156 iTypeDimen
const*
const dimen) {
159 int check_input = ARRAY_LAYOUT_MAX_RANK < rank ? 0 : int(1 << rank) - 1;
160 for (
int r = 0; r < ARRAY_LAYOUT_MAX_RANK; ++r) {
161 tmp.dimension[r] = 0;
164 for (
int r = 0; r <
rank; ++r) {
165 check_input &= ~int(1 << order[r]);
167 if (0 == check_input) {
169 for (
int r = 0; r <
rank; ++r) {
170 tmp.stride[order[r]] = n;
171 n *= (dimen[order[r]]);
172 tmp.dimension[r] = dimen[r];
178 KOKKOS_INLINE_FUNCTION
179 explicit constexpr
LayoutStride(
size_t N0 = 0,
size_t S0 = 0,
size_t N1 = 0,
180 size_t S1 = 0,
size_t N2 = 0,
size_t S2 = 0,
181 size_t N3 = 0,
size_t S3 = 0,
size_t N4 = 0,
182 size_t S4 = 0,
size_t N5 = 0,
size_t S5 = 0,
183 size_t N6 = 0,
size_t S6 = 0,
size_t N7 = 0,
185 : dimension{N0, N1, N2, N3, N4, N5, N6, N7}, stride{S0, S1, S2, S3,
190 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE
209 template <
unsigned ArgN0,
unsigned ArgN1,
210 bool IsPowerOfTwo = (Impl::is_integral_power_of_two(ArgN0) &&
211 Impl::is_integral_power_of_two(ArgN1))>
212 struct LayoutTileLeft {
213 static_assert(Impl::is_integral_power_of_two(ArgN0) &&
214 Impl::is_integral_power_of_two(ArgN1),
215 "LayoutTileLeft must be given power-of-two tile dimensions");
218 typedef LayoutTileLeft<ArgN0, ArgN1, IsPowerOfTwo> array_layout;
223 size_t dimension[ARRAY_LAYOUT_MAX_RANK];
225 enum { is_extent_constructible =
true };
227 LayoutTileLeft(LayoutTileLeft
const&) =
default;
228 LayoutTileLeft(LayoutTileLeft&&) =
default;
229 LayoutTileLeft& operator=(LayoutTileLeft
const&) =
default;
230 LayoutTileLeft& operator=(LayoutTileLeft&&) =
default;
232 KOKKOS_INLINE_FUNCTION
233 explicit constexpr LayoutTileLeft(
size_t argN0 = 0,
size_t argN1 = 0,
234 size_t argN2 = 0,
size_t argN3 = 0,
235 size_t argN4 = 0,
size_t argN5 = 0,
236 size_t argN6 = 0,
size_t argN7 = 0)
237 : dimension{argN0, argN1, argN2, argN3, argN4, argN5, argN6, argN7} {}
240 #endif // KOKKOS_ENABLE_DEPRECATED_CODE
254 template <
typename LayoutTiledCheck,
class Enable =
void>
255 struct is_layouttiled : std::false_type {};
257 #ifndef KOKKOS_ENABLE_DEPRECATED_CODE
258 template <
typename LayoutTiledCheck>
259 struct is_layouttiled<
261 typename std::enable_if<LayoutTiledCheck::is_array_layout_tiled>::type>
264 namespace Experimental {
269 Kokkos::Iterate OuterP, Kokkos::Iterate InnerP,
unsigned ArgN0,
270 unsigned ArgN1,
unsigned ArgN2 = 0,
unsigned ArgN3 = 0,
unsigned ArgN4 = 0,
271 unsigned ArgN5 = 0,
unsigned ArgN6 = 0,
unsigned ArgN7 = 0,
273 (Kokkos::Impl::is_integral_power_of_two(ArgN0) &&
274 Kokkos::Impl::is_integral_power_of_two(ArgN1) &&
275 (Kokkos::Impl::is_integral_power_of_two(ArgN2) || (ArgN2 == 0)) &&
276 (Kokkos::Impl::is_integral_power_of_two(ArgN3) || (ArgN3 == 0)) &&
277 (Kokkos::Impl::is_integral_power_of_two(ArgN4) || (ArgN4 == 0)) &&
278 (Kokkos::Impl::is_integral_power_of_two(ArgN5) || (ArgN5 == 0)) &&
279 (Kokkos::Impl::is_integral_power_of_two(ArgN6) || (ArgN6 == 0)) &&
280 (Kokkos::Impl::is_integral_power_of_two(ArgN7) || (ArgN7 == 0)))>
282 static_assert(IsPowerOfTwo,
283 "LayoutTiled must be given power-of-two tile dimensions");
286 static_assert( (Impl::is_integral_power_of_two(ArgN0) ) &&
287 (Impl::is_integral_power_of_two(ArgN1) ) &&
288 (Impl::is_integral_power_of_two(ArgN2) || (ArgN2 == 0) ) &&
289 (Impl::is_integral_power_of_two(ArgN3) || (ArgN3 == 0) ) &&
290 (Impl::is_integral_power_of_two(ArgN4) || (ArgN4 == 0) ) &&
291 (Impl::is_integral_power_of_two(ArgN5) || (ArgN5 == 0) ) &&
292 (Impl::is_integral_power_of_two(ArgN6) || (ArgN6 == 0) ) &&
293 (Impl::is_integral_power_of_two(ArgN7) || (ArgN7 == 0) )
294 ,
"LayoutTiled must be given power-of-two tile dimensions" );
297 typedef LayoutTiled<OuterP, InnerP, ArgN0, ArgN1, ArgN2, ArgN3, ArgN4, ArgN5,
298 ArgN6, ArgN7, IsPowerOfTwo>
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
322 explicit constexpr
LayoutTiled(
size_t argN0 = 0,
size_t argN1 = 0,
323 size_t argN2 = 0,
size_t argN3 = 0,
324 size_t argN4 = 0,
size_t argN5 = 0,
325 size_t argN6 = 0,
size_t argN7 = 0)
326 : dimension{argN0, argN1, argN2, argN3, argN4, argN5, argN6, argN7} {}
333 template <
typename... Layout>
334 struct layout_iterate_type_selector {
335 static const Kokkos::Iterate outer_iteration_pattern =
336 Kokkos::Iterate::Default;
337 static const Kokkos::Iterate inner_iteration_pattern =
338 Kokkos::Iterate::Default;
342 struct layout_iterate_type_selector<Kokkos::LayoutRight> {
343 static const Kokkos::Iterate outer_iteration_pattern = Kokkos::Iterate::Right;
344 static const Kokkos::Iterate inner_iteration_pattern = Kokkos::Iterate::Right;
348 struct layout_iterate_type_selector<Kokkos::LayoutLeft> {
349 static const Kokkos::Iterate outer_iteration_pattern = Kokkos::Iterate::Left;
350 static const Kokkos::Iterate inner_iteration_pattern = Kokkos::Iterate::Left;
354 struct layout_iterate_type_selector<Kokkos::LayoutStride> {
355 static const Kokkos::Iterate outer_iteration_pattern =
356 Kokkos::Iterate::Default;
357 static const Kokkos::Iterate inner_iteration_pattern =
358 Kokkos::Iterate::Default;
361 #ifndef KOKKOS_ENABLE_DEPRECATED_CODE
362 template <
unsigned ArgN0,
unsigned ArgN1,
unsigned ArgN2,
unsigned ArgN3,
363 unsigned ArgN4,
unsigned ArgN5,
unsigned ArgN6,
unsigned ArgN7>
364 struct layout_iterate_type_selector<Kokkos::Experimental::LayoutTiled<
365 Kokkos::Iterate::Left, Kokkos::Iterate::Left, ArgN0, ArgN1, ArgN2, ArgN3,
366 ArgN4, ArgN5, ArgN6, ArgN7, true> > {
367 static const Kokkos::Iterate outer_iteration_pattern = Kokkos::Iterate::Left;
368 static const Kokkos::Iterate inner_iteration_pattern = Kokkos::Iterate::Left;
371 template <
unsigned ArgN0,
unsigned ArgN1,
unsigned ArgN2,
unsigned ArgN3,
372 unsigned ArgN4,
unsigned ArgN5,
unsigned ArgN6,
unsigned ArgN7>
373 struct layout_iterate_type_selector<Kokkos::Experimental::LayoutTiled<
374 Kokkos::Iterate::Right, Kokkos::Iterate::Left, ArgN0, ArgN1, ArgN2, ArgN3,
375 ArgN4, ArgN5, ArgN6, ArgN7, true> > {
376 static const Kokkos::Iterate outer_iteration_pattern = Kokkos::Iterate::Right;
377 static const Kokkos::Iterate inner_iteration_pattern = Kokkos::Iterate::Left;
380 template <
unsigned ArgN0,
unsigned ArgN1,
unsigned ArgN2,
unsigned ArgN3,
381 unsigned ArgN4,
unsigned ArgN5,
unsigned ArgN6,
unsigned ArgN7>
382 struct layout_iterate_type_selector<Kokkos::Experimental::LayoutTiled<
383 Kokkos::Iterate::Left, Kokkos::Iterate::Right, ArgN0, ArgN1, ArgN2, ArgN3,
384 ArgN4, ArgN5, ArgN6, ArgN7, true> > {
385 static const Kokkos::Iterate outer_iteration_pattern = Kokkos::Iterate::Left;
386 static const Kokkos::Iterate inner_iteration_pattern = Kokkos::Iterate::Right;
389 template <
unsigned ArgN0,
unsigned ArgN1,
unsigned ArgN2,
unsigned ArgN3,
390 unsigned ArgN4,
unsigned ArgN5,
unsigned ArgN6,
unsigned ArgN7>
391 struct layout_iterate_type_selector<Kokkos::Experimental::LayoutTiled<
392 Kokkos::Iterate::Right, Kokkos::Iterate::Right, ArgN0, ArgN1, ArgN2, ArgN3,
393 ArgN4, ArgN5, ArgN6, ArgN7, true> > {
394 static const Kokkos::Iterate outer_iteration_pattern = Kokkos::Iterate::Right;
395 static const Kokkos::Iterate inner_iteration_pattern = Kokkos::Iterate::Right;
401 #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.
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.