Kokkos Core Kernels Package  Version of the Day
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 #include <type_traits>
49 #include <Kokkos_Macros.hpp>
50 
51 namespace Kokkos {
52 namespace Experimental {
53 
54 constexpr ptrdiff_t dynamic_extent = -1;
55 
56 template <ptrdiff_t... ExtentSpecs>
57 struct Extents {
58  /* TODO @enhancement flesh this out more */
59 };
60 
61 template <class Exts, ptrdiff_t NewExtent>
62 struct PrependExtent;
63 
64 template <ptrdiff_t... Exts, ptrdiff_t NewExtent>
65 struct PrependExtent<Extents<Exts...>, NewExtent> {
66  using type = Extents<NewExtent, Exts...>;
67 };
68 
69 template <class Exts, ptrdiff_t NewExtent>
70 struct AppendExtent;
71 
72 template <ptrdiff_t... Exts, ptrdiff_t NewExtent>
73 struct AppendExtent<Extents<Exts...>, NewExtent> {
74  using type = Extents<Exts..., NewExtent>;
75 };
76 
77 } // end namespace Experimental
78 
79 namespace Impl {
80 
81 namespace _parse_view_extents_impl {
82 
83 template <class T>
84 struct _all_remaining_extents_dynamic : std::true_type {};
85 
86 template <class T>
87 struct _all_remaining_extents_dynamic<T*> : _all_remaining_extents_dynamic<T> {
88 };
89 
90 template <class T, unsigned N>
91 struct _all_remaining_extents_dynamic<T[N]> : std::false_type {};
92 
93 template <class T, class Result, class = void>
94 struct _parse_impl {
95  using type = Result;
96 };
97 
98 // We have to treat the case of int**[x] specially, since it *doesn't* go
99 // backwards
100 template <class T, ptrdiff_t... ExtentSpec>
101 struct _parse_impl<
102  T*, Kokkos::Experimental::Extents<ExtentSpec...>,
103  typename std::enable_if<_all_remaining_extents_dynamic<T>::value>::type>
104  : _parse_impl<T, Kokkos::Experimental::Extents<
105  Kokkos::Experimental::dynamic_extent, ExtentSpec...>> {
106 };
107 
108 // int*(*[x])[y] should still work also (meaning int[][x][][y])
109 template <class T, ptrdiff_t... ExtentSpec>
110 struct _parse_impl<
111  T*, Kokkos::Experimental::Extents<ExtentSpec...>,
112  typename std::enable_if<!_all_remaining_extents_dynamic<T>::value>::type> {
113  using _next = Kokkos::Experimental::AppendExtent<
114  typename _parse_impl<T, Kokkos::Experimental::Extents<ExtentSpec...>,
115  void>::type,
116  Kokkos::Experimental::dynamic_extent>;
117  using type = typename _next::type;
118 };
119 
120 template <class T, ptrdiff_t... ExtentSpec, unsigned N>
121 struct _parse_impl<T[N], Kokkos::Experimental::Extents<ExtentSpec...>, void>
122  : _parse_impl<
123  T, Kokkos::Experimental::Extents<ExtentSpec...,
124  ptrdiff_t(N)> // TODO @pedantic this
125  // could be a
126  // narrowing cast
127  > {};
128 
129 } // end namespace _parse_view_extents_impl
130 
131 template <class DataType>
132 struct ParseViewExtents {
133  using type = typename _parse_view_extents_impl ::_parse_impl<
134  DataType, Kokkos::Experimental::Extents<>>::type;
135 };
136 
137 template <class ValueType, ptrdiff_t Ext>
138 struct ApplyExtent {
139  using type = ValueType[Ext];
140 };
141 
142 template <class ValueType>
143 struct ApplyExtent<ValueType, Kokkos::Experimental::dynamic_extent> {
144  using type = ValueType*;
145 };
146 
147 template <class ValueType, unsigned N, ptrdiff_t Ext>
148 struct ApplyExtent<ValueType[N], Ext> {
149  using type = typename ApplyExtent<ValueType, Ext>::type[N];
150 };
151 
152 template <class ValueType, ptrdiff_t Ext>
153 struct ApplyExtent<ValueType*, Ext> {
154  using type = ValueType * [Ext];
155 };
156 
157 template <class ValueType>
158 struct ApplyExtent<ValueType*, Kokkos::Experimental::dynamic_extent> {
159  using type =
160  typename ApplyExtent<ValueType,
161  Kokkos::Experimental::dynamic_extent>::type*;
162 };
163 
164 template <class ValueType, unsigned N>
165 struct ApplyExtent<ValueType[N], Kokkos::Experimental::dynamic_extent> {
166  using type =
167  typename ApplyExtent<ValueType,
168  Kokkos::Experimental::dynamic_extent>::type[N];
169 };
170 
171 } // end namespace Impl
172 
173 } // end namespace Kokkos
174 
175 #endif // KOKKOS_KOKKOS_EXTENTS_HPP
Definition: dummy.cpp:3