TensorMeta.h (8104B)
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 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 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 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 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