$darkmode
Eigen-unsupported  5.0.1-dev
TensorEvalTo.h
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 // IWYU pragma: private
14 #include "./InternalHeaderCheck.h"
15 
16 namespace Eigen {
17 
18 namespace internal {
19 template <typename XprType, template <class> class MakePointer_>
20 struct traits<TensorEvalToOp<XprType, MakePointer_> > {
21  // Type promotion to handle the case where the types of the lhs and the rhs are different.
22  typedef typename XprType::Scalar Scalar;
23  typedef traits<XprType> XprTraits;
24  typedef typename XprTraits::StorageKind StorageKind;
25  typedef typename XprTraits::Index Index;
26  typedef typename XprType::Nested Nested;
27  typedef std::remove_reference_t<Nested> Nested_;
28  static constexpr int NumDimensions = XprTraits::NumDimensions;
29  static constexpr int Layout = XprTraits::Layout;
30  typedef typename MakePointer_<Scalar>::Type PointerType;
31 
32  enum { Flags = 0 };
33  template <class T>
34  struct MakePointer {
35  // Intermediate typedef to workaround MSVC issue.
36  typedef MakePointer_<T> MakePointerT;
37  typedef typename MakePointerT::Type Type;
38  };
39 };
40 
41 template <typename XprType, template <class> class MakePointer_>
42 struct eval<TensorEvalToOp<XprType, MakePointer_>, Eigen::Dense> {
43  typedef const TensorEvalToOp<XprType, MakePointer_>& type;
44 };
45 
46 template <typename XprType, template <class> class MakePointer_>
47 struct nested<TensorEvalToOp<XprType, MakePointer_>, 1, typename eval<TensorEvalToOp<XprType, MakePointer_> >::type> {
48  typedef TensorEvalToOp<XprType, MakePointer_> type;
49 };
50 
51 } // end namespace internal
52 
53 template <typename XprType, template <class> class MakePointer_>
54 class TensorEvalToOp : public TensorBase<TensorEvalToOp<XprType, MakePointer_>, ReadOnlyAccessors> {
55  public:
56  typedef typename Eigen::internal::traits<TensorEvalToOp>::Scalar Scalar;
57  typedef typename Eigen::NumTraits<Scalar>::Real RealScalar;
58  typedef std::remove_const_t<typename XprType::CoeffReturnType> CoeffReturnType;
59  typedef typename MakePointer_<CoeffReturnType>::Type PointerType;
60  typedef typename Eigen::internal::nested<TensorEvalToOp>::type Nested;
61  typedef typename Eigen::internal::traits<TensorEvalToOp>::StorageKind StorageKind;
62  typedef typename Eigen::internal::traits<TensorEvalToOp>::Index Index;
63 
64  static constexpr int NumDims = Eigen::internal::traits<TensorEvalToOp>::NumDimensions;
65 
66  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorEvalToOp(PointerType buffer, const XprType& expr)
67  : m_xpr(expr), m_buffer(buffer) {}
68 
69  EIGEN_DEVICE_FUNC const internal::remove_all_t<typename XprType::Nested>& expression() const { return m_xpr; }
70 
71  EIGEN_DEVICE_FUNC PointerType buffer() const { return m_buffer; }
72 
73  protected:
74  typename XprType::Nested m_xpr;
75  PointerType m_buffer;
76 };
77 
78 template <typename ArgType, typename Device, template <class> class MakePointer_>
79 struct TensorEvaluator<const TensorEvalToOp<ArgType, MakePointer_>, Device> {
80  typedef TensorEvalToOp<ArgType, MakePointer_> XprType;
81  typedef typename ArgType::Scalar Scalar;
82  typedef typename TensorEvaluator<ArgType, Device>::Dimensions Dimensions;
83  typedef typename XprType::Index Index;
84  typedef std::remove_const_t<typename XprType::CoeffReturnType> CoeffReturnType;
85  typedef typename PacketType<CoeffReturnType, Device>::type PacketReturnType;
86  static constexpr int PacketSize = PacketType<CoeffReturnType, Device>::size;
87  typedef typename Eigen::internal::traits<XprType>::PointerType TensorPointerType;
88  typedef StorageMemory<CoeffReturnType, Device> Storage;
89  typedef typename Storage::Type EvaluatorPointerType;
90  enum {
91  IsAligned = TensorEvaluator<ArgType, Device>::IsAligned,
92  PacketAccess = TensorEvaluator<ArgType, Device>::PacketAccess,
93  BlockAccess = true,
94  PreferBlockAccess = false,
95  CoordAccess = false, // to be implemented
96  RawAccess = true
97  };
98 
99  static constexpr int Layout = TensorEvaluator<ArgType, Device>::Layout;
100  static constexpr int NumDims = internal::traits<ArgType>::NumDimensions;
101 
102  //===- Tensor block evaluation strategy (see TensorBlock.h) -------------===//
103  typedef internal::TensorBlockDescriptor<NumDims, Index> TensorBlockDesc;
104  typedef internal::TensorBlockScratchAllocator<Device> TensorBlockScratch;
105 
106  typedef typename TensorEvaluator<const ArgType, Device>::TensorBlock ArgTensorBlock;
107 
108  typedef internal::TensorBlockAssignment<CoeffReturnType, NumDims, typename ArgTensorBlock::XprType, Index>
109  TensorBlockAssignment;
110  //===--------------------------------------------------------------------===//
111 
112  EIGEN_STRONG_INLINE TensorEvaluator(const XprType& op, const Device& device)
113  : m_impl(op.expression(), device), m_buffer(device.get(op.buffer())), m_expression(op.expression()) {}
114 
115  EIGEN_STRONG_INLINE ~TensorEvaluator() {}
116 
117  EIGEN_DEVICE_FUNC const Dimensions& dimensions() const { return m_impl.dimensions(); }
118 
119  EIGEN_STRONG_INLINE bool evalSubExprsIfNeeded(EvaluatorPointerType scalar) {
120  EIGEN_UNUSED_VARIABLE(scalar);
121  eigen_assert(scalar == NULL);
122  return m_impl.evalSubExprsIfNeeded(m_buffer);
123  }
124 
125 #ifdef EIGEN_USE_THREADS
126  template <typename EvalSubExprsCallback>
127  EIGEN_STRONG_INLINE void evalSubExprsIfNeededAsync(EvaluatorPointerType scalar, EvalSubExprsCallback done) {
128  EIGEN_UNUSED_VARIABLE(scalar);
129  eigen_assert(scalar == NULL);
130  m_impl.evalSubExprsIfNeededAsync(m_buffer, std::move(done));
131  }
132 #endif
133 
134  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalScalar(Index i) const { m_buffer[i] = m_impl.coeff(i); }
135  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalPacket(Index i) const {
136  internal::pstoret<CoeffReturnType, PacketReturnType, Aligned>(
137  m_buffer + i, m_impl.template packet < TensorEvaluator<ArgType, Device>::IsAligned ? Aligned : Unaligned > (i));
138  }
139 
140  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE internal::TensorBlockResourceRequirements getResourceRequirements() const {
141  return m_impl.getResourceRequirements();
142  }
143 
144  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalBlock(TensorBlockDesc& desc, TensorBlockScratch& scratch) {
145  // Add `m_buffer` as destination buffer to the block descriptor.
146  desc.template AddDestinationBuffer<Layout>(
147  /*dst_base=*/m_buffer + desc.offset(),
148  /*dst_strides=*/internal::strides<Layout>(m_impl.dimensions()));
149 
150  ArgTensorBlock block = m_impl.block(desc, scratch, /*root_of_expr_ast=*/true);
151 
152  // If block was evaluated into a destination buffer, there is no need to do
153  // an assignment.
154  if (block.kind() != internal::TensorBlockKind::kMaterializedInOutput) {
155  TensorBlockAssignment::Run(
156  TensorBlockAssignment::target(desc.dimensions(), internal::strides<Layout>(m_impl.dimensions()), m_buffer,
157  desc.offset()),
158  block.expr());
159  }
160  block.cleanup();
161  }
162 
163  EIGEN_STRONG_INLINE void cleanup() { m_impl.cleanup(); }
164 
165  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index) const { return m_buffer[index]; }
166 
167  template <int LoadMode>
168  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketReturnType packet(Index index) const {
169  return internal::ploadt<PacketReturnType, LoadMode>(m_buffer + index);
170  }
171 
172  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorOpCost costPerCoeff(bool vectorized) const {
173  // We assume that evalPacket or evalScalar is called to perform the
174  // assignment and account for the cost of the write here.
175  return m_impl.costPerCoeff(vectorized) + TensorOpCost(0, sizeof(CoeffReturnType), 0, vectorized, PacketSize);
176  }
177 
178  EIGEN_DEVICE_FUNC EvaluatorPointerType data() const { return m_buffer; }
179  ArgType expression() const { return m_expression; }
180 
181  private:
182  TensorEvaluator<ArgType, Device> m_impl;
183  EvaluatorPointerType m_buffer;
184  const ArgType m_expression;
185 };
186 
187 } // end namespace Eigen
188 
189 #endif // EIGEN_CXX11_TENSOR_TENSOR_EVAL_TO_H
Namespace containing all symbols from the Eigen library.
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index