TensorAssign.h
Go to the documentation of this file.
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_ASSIGN_H
11 #define EIGEN_CXX11_TENSOR_TENSOR_ASSIGN_H
12 
13 // IWYU pragma: private
14 #include "./InternalHeaderCheck.h"
15 
16 namespace Eigen {
17 
26 namespace internal {
27 template <typename LhsXprType, typename RhsXprType>
28 struct traits<TensorAssignOp<LhsXprType, RhsXprType> > {
29  typedef typename LhsXprType::Scalar Scalar;
31  typedef
33  typedef typename LhsXprType::Nested LhsNested;
34  typedef typename RhsXprType::Nested RhsNested;
35  typedef std::remove_reference_t<LhsNested> LhsNested_;
36  typedef std::remove_reference_t<RhsNested> RhsNested_;
37  static constexpr std::size_t NumDimensions = internal::traits<LhsXprType>::NumDimensions;
38  static constexpr int Layout = internal::traits<LhsXprType>::Layout;
40 
41  enum { Flags = 0 };
42 };
43 
44 template <typename LhsXprType, typename RhsXprType>
45 struct eval<TensorAssignOp<LhsXprType, RhsXprType>, Eigen::Dense> {
47 };
48 
49 template <typename LhsXprType, typename RhsXprType>
50 struct nested<TensorAssignOp<LhsXprType, RhsXprType>, 1, typename eval<TensorAssignOp<LhsXprType, RhsXprType> >::type> {
52 };
53 
54 } // end namespace internal
55 
56 template <typename LhsXprType, typename RhsXprType>
57 class TensorAssignOp : public TensorBase<TensorAssignOp<LhsXprType, RhsXprType> > {
58  public:
61  typedef typename LhsXprType::CoeffReturnType CoeffReturnType;
65 
67 
68  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorAssignOp(LhsXprType& lhs, const RhsXprType& rhs)
69  : m_lhs_xpr(lhs), m_rhs_xpr(rhs) {}
70 
74  }
75 
77  return m_rhs_xpr;
78  }
79 
80  protected:
83 };
84 
85 template <typename LeftArgType, typename RightArgType, typename Device>
86 struct TensorEvaluator<const TensorAssignOp<LeftArgType, RightArgType>, Device> {
88  typedef typename XprType::Index Index;
89  typedef typename XprType::Scalar Scalar;
95 
97  static constexpr int NumDims = XprType::NumDims;
99 
100  enum {
101  IsAligned =
110  };
111 
112  //===- Tensor block evaluation strategy (see TensorBlock.h) -------------===//
115 
117  //===--------------------------------------------------------------------===//
118 
119  TensorEvaluator(const XprType& op, const Device& device)
120  : m_leftImpl(op.lhsExpression(), device), m_rightImpl(op.rhsExpression(), device) {
123  YOU_MADE_A_PROGRAMMING_MISTAKE);
124  }
125 
127  // The dimensions of the lhs and the rhs tensors should be equal to prevent
128  // overflows and ensure the result is fully initialized.
129  // TODO: use left impl instead if right impl dimensions are known at compile time.
130  return m_rightImpl.dimensions();
131  }
132 
134  eigen_assert(dimensions_match(m_leftImpl.dimensions(), m_rightImpl.dimensions()));
135  m_leftImpl.evalSubExprsIfNeeded(NULL);
136  // If the lhs provides raw access to its storage area (i.e. if m_leftImpl.data() returns a non
137  // null value), attempt to evaluate the rhs expression in place. Returns true iff in place
138  // evaluation isn't supported and the caller still needs to manually assign the values generated
139  // by the rhs to the lhs.
140  return m_rightImpl.evalSubExprsIfNeeded(m_leftImpl.data());
141  }
142 
143 #ifdef EIGEN_USE_THREADS
144  template <typename EvalSubExprsCallback>
145  EIGEN_STRONG_INLINE void evalSubExprsIfNeededAsync(EvaluatorPointerType, EvalSubExprsCallback done) {
146  m_leftImpl.evalSubExprsIfNeededAsync(nullptr, [this, done](bool) {
147  m_rightImpl.evalSubExprsIfNeededAsync(m_leftImpl.data(), [done](bool need_assign) { done(need_assign); });
148  });
149  }
150 #endif // EIGEN_USE_THREADS
151 
153  m_leftImpl.cleanup();
154  m_rightImpl.cleanup();
155  }
156 
158  m_leftImpl.coeffRef(i) = m_rightImpl.coeff(i);
159  }
163  m_leftImpl.template writePacket<LhsStoreMode>(i, m_rightImpl.template packet<RhsLoadMode>(i));
164  }
165  EIGEN_DEVICE_FUNC CoeffReturnType coeff(Index index) const { return m_leftImpl.coeff(index); }
166  template <int LoadMode>
168  return m_leftImpl.template packet<LoadMode>(index);
169  }
170 
172  // We assume that evalPacket or evalScalar is called to perform the
173  // assignment and account for the cost of the write here, but reduce left
174  // cost by one load because we are using m_leftImpl.coeffRef.
175  TensorOpCost left = m_leftImpl.costPerCoeff(vectorized);
176  return m_rightImpl.costPerCoeff(vectorized) +
177  TensorOpCost(numext::maxi(0.0, left.bytes_loaded() - sizeof(CoeffReturnType)), left.bytes_stored(),
178  left.compute_cycles()) +
179  TensorOpCost(0, sizeof(CoeffReturnType), 0, vectorized, PacketSize);
180  }
181 
183  return internal::TensorBlockResourceRequirements::merge(m_leftImpl.getResourceRequirements(),
184  m_rightImpl.getResourceRequirements());
185  }
186 
188  if (TensorEvaluator<LeftArgType, Device>::RawAccess && m_leftImpl.data() != NULL) {
189  // If destination has raw data access, we pass it as a potential
190  // destination for a block descriptor evaluation.
191  desc.template AddDestinationBuffer<Layout>(
192  /*dst_base=*/m_leftImpl.data() + desc.offset(),
193  /*dst_strides=*/internal::strides<Layout>(m_leftImpl.dimensions()));
194  }
195 
196  RightTensorBlock block = m_rightImpl.block(desc, scratch, /*root_of_expr_ast=*/true);
197  // If block was evaluated into a destination, there is no need to do assignment.
199  m_leftImpl.writeBlock(desc, block);
200  }
201  block.cleanup();
202  }
203 
204  EIGEN_DEVICE_FUNC EvaluatorPointerType data() const { return m_leftImpl.data(); }
205 
206  private:
209 };
210 
211 } // namespace Eigen
212 
213 #endif // EIGEN_CXX11_TENSOR_TENSOR_ASSIGN_H
int i
Definition: BiCGSTAB_step_by_step.cpp:9
#define EIGEN_DEVICE_FUNC
Definition: Macros.h:892
#define eigen_assert(x)
Definition: Macros.h:910
#define EIGEN_STRONG_INLINE
Definition: Macros.h:834
#define EIGEN_STATIC_ASSERT(X, MSG)
Definition: StaticAssert.h:26
SCALAR Scalar
Definition: bench_gemm.cpp:45
Definition: TensorAssign.h:57
const internal::remove_all_t< typename RhsXprType::Nested > & m_rhs_xpr
Definition: TensorAssign.h:82
internal::remove_all_t< typename LhsXprType::Nested > & m_lhs_xpr
Definition: TensorAssign.h:81
LhsXprType::CoeffReturnType CoeffReturnType
Definition: TensorAssign.h:61
Eigen::internal::traits< TensorAssignOp >::StorageKind StorageKind
Definition: TensorAssign.h:63
Eigen::internal::traits< TensorAssignOp >::Scalar Scalar
Definition: TensorAssign.h:59
static constexpr int NumDims
Definition: TensorAssign.h:66
Eigen::internal::nested< TensorAssignOp >::type Nested
Definition: TensorAssign.h:62
EIGEN_DEVICE_FUNC const internal::remove_all_t< typename RhsXprType::Nested > & rhsExpression() const
Definition: TensorAssign.h:76
Eigen::NumTraits< Scalar >::Real RealScalar
Definition: TensorAssign.h:60
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorAssignOp(LhsXprType &lhs, const RhsXprType &rhs)
Definition: TensorAssign.h:68
EIGEN_DEVICE_FUNC internal::remove_all_t< typename LhsXprType::Nested > & lhsExpression() const
Definition: TensorAssign.h:72
Eigen::internal::traits< TensorAssignOp >::Index Index
Definition: TensorAssign.h:64
The tensor base class.
Definition: TensorBase.h:1026
Definition: TensorCostModel.h:28
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE double bytes_stored() const
Definition: TensorCostModel.h:69
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE double bytes_loaded() const
Definition: TensorCostModel.h:68
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE double compute_cycles() const
Definition: TensorCostModel.h:70
IndexType offset() const
Definition: TensorBlock.h:270
Definition: TensorBlock.h:604
TensorBlockKind kind() const
Definition: TensorBlock.h:617
void cleanup()
Definition: TensorBlock.h:626
@ Unaligned
Definition: Constants.h:235
@ Aligned
Definition: Constants.h:242
return int(ret)+1
char char * op
Definition: level2_impl.h:374
@ kMaterializedInOutput
Definition: TensorBlock.h:559
typename remove_all< T >::type remove_all_t
Definition: Meta.h:142
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE T maxi(const T &x, const T &y)
Definition: MathFunctions.h:926
Namespace containing all symbols from the Eigen library.
Definition: bench_norm.cpp:70
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool dimensions_match(Dims1 dims1, Dims2 dims2)
Definition: TensorDimensions.h:322
Extend namespace for flags.
Definition: fsi_chan_precond_driver.cc:56
type
Definition: compute_granudrum_aor.py:141
Definition: Eigen_Colamd.h:49
Definition: Constants.h:519
T Real
Definition: NumTraits.h:183
Definition: TensorMeta.h:47
Definition: TensorForwardDeclarations.h:42
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalPacket(Index i) const
Definition: TensorAssign.h:160
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorOpCost costPerCoeff(bool vectorized) const
Definition: TensorAssign.h:171
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalScalar(Index i) const
Definition: TensorAssign.h:157
TensorAssignOp< LeftArgType, RightArgType > XprType
Definition: TensorAssign.h:87
EIGEN_STRONG_INLINE bool evalSubExprsIfNeeded(EvaluatorPointerType)
Definition: TensorAssign.h:133
TensorEvaluator< RightArgType, Device >::Dimensions Dimensions
Definition: TensorAssign.h:92
TensorEvaluator(const XprType &op, const Device &device)
Definition: TensorAssign.h:119
internal::TensorBlockDescriptor< NumDims, Index > TensorBlockDesc
Definition: TensorAssign.h:113
EIGEN_DEVICE_FUNC PacketReturnType packet(Index index) const
Definition: TensorAssign.h:167
EIGEN_STRONG_INLINE void cleanup()
Definition: TensorAssign.h:152
EIGEN_DEVICE_FUNC const Dimensions & dimensions() const
Definition: TensorAssign.h:126
XprType::CoeffReturnType CoeffReturnType
Definition: TensorAssign.h:90
internal::TensorBlockScratchAllocator< Device > TensorBlockScratch
Definition: TensorAssign.h:114
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE internal::TensorBlockResourceRequirements getResourceRequirements() const
Definition: TensorAssign.h:182
TensorEvaluator< const RightArgType, Device >::TensorBlock RightTensorBlock
Definition: TensorAssign.h:116
StorageMemory< CoeffReturnType, Device > Storage
Definition: TensorAssign.h:93
PacketType< CoeffReturnType, Device >::type PacketReturnType
Definition: TensorAssign.h:91
TensorEvaluator< LeftArgType, Device > m_leftImpl
Definition: TensorAssign.h:207
TensorEvaluator< RightArgType, Device > m_rightImpl
Definition: TensorAssign.h:208
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalBlock(TensorBlockDesc &desc, TensorBlockScratch &scratch)
Definition: TensorAssign.h:187
EIGEN_DEVICE_FUNC EvaluatorPointerType data() const
Definition: TensorAssign.h:204
EIGEN_DEVICE_FUNC CoeffReturnType coeff(Index index) const
Definition: TensorAssign.h:165
A cost model used to limit the number of threads used for evaluating tensor expression.
Definition: TensorEvaluator.h:31
static constexpr int Layout
Definition: TensorEvaluator.h:46
Storage::Type EvaluatorPointerType
Definition: TensorEvaluator.h:41
@ PacketAccess
Definition: TensorEvaluator.h:50
@ IsAligned
Definition: TensorEvaluator.h:49
static constexpr int PacketSize
Definition: TensorEvaluator.h:38
EIGEN_DEVICE_FUNC EvaluatorPointerType data() const
Definition: TensorEvaluator.h:165
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorBlock block(TensorBlockDesc &desc, TensorBlockScratch &scratch, bool=false) const
Definition: TensorEvaluator.h:147
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorBlockResourceRequirements merge(const TensorBlockResourceRequirements &lhs, const TensorBlockResourceRequirements &rhs)
Definition: TensorBlock.h:129
const TensorAssignOp< LhsXprType, RhsXprType > & type
Definition: TensorAssign.h:46
Definition: XprHelper.h:427
Definition: TensorTraits.h:152
ref_selector< T >::type type
Definition: TensorTraits.h:153
Definition: XprHelper.h:145
RhsXprType::Nested RhsNested
Definition: TensorAssign.h:34
traits< LhsXprType >::StorageKind StorageKind
Definition: TensorAssign.h:30
std::remove_reference_t< RhsNested > RhsNested_
Definition: TensorAssign.h:36
traits< LhsXprType >::PointerType PointerType
Definition: TensorAssign.h:39
LhsXprType::Nested LhsNested
Definition: TensorAssign.h:33
LhsXprType::Scalar Scalar
Definition: TensorAssign.h:29
promote_index_type< typename traits< LhsXprType >::Index, typename traits< RhsXprType >::Index >::type Index
Definition: TensorAssign.h:32
std::remove_reference_t< LhsNested > LhsNested_
Definition: TensorAssign.h:35
Definition: ForwardDeclarations.h:21