TensorRef.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_REF_H
11 #define EIGEN_CXX11_TENSOR_TENSOR_REF_H
12 
13 // IWYU pragma: private
14 #include "./InternalHeaderCheck.h"
15 
16 namespace Eigen {
17 
18 namespace internal {
19 
20 template <typename Dimensions, typename Scalar>
22  public:
25 
26  EIGEN_DEVICE_FUNC virtual const Dimensions& dimensions() const = 0;
27  EIGEN_DEVICE_FUNC virtual const Scalar* data() const = 0;
28 
29  EIGEN_DEVICE_FUNC virtual const Scalar coeff(DenseIndex index) const = 0;
31 
32  void incrRefCount() { ++m_refcount; }
33  void decrRefCount() { --m_refcount; }
34  int refCount() const { return m_refcount; }
35 
36  private:
37  // No copy, no assignment;
40 
42 };
43 
44 template <typename Dimensions, typename Expr, typename Device>
46  : public TensorLazyBaseEvaluator<Dimensions, typename TensorEvaluator<Expr, Device>::Scalar> {
47  public:
48  // typedef typename TensorEvaluator<Expr, Device>::Dimensions Dimensions;
53 
54  TensorLazyEvaluatorReadOnly(const Expr& expr, const Device& device) : m_impl(expr, device), m_dummy(Scalar(0)) {
57  }
59 
60  EIGEN_DEVICE_FUNC virtual const Dimensions& dimensions() const { return m_dims; }
61  EIGEN_DEVICE_FUNC virtual const Scalar* data() const { return m_impl.data(); }
62 
63  EIGEN_DEVICE_FUNC virtual const Scalar coeff(DenseIndex index) const { return m_impl.coeff(index); }
65  eigen_assert(false && "can't reference the coefficient of a rvalue");
66  return m_dummy;
67  };
68 
69  protected:
71  Dimensions m_dims;
73 };
74 
75 template <typename Dimensions, typename Expr, typename Device>
76 class TensorLazyEvaluatorWritable : public TensorLazyEvaluatorReadOnly<Dimensions, Expr, Device> {
77  public:
79  typedef typename Base::Scalar Scalar;
82 
83  TensorLazyEvaluatorWritable(const Expr& expr, const Device& device) : Base(expr, device) {}
85 
86  EIGEN_DEVICE_FUNC virtual Scalar& coeffRef(DenseIndex index) { return this->m_impl.coeffRef(index); }
87 };
88 
89 template <typename Dimensions, typename Expr, typename Device>
90 class TensorLazyEvaluator : public std::conditional_t<bool(internal::is_lvalue<Expr>::value),
91  TensorLazyEvaluatorWritable<Dimensions, Expr, Device>,
92  TensorLazyEvaluatorReadOnly<Dimensions, const Expr, Device> > {
93  public:
94  typedef std::conditional_t<bool(internal::is_lvalue<Expr>::value),
98  typedef typename Base::Scalar Scalar;
99 
100  TensorLazyEvaluator(const Expr& expr, const Device& device) : Base(expr, device) {}
101  virtual ~TensorLazyEvaluator() {}
102 };
103 
104 } // namespace internal
105 
113 template <typename PlainObjectType>
114 class TensorRef : public TensorBase<TensorRef<PlainObjectType> > {
115  public:
117  typedef typename PlainObjectType::Base Base;
123  typedef typename Base::CoeffReturnType CoeffReturnType;
124  typedef Scalar* PointerType;
126 
127  static constexpr Index NumIndices = PlainObjectType::NumIndices;
128  typedef typename PlainObjectType::Dimensions Dimensions;
129 
130  static constexpr int Layout = PlainObjectType::Layout;
131  enum {
132  IsAligned = false,
133  PacketAccess = false,
134  BlockAccess = false,
136  CoordAccess = false, // to be implemented
137  RawAccess = false
138  };
139 
140  //===- Tensor block evaluation strategy (see TensorBlock.h) -----------===//
142  //===------------------------------------------------------------------===//
143 
145 
146  template <typename Expression>
147  EIGEN_STRONG_INLINE TensorRef(const Expression& expr)
148  : m_evaluator(new internal::TensorLazyEvaluator<Dimensions, Expression, DefaultDevice>(expr, DefaultDevice())) {
149  m_evaluator->incrRefCount();
150  }
151 
152  template <typename Expression>
153  EIGEN_STRONG_INLINE TensorRef& operator=(const Expression& expr) {
154  unrefEvaluator();
156  m_evaluator->incrRefCount();
157  return *this;
158  }
159 
161 
162  TensorRef(const TensorRef& other) : TensorBase<TensorRef<PlainObjectType> >(other), m_evaluator(other.m_evaluator) {
163  eigen_assert(m_evaluator->refCount() > 0);
164  m_evaluator->incrRefCount();
165  }
166 
167  TensorRef& operator=(const TensorRef& other) {
168  if (this != &other) {
169  unrefEvaluator();
170  m_evaluator = other.m_evaluator;
171  eigen_assert(m_evaluator->refCount() > 0);
172  m_evaluator->incrRefCount();
173  }
174  return *this;
175  }
176 
177  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index rank() const { return m_evaluator->dimensions().size(); }
179  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions& dimensions() const { return m_evaluator->dimensions(); }
180  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index size() const { return m_evaluator->dimensions().TotalSize(); }
181  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar* data() const { return m_evaluator->data(); }
182 
183  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator()(Index index) const { return m_evaluator->coeff(index); }
184 
185  template <typename... IndexTypes>
186  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator()(Index firstIndex, IndexTypes... otherIndices) const {
187  const std::size_t num_indices = (sizeof...(otherIndices) + 1);
188  const array<Index, num_indices> indices{{firstIndex, otherIndices...}};
189  return coeff(indices);
190  }
191  template <typename... IndexTypes>
192  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& coeffRef(Index firstIndex, IndexTypes... otherIndices) {
193  const std::size_t num_indices = (sizeof...(otherIndices) + 1);
194  const array<Index, num_indices> indices{{firstIndex, otherIndices...}};
195  return coeffRef(indices);
196  }
197 
198  template <std::size_t NumIndices>
200  const Dimensions& dims = this->dimensions();
201  Index index = 0;
202  if (PlainObjectType::Options & RowMajor) {
203  index += indices[0];
204  for (size_t i = 1; i < NumIndices; ++i) {
205  index = index * dims[i] + indices[i];
206  }
207  } else {
208  index += indices[NumIndices - 1];
209  for (int i = NumIndices - 2; i >= 0; --i) {
210  index = index * dims[i] + indices[i];
211  }
212  }
213  return m_evaluator->coeff(index);
214  }
215  template <std::size_t NumIndices>
217  const Dimensions& dims = this->dimensions();
218  Index index = 0;
219  if (PlainObjectType::Options & RowMajor) {
220  index += indices[0];
221  for (size_t i = 1; i < NumIndices; ++i) {
222  index = index * dims[i] + indices[i];
223  }
224  } else {
225  index += indices[NumIndices - 1];
226  for (int i = NumIndices - 2; i >= 0; --i) {
227  index = index * dims[i] + indices[i];
228  }
229  }
230  return m_evaluator->coeffRef(index);
231  }
232 
233  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar coeff(Index index) const { return m_evaluator->coeff(index); }
234 
236 
237  private:
239  if (m_evaluator) {
240  m_evaluator->decrRefCount();
241  if (m_evaluator->refCount() == 0) {
242  delete m_evaluator;
243  }
244  }
245  }
246 
248 };
249 
250 // evaluator for rvalues
251 template <typename Derived, typename Device>
252 struct TensorEvaluator<const TensorRef<Derived>, Device> {
253  typedef typename Derived::Index Index;
254  typedef typename Derived::Scalar Scalar;
257  typedef typename Derived::Dimensions Dimensions;
260 
261  static constexpr int Layout = TensorRef<Derived>::Layout;
262  enum {
263  IsAligned = false,
264  PacketAccess = false,
265  BlockAccess = false,
266  PreferBlockAccess = false,
267  CoordAccess = false, // to be implemented
268  RawAccess = false
269  };
270 
271  //===- Tensor block evaluation strategy (see TensorBlock.h) -------------===//
273  //===--------------------------------------------------------------------===//
274 
275  EIGEN_STRONG_INLINE TensorEvaluator(const TensorRef<Derived>& m, const Device&) : m_ref(m) {}
276 
277  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions& dimensions() const { return m_ref.dimensions(); }
278 
280 
282 
283  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index) const { return m_ref.coeff(index); }
284 
285  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& coeffRef(Index index) { return m_ref.coeffRef(index); }
286 
287  EIGEN_DEVICE_FUNC const Scalar* data() const { return m_ref.data(); }
288 
289  protected:
291 };
292 
293 // evaluator for lvalues
294 template <typename Derived, typename Device>
295 struct TensorEvaluator<TensorRef<Derived>, Device> : public TensorEvaluator<const TensorRef<Derived>, Device> {
296  typedef typename Derived::Index Index;
297  typedef typename Derived::Scalar Scalar;
300  typedef typename Derived::Dimensions Dimensions;
301 
303 
304  enum { IsAligned = false, PacketAccess = false, BlockAccess = false, PreferBlockAccess = false, RawAccess = false };
305 
306  //===- Tensor block evaluation strategy (see TensorBlock.h) -------------===//
308  //===--------------------------------------------------------------------===//
309 
311 
312  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& coeffRef(Index index) { return this->m_ref.coeffRef(index); }
313 };
314 
315 } // end namespace Eigen
316 
317 #endif // EIGEN_CXX11_TENSOR_TENSOR_REF_H
int i
Definition: BiCGSTAB_step_by_step.cpp:9
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
#define EIGEN_DEVICE_FUNC
Definition: Macros.h:892
#define eigen_assert(x)
Definition: Macros.h:910
#define EIGEN_STRONG_INLINE
Definition: Macros.h:834
SCALAR Scalar
Definition: bench_gemm.cpp:45
The tensor base class.
Definition: TensorBase.h:1026
A reference to a tensor expression The expression will be evaluated lazily (as much as possible).
Definition: TensorRef.h:114
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar coeff(Index index) const
Definition: TensorRef.h:233
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index dimension(Index n) const
Definition: TensorRef.h:178
internal::traits< PlainObjectType >::Index Index
Definition: TensorRef.h:120
TensorRef(const TensorRef &other)
Definition: TensorRef.h:162
TensorRef & operator=(const TensorRef &other)
Definition: TensorRef.h:167
PlainObjectType::Dimensions Dimensions
Definition: TensorRef.h:128
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions & dimensions() const
Definition: TensorRef.h:179
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar & coeffRef(Index index)
Definition: TensorRef.h:235
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator()(Index firstIndex, IndexTypes... otherIndices) const
Definition: TensorRef.h:186
EIGEN_STRONG_INLINE TensorRef & operator=(const Expression &expr)
Definition: TensorRef.h:153
~TensorRef()
Definition: TensorRef.h:160
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar coeff(const array< Index, NumIndices > &indices) const
Definition: TensorRef.h:199
internal::TensorLazyBaseEvaluator< Dimensions, Scalar > * m_evaluator
Definition: TensorRef.h:247
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar & coeffRef(const array< Index, NumIndices > &indices)
Definition: TensorRef.h:216
Base::CoeffReturnType CoeffReturnType
Definition: TensorRef.h:123
NumTraits< Scalar >::Real RealScalar
Definition: TensorRef.h:122
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index rank() const
Definition: TensorRef.h:177
static constexpr Index NumIndices
Definition: TensorRef.h:127
EIGEN_STRONG_INLINE TensorRef()
Definition: TensorRef.h:144
PlainObjectType::Base Base
Definition: TensorRef.h:117
@ PacketAccess
Definition: TensorRef.h:133
@ PreferBlockAccess
Definition: TensorRef.h:135
@ BlockAccess
Definition: TensorRef.h:134
@ IsAligned
Definition: TensorRef.h:132
@ CoordAccess
Definition: TensorRef.h:136
@ RawAccess
Definition: TensorRef.h:137
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar * data() const
Definition: TensorRef.h:181
PointerType PointerArgType
Definition: TensorRef.h:125
EIGEN_STRONG_INLINE void unrefEvaluator()
Definition: TensorRef.h:238
TensorRef< PlainObjectType > Self
Definition: TensorRef.h:116
Eigen::internal::nested< Self >::type Nested
Definition: TensorRef.h:118
internal::TensorBlockNotImplemented TensorBlock
Definition: TensorRef.h:141
EIGEN_STRONG_INLINE TensorRef(const Expression &expr)
Definition: TensorRef.h:147
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar & coeffRef(Index firstIndex, IndexTypes... otherIndices)
Definition: TensorRef.h:192
internal::traits< PlainObjectType >::StorageKind StorageKind
Definition: TensorRef.h:119
internal::traits< PlainObjectType >::Scalar Scalar
Definition: TensorRef.h:121
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator()(Index index) const
Definition: TensorRef.h:183
static constexpr int Layout
Definition: TensorRef.h:130
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index size() const
Definition: TensorRef.h:180
Scalar * PointerType
Definition: TensorRef.h:124
Definition: TensorBlock.h:566
int refCount() const
Definition: TensorRef.h:34
void decrRefCount()
Definition: TensorRef.h:33
virtual EIGEN_DEVICE_FUNC const Scalar coeff(DenseIndex index) const =0
virtual EIGEN_DEVICE_FUNC const Dimensions & dimensions() const =0
virtual ~TensorLazyBaseEvaluator()
Definition: TensorRef.h:24
int m_refcount
Definition: TensorRef.h:41
void incrRefCount()
Definition: TensorRef.h:32
TensorLazyBaseEvaluator()
Definition: TensorRef.h:23
virtual EIGEN_DEVICE_FUNC Scalar & coeffRef(DenseIndex index)=0
TensorLazyBaseEvaluator & operator=(const TensorLazyBaseEvaluator &other)
virtual EIGEN_DEVICE_FUNC const Scalar * data() const =0
TensorLazyBaseEvaluator(const TensorLazyBaseEvaluator &other)
virtual EIGEN_DEVICE_FUNC const Scalar coeff(DenseIndex index) const
Definition: TensorRef.h:63
TensorLazyEvaluatorReadOnly(const Expr &expr, const Device &device)
Definition: TensorRef.h:54
Storage::Type EvaluatorPointerType
Definition: TensorRef.h:51
Scalar m_dummy
Definition: TensorRef.h:72
virtual ~TensorLazyEvaluatorReadOnly()
Definition: TensorRef.h:58
StorageMemory< Scalar, Device > Storage
Definition: TensorRef.h:50
virtual EIGEN_DEVICE_FUNC const Scalar * data() const
Definition: TensorRef.h:61
TensorEvaluator< Expr, Device >::Scalar Scalar
Definition: TensorRef.h:49
TensorEvaluator< Expr, Device > m_impl
Definition: TensorRef.h:67
virtual EIGEN_DEVICE_FUNC const Dimensions & dimensions() const
Definition: TensorRef.h:60
virtual EIGEN_DEVICE_FUNC Scalar & coeffRef(DenseIndex)
Definition: TensorRef.h:64
TensorEvaluator< Expr, Device > EvalType
Definition: TensorRef.h:52
Dimensions m_dims
Definition: TensorRef.h:71
Storage::Type EvaluatorPointerType
Definition: TensorRef.h:81
TensorLazyEvaluatorReadOnly< Dimensions, Expr, Device > Base
Definition: TensorRef.h:78
virtual EIGEN_DEVICE_FUNC Scalar & coeffRef(DenseIndex index)
Definition: TensorRef.h:86
virtual ~TensorLazyEvaluatorWritable()
Definition: TensorRef.h:84
TensorLazyEvaluatorWritable(const Expr &expr, const Device &device)
Definition: TensorRef.h:83
StorageMemory< Scalar, Device > Storage
Definition: TensorRef.h:80
Base::Scalar Scalar
Definition: TensorRef.h:79
Definition: TensorRef.h:92
TensorLazyEvaluator(const Expr &expr, const Device &device)
Definition: TensorRef.h:100
virtual ~TensorLazyEvaluator()
Definition: TensorRef.h:101
Base::Scalar Scalar
Definition: TensorRef.h:98
std::conditional_t< bool(internal::is_lvalue< Expr >::value), TensorLazyEvaluatorWritable< Dimensions, Expr, Device >, TensorLazyEvaluatorReadOnly< Dimensions, const Expr, Device > > Base
Definition: TensorRef.h:97
@ RowMajor
Definition: Constants.h:320
int * m
Definition: level2_cplx_impl.h:294
Namespace containing all symbols from the Eigen library.
Definition: bench_norm.cpp:70
std::array< T, N > array
Definition: EmulateArray.h:231
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:83
EIGEN_DEFAULT_DENSE_INDEX_TYPE DenseIndex
Definition: Meta.h:75
Definition: Eigen_Colamd.h:49
Definition: TensorDeviceDefault.h:19
Holds information about the various numeric (i.e. scalar) types allowed by Eigen.
Definition: NumTraits.h:217
Definition: TensorForwardDeclarations.h:42
internal::TensorBlockNotImplemented TensorBlock
Definition: TensorRef.h:307
PacketType< CoeffReturnType, Device >::type PacketReturnType
Definition: TensorRef.h:299
TensorEvaluator< const TensorRef< Derived >, Device > Base
Definition: TensorRef.h:302
Derived::Scalar CoeffReturnType
Definition: TensorRef.h:298
EIGEN_STRONG_INLINE TensorEvaluator(TensorRef< Derived > &m, const Device &d)
Definition: TensorRef.h:310
Derived::Dimensions Dimensions
Definition: TensorRef.h:300
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar & coeffRef(Index index)
Definition: TensorRef.h:312
Derived::Index Index
Definition: TensorRef.h:296
Derived::Scalar Scalar
Definition: TensorRef.h:297
EIGEN_DEVICE_FUNC const Scalar * data() const
Definition: TensorRef.h:287
Derived::Index Index
Definition: TensorRef.h:253
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar & coeffRef(Index index)
Definition: TensorRef.h:285
TensorRef< Derived > m_ref
Definition: TensorRef.h:290
EIGEN_STRONG_INLINE void cleanup()
Definition: TensorRef.h:281
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index) const
Definition: TensorRef.h:283
Derived::Scalar Scalar
Definition: TensorRef.h:254
EIGEN_STRONG_INLINE bool evalSubExprsIfNeeded(EvaluatorPointerType)
Definition: TensorRef.h:279
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions & dimensions() const
Definition: TensorRef.h:277
PacketType< CoeffReturnType, Device >::type PacketReturnType
Definition: TensorRef.h:256
EIGEN_STRONG_INLINE TensorEvaluator(const TensorRef< Derived > &m, const Device &)
Definition: TensorRef.h:275
Derived::Dimensions Dimensions
Definition: TensorRef.h:257
internal::TensorBlockNotImplemented TensorBlock
Definition: TensorRef.h:272
Derived::Scalar CoeffReturnType
Definition: TensorRef.h:255
Storage::Type EvaluatorPointerType
Definition: TensorRef.h:259
StorageMemory< CoeffReturnType, Device > Storage
Definition: TensorRef.h:258
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
EIGEN_STRONG_INLINE bool evalSubExprsIfNeeded(EvaluatorPointerType dest)
Definition: TensorEvaluator.h:71
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType & coeffRef(Index index) const
Definition: TensorEvaluator.h:94
@ PacketAccess
Definition: TensorEvaluator.h:50
@ IsAligned
Definition: TensorEvaluator.h:49
EIGEN_DEVICE_FUNC EvaluatorPointerType data() const
Definition: TensorEvaluator.h:165
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index) const
Definition: TensorEvaluator.h:89
EIGEN_STRONG_INLINE void cleanup()
Definition: TensorEvaluator.h:87
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions & dimensions() const
Definition: TensorEvaluator.h:69
Definition: XprHelper.h:819
ref_selector< T >::type type
Definition: TensorTraits.h:153
Definition: ForwardDeclarations.h:21