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 :
bool { 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 :
bool { 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 :
bool { 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,
202 template <
typename LayoutTiledCheck,
class Enable =
void>
203 struct is_layouttiled : std::false_type {};
205 template <
typename LayoutTiledCheck>
206 struct is_layouttiled<
208 typename std::enable_if<LayoutTiledCheck::is_array_layout_tiled>::type>
216 Kokkos::Iterate OuterP, Kokkos::Iterate InnerP,
unsigned ArgN0,
217 unsigned ArgN1,
unsigned ArgN2 = 0,
unsigned ArgN3 = 0,
unsigned ArgN4 = 0,
218 unsigned ArgN5 = 0,
unsigned ArgN6 = 0,
unsigned ArgN7 = 0,
220 (Kokkos::Impl::is_integral_power_of_two(ArgN0) &&
221 Kokkos::Impl::is_integral_power_of_two(ArgN1) &&
222 (Kokkos::Impl::is_integral_power_of_two(ArgN2) || (ArgN2 == 0)) &&
223 (Kokkos::Impl::is_integral_power_of_two(ArgN3) || (ArgN3 == 0)) &&
224 (Kokkos::Impl::is_integral_power_of_two(ArgN4) || (ArgN4 == 0)) &&
225 (Kokkos::Impl::is_integral_power_of_two(ArgN5) || (ArgN5 == 0)) &&
226 (Kokkos::Impl::is_integral_power_of_two(ArgN6) || (ArgN6 == 0)) &&
227 (Kokkos::Impl::is_integral_power_of_two(ArgN7) || (ArgN7 == 0)))>
229 static_assert(IsPowerOfTwo,
230 "LayoutTiled must be given power-of-two tile dimensions");
233 static_assert( (Impl::is_integral_power_of_two(ArgN0) ) &&
234 (Impl::is_integral_power_of_two(ArgN1) ) &&
235 (Impl::is_integral_power_of_two(ArgN2) || (ArgN2 == 0) ) &&
236 (Impl::is_integral_power_of_two(ArgN3) || (ArgN3 == 0) ) &&
237 (Impl::is_integral_power_of_two(ArgN4) || (ArgN4 == 0) ) &&
238 (Impl::is_integral_power_of_two(ArgN5) || (ArgN5 == 0) ) &&
239 (Impl::is_integral_power_of_two(ArgN6) || (ArgN6 == 0) ) &&
240 (Impl::is_integral_power_of_two(ArgN7) || (ArgN7 == 0) )
241 ,
"LayoutTiled must be given power-of-two tile dimensions" );
245 ArgN4, ArgN5, ArgN6, ArgN7, IsPowerOfTwo>;
246 static constexpr Iterate outer_pattern = OuterP;
247 static constexpr Iterate inner_pattern = InnerP;
258 size_t dimension[ARRAY_LAYOUT_MAX_RANK];
260 enum :
bool { is_extent_constructible =
true };
267 KOKKOS_INLINE_FUNCTION
268 explicit constexpr
LayoutTiled(
size_t argN0 = 0,
size_t argN1 = 0,
269 size_t argN2 = 0,
size_t argN3 = 0,
270 size_t argN4 = 0,
size_t argN5 = 0,
271 size_t argN6 = 0,
size_t argN7 = 0)
272 : dimension{argN0, argN1, argN2, argN3, argN4, argN5, argN6, argN7} {}
278 template <
typename... Layout>
279 struct layout_iterate_type_selector {
280 static const Kokkos::Iterate outer_iteration_pattern =
281 Kokkos::Iterate::Default;
282 static const Kokkos::Iterate inner_iteration_pattern =
283 Kokkos::Iterate::Default;
287 struct layout_iterate_type_selector<
Kokkos::LayoutRight> {
288 static const Kokkos::Iterate outer_iteration_pattern = Kokkos::Iterate::Right;
289 static const Kokkos::Iterate inner_iteration_pattern = Kokkos::Iterate::Right;
293 struct layout_iterate_type_selector<
Kokkos::LayoutLeft> {
294 static const Kokkos::Iterate outer_iteration_pattern = Kokkos::Iterate::Left;
295 static const Kokkos::Iterate inner_iteration_pattern = Kokkos::Iterate::Left;
299 struct layout_iterate_type_selector<
Kokkos::LayoutStride> {
300 static const Kokkos::Iterate outer_iteration_pattern =
301 Kokkos::Iterate::Default;
302 static const Kokkos::Iterate inner_iteration_pattern =
303 Kokkos::Iterate::Default;
306 template <
unsigned ArgN0,
unsigned ArgN1,
unsigned ArgN2,
unsigned ArgN3,
307 unsigned ArgN4,
unsigned ArgN5,
unsigned ArgN6,
unsigned ArgN7>
308 struct layout_iterate_type_selector<
Kokkos::Experimental::LayoutTiled<
309 Kokkos::Iterate::Left, Kokkos::Iterate::Left, ArgN0, ArgN1, ArgN2, ArgN3,
310 ArgN4, ArgN5, ArgN6, ArgN7, true> > {
311 static const Kokkos::Iterate outer_iteration_pattern = Kokkos::Iterate::Left;
312 static const Kokkos::Iterate inner_iteration_pattern = Kokkos::Iterate::Left;
315 template <
unsigned ArgN0,
unsigned ArgN1,
unsigned ArgN2,
unsigned ArgN3,
316 unsigned ArgN4,
unsigned ArgN5,
unsigned ArgN6,
unsigned ArgN7>
317 struct layout_iterate_type_selector<
Kokkos::Experimental::LayoutTiled<
318 Kokkos::Iterate::Right, Kokkos::Iterate::Left, ArgN0, ArgN1, ArgN2, ArgN3,
319 ArgN4, ArgN5, ArgN6, ArgN7, true> > {
320 static const Kokkos::Iterate outer_iteration_pattern = Kokkos::Iterate::Right;
321 static const Kokkos::Iterate inner_iteration_pattern = Kokkos::Iterate::Left;
324 template <
unsigned ArgN0,
unsigned ArgN1,
unsigned ArgN2,
unsigned ArgN3,
325 unsigned ArgN4,
unsigned ArgN5,
unsigned ArgN6,
unsigned ArgN7>
326 struct layout_iterate_type_selector<
Kokkos::Experimental::LayoutTiled<
327 Kokkos::Iterate::Left, Kokkos::Iterate::Right, ArgN0, ArgN1, ArgN2, ArgN3,
328 ArgN4, ArgN5, ArgN6, ArgN7, true> > {
329 static const Kokkos::Iterate outer_iteration_pattern = Kokkos::Iterate::Left;
330 static const Kokkos::Iterate inner_iteration_pattern = Kokkos::Iterate::Right;
333 template <
unsigned ArgN0,
unsigned ArgN1,
unsigned ArgN2,
unsigned ArgN3,
334 unsigned ArgN4,
unsigned ArgN5,
unsigned ArgN6,
unsigned ArgN7>
335 struct layout_iterate_type_selector<
Kokkos::Experimental::LayoutTiled<
336 Kokkos::Iterate::Right, Kokkos::Iterate::Right, ArgN0, ArgN1, ArgN2, ArgN3,
337 ArgN4, ArgN5, ArgN6, ArgN7, true> > {
338 static const Kokkos::Iterate outer_iteration_pattern = Kokkos::Iterate::Right;
339 static const Kokkos::Iterate inner_iteration_pattern = Kokkos::Iterate::Right;
344 #endif // #ifndef KOKKOS_LAYOUT_HPP
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...
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.