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