TensorEvalTo.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_EVAL_TO_H
00011 #define EIGEN_CXX11_TENSOR_TENSOR_EVAL_TO_H
00012 
00013 namespace Eigen {
00014 
00022 namespace internal {
00023 template<typename XprType, template <class> class MakePointer_>
00024 struct traits<TensorEvalToOp<XprType, MakePointer_> >
00025 {
00026   // Type promotion to handle the case where the types of the lhs and the rhs are different.
00027   typedef typename XprType::Scalar Scalar;
00028   typedef traits<XprType> XprTraits;
00029   typedef typename XprTraits::StorageKind StorageKind;
00030   typedef typename XprTraits::Index Index;
00031   typedef typename XprType::Nested Nested;
00032   typedef typename remove_reference<Nested>::type _Nested;
00033   static const int NumDimensions = XprTraits::NumDimensions;
00034   static const int Layout = XprTraits::Layout;
00035 
00036   enum {
00037     Flags = 0
00038   };
00039   template <class T>
00040   struct MakePointer {
00041     // Intermediate typedef to workaround MSVC issue.
00042     typedef MakePointer_<T> MakePointerT;
00043     typedef typename MakePointerT::Type Type;
00044   };
00045 };
00046 
00047 template<typename XprType, template <class> class MakePointer_>
00048 struct eval<TensorEvalToOp<XprType, MakePointer_>, Eigen::Dense>
00049 {
00050   typedef const TensorEvalToOp<XprType, MakePointer_>& type;
00051 };
00052 
00053 template<typename XprType, template <class> class MakePointer_>
00054 struct nested<TensorEvalToOp<XprType, MakePointer_>, 1, typename eval<TensorEvalToOp<XprType, MakePointer_> >::type>
00055 {
00056   typedef TensorEvalToOp<XprType, MakePointer_> type;
00057 };
00058 
00059 }  // end namespace internal
00060 
00061 
00062 
00063 
00064 template<typename XprType, template <class> class MakePointer_>
00065 class TensorEvalToOp : public TensorBase<TensorEvalToOp<XprType, MakePointer_>, ReadOnlyAccessors>
00066 {
00067   public:
00068   typedef typename Eigen::internal::traits<TensorEvalToOp>::Scalar Scalar;
00069   typedef typename Eigen::NumTraits<Scalar>::Real RealScalar;
00070   typedef typename internal::remove_const<typename XprType::CoeffReturnType>::type CoeffReturnType;
00071   typedef typename MakePointer_<CoeffReturnType>::Type PointerType;
00072   typedef typename Eigen::internal::nested<TensorEvalToOp>::type Nested;
00073   typedef typename Eigen::internal::traits<TensorEvalToOp>::StorageKind StorageKind;
00074   typedef typename Eigen::internal::traits<TensorEvalToOp>::Index Index;
00075 
00076   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorEvalToOp(PointerType buffer, const XprType& expr)
00077       : m_xpr(expr), m_buffer(buffer) {}
00078 
00079     EIGEN_DEVICE_FUNC
00080     const typename internal::remove_all<typename XprType::Nested>::type&
00081     expression() const { return m_xpr; }
00082 
00083     EIGEN_DEVICE_FUNC PointerType buffer() const { return m_buffer; }
00084 
00085   protected:
00086     typename XprType::Nested m_xpr;
00087     PointerType m_buffer;
00088 };
00089 
00090 
00091 
00092 template<typename ArgType, typename Device, template <class> class MakePointer_>
00093 struct TensorEvaluator<const TensorEvalToOp<ArgType, MakePointer_>, Device>
00094 {
00095   typedef TensorEvalToOp<ArgType, MakePointer_> XprType;
00096   typedef typename ArgType::Scalar Scalar;
00097   typedef typename TensorEvaluator<ArgType, Device>::Dimensions Dimensions;
00098   typedef typename XprType::Index Index;
00099   typedef typename internal::remove_const<typename XprType::CoeffReturnType>::type CoeffReturnType;
00100   typedef typename PacketType<CoeffReturnType, Device>::type PacketReturnType;
00101   static const int PacketSize = internal::unpacket_traits<PacketReturnType>::size;
00102 
00103   enum {
00104     IsAligned = TensorEvaluator<ArgType, Device>::IsAligned,
00105     PacketAccess = TensorEvaluator<ArgType, Device>::PacketAccess,
00106     Layout = TensorEvaluator<ArgType, Device>::Layout,
00107     CoordAccess = false,  // to be implemented
00108     RawAccess = true
00109   };
00110 
00111   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorEvaluator(const XprType& op, const Device& device)
00112       : m_impl(op.expression(), device), m_device(device),
00113           m_buffer(op.buffer()), m_op(op), m_expression(op.expression())
00114   { }
00115 
00116   // Used for accessor extraction in SYCL Managed TensorMap:
00117   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const XprType& op() const {
00118     return m_op;
00119   }
00120   
00121   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ~TensorEvaluator() {
00122   }
00123 
00124   typedef typename internal::traits<const TensorEvalToOp<ArgType, MakePointer_> >::template MakePointer<CoeffReturnType>::Type DevicePointer;
00125   EIGEN_DEVICE_FUNC const Dimensions& dimensions() const { return m_impl.dimensions(); }
00126 
00127   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool evalSubExprsIfNeeded(DevicePointer scalar) {
00128     EIGEN_UNUSED_VARIABLE(scalar);
00129     eigen_assert(scalar == NULL);
00130     return m_impl.evalSubExprsIfNeeded(m_buffer);
00131   }
00132 
00133   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalScalar(Index i) {
00134     m_buffer[i] = m_impl.coeff(i);
00135   }
00136   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalPacket(Index i) {
00137     internal::pstoret<CoeffReturnType, PacketReturnType, Aligned>(m_buffer + i, m_impl.template packet<TensorEvaluator<ArgType, Device>::IsAligned ? Aligned : Unaligned>(i));
00138   }
00139 
00140   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void cleanup() {
00141     m_impl.cleanup();
00142   }
00143 
00144   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index) const
00145   {
00146     return m_buffer[index];
00147   }
00148 
00149   template<int LoadMode>
00150   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketReturnType packet(Index index) const
00151   {
00152     return internal::ploadt<PacketReturnType, LoadMode>(m_buffer + index);
00153   }
00154 
00155   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorOpCost costPerCoeff(bool vectorized) const {
00156     // We assume that evalPacket or evalScalar is called to perform the
00157     // assignment and account for the cost of the write here.
00158     return m_impl.costPerCoeff(vectorized) +
00159         TensorOpCost(0, sizeof(CoeffReturnType), 0, vectorized, PacketSize);
00160   }
00161 
00162   EIGEN_DEVICE_FUNC DevicePointer data() const { return m_buffer; }
00163   ArgType expression() const { return m_expression; }
00164 
00166   const TensorEvaluator<ArgType, Device>& impl() const { return m_impl; }
00168   const Device& device() const{return m_device;}
00169 
00170  private:
00171   TensorEvaluator<ArgType, Device> m_impl;
00172   const Device& m_device;
00173   DevicePointer m_buffer;
00174   const XprType& m_op;
00175   const ArgType m_expression;
00176 };
00177 
00178 
00179 } // end namespace Eigen
00180 
00181 #endif // EIGEN_CXX11_TENSOR_TENSOR_EVAL_TO_H
 All Classes Functions Variables Typedefs Enumerator