• 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(__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