Tuple.h
Go to the documentation of this file.
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2021 The Eigen Team
5 //
6 // This Source Code Form is subject to the terms of the Mozilla
7 // Public License v. 2.0. If a copy of the MPL was not distributed
8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 
10 #ifndef EIGEN_TUPLE_GPU
11 #define EIGEN_TUPLE_GPU
12 
13 #include <type_traits>
14 #include <utility>
15 
16 // This is a replacement of std::tuple that can be used in device code.
17 
18 namespace Eigen {
19 namespace internal {
20 namespace tuple_impl {
21 
22 // Internal tuple implementation.
23 template <size_t N, typename... Types>
24 class TupleImpl;
25 
26 // Generic recursive tuple.
27 template <size_t N, typename T1, typename... Ts>
28 class TupleImpl<N, T1, Ts...> {
29  public:
30  // Tuple may contain Eigen types.
32 
33  // Default constructor, enable if all types are default-constructible.
34  template <typename U1 = T1,
38 
39  // Element constructor.
40  template <typename U1, typename... Us,
41  // Only enable if...
42  typename EnableIf = std::enable_if_t<
43  // the number of input arguments match, and ...
44  sizeof...(Us) == sizeof...(Ts) && (
45  // this does not look like a copy/move constructor.
48  : head_(std::forward<U1>(arg1)), tail_(std::forward<Us>(args)...) {}
49 
50  // The first stored value.
51  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE T1& head() { return head_; }
52 
53  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE const T1& head() const { return head_; }
54 
55  // The tail values.
56  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE TupleImpl<N - 1, Ts...>& tail() { return tail_; }
57 
58  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE const TupleImpl<N - 1, Ts...>& tail() const { return tail_; }
59 
61  using numext::swap;
62  swap(head_, other.head_);
63  swap(tail_, other.tail_);
64  }
65 
66  template <typename... UTypes>
68  head_ = other.head_;
69  tail_ = other.tail_;
70  return *this;
71  }
72 
73  template <typename... UTypes>
75  head_ = std::move(other.head_);
76  tail_ = std::move(other.tail_);
77  return *this;
78  }
79 
80  private:
81  // Allow related tuples to reference head_/tail_.
82  template <size_t M, typename... UTypes>
83  friend class TupleImpl;
84 
85  T1 head_;
86  TupleImpl<N - 1, Ts...> tail_;
87 };
88 
89 // Empty tuple specialization.
90 template <>
91 class TupleImpl<size_t(0)> {};
92 
93 template <typename TupleType>
94 struct is_tuple : std::false_type {};
95 
96 template <typename... Types>
97 struct is_tuple<TupleImpl<sizeof...(Types), Types...>> : std::true_type {};
98 
99 // Gets an element from a tuple.
100 template <size_t Idx, typename T1, typename... Ts>
102  using TupleType = TupleImpl<sizeof...(Ts) + 1, T1, Ts...>;
104 
107  }
108 
111  }
112 };
113 
114 // Base case, getting the head element.
115 template <typename T1, typename... Ts>
116 struct tuple_get_impl<0, T1, Ts...> {
117  using TupleType = TupleImpl<sizeof...(Ts) + 1, T1, Ts...>;
118  using ReturnType = T1;
119 
121 
123  return tuple.head();
124  }
125 };
126 
127 // Concatenates N Tuples.
128 template <size_t NTuples, typename... Tuples>
130 
131 template <size_t NTuples, size_t N1, typename... Args1, size_t N2, typename... Args2, typename... Tuples>
132 struct tuple_cat_impl<NTuples, TupleImpl<N1, Args1...>, TupleImpl<N2, Args2...>, Tuples...> {
133  using TupleType1 = TupleImpl<N1, Args1...>;
134  using TupleType2 = TupleImpl<N2, Args2...>;
135  using MergedTupleType = TupleImpl<N1 + N2, Args1..., Args2...>;
136 
137  using ReturnType = typename tuple_cat_impl<NTuples - 1, MergedTupleType, Tuples...>::ReturnType;
138 
139  // Uses the index sequences to extract and merge elements from tuple1 and tuple2,
140  // then recursively calls again.
141  template <typename Tuple1, size_t... I1s, typename Tuple2, size_t... I2s, typename... MoreTuples>
143  std::index_sequence<I1s...>,
144  Tuple2&& tuple2,
145  std::index_sequence<I2s...>,
146  MoreTuples&&... tuples) {
148  MergedTupleType(tuple_get_impl<I1s, Args1...>::run(std::forward<Tuple1>(tuple1))...,
149  tuple_get_impl<I2s, Args2...>::run(std::forward<Tuple2>(tuple2))...),
150  std::forward<MoreTuples>(tuples)...);
151  }
152 
153  // Concatenates the first two tuples.
154  template <typename Tuple1, typename Tuple2, typename... MoreTuples>
155  static EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ReturnType run(Tuple1&& tuple1, Tuple2&& tuple2,
156  MoreTuples&&... tuples) {
157  return run(std::forward<Tuple1>(tuple1), std::make_index_sequence<N1>{}, std::forward<Tuple2>(tuple2),
158  std::make_index_sequence<N2>{}, std::forward<MoreTuples>(tuples)...);
159  }
160 };
161 
162 // Base case with a single tuple.
163 template <size_t N, typename... Args>
164 struct tuple_cat_impl<1, TupleImpl<N, Args...>> {
165  using ReturnType = TupleImpl<N, Args...>;
166 
167  template <typename Tuple1>
169  return tuple1;
170  }
171 };
172 
173 // Special case of no tuples.
174 template <>
175 struct tuple_cat_impl<0> {
178 };
179 
180 // For use in make_tuple, unwraps a reference_wrapper.
181 template <typename T>
183  using type = T;
184 };
185 
186 template <typename T>
187 struct unwrap_reference_wrapper<std::reference_wrapper<T>> {
188  using type = T&;
189 };
190 
191 // For use in make_tuple, decays a type and unwraps a reference_wrapper.
192 template <typename T>
193 struct unwrap_decay {
195 };
196 
200 template <typename Tuple>
201 struct tuple_size;
202 
203 template <typename... Types>
204 struct tuple_size<TupleImpl<sizeof...(Types), Types...>> : std::integral_constant<size_t, sizeof...(Types)> {};
205 
213 template <size_t Idx, typename... Types>
214 EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename tuple_get_impl<Idx, Types...>::ReturnType& get(
215  const TupleImpl<sizeof...(Types), Types...>& tuple) {
217 }
218 
219 template <size_t Idx, typename... Types>
221  TupleImpl<sizeof...(Types), Types...>& tuple) {
223 }
224 
230 template <typename... Tuples, typename EnableIf = std::enable_if_t<
233  typename tuple_cat_impl<sizeof...(Tuples), typename std::decay<Tuples>::type...>::ReturnType
234  tuple_cat(Tuples&&... tuples) {
235  return tuple_cat_impl<sizeof...(Tuples), typename std::decay<Tuples>::type...>::run(std::forward<Tuples>(tuples)...);
236 }
237 
241 template <typename... Args, typename ReturnType = TupleImpl<sizeof...(Args), Args&...>>
243  return ReturnType{args...};
244 }
245 
249 template <typename... Args, typename ReturnType = TupleImpl<sizeof...(Args), typename unwrap_decay<Args>::type...>>
251  return ReturnType{std::forward<Args>(args)...};
252 }
253 
257 template <typename... Args>
259  Args&&... args) {
260  return TupleImpl<sizeof...(Args), Args...>(std::forward<Args>(args)...);
261 }
262 
266 template <typename... Types>
267 using tuple = TupleImpl<sizeof...(Types), Types...>;
268 
269 } // namespace tuple_impl
270 } // namespace internal
271 } // namespace Eigen
272 
273 #endif // EIGEN_TUPLE_GPU
Eigen::Triplet< double > T
Definition: EigenUnitTest.cpp:11
#define EIGEN_ALWAYS_INLINE
Definition: Macros.h:845
#define EIGEN_NOEXCEPT
Definition: Macros.h:1267
#define EIGEN_CONSTEXPR
Definition: Macros.h:758
#define EIGEN_DEVICE_FUNC
Definition: Macros.h:892
#define EIGEN_STRONG_INLINE
Definition: Macros.h:834
#define EIGEN_MAKE_ALIGNED_OPERATOR_NEW
Definition: Memory.h:879
Matrix< RealScalar, Dynamic, Dynamic > M
Definition: bench_gemm.cpp:50
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TupleImpl & operator=(const TupleImpl< N, UTypes... > &other)
Definition: Tuple.h:67
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE const TupleImpl< N - 1, Ts... > & tail() const
Definition: Tuple.h:58
EIGEN_MAKE_ALIGNED_OPERATOR_NEW EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC TupleImpl()
Definition: Tuple.h:37
TupleImpl< N - 1, Ts... > tail_
Definition: Tuple.h:86
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE const T1 & head() const
Definition: Tuple.h:53
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void swap(TupleImpl &other)
Definition: Tuple.h:60
EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC TupleImpl(U1 &&arg1, Us &&... args)
Definition: Tuple.h:47
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE T1 & head()
Definition: Tuple.h:51
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TupleImpl & operator=(TupleImpl< N, UTypes... > &&other)
Definition: Tuple.h:74
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE TupleImpl< N - 1, Ts... > & tail()
Definition: Tuple.h:56
@ N
Definition: constructor.cpp:22
EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const tuple_get_impl< Idx, Types... >::ReturnType & get(const TupleImpl< sizeof...(Types), Types... > &tuple)
Definition: Tuple.h:214
EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ReturnType tie(Args &... args) EIGEN_NOEXCEPT
Definition: Tuple.h:242
EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ReturnType make_tuple(Args &&... args)
Definition: Tuple.h:250
EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE tuple_cat_impl< sizeof...(Tuples), typename std::decay< Tuples >::type... >::ReturnType tuple_cat(Tuples &&... tuples)
Definition: Tuple.h:234
EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TupleImpl< sizeof...(Args), Args... > forward_as_tuple(Args &&... args)
Definition: Tuple.h:258
std::is_same< std::integer_sequence< bool, values..., true >, std::integer_sequence< bool, true, values... > > reduce_all
Definition: Meta.h:403
void swap(scoped_array< T > &a, scoped_array< T > &b)
Definition: Memory.h:734
EIGEN_STRONG_INLINE void swap(T &a, T &b)
Definition: Meta.h:536
Namespace containing all symbols from the Eigen library.
Definition: bench_norm.cpp:70
auto run(Kernel kernel, Args &&... args) -> decltype(kernel(args...))
Definition: gpu_test_helper.h:414
squared absolute value
Definition: GlobalFunctions.h:87
args
Definition: compute_granudrum_aor.py:143
type
Definition: compute_granudrum_aor.py:141
Definition: Eigen_Colamd.h:49
Definition: ForwardDeclarations.h:221
static EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ReturnType run()
Definition: Tuple.h:177
static EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ReturnType run(Tuple1 &&tuple1)
Definition: Tuple.h:168
static EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ReturnType run(Tuple1 &&tuple1, std::index_sequence< I1s... >, Tuple2 &&tuple2, std::index_sequence< I2s... >, MoreTuples &&... tuples)
Definition: Tuple.h:142
typename tuple_cat_impl< NTuples - 1, MergedTupleType, Tuples... >::ReturnType ReturnType
Definition: Tuple.h:137
static EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ReturnType run(Tuple1 &&tuple1, Tuple2 &&tuple2, MoreTuples &&... tuples)
Definition: Tuple.h:155
static EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE const T1 & run(const TupleType &tuple)
Definition: Tuple.h:122
typename tuple_get_impl< Idx - 1, Ts... >::ReturnType ReturnType
Definition: Tuple.h:103
static EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE const ReturnType & run(const TupleType &tuple)
Definition: Tuple.h:109
static EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE ReturnType & run(TupleType &tuple)
Definition: Tuple.h:105
typename unwrap_reference_wrapper< typename std::decay< T >::type >::type type
Definition: Tuple.h:194
void run(const string &dir_name, LinearSolver *linear_solver_pt, const unsigned nel_1d, bool mess_up_order)
Definition: two_d_poisson_compare_solvers.cc:317