• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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@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