10#ifndef EIGEN_CXX11_TENSOR_TENSOR_REF_H
11#define EIGEN_CXX11_TENSOR_TENSOR_REF_H
17template <
typename Dimensions,
typename Scalar>
18class TensorLazyBaseEvaluator {
20 TensorLazyBaseEvaluator() : m_refcount(0) { }
21 virtual ~TensorLazyBaseEvaluator() { }
23 EIGEN_DEVICE_FUNC
virtual const Dimensions& dimensions()
const = 0;
24 EIGEN_DEVICE_FUNC
virtual const Scalar* data()
const = 0;
26 EIGEN_DEVICE_FUNC
virtual const Scalar coeff(DenseIndex index)
const = 0;
27 EIGEN_DEVICE_FUNC
virtual Scalar& coeffRef(DenseIndex index) = 0;
29 void incrRefCount() { ++m_refcount; }
30 void decrRefCount() { --m_refcount; }
31 int refCount()
const {
return m_refcount; }
35 TensorLazyBaseEvaluator(
const TensorLazyBaseEvaluator& other);
36 TensorLazyBaseEvaluator& operator = (
const TensorLazyBaseEvaluator& other);
42template <
typename Dimensions,
typename Expr,
typename Device>
43class TensorLazyEvaluatorReadOnly :
public TensorLazyBaseEvaluator<Dimensions, typename TensorEvaluator<Expr, Device>::Scalar> {
46 typedef typename TensorEvaluator<Expr, Device>::Scalar Scalar;
47 typedef StorageMemory<Scalar, Device> Storage;
48 typedef typename Storage::Type EvaluatorPointerType;
49 typedef TensorEvaluator<Expr, Device> EvalType;
51 TensorLazyEvaluatorReadOnly(
const Expr& expr,
const Device& device) : m_impl(expr, device), m_dummy(Scalar(0)) {
52 m_dims = m_impl.dimensions();
53 m_impl.evalSubExprsIfNeeded(NULL);
55 virtual ~TensorLazyEvaluatorReadOnly() {
59 EIGEN_DEVICE_FUNC
virtual const Dimensions& dimensions()
const {
62 EIGEN_DEVICE_FUNC
virtual const Scalar* data()
const {
66 EIGEN_DEVICE_FUNC
virtual const Scalar coeff(DenseIndex index)
const {
67 return m_impl.coeff(index);
69 EIGEN_DEVICE_FUNC
virtual Scalar& coeffRef(DenseIndex ) {
70 eigen_assert(
false &&
"can't reference the coefficient of a rvalue");
75 TensorEvaluator<Expr, Device> m_impl;
80template <
typename Dimensions,
typename Expr,
typename Device>
81class TensorLazyEvaluatorWritable :
public TensorLazyEvaluatorReadOnly<Dimensions, Expr, Device> {
83 typedef TensorLazyEvaluatorReadOnly<Dimensions, Expr, Device> Base;
84 typedef typename Base::Scalar Scalar;
85 typedef StorageMemory<Scalar, Device> Storage;
86 typedef typename Storage::Type EvaluatorPointerType;
88 TensorLazyEvaluatorWritable(
const Expr& expr,
const Device& device) : Base(expr, device) {
90 virtual ~TensorLazyEvaluatorWritable() {
93 EIGEN_DEVICE_FUNC
virtual Scalar& coeffRef(DenseIndex index) {
94 return this->m_impl.coeffRef(index);
98template <
typename Dimensions,
typename Expr,
typename Device>
99class TensorLazyEvaluator :
public internal::conditional<bool(internal::is_lvalue<Expr>::value),
100 TensorLazyEvaluatorWritable<Dimensions, Expr, Device>,
101 TensorLazyEvaluatorReadOnly<Dimensions, const Expr, Device> >::type {
103 typedef typename internal::conditional<bool(internal::is_lvalue<Expr>::value),
104 TensorLazyEvaluatorWritable<Dimensions, Expr, Device>,
105 TensorLazyEvaluatorReadOnly<Dimensions, const Expr, Device> >::type Base;
106 typedef typename Base::Scalar Scalar;
108 TensorLazyEvaluator(
const Expr& expr,
const Device& device) : Base(expr, device) {
110 virtual ~TensorLazyEvaluator() {
128 typedef typename PlainObjectType::Base Base;
129 typedef typename Eigen::internal::nested<Self>::type Nested;
130 typedef typename internal::traits<PlainObjectType>::StorageKind StorageKind;
131 typedef typename internal::traits<PlainObjectType>::Index Index;
132 typedef typename internal::traits<PlainObjectType>::Scalar Scalar;
134 typedef typename Base::CoeffReturnType CoeffReturnType;
135 typedef Scalar* PointerType;
136 typedef PointerType PointerArgType;
138 static const Index NumIndices = PlainObjectType::NumIndices;
139 typedef typename PlainObjectType::Dimensions Dimensions;
143 PacketAccess =
false,
145 PreferBlockAccess =
false,
146 Layout = PlainObjectType::Layout,
152 typedef internal::TensorBlockNotImplemented TensorBlock;
155 EIGEN_STRONG_INLINE
TensorRef() : m_evaluator(NULL) {
158 template <
typename Expression>
159 EIGEN_STRONG_INLINE
TensorRef(
const Expression& expr) : m_evaluator(
new internal::TensorLazyEvaluator<Dimensions, Expression, DefaultDevice>(expr, DefaultDevice())) {
160 m_evaluator->incrRefCount();
163 template <
typename Expression>
164 EIGEN_STRONG_INLINE
TensorRef& operator = (
const Expression& expr) {
166 m_evaluator =
new internal::TensorLazyEvaluator<Dimensions, Expression, DefaultDevice>(expr, DefaultDevice());
167 m_evaluator->incrRefCount();
176 eigen_assert(m_evaluator->refCount() > 0);
177 m_evaluator->incrRefCount();
181 if (
this != &other) {
183 m_evaluator = other.m_evaluator;
184 eigen_assert(m_evaluator->refCount() > 0);
185 m_evaluator->incrRefCount();
191 EIGEN_STRONG_INLINE Index rank()
const {
return m_evaluator->dimensions().size(); }
193 EIGEN_STRONG_INLINE Index dimension(Index n)
const {
return m_evaluator->dimensions()[n]; }
195 EIGEN_STRONG_INLINE
const Dimensions& dimensions()
const {
return m_evaluator->dimensions(); }
197 EIGEN_STRONG_INLINE Index size()
const {
return m_evaluator->dimensions().TotalSize(); }
199 EIGEN_STRONG_INLINE
const Scalar* data()
const {
return m_evaluator->data(); }
202 EIGEN_STRONG_INLINE
const Scalar operator()(Index index)
const
204 return m_evaluator->coeff(index);
207#if EIGEN_HAS_VARIADIC_TEMPLATES
208 template<
typename... IndexTypes> EIGEN_DEVICE_FUNC
209 EIGEN_STRONG_INLINE
const Scalar operator()(Index firstIndex, IndexTypes... otherIndices)
const
211 const std::size_t num_indices = (
sizeof...(otherIndices) + 1);
212 const array<Index, num_indices> indices{{firstIndex, otherIndices...}};
213 return coeff(indices);
215 template<
typename... IndexTypes> EIGEN_DEVICE_FUNC
216 EIGEN_STRONG_INLINE Scalar& coeffRef(Index firstIndex, IndexTypes... otherIndices)
218 const std::size_t num_indices = (
sizeof...(otherIndices) + 1);
219 const array<Index, num_indices> indices{{firstIndex, otherIndices...}};
220 return coeffRef(indices);
225 EIGEN_STRONG_INLINE
const Scalar operator()(Index i0, Index i1)
const
227 array<Index, 2> indices;
230 return coeff(indices);
233 EIGEN_STRONG_INLINE
const Scalar operator()(Index i0, Index i1, Index i2)
const
235 array<Index, 3> indices;
239 return coeff(indices);
242 EIGEN_STRONG_INLINE
const Scalar operator()(Index i0, Index i1, Index i2, Index i3)
const
244 array<Index, 4> indices;
249 return coeff(indices);
252 EIGEN_STRONG_INLINE
const Scalar operator()(Index i0, Index i1, Index i2, Index i3, Index i4)
const
254 array<Index, 5> indices;
260 return coeff(indices);
263 EIGEN_STRONG_INLINE Scalar& coeffRef(Index i0, Index i1)
265 array<Index, 2> indices;
268 return coeffRef(indices);
271 EIGEN_STRONG_INLINE Scalar& coeffRef(Index i0, Index i1, Index i2)
273 array<Index, 3> indices;
277 return coeffRef(indices);
280 EIGEN_STRONG_INLINE Scalar& operator()(Index i0, Index i1, Index i2, Index i3)
282 array<Index, 4> indices;
287 return coeffRef(indices);
290 EIGEN_STRONG_INLINE Scalar& coeffRef(Index i0, Index i1, Index i2, Index i3, Index i4)
292 array<Index, 5> indices;
298 return coeffRef(indices);
302 template <std::
size_t NumIndices> EIGEN_DEVICE_FUNC
303 EIGEN_STRONG_INLINE
const Scalar coeff(
const array<Index, NumIndices>& indices)
const
305 const Dimensions& dims = this->dimensions();
307 if (PlainObjectType::Options &
RowMajor) {
309 for (
size_t i = 1; i < NumIndices; ++i) {
310 index = index * dims[i] + indices[i];
313 index += indices[NumIndices-1];
314 for (
int i = NumIndices-2; i >= 0; --i) {
315 index = index * dims[i] + indices[i];
318 return m_evaluator->coeff(index);
320 template <std::
size_t NumIndices> EIGEN_DEVICE_FUNC
321 EIGEN_STRONG_INLINE Scalar& coeffRef(
const array<Index, NumIndices>& indices)
323 const Dimensions& dims = this->dimensions();
325 if (PlainObjectType::Options &
RowMajor) {
327 for (
size_t i = 1; i < NumIndices; ++i) {
328 index = index * dims[i] + indices[i];
331 index += indices[NumIndices-1];
332 for (
int i = NumIndices-2; i >= 0; --i) {
333 index = index * dims[i] + indices[i];
336 return m_evaluator->coeffRef(index);
340 EIGEN_STRONG_INLINE
const Scalar coeff(Index index)
const
342 return m_evaluator->coeff(index);
346 EIGEN_STRONG_INLINE Scalar& coeffRef(Index index)
348 return m_evaluator->coeffRef(index);
352 EIGEN_STRONG_INLINE
void unrefEvaluator() {
354 m_evaluator->decrRefCount();
355 if (m_evaluator->refCount() == 0) {
361 internal::TensorLazyBaseEvaluator<Dimensions, Scalar>* m_evaluator;
366template<
typename Derived,
typename Device>
369 typedef typename Derived::Index
Index;
370 typedef typename Derived::Scalar Scalar;
371 typedef typename Derived::Scalar CoeffReturnType;
372 typedef typename PacketType<CoeffReturnType, Device>::type PacketReturnType;
373 typedef typename Derived::Dimensions Dimensions;
374 typedef StorageMemory<CoeffReturnType, Device> Storage;
375 typedef typename Storage::Type EvaluatorPointerType;
379 PacketAccess =
false,
381 PreferBlockAccess =
false,
388 typedef internal::TensorBlockNotImplemented TensorBlock;
391 EIGEN_STRONG_INLINE TensorEvaluator(
const TensorRef<Derived>& m,
const Device&)
395 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Dimensions& dimensions()
const {
return m_ref.dimensions(); }
397 EIGEN_STRONG_INLINE
bool evalSubExprsIfNeeded(EvaluatorPointerType) {
401 EIGEN_STRONG_INLINE
void cleanup() { }
403 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index)
const {
404 return m_ref.coeff(index);
407 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& coeffRef(Index index) {
408 return m_ref.coeffRef(index);
411 EIGEN_DEVICE_FUNC
const Scalar* data()
const {
return m_ref.data(); }
414 TensorRef<Derived> m_ref;
419template<
typename Derived,
typename Device>
420struct TensorEvaluator<TensorRef<Derived>, Device> :
public TensorEvaluator<const TensorRef<Derived>, Device>
422 typedef typename Derived::Index
Index;
423 typedef typename Derived::Scalar Scalar;
424 typedef typename Derived::Scalar CoeffReturnType;
425 typedef typename PacketType<CoeffReturnType, Device>::type PacketReturnType;
426 typedef typename Derived::Dimensions Dimensions;
428 typedef TensorEvaluator<const TensorRef<Derived>, Device> Base;
432 PacketAccess =
false,
434 PreferBlockAccess =
false,
439 typedef internal::TensorBlockNotImplemented TensorBlock;
442 EIGEN_STRONG_INLINE TensorEvaluator(TensorRef<Derived>& m,
const Device& d) : Base(m, d)
445 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& coeffRef(Index index) {
446 return this->m_ref.coeffRef(index);
The tensor base class.
Definition: TensorForwardDeclarations.h:56
A reference to a tensor expression The expression will be evaluated lazily (as much as possible).
Definition: TensorRef.h:125
Namespace containing all symbols from the Eigen library.
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
A cost model used to limit the number of threads used for evaluating tensor expression.
Definition: TensorEvaluator.h:29