tuple.hpp Source File

tuple.hpp Source File#

Composable Kernel: tuple.hpp Source File
utility/tuple.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: MIT
2// Copyright (c) 2018-2025, Advanced Micro Devices, Inc. All rights reserved.
3
4#pragma once
5
8#include "ck/utility/type.hpp"
10
11namespace ck {
12
13namespace detail {
14
15template <index_t>
17{
18 __host__ __device__ constexpr TupleElementKey() = default;
19};
20
21template <typename Key, typename Data>
23{
24 using DataType = Data;
25
26#if 0 // workaround compiler complaint about implicitly-deleted default constructor
27 __host__ __device__ constexpr TupleElementKeyData() = default;
28#else
29 __host__ __device__ constexpr TupleElementKeyData() : mData{} {}
30#endif
31
32 template <typename T,
34 bool>::type = false>
35 __host__ __device__ constexpr TupleElementKeyData(T&& v) : mData(ck::forward<T>(v))
36 {
37 }
38
40};
41
42// for read access of tuple element
43template <typename Key, typename Data>
44__host__ __device__ constexpr const Data&
46{
47 return static_cast<const Data&>(x.mData);
48}
49
50// for write access of tuple element
51template <typename Key, typename Data>
52__host__ __device__ constexpr Data&
57
58// TODO: not sure the use of reference is correct
59template <typename Key, typename Data>
60__host__ __device__ constexpr Data&&
62{
63 return static_cast<Data&&>(x.mData);
64}
65
66// for infering type of tuple element
67template <typename Key, typename Data>
68__host__ __device__ constexpr Data get_tuple_element_data(const TupleElementKeyData<Key, Data>& x)
69{
70 return ck::forward(x.mData);
71}
72
73template <typename Indices, typename... Xs>
74struct TupleImpl;
75
76template <index_t... Is, typename... Xs>
77struct TupleImpl<Sequence<Is...>, Xs...> : TupleElementKeyData<TupleElementKey<Is>, Xs>...
78{
79 __host__ __device__ constexpr TupleImpl() = default;
80
81 template <typename Y,
82 typename enable_if<sizeof...(Is) == 1 && sizeof...(Xs) == 1 &&
84 bool>::type = false>
85 __host__ __device__ constexpr TupleImpl(Y&& y)
86 : TupleElementKeyData<TupleElementKey<Is>, Xs>(ck::forward<Y>(y))...
87 {
88 }
89
90 template <typename... Ys, typename enable_if<sizeof...(Ys) >= 2, bool>::type = false>
91 __host__ __device__ constexpr TupleImpl(Ys&&... ys)
92 : TupleElementKeyData<TupleElementKey<Is>, Xs>(ck::forward<Ys>(ys))...
93 {
94 static_assert(sizeof...(Is) == sizeof...(Xs) && sizeof...(Is) == sizeof...(Ys),
95 "wrong! inconsistent size");
96 }
97
98 __host__ __device__ static constexpr index_t Size() { return sizeof...(Xs); }
99
100 template <index_t I>
101 __host__ __device__ constexpr const auto& GetElementDataByKey(TupleElementKey<I>) const
102 {
104 }
105
106 template <index_t I>
107 __host__ __device__ constexpr auto& GetElementDataByKey(TupleElementKey<I>)
108 {
110 }
111};
112
113} // namespace detail
114
115template <typename... Xs>
116struct Tuple : detail::TupleImpl<typename arithmetic_sequence_gen<0, sizeof...(Xs), 1>::type, Xs...>
117{
118 using base =
119 detail::TupleImpl<typename arithmetic_sequence_gen<0, sizeof...(Xs), 1>::type, Xs...>;
120
121 __host__ __device__ constexpr Tuple() = default;
122
123 template <typename Y,
124 typename enable_if<sizeof...(Xs) == 1 && !is_same<remove_cvref_t<Y>, Tuple>::value,
125 bool>::type = false>
126 __host__ __device__ constexpr Tuple(Y&& y) : base(ck::forward<Y>(y))
127 {
128 }
129
130 template <typename... Ys,
131 typename enable_if<sizeof...(Ys) == sizeof...(Xs) && sizeof...(Ys) >= 2, bool>::type =
132 false>
133 __host__ __device__ constexpr Tuple(Ys&&... ys) : base(ck::forward<Ys>(ys)...)
134 {
135 }
136
137 __host__ __device__ static constexpr index_t Size() { return sizeof...(Xs); }
138
139 // read access
140 template <index_t I>
141 __host__ __device__ constexpr const auto& At(Number<I>) const
142 {
143 static_assert(I < base::Size(), "wrong! out of range");
144 return base::GetElementDataByKey(detail::TupleElementKey<I>{});
145 }
146
147 // write access
148 template <index_t I>
149 __host__ __device__ constexpr auto& At(Number<I>)
150 {
151 static_assert(I < base::Size(), "wrong! out of range");
152 return base::GetElementDataByKey(detail::TupleElementKey<I>{});
153 }
154
155 // read access
156 template <index_t I>
157 __host__ __device__ constexpr const auto& operator[](Number<I> i) const
158 {
159 return At(i);
160 }
161
162 // write access
163 template <index_t I>
164 __host__ __device__ constexpr auto& operator()(Number<I> i)
165 {
166 return At(i);
167 }
168
169 template <typename T>
170 __host__ __device__ constexpr auto operator=(const T& a)
171 {
172 static_assert(T::Size() == Size(), "wrong! size not the same");
173
174 static_for<0, Size(), 1>{}([&](auto i) { operator()(i) = a[i]; });
175
176 return *this;
177 }
178
179 __host__ __device__ static constexpr bool IsStaticBuffer() { return true; }
180
181 __host__ __device__ static constexpr bool IsTuple() { return true; }
182};
183
184template <>
185struct Tuple<>
186{
187 __host__ __device__ constexpr Tuple() = default;
188
189 __host__ __device__ static constexpr index_t Size() { return 0; }
190
191 template <typename T>
192 __host__ __device__ constexpr auto operator=(const T&)
193 {
194 return *this;
195 }
196
197 __host__ __device__ static constexpr bool IsStaticBuffer() { return true; }
198};
199
200template <index_t I, typename TTuple>
202{
203 // type should keep the cv/ref qualifier of original tuple element
205};
206
207template <index_t I, typename TTuple>
209
210template <typename... Xs>
211__host__ __device__ constexpr auto make_tuple(Xs&&... xs)
212{
213 return Tuple<remove_cvref_t<Xs>...>(ck::forward<Xs>(xs)...);
214}
215
216// https://en.cppreference.com/w/cpp/utility/tuple/tie
217template <typename... Args>
218constexpr Tuple<Args&...> tie(Args&... args) noexcept
219{
220 return {args...};
221}
222
223} // namespace ck
Definition threadwise_tensor_slice_transfer_util.hpp:15
__host__ __device__ constexpr const Data & get_tuple_element_data_reference(const TupleElementKeyData< Key, Data > &x)
Definition utility/tuple.hpp:45
__host__ __device__ constexpr Data get_tuple_element_data(const TupleElementKeyData< Key, Data > &x)
Definition utility/tuple.hpp:68
Definition ck.hpp:268
int32_t index_t
Definition ck.hpp:299
remove_cv_t< remove_reference_t< T > > remove_cvref_t
Definition type.hpp:297
constexpr Tuple< Args &... > tie(Args &... args) noexcept
Definition utility/tuple.hpp:218
integral_constant< index_t, N > Number
Definition number.hpp:12
typename tuple_element< I, TTuple >::type tuple_element_t
Definition utility/tuple.hpp:208
std::enable_if< B, T > enable_if
Definition enable_if.hpp:24
__host__ __device__ constexpr auto make_tuple(Xs &&... xs)
Definition utility/tuple.hpp:211
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 utility/sequence.hpp:43
__host__ __device__ constexpr Tuple()=default
__host__ static __device__ constexpr index_t Size()
Definition utility/tuple.hpp:189
__host__ static __device__ constexpr bool IsStaticBuffer()
Definition utility/tuple.hpp:197
__host__ __device__ constexpr auto operator=(const T &)
Definition utility/tuple.hpp:192
Definition utility/tuple.hpp:117
__host__ __device__ constexpr auto & operator()(Number< I > i)
Definition utility/tuple.hpp:164
detail::TupleImpl< typename arithmetic_sequence_gen< 0, sizeof...(Xs), 1 >::type, Xs... > base
Definition utility/tuple.hpp:118
__host__ __device__ constexpr const auto & operator[](Number< I > i) const
Definition utility/tuple.hpp:157
__host__ static __device__ constexpr index_t Size()
Definition utility/tuple.hpp:137
__host__ __device__ constexpr Tuple(Y &&y)
Definition utility/tuple.hpp:126
__host__ __device__ constexpr auto & At(Number< I >)
Definition utility/tuple.hpp:149
__host__ __device__ constexpr auto operator=(const T &a)
Definition utility/tuple.hpp:170
__host__ static __device__ constexpr bool IsStaticBuffer()
Definition utility/tuple.hpp:179
__host__ __device__ constexpr const auto & At(Number< I >) const
Definition utility/tuple.hpp:141
__host__ static __device__ constexpr bool IsTuple()
Definition utility/tuple.hpp:181
__host__ __device__ constexpr Tuple()=default
__host__ __device__ constexpr Tuple(Ys &&... ys)
Definition utility/tuple.hpp:133
Definition utility/sequence.hpp:256
Definition utility/tuple.hpp:23
__host__ __device__ constexpr TupleElementKeyData(T &&v)
Definition utility/tuple.hpp:35
__host__ __device__ constexpr TupleElementKeyData()
Definition utility/tuple.hpp:29
Data DataType
Definition utility/tuple.hpp:24
DataType mData
Definition utility/tuple.hpp:39
Definition utility/tuple.hpp:17
__host__ __device__ constexpr TupleElementKey()=default
__host__ __device__ constexpr const auto & GetElementDataByKey(TupleElementKey< I >) const
Definition utility/tuple.hpp:101
__host__ __device__ constexpr TupleImpl()=default
__host__ __device__ constexpr TupleImpl(Y &&y)
Definition utility/tuple.hpp:85
__host__ __device__ constexpr auto & GetElementDataByKey(TupleElementKey< I >)
Definition utility/tuple.hpp:107
__host__ __device__ constexpr TupleImpl(Ys &&... ys)
Definition utility/tuple.hpp:91
__host__ static __device__ constexpr index_t Size()
Definition utility/tuple.hpp:98
Definition utility/tuple.hpp:74
Definition type.hpp:177
Definition functional2.hpp:33
Definition utility/tuple.hpp:202
decltype(detail::get_tuple_element_data< detail::TupleElementKey< I > >(TTuple{})) type
Definition utility/tuple.hpp:204