1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2015 Benoit Steiner <benoit.steiner.goog@gmail.com>
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_CXX11_TENSOR_TENSOR_META_H
11 #define EIGEN_CXX11_TENSOR_TENSOR_META_H
12
13 namespace Eigen {
14
15 template<bool cond> struct Cond {};
16
17 template<typename T1, typename T2> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
choose(Cond<true>,const T1 & first,const T2 &)18 const T1& choose(Cond<true>, const T1& first, const T2&) {
19 return first;
20 }
21
22 template<typename T1, typename T2> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
choose(Cond<false>,const T1 &,const T2 & second)23 const T2& choose(Cond<false>, const T1&, const T2& second) {
24 return second;
25 }
26
27
28 template <typename T, typename X, typename Y>
29 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
divup(const X x,const Y y)30 T divup(const X x, const Y y) {
31 return static_cast<T>((x + y - 1) / y);
32 }
33
34 template <typename T>
35 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
divup(const T x,const T y)36 T divup(const T x, const T y) {
37 return static_cast<T>((x + y - 1) / y);
38 }
39
40 template <size_t n> struct max_n_1 {
41 static const size_t size = n;
42 };
43 template <> struct max_n_1<0> {
44 static const size_t size = 1;
45 };
46
47
48 // Default packet types
49 template <typename Scalar, typename Device>
50 struct PacketType : internal::packet_traits<Scalar> {
51 typedef typename internal::packet_traits<Scalar>::type type;
52 };
53
54 // For CUDA packet types when using a GpuDevice
55 #if defined(EIGEN_USE_GPU) && defined(__CUDACC__) && defined(EIGEN_HAS_CUDA_FP16)
56 template <>
57 struct PacketType<half, GpuDevice> {
58 typedef half2 type;
59 static const int size = 2;
60 enum {
61 HasAdd = 1,
62 HasSub = 1,
63 HasMul = 1,
64 HasNegate = 1,
65 HasAbs = 1,
66 HasArg = 0,
67 HasAbs2 = 0,
68 HasMin = 1,
69 HasMax = 1,
70 HasConj = 0,
71 HasSetLinear = 0,
72 HasBlend = 0,
73
74 HasDiv = 1,
75 HasSqrt = 1,
76 HasRsqrt = 1,
77 HasExp = 1,
78 HasLog = 1,
79 HasLog1p = 0,
80 HasLog10 = 0,
81 HasPow = 1,
82 };
83 };
84 #endif
85
86 #if defined(EIGEN_USE_SYCL)
87 template <typename T>
88 struct PacketType<T, SyclDevice> {
89 typedef T type;
90 static const int size = 1;
91 enum {
92 HasAdd = 0,
93 HasSub = 0,
94 HasMul = 0,
95 HasNegate = 0,
96 HasAbs = 0,
97 HasArg = 0,
98 HasAbs2 = 0,
99 HasMin = 0,
100 HasMax = 0,
101 HasConj = 0,
102 HasSetLinear = 0,
103 HasBlend = 0
104 };
105 };
106 #endif
107
108
109 // Tuple mimics std::pair but works on e.g. nvcc.
110 template <typename U, typename V> struct Tuple {
111 public:
112 U first;
113 V second;
114
115 typedef U first_type;
116 typedef V second_type;
117
118 EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
119 Tuple() : first(), second() {}
120
121 EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
122 Tuple(const U& f, const V& s) : first(f), second(s) {}
123
124 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
125 Tuple& operator= (const Tuple& rhs) {
126 if (&rhs == this) return *this;
127 first = rhs.first;
128 second = rhs.second;
129 return *this;
130 }
131
132 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
133 void swap(Tuple& rhs) {
134 using numext::swap;
135 swap(first, rhs.first);
136 swap(second, rhs.second);
137 }
138 };
139
140 template <typename U, typename V>
141 EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
142 bool operator==(const Tuple<U, V>& x, const Tuple<U, V>& y) {
143 return (x.first == y.first && x.second == y.second);
144 }
145
146 template <typename U, typename V>
147 EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
148 bool operator!=(const Tuple<U, V>& x, const Tuple<U, V>& y) {
149 return !(x == y);
150 }
151
152
153 // Can't use std::pairs on cuda devices
154 template <typename Idx> struct IndexPair {
155 EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE IndexPair() : first(0), second(0) {}
156 EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE IndexPair(Idx f, Idx s) : first(f), second(s) {}
157
158 EIGEN_DEVICE_FUNC void set(IndexPair<Idx> val) {
159 first = val.first;
160 second = val.second;
161 }
162
163 Idx first;
164 Idx second;
165 };
166
167
168 #ifdef EIGEN_HAS_SFINAE
169 namespace internal {
170
171 template<typename IndexType, Index... Is>
172 EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
173 array<Index, sizeof...(Is)> customIndices2Array(IndexType& idx, numeric_list<Index, Is...>) {
174 return { idx[Is]... };
175 }
176 template<typename IndexType>
177 EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
178 array<Index, 0> customIndices2Array(IndexType&, numeric_list<Index>) {
179 return array<Index, 0>();
180 }
181
182 /** Make an array (for index/dimensions) out of a custom index */
183 template<typename Index, std::size_t NumIndices, typename IndexType>
184 EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
185 array<Index, NumIndices> customIndices2Array(IndexType& idx) {
186 return customIndices2Array(idx, typename gen_numeric_list<Index, NumIndices>::type{});
187 }
188
189
190 template <typename B, typename D>
191 struct is_base_of
192 {
193
194 typedef char (&yes)[1];
195 typedef char (&no)[2];
196
197 template <typename BB, typename DD>
198 struct Host
199 {
200 operator BB*() const;
201 operator DD*();
202 };
203
204 template<typename T>
205 static yes check(D*, T);
206 static no check(B*, int);
207
208 static const bool value = sizeof(check(Host<B,D>(), int())) == sizeof(yes);
209 };
210
211 }
212 #endif
213
214
215
216 } // namespace Eigen
217
218 #endif // EIGEN_CXX11_TENSOR_TENSOR_META_H
219