Kokkos Core Kernels Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Kokkos_Layout.hpp
Go to the documentation of this file.
1 /*
2 //@HEADER
3 // ************************************************************************
4 //
5 // Kokkos v. 3.0
6 // Copyright (2020) National Technology & Engineering
7 // Solutions of Sandia, LLC (NTESS).
8 //
9 // Under the terms of Contract DE-NA0003525 with NTESS,
10 // the U.S. Government retains certain rights in this software.
11 //
12 // Redistribution and use in source and binary forms, with or without
13 // modification, are permitted provided that the following conditions are
14 // met:
15 //
16 // 1. Redistributions of source code must retain the above copyright
17 // notice, this list of conditions and the following disclaimer.
18 //
19 // 2. Redistributions in binary form must reproduce the above copyright
20 // notice, this list of conditions and the following disclaimer in the
21 // documentation and/or other materials provided with the distribution.
22 //
23 // 3. Neither the name of the Corporation nor the names of the
24 // contributors may be used to endorse or promote products derived from
25 // this software without specific prior written permission.
26 //
27 // THIS SOFTWARE IS PROVIDED BY NTESS "AS IS" AND ANY
28 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NTESS OR THE
31 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
32 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
33 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
34 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
35 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
36 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 //
39 // Questions? Contact Christian R. Trott (crtrott@sandia.gov)
40 //
41 // ************************************************************************
42 //@HEADER
43 */
44 
47 
48 #ifndef KOKKOS_LAYOUT_HPP
49 #define KOKKOS_LAYOUT_HPP
50 
51 #include <cstddef>
52 #include <impl/Kokkos_Traits.hpp>
53 #include <impl/Kokkos_Tags.hpp>
54 
55 namespace Kokkos {
56 
57 enum { ARRAY_LAYOUT_MAX_RANK = 8 };
58 
59 //----------------------------------------------------------------------------
74 struct LayoutLeft {
77 
78  size_t dimension[ARRAY_LAYOUT_MAX_RANK];
79 
80  enum { is_extent_constructible = true };
81 
82  LayoutLeft(LayoutLeft const&) = default;
83  LayoutLeft(LayoutLeft&&) = default;
84  LayoutLeft& operator=(LayoutLeft const&) = default;
85  LayoutLeft& operator=(LayoutLeft&&) = default;
86 
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} {}
92 };
93 
94 //----------------------------------------------------------------------------
108 struct LayoutRight {
111 
112  size_t dimension[ARRAY_LAYOUT_MAX_RANK];
113 
114  enum { is_extent_constructible = true };
115 
116  LayoutRight(LayoutRight const&) = default;
117  LayoutRight(LayoutRight&&) = default;
118  LayoutRight& operator=(LayoutRight const&) = default;
119  LayoutRight& operator=(LayoutRight&&) = default;
120 
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} {}
126 };
127 
128 //----------------------------------------------------------------------------
132 struct LayoutStride {
135 
136  size_t dimension[ARRAY_LAYOUT_MAX_RANK];
137  size_t stride[ARRAY_LAYOUT_MAX_RANK];
138 
139  enum { is_extent_constructible = false };
140 
141  LayoutStride(LayoutStride const&) = default;
142  LayoutStride(LayoutStride&&) = default;
143  LayoutStride& operator=(LayoutStride const&) = default;
144  LayoutStride& operator=(LayoutStride&&) = default;
145 
153  template <typename iTypeOrder, typename iTypeDimen>
154  KOKKOS_INLINE_FUNCTION static LayoutStride order_dimensions(
155  int const rank, iTypeOrder const* const order,
156  iTypeDimen const* const dimen) {
157  LayoutStride tmp;
158  // Verify valid rank order:
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;
162  tmp.stride[r] = 0;
163  }
164  for (int r = 0; r < rank; ++r) {
165  check_input &= ~int(1 << order[r]);
166  }
167  if (0 == check_input) {
168  size_t n = 1;
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];
173  }
174  }
175  return tmp;
176  }
177 
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,
184  size_t S7 = 0)
185  : dimension{N0, N1, N2, N3, N4, N5, N6, N7}, stride{S0, S1, S2, S3,
186  S4, S5, S6, S7} {}
187 };
188 
189 // ==========================================================================
190 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE
191 
192 //----------------------------------------------------------------------------
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");
216 
218  typedef LayoutTileLeft<ArgN0, ArgN1, IsPowerOfTwo> array_layout;
219 
220  enum { N0 = ArgN0 };
221  enum { N1 = ArgN1 };
222 
223  size_t dimension[ARRAY_LAYOUT_MAX_RANK];
224 
225  enum { is_extent_constructible = true };
226 
227  LayoutTileLeft(LayoutTileLeft const&) = default;
228  LayoutTileLeft(LayoutTileLeft&&) = default;
229  LayoutTileLeft& operator=(LayoutTileLeft const&) = default;
230  LayoutTileLeft& operator=(LayoutTileLeft&&) = default;
231 
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} {}
238 };
239 
240 #endif // KOKKOS_ENABLE_DEPRECATED_CODE
241 // ===================================================================================
242 
244 
245 enum class Iterate {
246  Default,
247  Left, // Left indices stride fastest
248  Right // Right indices stride fastest
249 };
250 
251 // To check for LayoutTiled
252 // This is to hide extra compile-time 'identifier' info within the LayoutTiled
253 // class by not relying on template specialization to include the ArgN*'s
254 template <typename LayoutTiledCheck, class Enable = void>
255 struct is_layouttiled : std::false_type {};
256 
257 #ifndef KOKKOS_ENABLE_DEPRECATED_CODE
258 template <typename LayoutTiledCheck>
259 struct is_layouttiled<
260  LayoutTiledCheck,
261  typename std::enable_if<LayoutTiledCheck::is_array_layout_tiled>::type>
262  : std::true_type {};
263 
264 namespace Experimental {
265 
267 // Must have Rank >= 2
268 template <
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,
272  bool IsPowerOfTwo =
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)))>
281 struct LayoutTiled {
282  static_assert(IsPowerOfTwo,
283  "LayoutTiled must be given power-of-two tile dimensions");
284 
285 #if 0
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" );
295 #endif
296 
297  typedef LayoutTiled<OuterP, InnerP, ArgN0, ArgN1, ArgN2, ArgN3, ArgN4, ArgN5,
298  ArgN6, ArgN7, IsPowerOfTwo>
299  array_layout;
300  static constexpr Iterate outer_pattern = OuterP;
301  static constexpr Iterate inner_pattern = InnerP;
302 
303  enum { N0 = ArgN0 };
304  enum { N1 = ArgN1 };
305  enum { N2 = ArgN2 };
306  enum { N3 = ArgN3 };
307  enum { N4 = ArgN4 };
308  enum { N5 = ArgN5 };
309  enum { N6 = ArgN6 };
310  enum { N7 = ArgN7 };
311 
312  size_t dimension[ARRAY_LAYOUT_MAX_RANK];
313 
314  enum { is_extent_constructible = true };
315 
316  LayoutTiled(LayoutTiled const&) = default;
317  LayoutTiled(LayoutTiled&&) = default;
318  LayoutTiled& operator=(LayoutTiled const&) = default;
319  LayoutTiled& operator=(LayoutTiled&&) = default;
320 
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} {}
327 };
328 
329 } // namespace Experimental
330 #endif
331 
332 // For use with view_copy
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;
339 };
340 
341 template <>
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;
345 };
346 
347 template <>
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;
351 };
352 
353 template <>
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;
359 };
360 
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;
369 };
370 
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;
378 };
379 
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;
387 };
388 
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;
396 };
397 #endif
398 
399 } // namespace Kokkos
400 
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.