Home | History | Annotate | Download | only in Tensor
      1 // This file is part of Eigen, a lightweight C++ template library
      2 // for linear algebra.
      3 //
      4 // Copyright (C) 2014 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_EVAL_TO_H
     11 #define EIGEN_CXX11_TENSOR_TENSOR_EVAL_TO_H
     12 
     13 namespace Eigen {
     14 
     15 /** \class TensorForcedEval
     16   * \ingroup CXX11_Tensor_Module
     17   *
     18   * \brief Tensor reshaping class.
     19   *
     20   *
     21   */
     22 namespace internal {
     23 template<typename XprType, template <class> class MakePointer_>
     24 struct traits<TensorEvalToOp<XprType, MakePointer_> >
     25 {
     26   // Type promotion to handle the case where the types of the lhs and the rhs are different.
     27   typedef typename XprType::Scalar Scalar;
     28   typedef traits<XprType> XprTraits;
     29   typedef typename XprTraits::StorageKind StorageKind;
     30   typedef typename XprTraits::Index Index;
     31   typedef typename XprType::Nested Nested;
     32   typedef typename remove_reference<Nested>::type _Nested;
     33   static const int NumDimensions = XprTraits::NumDimensions;
     34   static const int Layout = XprTraits::Layout;
     35 
     36   enum {
     37     Flags = 0
     38   };
     39   template <class T>
     40   struct MakePointer {
     41     // Intermediate typedef to workaround MSVC issue.
     42     typedef MakePointer_<T> MakePointerT;
     43     typedef typename MakePointerT::Type Type;
     44   };
     45 };
     46 
     47 template<typename XprType, template <class> class MakePointer_>
     48 struct eval<TensorEvalToOp<XprType, MakePointer_>, Eigen::Dense>
     49 {
     50   typedef const TensorEvalToOp<XprType, MakePointer_>& type;
     51 };
     52 
     53 template<typename XprType, template <class> class MakePointer_>
     54 struct nested<TensorEvalToOp<XprType, MakePointer_>, 1, typename eval<TensorEvalToOp<XprType, MakePointer_> >::type>
     55 {
     56   typedef TensorEvalToOp<XprType, MakePointer_> type;
     57 };
     58 
     59 }  // end namespace internal
     60 
     61 
     62 
     63 
     64 template<typename XprType, template <class> class MakePointer_>
     65 class TensorEvalToOp : public TensorBase<TensorEvalToOp<XprType, MakePointer_>, ReadOnlyAccessors>
     66 {
     67   public:
     68   typedef typename Eigen::internal::traits<TensorEvalToOp>::Scalar Scalar;
     69   typedef typename Eigen::NumTraits<Scalar>::Real RealScalar;
     70   typedef typename internal::remove_const<typename XprType::CoeffReturnType>::type CoeffReturnType;
     71   typedef typename MakePointer_<CoeffReturnType>::Type PointerType;
     72   typedef typename Eigen::internal::nested<TensorEvalToOp>::type Nested;
     73   typedef typename Eigen::internal::traits<TensorEvalToOp>::StorageKind StorageKind;
     74   typedef typename Eigen::internal::traits<TensorEvalToOp>::Index Index;
     75 
     76   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorEvalToOp(PointerType buffer, const XprType& expr)
     77       : m_xpr(expr), m_buffer(buffer) {}
     78 
     79     EIGEN_DEVICE_FUNC
     80     const typename internal::remove_all<typename XprType::Nested>::type&
     81     expression() const { return m_xpr; }
     82 
     83     EIGEN_DEVICE_FUNC PointerType buffer() const { return m_buffer; }
     84 
     85   protected:
     86     typename XprType::Nested m_xpr;
     87     PointerType m_buffer;
     88 };
     89 
     90 
     91 
     92 template<typename ArgType, typename Device, template <class> class MakePointer_>
     93 struct TensorEvaluator<const TensorEvalToOp<ArgType, MakePointer_>, Device>
     94 {
     95   typedef TensorEvalToOp<ArgType, MakePointer_> XprType;
     96   typedef typename ArgType::Scalar Scalar;
     97   typedef typename TensorEvaluator<ArgType, Device>::Dimensions Dimensions;
     98   typedef typename XprType::Index Index;
     99   typedef typename internal::remove_const<typename XprType::CoeffReturnType>::type CoeffReturnType;
    100   typedef typename PacketType<CoeffReturnType, Device>::type PacketReturnType;
    101   static const int PacketSize = internal::unpacket_traits<PacketReturnType>::size;
    102 
    103   enum {
    104     IsAligned = TensorEvaluator<ArgType, Device>::IsAligned,
    105     PacketAccess = TensorEvaluator<ArgType, Device>::PacketAccess,
    106     Layout = TensorEvaluator<ArgType, Device>::Layout,
    107     CoordAccess = false,  // to be implemented
    108     RawAccess = true
    109   };
    110 
    111   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorEvaluator(const XprType& op, const Device& device)
    112       : m_impl(op.expression(), device), m_device(device),
    113           m_buffer(op.buffer()), m_op(op), m_expression(op.expression())
    114   { }
    115 
    116   // Used for accessor extraction in SYCL Managed TensorMap:
    117   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const XprType& op() const {
    118     return m_op;
    119   }
    120 
    121   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ~TensorEvaluator() {
    122   }
    123 
    124   typedef typename internal::traits<const TensorEvalToOp<ArgType, MakePointer_> >::template MakePointer<CoeffReturnType>::Type DevicePointer;
    125   EIGEN_DEVICE_FUNC const Dimensions& dimensions() const { return m_impl.dimensions(); }
    126 
    127   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool evalSubExprsIfNeeded(DevicePointer scalar) {
    128     EIGEN_UNUSED_VARIABLE(scalar);
    129     eigen_assert(scalar == NULL);
    130     return m_impl.evalSubExprsIfNeeded(m_buffer);
    131   }
    132 
    133   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalScalar(Index i) {
    134     m_buffer[i] = m_impl.coeff(i);
    135   }
    136   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalPacket(Index i) {
    137     internal::pstoret<CoeffReturnType, PacketReturnType, Aligned>(m_buffer + i, m_impl.template packet<TensorEvaluator<ArgType, Device>::IsAligned ? Aligned : Unaligned>(i));
    138   }
    139 
    140   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void cleanup() {
    141     m_impl.cleanup();
    142   }
    143 
    144   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index) const
    145   {
    146     return m_buffer[index];
    147   }
    148 
    149   template<int LoadMode>
    150   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketReturnType packet(Index index) const
    151   {
    152     return internal::ploadt<PacketReturnType, LoadMode>(m_buffer + index);
    153   }
    154 
    155   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorOpCost costPerCoeff(bool vectorized) const {
    156     // We assume that evalPacket or evalScalar is called to perform the
    157     // assignment and account for the cost of the write here.
    158     return m_impl.costPerCoeff(vectorized) +
    159         TensorOpCost(0, sizeof(CoeffReturnType), 0, vectorized, PacketSize);
    160   }
    161 
    162   EIGEN_DEVICE_FUNC DevicePointer data() const { return m_buffer; }
    163   ArgType expression() const { return m_expression; }
    164 
    165   /// required by sycl in order to extract the accessor
    166   const TensorEvaluator<ArgType, Device>& impl() const { return m_impl; }
    167   /// added for sycl in order to construct the buffer from the sycl device
    168   const Device& device() const{return m_device;}
    169 
    170  private:
    171   TensorEvaluator<ArgType, Device> m_impl;
    172   const Device& m_device;
    173   DevicePointer m_buffer;
    174   const XprType& m_op;
    175   const ArgType m_expression;
    176 };
    177 
    178 
    179 } // end namespace Eigen
    180 
    181 #endif // EIGEN_CXX11_TENSOR_TENSOR_EVAL_TO_H
    182