TensorForcedEval.h
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
 All Classes Functions Variables Typedefs Enumerator