Kokkos Core Kernels Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Kokkos_Extents.hpp
1 //@HEADER
2 // ************************************************************************
3 //
4 // Kokkos v. 4.0
5 // Copyright (2022) National Technology & Engineering
6 // Solutions of Sandia, LLC (NTESS).
7 //
8 // Under the terms of Contract DE-NA0003525 with NTESS,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions.
12 // See https://kokkos.org/LICENSE for license information.
13 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
14 //
15 //@HEADER
16 
17 #ifndef KOKKOS_IMPL_PUBLIC_INCLUDE
18 #include <Kokkos_Macros.hpp>
19 static_assert(false,
20  "Including non-public Kokkos header files is not allowed.");
21 #endif
22 #ifndef KOKKOS_KOKKOS_EXTENTS_HPP
23 #define KOKKOS_KOKKOS_EXTENTS_HPP
24 
25 #include <cstddef>
26 #include <type_traits>
27 #include <Kokkos_Macros.hpp>
28 #ifdef KOKKOS_ENABLE_IMPL_MDSPAN
29 #include <mdspan/mdspan.hpp>
30 #else
31 #include <limits>
32 #endif
33 
34 namespace Kokkos {
35 
36 #ifndef KOKKOS_ENABLE_IMPL_MDSPAN
37 constexpr size_t dynamic_extent = std::numeric_limits<size_t>::max();
38 #endif
39 
40 namespace Experimental {
41 
42 template <size_t... ExtentSpecs>
43 struct Extents {
44  /* TODO @enhancement flesh this out more */
45 };
46 
47 template <class Exts, size_t NewExtent>
48 struct PrependExtent;
49 
50 template <size_t... Exts, size_t NewExtent>
51 struct PrependExtent<Extents<Exts...>, NewExtent> {
52  using type = Extents<NewExtent, Exts...>;
53 };
54 
55 template <class Exts, size_t NewExtent>
56 struct AppendExtent;
57 
58 template <size_t... Exts, size_t NewExtent>
59 struct AppendExtent<Extents<Exts...>, NewExtent> {
60  using type = Extents<Exts..., NewExtent>;
61 };
62 } // end namespace Experimental
63 
64 namespace Impl {
65 
66 namespace _parse_view_extents_impl {
67 
68 template <class T>
69 struct _all_remaining_extents_dynamic : std::true_type {};
70 
71 template <class T>
72 struct _all_remaining_extents_dynamic<T*> : _all_remaining_extents_dynamic<T> {
73 };
74 
75 template <class T, unsigned N>
76 struct _all_remaining_extents_dynamic<T[N]> : std::false_type {};
77 
78 template <class T, class Result, class = void>
79 struct _parse_impl {
80  using type = Result;
81 };
82 
83 // We have to treat the case of int**[x] specially, since it *doesn't* go
84 // backwards
85 template <class T, size_t... ExtentSpec>
86 struct _parse_impl<T*, Kokkos::Experimental::Extents<ExtentSpec...>,
87  std::enable_if_t<_all_remaining_extents_dynamic<T>::value>>
88  : _parse_impl<T, Kokkos::Experimental::Extents<Kokkos::dynamic_extent,
89  ExtentSpec...>> {};
90 
91 // int*(*[x])[y] should still work also (meaning int[][x][][y])
92 template <class T, size_t... ExtentSpec>
93 struct _parse_impl<
94  T*, Kokkos::Experimental::Extents<ExtentSpec...>,
95  std::enable_if_t<!_all_remaining_extents_dynamic<T>::value>> {
96  using _next = Kokkos::Experimental::AppendExtent<
97  typename _parse_impl<T, Kokkos::Experimental::Extents<ExtentSpec...>,
98  void>::type,
99  Kokkos::dynamic_extent>;
100  using type = typename _next::type;
101 };
102 
103 template <class T, size_t... ExtentSpec, unsigned N>
104 struct _parse_impl<T[N], Kokkos::Experimental::Extents<ExtentSpec...>, void>
105  : _parse_impl<T,
106  Kokkos::Experimental::Extents<ExtentSpec...,
107  size_t(N)> // TODO @pedantic
108  // this could be a
109  // narrowing cast
110  > {};
111 
112 } // end namespace _parse_view_extents_impl
113 
114 template <class DataType>
115 struct ParseViewExtents {
116  using type = typename _parse_view_extents_impl ::_parse_impl<
117  DataType, Kokkos::Experimental::Extents<>>::type;
118 };
119 
120 template <class ValueType, size_t Ext>
121 struct ApplyExtent {
122  using type = ValueType[Ext];
123 };
124 
125 template <class ValueType>
126 struct ApplyExtent<ValueType, Kokkos::dynamic_extent> {
127  using type = ValueType*;
128 };
129 
130 template <class ValueType, unsigned N, size_t Ext>
131 struct ApplyExtent<ValueType[N], Ext> {
132  using type = typename ApplyExtent<ValueType, Ext>::type[N];
133 };
134 
135 template <class ValueType, size_t Ext>
136 struct ApplyExtent<ValueType*, Ext> {
137  using type = ValueType* [Ext];
138 };
139 
140 template <class ValueType>
141 struct ApplyExtent<ValueType*, dynamic_extent> {
142  using type = typename ApplyExtent<ValueType, dynamic_extent>::type*;
143 };
144 
145 template <class ValueType, unsigned N>
146 struct ApplyExtent<ValueType[N], dynamic_extent> {
147  using type = typename ApplyExtent<ValueType, dynamic_extent>::type[N];
148 };
149 
150 } // end namespace Impl
151 
152 } // end namespace Kokkos
153 
154 #endif // KOKKOS_KOKKOS_EXTENTS_HPP