/home/docs/checkouts/readthedocs.org/user_builds/advanced-micro-devices-composable-kernel/checkouts/3643/include/ck/utility/tuple.hpp Source File

/home/docs/checkouts/readthedocs.org/user_builds/advanced-micro-devices-composable-kernel/checkouts/3643/include/ck/utility/tuple.hpp Source File#

Composable Kernel: /home/docs/checkouts/readthedocs.org/user_builds/advanced-micro-devices-composable-kernel/checkouts/3643/include/ck/utility/tuple.hpp Source File
tuple.hpp
Go to the documentation of this file.
1 // Copyright (c) Advanced Micro Devices, Inc., or its affiliates.
2 // SPDX-License-Identifier: MIT
3 
4 #pragma once
5 
8 #include "ck/utility/type.hpp"
10 #include <tuple>
11 
12 namespace ck {
13 
14 namespace detail {
15 
16 template <index_t>
18 {
19  __host__ __device__ constexpr TupleElementKey() = default;
20 };
21 
22 template <typename Key, typename Data>
24 {
25  using DataType = Data;
26 
27 #if 0 // workaround compiler complaint about implicitly-deleted default constructor
28  __host__ __device__ constexpr TupleElementKeyData() = default;
29 #else
30  __host__ __device__ constexpr TupleElementKeyData() : mData{} {}
31 #endif
32 
33  template <typename T,
35  bool>::type = false>
36  __host__ __device__ constexpr TupleElementKeyData(T&& v) : mData(ck::forward<T>(v))
37  {
38  }
39 
41 };
42 
43 // for read access of tuple element
44 template <typename Key, typename Data>
45 __host__ __device__ constexpr const Data&
47 {
48  return static_cast<const Data&>(x.mData);
49 }
50 
51 // for write access of tuple element
52 template <typename Key, typename Data>
53 __host__ __device__ constexpr Data&
55 {
56  return x.mData;
57 }
58 
59 // TODO: not sure the use of reference is correct
60 template <typename Key, typename Data>
61 __host__ __device__ constexpr Data&&
63 {
64  return static_cast<Data&&>(x.mData);
65 }
66 
67 // for infering type of tuple element
68 template <typename Key, typename Data>
69 __host__ __device__ constexpr Data get_tuple_element_data(const TupleElementKeyData<Key, Data>& x)
70 {
71  return ck::forward(x.mData);
72 }
73 
74 template <typename Indices, typename... Xs>
75 struct TupleImpl;
76 
77 template <index_t... Is, typename... Xs>
78 struct TupleImpl<Sequence<Is...>, Xs...> : TupleElementKeyData<TupleElementKey<Is>, Xs>...
79 {
80  __host__ __device__ constexpr TupleImpl() = default;
81 
82  template <typename Y,
83  typename enable_if<sizeof...(Is) == 1 && sizeof...(Xs) == 1 &&
85  bool>::type = false>
86  __host__ __device__ constexpr TupleImpl(Y&& y)
87  : TupleElementKeyData<TupleElementKey<Is>, Xs>(ck::forward<Y>(y))...
88  {
89  }
90 
91  template <typename... Ys, typename enable_if<sizeof...(Ys) >= 2, bool>::type = false>
92  __host__ __device__ constexpr TupleImpl(Ys&&... ys)
93  : TupleElementKeyData<TupleElementKey<Is>, Xs>(ck::forward<Ys>(ys))...
94  {
95  static_assert(sizeof...(Is) == sizeof...(Xs) && sizeof...(Is) == sizeof...(Ys),
96  "wrong! inconsistent size");
97  }
98 
99  __host__ __device__ static constexpr index_t Size() { return sizeof...(Xs); }
100 
101  template <index_t I>
102  __host__ __device__ constexpr const auto& GetElementDataByKey(TupleElementKey<I>) const
103  {
104  return get_tuple_element_data_reference<TupleElementKey<I>>(*this);
105  }
106 
107  template <index_t I>
108  __host__ __device__ constexpr auto& GetElementDataByKey(TupleElementKey<I>)
109  {
110  return get_tuple_element_data_reference<TupleElementKey<I>>(*this);
111  }
112 };
113 
114 } // namespace detail
115 
116 template <typename... Xs>
117 struct Tuple : detail::TupleImpl<typename arithmetic_sequence_gen<0, sizeof...(Xs), 1>::type, Xs...>
118 {
119  using base =
120  detail::TupleImpl<typename arithmetic_sequence_gen<0, sizeof...(Xs), 1>::type, Xs...>;
121 
122  __host__ __device__ constexpr Tuple() = default;
123 
124  template <typename Y,
125  typename enable_if<sizeof...(Xs) == 1 && !is_same<remove_cvref_t<Y>, Tuple>::value,
126  bool>::type = false>
127  __host__ __device__ constexpr Tuple(Y&& y) : base(ck::forward<Y>(y))
128  {
129  }
130 
131  template <typename... Ys,
132  typename enable_if<sizeof...(Ys) == sizeof...(Xs) && sizeof...(Ys) >= 2, bool>::type =
133  false>
134  __host__ __device__ constexpr Tuple(Ys&&... ys) : base(ck::forward<Ys>(ys)...)
135  {
136  }
137 
138  __host__ __device__ static constexpr index_t Size() { return sizeof...(Xs); }
139 
140  // read access
141  template <index_t I>
142  __host__ __device__ constexpr const auto& At(Number<I>) const
143  {
144  static_assert(I < base::Size(), "wrong! out of range");
145  return base::GetElementDataByKey(detail::TupleElementKey<I>{});
146  }
147 
148  // write access
149  template <index_t I>
150  __host__ __device__ constexpr auto& At(Number<I>)
151  {
152  static_assert(I < base::Size(), "wrong! out of range");
153  return base::GetElementDataByKey(detail::TupleElementKey<I>{});
154  }
155 
156  // read access
157  template <index_t I>
158  __host__ __device__ constexpr const auto& operator[](Number<I> i) const
159  {
160  return At(i);
161  }
162 
163  // write access
164  template <index_t I>
165  __host__ __device__ constexpr auto& operator()(Number<I> i)
166  {
167  return At(i);
168  }
169 
170  template <typename T>
171  __host__ __device__ constexpr auto operator=(const T& a)
172  {
173  static_assert(T::Size() == Size(), "wrong! size not the same");
174 
175  static_for<0, Size(), 1>{}([&](auto i) { operator()(i) = a[i]; });
176 
177  return *this;
178  }
179 
180  __host__ __device__ static constexpr bool IsStaticBuffer() { return true; }
181 
182  __host__ __device__ static constexpr bool IsTuple() { return true; }
183 };
184 
185 template <>
186 struct Tuple<>
187 {
188  __host__ __device__ constexpr Tuple() = default;
189 
190  __host__ __device__ static constexpr index_t Size() { return 0; }
191 
192  template <typename T>
193  __host__ __device__ constexpr auto operator=(const T&)
194  {
195  return *this;
196  }
197 
198  __host__ __device__ static constexpr bool IsStaticBuffer() { return true; }
199 };
200 
201 template <index_t I, typename TTuple>
203 {
204  // type should keep the cv/ref qualifier of original tuple element
206 };
207 
208 template <index_t I, typename TTuple>
210 
211 template <typename... Xs>
212 __host__ __device__ constexpr auto make_tuple(Xs&&... xs)
213 {
214  return Tuple<remove_cvref_t<Xs>...>(ck::forward<Xs>(xs)...);
215 }
216 
217 // https://en.cppreference.com/w/cpp/utility/tuple/tie
218 template <typename... Args>
219 constexpr Tuple<Args&...> tie(Args&... args) noexcept
220 {
221  return {args...};
222 }
223 
224 //
225 // tuple_map: Map tuple with a different type
226 // e.g. tuple_map<Wrapper, Tuple<T1, T2, T3>> becomes Tuple<Wrapper<T1>, Wrapper<T2>, Wrapper<T3>>
227 //
228 template <template <typename> class Wrapper, typename Tuple>
229 struct tuple_map;
230 
231 template <template <typename> class Wrapper, typename... Ts>
232 struct tuple_map<Wrapper, Tuple<Ts...>>
233 {
234  using type = Tuple<Wrapper<Ts>...>;
235 };
236 
237 template <template <typename> class Wrapper, typename Tuple>
239 
240 //
241 // tuple_element_or: helper to access type element of a tuple by index, with the option to default
242 // to a type if the index is out of range of the tuple size
243 //
244 namespace detail {
245 
246 // Base template (will be specialized on the boolean)
247 template <ck::index_t N, typename Tuple, typename Default, bool InRange = (N < Tuple::Size())>
248 struct tuple_element_or_impl;
249 
250 // Specialization for the in-range case: use tuple_element_t
251 template <ck::index_t N, typename Tuple, typename Default>
253 {
255 };
256 
257 // Specialization for the out-of-range case: use Default
258 template <ck::index_t N, typename Tuple, typename Default>
260 {
261  using type = Default;
262 };
263 } // namespace detail
264 
265 // User-facing alias
266 template <ck::index_t N, typename Tuple, typename Default>
268 
269 } // namespace ck
__host__ constexpr __device__ Data get_tuple_element_data(const TupleElementKeyData< Key, Data > &x)
Definition: tuple.hpp:69
__host__ constexpr __device__ const Data & get_tuple_element_data_reference(const TupleElementKeyData< Key, Data > &x)
Definition: tuple.hpp:46
Definition: ck.hpp:270
typename tuple_map< Wrapper, Tuple >::type tuple_map_t
Definition: tuple.hpp:238
typename tuple_element< I, TTuple >::type tuple_element_t
Definition: tuple.hpp:209
typename detail::tuple_element_or_impl< N, Tuple, Default >::type tuple_element_or_t
Definition: tuple.hpp:267
constexpr Tuple< Args &... > tie(Args &... args) noexcept
Definition: tuple.hpp:219
std::enable_if< B, T > enable_if
Definition: enable_if.hpp:24
__host__ constexpr __device__ auto make_tuple(Xs &&... xs)
Definition: tuple.hpp:212
remove_cv_t< remove_reference_t< T > > remove_cvref_t
Definition: type.hpp:297
int32_t index_t
Definition: ck.hpp:301
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1697
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1517
Definition: sequence.hpp:43
__host__ static constexpr __device__ index_t Size()
Definition: tuple.hpp:190
__host__ constexpr __device__ auto operator=(const T &)
Definition: tuple.hpp:193
__host__ static constexpr __device__ bool IsStaticBuffer()
Definition: tuple.hpp:198
__host__ constexpr __device__ Tuple()=default
Definition: tuple.hpp:118
__host__ constexpr __device__ Tuple(Y &&y)
Definition: tuple.hpp:127
detail::TupleImpl< typename arithmetic_sequence_gen< 0, sizeof...(Xs), 1 >::type, Xs... > base
Definition: tuple.hpp:120
__host__ constexpr __device__ Tuple()=default
Definition: sequence.hpp:256
Definition: tuple.hpp:24
__host__ constexpr __device__ TupleElementKeyData(T &&v)
Definition: tuple.hpp:36
Data DataType
Definition: tuple.hpp:25
DataType mData
Definition: tuple.hpp:40
__host__ constexpr __device__ TupleElementKeyData()
Definition: tuple.hpp:30
Definition: tuple.hpp:18
__host__ constexpr __device__ TupleElementKey()=default
__host__ constexpr __device__ auto & GetElementDataByKey(TupleElementKey< I >)
Definition: tuple.hpp:108
__host__ constexpr __device__ TupleImpl()=default
__host__ constexpr __device__ TupleImpl(Y &&y)
Definition: tuple.hpp:86
__host__ static constexpr __device__ index_t Size()
Definition: tuple.hpp:99
__host__ constexpr __device__ const auto & GetElementDataByKey(TupleElementKey< I >) const
Definition: tuple.hpp:102
Definition: tuple.hpp:75
tuple_element_t< N, Tuple > type
Definition: tuple.hpp:254
Definition: tuple.hpp:248
Definition: type.hpp:177
Definition: tuple.hpp:203
decltype(detail::get_tuple_element_data< detail::TupleElementKey< I > >(TTuple{})) type
Definition: tuple.hpp:205
Definition: tuple.hpp:229