![]() |
Eigen-unsupported
3.3.3
|
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2014 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_FORCED_EVAL_H 00011 #define EIGEN_CXX11_TENSOR_TENSOR_FORCED_EVAL_H 00012 00013 namespace Eigen { 00014 00022 00023 00024 00025 00026 00027 00028 namespace internal { 00029 template<typename XprType, template <class> class MakePointer_> 00030 struct traits<TensorForcedEvalOp<XprType, MakePointer_> > 00031 { 00032 // Type promotion to handle the case where the types of the lhs and the rhs are different. 00033 typedef typename XprType::Scalar Scalar; 00034 typedef traits<XprType> XprTraits; 00035 typedef typename traits<XprType>::StorageKind StorageKind; 00036 typedef typename traits<XprType>::Index Index; 00037 typedef typename XprType::Nested Nested; 00038 typedef typename remove_reference<Nested>::type _Nested; 00039 static const int NumDimensions = XprTraits::NumDimensions; 00040 static const int Layout = XprTraits::Layout; 00041 00042 enum { 00043 Flags = 0 00044 }; 00045 template <class T> struct MakePointer { 00046 // Intermediate typedef to workaround MSVC issue. 00047 typedef MakePointer_<T> MakePointerT; 00048 typedef typename MakePointerT::Type Type; 00049 }; 00050 }; 00051 00052 template<typename XprType, template <class> class MakePointer_> 00053 struct eval<TensorForcedEvalOp<XprType, MakePointer_>, Eigen::Dense> 00054 { 00055 typedef const TensorForcedEvalOp<XprType, MakePointer_>& type; 00056 }; 00057 00058 template<typename XprType, template <class> class MakePointer_> 00059 struct nested<TensorForcedEvalOp<XprType, MakePointer_>, 1, typename eval<TensorForcedEvalOp<XprType, MakePointer_> >::type> 00060 { 00061 typedef TensorForcedEvalOp<XprType, MakePointer_> type; 00062 }; 00063 00064 } // end namespace internal 00065 00066 00067 00068 template<typename XprType, template <class> class MakePointer_> 00069 class TensorForcedEvalOp : public TensorBase<TensorForcedEvalOp<XprType, MakePointer_>, ReadOnlyAccessors> 00070 { 00071 public: 00072 typedef typename Eigen::internal::traits<TensorForcedEvalOp>::Scalar Scalar; 00073 typedef typename Eigen::NumTraits<Scalar>::Real RealScalar; 00074 typedef typename internal::remove_const<typename XprType::CoeffReturnType>::type CoeffReturnType; 00075 typedef typename Eigen::internal::nested<TensorForcedEvalOp>::type Nested; 00076 typedef typename Eigen::internal::traits<TensorForcedEvalOp>::StorageKind StorageKind; 00077 typedef typename Eigen::internal::traits<TensorForcedEvalOp>::Index Index; 00078 00079 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorForcedEvalOp(const XprType& expr) 00080 : m_xpr(expr) {} 00081 00082 EIGEN_DEVICE_FUNC 00083 const typename internal::remove_all<typename XprType::Nested>::type& 00084 expression() const { return m_xpr; } 00085 00086 protected: 00087 typename XprType::Nested m_xpr; 00088 }; 00089 00090 00091 template<typename ArgType, typename Device, template <class> class MakePointer_> 00092 struct TensorEvaluator<const TensorForcedEvalOp<ArgType, MakePointer_>, Device> 00093 { 00094 typedef TensorForcedEvalOp<ArgType, MakePointer_> XprType; 00095 typedef typename ArgType::Scalar Scalar; 00096 typedef typename TensorEvaluator<ArgType, Device>::Dimensions Dimensions; 00097 typedef typename XprType::Index Index; 00098 typedef typename XprType::CoeffReturnType CoeffReturnType; 00099 typedef typename PacketType<CoeffReturnType, Device>::type PacketReturnType; 00100 static const int PacketSize = internal::unpacket_traits<PacketReturnType>::size; 00101 00102 enum { 00103 IsAligned = true, 00104 PacketAccess = (PacketSize > 1), 00105 Layout = TensorEvaluator<ArgType, Device>::Layout, 00106 RawAccess = true 00107 }; 00108 00109 EIGEN_DEVICE_FUNC TensorEvaluator(const XprType& op, const Device& device) 00111 : m_impl(op.expression(), device), m_op(op.expression()), m_device(device), m_buffer(NULL) 00112 { } 00113 00114 EIGEN_DEVICE_FUNC const Dimensions& dimensions() const { return m_impl.dimensions(); } 00115 00116 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool evalSubExprsIfNeeded(CoeffReturnType*) { 00117 const Index numValues = internal::array_prod(m_impl.dimensions()); 00118 m_buffer = (CoeffReturnType*)m_device.allocate(numValues * sizeof(CoeffReturnType)); 00119 // Should initialize the memory in case we're dealing with non POD types. 00120 if (NumTraits<CoeffReturnType>::RequireInitialization) { 00121 for (Index i = 0; i < numValues; ++i) { 00122 new(m_buffer+i) CoeffReturnType(); 00123 } 00124 } 00125 typedef TensorEvalToOp< const typename internal::remove_const<ArgType>::type > EvalTo; 00126 EvalTo evalToTmp(m_buffer, m_op); 00127 const bool PacketAccess = internal::IsVectorizable<Device, const ArgType>::value; 00128 internal::TensorExecutor<const EvalTo, typename internal::remove_const<Device>::type, PacketAccess>::run(evalToTmp, m_device); 00129 return true; 00130 } 00131 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void cleanup() { 00132 m_device.deallocate(m_buffer); 00133 m_buffer = NULL; 00134 } 00135 00136 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index) const 00137 { 00138 return m_buffer[index]; 00139 } 00140 00141 template<int LoadMode> 00142 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketReturnType packet(Index index) const 00143 { 00144 return internal::ploadt<PacketReturnType, LoadMode>(m_buffer + index); 00145 } 00146 00147 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorOpCost costPerCoeff(bool vectorized) const { 00148 return TensorOpCost(sizeof(CoeffReturnType), 0, 0, vectorized, PacketSize); 00149 } 00150 00151 EIGEN_DEVICE_FUNC typename MakePointer<Scalar>::Type data() const { return m_buffer; } 00152 00154 const TensorEvaluator<ArgType, Device>& impl() { return m_impl; } 00156 const Device& device() const{return m_device;} 00157 private: 00158 TensorEvaluator<ArgType, Device> m_impl; 00159 const ArgType m_op; 00160 const Device& m_device; 00161 typename MakePointer<CoeffReturnType>::Type m_buffer; 00162 }; 00163 00164 00165 } // end namespace Eigen 00166 00167 #endif // EIGEN_CXX11_TENSOR_TENSOR_FORCED_EVAL_H