TensorMeta.h
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra.
00003 //
00004 // Copyright (C) 2015 Benoit Steiner <benoit.steiner.goog@gmail.com>
00005 //
00006 // This Source Code Form is subject to the terms of the Mozilla
00007 // Public License v. 2.0. If a copy of the MPL was not distributed
00008 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
00009 
00010 #ifndef EIGEN_CXX11_TENSOR_TENSOR_META_H
00011 #define EIGEN_CXX11_TENSOR_TENSOR_META_H
00012 
00013 namespace Eigen {
00014 
00015 template<bool cond> struct Cond {};
00016 
00017 template<typename T1, typename T2> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
00018 const T1& choose(Cond<true>, const T1& first, const T2&) {
00019   return first;
00020 }
00021 
00022 template<typename T1, typename T2> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
00023 const T2& choose(Cond<false>, const T1&, const T2& second) {
00024   return second;
00025 }
00026 
00027 
00028 template <typename T, typename X, typename Y>
00029 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
00030 T divup(const X x, const Y y) {
00031   return static_cast<T>((x + y - 1) / y);
00032 }
00033 
00034 template <typename T>
00035 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
00036 T divup(const T x, const T y) {
00037   return static_cast<T>((x + y - 1) / y);
00038 }
00039 
00040 template <size_t n> struct max_n_1 {
00041   static const size_t size = n;
00042 };
00043 template <> struct max_n_1<0> {
00044   static const size_t size = 1;
00045 };
00046 
00047 
00048 // Default packet types
00049 template <typename Scalar, typename Device>
00050 struct PacketType : internal::packet_traits<Scalar> {
00051   typedef typename internal::packet_traits<Scalar>::type type;
00052 };
00053 
00054 // For CUDA packet types when using a GpuDevice
00055 #if defined(EIGEN_USE_GPU) && defined(__CUDACC__) && defined(EIGEN_HAS_CUDA_FP16)
00056 template <>
00057 struct PacketType<half, GpuDevice> {
00058   typedef half2 type;
00059   static const int size = 2;
00060   enum {
00061     HasAdd    = 1,
00062     HasSub    = 1,
00063     HasMul    = 1,
00064     HasNegate = 1,
00065     HasAbs    = 1,
00066     HasArg    = 0,
00067     HasAbs2   = 0,
00068     HasMin    = 1,
00069     HasMax    = 1,
00070     HasConj   = 0,
00071     HasSetLinear = 0,
00072     HasBlend  = 0,
00073 
00074     HasDiv    = 1,
00075     HasSqrt   = 1,
00076     HasRsqrt  = 1,
00077     HasExp    = 1,
00078     HasLog    = 1,
00079     HasLog1p  = 0,
00080     HasLog10  = 0,
00081     HasPow    = 1,
00082   };
00083 };
00084 #endif
00085 
00086 #if defined(EIGEN_USE_SYCL)
00087 template <typename T>
00088   struct PacketType<T, SyclDevice> {
00089   typedef T type;
00090   static const int size = 1;
00091   enum {
00092     HasAdd    = 0,
00093     HasSub    = 0,
00094     HasMul    = 0,
00095     HasNegate = 0,
00096     HasAbs    = 0,
00097     HasArg    = 0,
00098     HasAbs2   = 0,
00099     HasMin    = 0,
00100     HasMax    = 0,
00101     HasConj   = 0,
00102     HasSetLinear = 0,
00103     HasBlend  = 0
00104   };
00105 };
00106 #endif
00107 
00108 
00109 // Tuple mimics std::pair but works on e.g. nvcc.
00110 template <typename U, typename V> struct Tuple {
00111  public:
00112   U first;
00113   V second;
00114 
00115   typedef U first_type;
00116   typedef V second_type;
00117 
00118   EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00119   Tuple() : first(), second() {}
00120 
00121   EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00122   Tuple(const U& f, const V& s) : first(f), second(s) {}
00123 
00124   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00125   Tuple& operator= (const Tuple& rhs) {
00126     if (&rhs == this) return *this;
00127     first = rhs.first;
00128     second = rhs.second;
00129     return *this;
00130   }
00131 
00132   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00133   void swap(Tuple& rhs) {
00134     using numext::swap;
00135     swap(first, rhs.first);
00136     swap(second, rhs.second);
00137   }
00138 };
00139 
00140 template <typename U, typename V>
00141 EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00142 bool operator==(const Tuple<U, V>& x, const Tuple<U, V>& y) {
00143   return (x.first == y.first && x.second == y.second);
00144 }
00145 
00146 template <typename U, typename V>
00147 EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00148 bool operator!=(const Tuple<U, V>& x, const Tuple<U, V>& y) {
00149   return !(x == y);
00150 }
00151 
00152 
00153 // Can't use std::pairs on cuda devices
00154 template <typename Idx> struct IndexPair {
00155   EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE IndexPair() : first(0), second(0) {}
00156   EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE IndexPair(Idx f, Idx s) : first(f), second(s) {}
00157 
00158   EIGEN_DEVICE_FUNC void set(IndexPair<Idx> val) {
00159     first = val.first;
00160     second = val.second;
00161   }
00162 
00163   Idx first;
00164   Idx second;
00165 };
00166 
00167 
00168 #ifdef EIGEN_HAS_SFINAE
00169 namespace internal {
00170 
00171   template<typename IndexType, Index... Is>
00172   EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00173   array<Index, sizeof...(Is)> customIndices2Array(IndexType& idx, numeric_list<Index, Is...>) {
00174     return { idx[Is]... };
00175   }
00176   template<typename IndexType>
00177   EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00178   array<Index, 0> customIndices2Array(IndexType&, numeric_list<Index>) {
00179     return array<Index, 0>();
00180   }
00181 
00183   template<typename Index, std::size_t NumIndices, typename IndexType>
00184   EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00185   array<Index, NumIndices> customIndices2Array(IndexType& idx) {
00186     return customIndices2Array(idx, typename gen_numeric_list<Index, NumIndices>::type{});
00187   }
00188 
00189 
00190   template <typename B, typename D>
00191   struct is_base_of
00192   {
00193 
00194     typedef char (&yes)[1];
00195     typedef char (&no)[2];
00196 
00197     template <typename BB, typename DD>
00198     struct Host
00199     {
00200       operator BB*() const;
00201       operator DD*();
00202     };
00203 
00204     template<typename T>
00205     static yes check(D*, T);
00206     static no check(B*, int);
00207 
00208     static const bool value = sizeof(check(Host<B,D>(), int())) == sizeof(yes);
00209   };
00210 
00211 }
00212 #endif
00213 
00214 
00215 
00216 }  // namespace Eigen
00217 
00218 #endif  // EIGEN_CXX11_TENSOR_TENSOR_META_H
 All Classes Functions Variables Typedefs Enumerator