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 (at) 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(__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