Kokkos Core Kernels Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Kokkos_Extents.hpp
1 /*
2 //@HEADER
3 // ************************************************************************
4 //
5 // Kokkos v. 3.0
6 // Copyright (2019) Sandia Corporation
7 //
8 // Under the terms of Contract DE-NA0003525 with NTESS,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY NTESS "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NTESS OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact Christian R. Trott (crtrott@sandia.gov)
39 //
40 // ************************************************************************
41 //@HEADER
42 */
43 
44 #ifndef KOKKOS_KOKKOS_EXTENTS_HPP
45 #define KOKKOS_KOKKOS_EXTENTS_HPP
46 
47 #include <cstddef>
48 
49 namespace Kokkos {
50 namespace Experimental {
51 
52 constexpr ptrdiff_t dynamic_extent = -1;
53 
54 template <ptrdiff_t... ExtentSpecs>
55 struct Extents {
56  /* TODO @enhancement flesh this out more */
57 };
58 
59 template <class Exts, ptrdiff_t NewExtent>
60 struct PrependExtent;
61 
62 template <ptrdiff_t... Exts, ptrdiff_t NewExtent>
63 struct PrependExtent<Extents<Exts...>, NewExtent> {
64  using type = Extents<NewExtent, Exts...>;
65 };
66 
67 template <class Exts, ptrdiff_t NewExtent>
68 struct AppendExtent;
69 
70 template <ptrdiff_t... Exts, ptrdiff_t NewExtent>
71 struct AppendExtent<Extents<Exts...>, NewExtent> {
72  using type = Extents<Exts..., NewExtent>;
73 };
74 
75 } // end namespace Experimental
76 
77 namespace Impl {
78 
79 namespace _parse_view_extents_impl {
80 
81 template <class T>
82 struct _all_remaining_extents_dynamic : std::true_type {};
83 
84 template <class T>
85 struct _all_remaining_extents_dynamic<T*> : _all_remaining_extents_dynamic<T> {
86 };
87 
88 template <class T, unsigned N>
89 struct _all_remaining_extents_dynamic<T[N]> : std::false_type {};
90 
91 template <class T, class Result, class = void>
92 struct _parse_impl {
93  using type = Result;
94 };
95 
96 // We have to treat the case of int**[x] specially, since it *doesn't* go
97 // backwards
98 template <class T, ptrdiff_t... ExtentSpec>
99 struct _parse_impl<
100  T*, Kokkos::Experimental::Extents<ExtentSpec...>,
101  typename std::enable_if<_all_remaining_extents_dynamic<T>::value>::type>
102  : _parse_impl<T, Kokkos::Experimental::Extents<
103  Kokkos::Experimental::dynamic_extent, ExtentSpec...>> {
104 };
105 
106 // int*(*[x])[y] should still work also (meaning int[][x][][y])
107 template <class T, ptrdiff_t... ExtentSpec>
108 struct _parse_impl<
109  T*, Kokkos::Experimental::Extents<ExtentSpec...>,
110  typename std::enable_if<!_all_remaining_extents_dynamic<T>::value>::type> {
111  using _next = Kokkos::Experimental::AppendExtent<
112  typename _parse_impl<T, Kokkos::Experimental::Extents<ExtentSpec...>,
113  void>::type,
114  Kokkos::Experimental::dynamic_extent>;
115  using type = typename _next::type;
116 };
117 
118 template <class T, ptrdiff_t... ExtentSpec, unsigned N>
119 struct _parse_impl<T[N], Kokkos::Experimental::Extents<ExtentSpec...>, void>
120  : _parse_impl<
121  T, Kokkos::Experimental::Extents<ExtentSpec...,
122  ptrdiff_t(N)> // TODO @pedantic this
123  // could be a
124  // narrowing cast
125  > {};
126 
127 } // end namespace _parse_view_extents_impl
128 
129 template <class DataType>
130 struct ParseViewExtents {
131  using type = typename _parse_view_extents_impl ::_parse_impl<
132  DataType, Kokkos::Experimental::Extents<>>::type;
133 };
134 
135 template <class ValueType, ptrdiff_t Ext>
136 struct ApplyExtent {
137  using type = ValueType[Ext];
138 };
139 
140 template <class ValueType>
141 struct ApplyExtent<ValueType, Kokkos::Experimental::dynamic_extent> {
142  using type = ValueType*;
143 };
144 
145 template <class ValueType, unsigned N, ptrdiff_t Ext>
146 struct ApplyExtent<ValueType[N], Ext> {
147  using type = typename ApplyExtent<ValueType, Ext>::type[N];
148 };
149 
150 template <class ValueType, ptrdiff_t Ext>
151 struct ApplyExtent<ValueType*, Ext> {
152  using type = ValueType * [Ext];
153 };
154 
155 template <class ValueType>
156 struct ApplyExtent<ValueType*, Kokkos::Experimental::dynamic_extent> {
157  using type =
158  typename ApplyExtent<ValueType,
159  Kokkos::Experimental::dynamic_extent>::type*;
160 };
161 
162 template <class ValueType, unsigned N>
163 struct ApplyExtent<ValueType[N], Kokkos::Experimental::dynamic_extent> {
164  using type =
165  typename ApplyExtent<ValueType,
166  Kokkos::Experimental::dynamic_extent>::type[N];
167 };
168 
169 } // end namespace Impl
170 
171 } // end namespace Kokkos
172 
173 #endif // KOKKOS_KOKKOS_EXTENTS_HPP