• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(EIGEN_HAS_GPU_FP16)
56 
57 typedef ulonglong2 Packet4h2;
58 template<>
59 struct PacketType<half, GpuDevice> {
60   typedef Packet4h2 type;
61   static const int size = 8;
62   enum {
63     HasAdd    = 1,
64     HasSub    = 1,
65     HasMul    = 1,
66     HasNegate = 1,
67     HasAbs    = 1,
68     HasArg    = 0,
69     HasAbs2   = 0,
70     HasMin    = 1,
71     HasMax    = 1,
72     HasConj   = 0,
73     HasSetLinear = 0,
74     HasBlend  = 0,
75 
76     HasDiv    = 1,
77     HasSqrt   = 1,
78     HasRsqrt  = 1,
79     HasExp    = 1,
80     HasExpm1  = 0,
81     HasLog    = 1,
82     HasLog1p  = 0,
83     HasLog10  = 0,
84     HasPow    = 1,
85   };
86 };
87 #endif
88 
89 #if defined(EIGEN_USE_SYCL)
90 
91 namespace TensorSycl {
92 namespace internal {
93 
94 template <typename Index, Index A, Index B> struct PlusOp {
95   static constexpr Index Value = A + B;
96 };
97 
98 template <typename Index, Index A, Index B> struct DivOp {
99   static constexpr Index Value = A / B;
100 };
101 
102 template <typename Index, Index start, Index end, Index step,
103           template <class Indx, Indx...> class StepOp>
104 struct static_for {
105   template <typename UnaryOperator>
106   static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void loop(UnaryOperator op) {
107     op(start);
108     static_for<Index, StepOp<Index, start, step>::Value, end, step,
109                StepOp>::loop(op);
110   }
111 };
112 template <typename Index, Index end, Index step,
113           template <class Indx, Indx...> class StepOp>
114 struct static_for<Index, end, end, step, StepOp> {
115   template <typename UnaryOperator>
116   static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void loop(UnaryOperator) {}
117 };
118 
119 template <typename OutScalar, typename Device, bool Vectorizable>
120 struct Vectorise {
121   static const int PacketSize = 1;
122   typedef OutScalar PacketReturnType;
123 };
124 
125 template <typename OutScalar, typename Device>
126 struct Vectorise<OutScalar, Device, true> {
127   static const int PacketSize = Eigen::PacketType<OutScalar, Device>::size;
128   typedef typename Eigen::PacketType<OutScalar, Device>::type PacketReturnType;
129 };
130 
131 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Index roundUp(Index x, Index y) {
132   return ((((x) + (y)-1) / (y)) * (y));
133 }
134 
135 } // namespace internal
136 } // namespace TensorSycl
137 
138 template <>
139   struct PacketType<half, SyclDevice> {
140   typedef half type;
141   static const int size = 1;
142   enum {
143     HasAdd    = 0,
144     HasSub    = 0,
145     HasMul    = 0,
146     HasNegate = 0,
147     HasAbs    = 0,
148     HasArg    = 0,
149     HasAbs2   = 0,
150     HasMin    = 0,
151     HasMax    = 0,
152     HasConj   = 0,
153     HasSetLinear = 0,
154     HasBlend  = 0
155   };
156 };
157 template <typename Scalar>
158 struct PacketType<Scalar, SyclDevice> : internal::default_packet_traits {
159   typedef Scalar type;
160   typedef Scalar half;
161   enum {
162     Vectorizable = 0,
163     size = 1,
164     AlignedOnScalar = 0,
165     HasHalfPacket = 0
166   };
167   enum {
168     HasAdd    = 0,
169     HasSub    = 0,
170     HasMul    = 0,
171     HasNegate = 0,
172     HasAbs    = 0,
173     HasAbs2   = 0,
174     HasMin    = 0,
175     HasMax    = 0,
176     HasConj   = 0,
177     HasSetLinear = 0
178   };
179 
180 };
181 
182 template <typename Scalar>
183 struct PacketType<Scalar, const SyclDevice> : PacketType<Scalar, SyclDevice>{};
184 
185 #ifndef EIGEN_DONT_VECTORIZE_SYCL
186 #define PACKET_TYPE(CVQual, Type, val, lengths, DEV)\
187 template<> struct PacketType<CVQual Type, DEV> : internal::sycl_packet_traits<val, lengths> \
188 {\
189   typedef typename internal::packet_traits<Type>::type type;\
190   typedef typename internal::packet_traits<Type>::half half;\
191 };
192 
193 
194 PACKET_TYPE(const, float, 1, 4, SyclDevice)
195 PACKET_TYPE(, float, 1, 4, SyclDevice)
196 PACKET_TYPE(const, float, 1, 4, const SyclDevice)
197 PACKET_TYPE(, float, 1, 4, const SyclDevice)
198 
199 PACKET_TYPE(const, double, 0, 2, SyclDevice)
200 PACKET_TYPE(, double, 0, 2, SyclDevice)
201 PACKET_TYPE(const, double, 0, 2, const SyclDevice)
202 PACKET_TYPE(, double, 0, 2, const SyclDevice)
203 #undef PACKET_TYPE
204 
205 template<> struct PacketType<half, const SyclDevice>: PacketType<half, SyclDevice>{};
206 template<> struct PacketType<const half, const SyclDevice>: PacketType<half, SyclDevice>{};
207 #endif
208 #endif
209 
210 // Tuple mimics std::pair but works on e.g. nvcc.
211 template <typename U, typename V> struct Tuple {
212  public:
213   U first;
214   V second;
215 
216   typedef U first_type;
217   typedef V second_type;
218 
219   EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
220   Tuple() : first(), second() {}
221 
222   EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
223   Tuple(const U& f, const V& s) : first(f), second(s) {}
224 
225   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
226   void swap(Tuple& rhs) {
227     using numext::swap;
228     swap(first, rhs.first);
229     swap(second, rhs.second);
230   }
231 };
232 
233 template <typename U, typename V>
234 EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
235 bool operator==(const Tuple<U, V>& x, const Tuple<U, V>& y) {
236   return (x.first == y.first && x.second == y.second);
237 }
238 
239 template <typename U, typename V>
240 EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
241 bool operator!=(const Tuple<U, V>& x, const Tuple<U, V>& y) {
242   return !(x == y);
243 }
244 
245 
246 // Can't use std::pairs on cuda devices
247 template <typename Idx> struct IndexPair {
248   EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE IndexPair() : first(0), second(0) {}
249   EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE IndexPair(Idx f, Idx s) : first(f), second(s) {}
250 
251   EIGEN_DEVICE_FUNC void set(IndexPair<Idx> val) {
252     first = val.first;
253     second = val.second;
254   }
255 
256   Idx first;
257   Idx second;
258 };
259 
260 
261 #ifdef EIGEN_HAS_SFINAE
262 namespace internal {
263 
264   template<typename IndexType, typename Index, Index... Is>
265   EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
266   array<Index, sizeof...(Is)> customIndices2Array(IndexType& idx, numeric_list<Index, Is...>) {
267     return { idx[Is]... };
268   }
269   template<typename IndexType, typename Index>
270   EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
271   array<Index, 0> customIndices2Array(IndexType&, numeric_list<Index>) {
272     return array<Index, 0>();
273   }
274 
275   /** Make an array (for index/dimensions) out of a custom index */
276   template<typename Index, std::size_t NumIndices, typename IndexType>
277   EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
278   array<Index, NumIndices> customIndices2Array(IndexType& idx) {
279     return customIndices2Array(idx, typename gen_numeric_list<Index, NumIndices>::type{});
280   }
281 
282 
283   template <typename B, typename D>
284   struct is_base_of
285   {
286 
287     typedef char (&yes)[1];
288     typedef char (&no)[2];
289 
290     template <typename BB, typename DD>
291     struct Host
292     {
293       operator BB*() const;
294       operator DD*();
295     };
296 
297     template<typename T>
298     static yes check(D*, T);
299     static no check(B*, int);
300 
301     static const bool value = sizeof(check(Host<B,D>(), int())) == sizeof(yes);
302   };
303 
304 }
305 #endif
306 
307 
308 
309 }  // namespace Eigen
310 
311 #endif  // EIGEN_CXX11_TENSOR_TENSOR_META_H
312