10 #ifndef EIGEN_CXX11_TENSOR_TENSOR_REF_H
11 #define EIGEN_CXX11_TENSOR_TENSOR_REF_H
13 #include "./InternalHeaderCheck.h"
19 template <
typename Dimensions,
typename Scalar>
20 class TensorLazyBaseEvaluator {
22 TensorLazyBaseEvaluator() : m_refcount(0) { }
23 virtual ~TensorLazyBaseEvaluator() { }
25 EIGEN_DEVICE_FUNC
virtual const Dimensions& dimensions()
const = 0;
26 EIGEN_DEVICE_FUNC
virtual const Scalar* data()
const = 0;
28 EIGEN_DEVICE_FUNC
virtual const Scalar coeff(DenseIndex index)
const = 0;
29 EIGEN_DEVICE_FUNC
virtual Scalar& coeffRef(DenseIndex index) = 0;
31 void incrRefCount() { ++m_refcount; }
32 void decrRefCount() { --m_refcount; }
33 int refCount()
const {
return m_refcount; }
37 TensorLazyBaseEvaluator(
const TensorLazyBaseEvaluator& other);
38 TensorLazyBaseEvaluator& operator = (
const TensorLazyBaseEvaluator& other);
44 template <
typename Dimensions,
typename Expr,
typename Device>
45 class TensorLazyEvaluatorReadOnly :
public TensorLazyBaseEvaluator<Dimensions, typename TensorEvaluator<Expr, Device>::Scalar> {
48 typedef typename TensorEvaluator<Expr, Device>::Scalar Scalar;
49 typedef StorageMemory<Scalar, Device> Storage;
50 typedef typename Storage::Type EvaluatorPointerType;
51 typedef TensorEvaluator<Expr, Device> EvalType;
53 TensorLazyEvaluatorReadOnly(
const Expr& expr,
const Device& device) : m_impl(expr, device), m_dummy(Scalar(0)) {
54 m_dims = m_impl.dimensions();
55 m_impl.evalSubExprsIfNeeded(NULL);
57 virtual ~TensorLazyEvaluatorReadOnly() {
61 EIGEN_DEVICE_FUNC
virtual const Dimensions& dimensions()
const {
64 EIGEN_DEVICE_FUNC
virtual const Scalar* data()
const {
68 EIGEN_DEVICE_FUNC
virtual const Scalar coeff(DenseIndex index)
const {
69 return m_impl.coeff(index);
71 EIGEN_DEVICE_FUNC
virtual Scalar& coeffRef(DenseIndex ) {
72 eigen_assert(
false &&
"can't reference the coefficient of a rvalue");
77 TensorEvaluator<Expr, Device> m_impl;
82 template <
typename Dimensions,
typename Expr,
typename Device>
83 class TensorLazyEvaluatorWritable :
public TensorLazyEvaluatorReadOnly<Dimensions, Expr, Device> {
85 typedef TensorLazyEvaluatorReadOnly<Dimensions, Expr, Device> Base;
86 typedef typename Base::Scalar Scalar;
87 typedef StorageMemory<Scalar, Device> Storage;
88 typedef typename Storage::Type EvaluatorPointerType;
90 TensorLazyEvaluatorWritable(
const Expr& expr,
const Device& device) : Base(expr, device) {
92 virtual ~TensorLazyEvaluatorWritable() {
95 EIGEN_DEVICE_FUNC
virtual Scalar& coeffRef(DenseIndex index) {
96 return this->m_impl.coeffRef(index);
100 template <
typename Dimensions,
typename Expr,
typename Device>
101 class TensorLazyEvaluator :
public std::conditional_t<bool(internal::is_lvalue<Expr>::value),
102 TensorLazyEvaluatorWritable<Dimensions, Expr, Device>,
103 TensorLazyEvaluatorReadOnly<Dimensions, const Expr, Device> > {
105 typedef std::conditional_t<bool(internal::is_lvalue<Expr>::value),
106 TensorLazyEvaluatorWritable<Dimensions, Expr, Device>,
107 TensorLazyEvaluatorReadOnly<Dimensions, const Expr, Device> > Base;
108 typedef typename Base::Scalar Scalar;
110 TensorLazyEvaluator(
const Expr& expr,
const Device& device) : Base(expr, device) {
112 virtual ~TensorLazyEvaluator() {
130 typedef typename PlainObjectType::Base Base;
131 typedef typename Eigen::internal::nested<Self>::type Nested;
132 typedef typename internal::traits<PlainObjectType>::StorageKind StorageKind;
133 typedef typename internal::traits<PlainObjectType>::Index Index;
134 typedef typename internal::traits<PlainObjectType>::Scalar Scalar;
136 typedef typename Base::CoeffReturnType CoeffReturnType;
137 typedef Scalar* PointerType;
138 typedef PointerType PointerArgType;
140 static constexpr Index NumIndices = PlainObjectType::NumIndices;
141 typedef typename PlainObjectType::Dimensions Dimensions;
143 static constexpr
int Layout = PlainObjectType::Layout;
146 PacketAccess =
false,
148 PreferBlockAccess =
false,
154 typedef internal::TensorBlockNotImplemented TensorBlock;
157 EIGEN_STRONG_INLINE
TensorRef() : m_evaluator(NULL) {
160 template <
typename Expression>
161 EIGEN_STRONG_INLINE
TensorRef(
const Expression& expr) : m_evaluator(
new internal::TensorLazyEvaluator<Dimensions, Expression, DefaultDevice>(expr, DefaultDevice())) {
162 m_evaluator->incrRefCount();
165 template <
typename Expression>
166 EIGEN_STRONG_INLINE
TensorRef& operator = (
const Expression& expr) {
168 m_evaluator =
new internal::TensorLazyEvaluator<Dimensions, Expression, DefaultDevice>(expr, DefaultDevice());
169 m_evaluator->incrRefCount();
178 eigen_assert(m_evaluator->refCount() > 0);
179 m_evaluator->incrRefCount();
183 if (
this != &other) {
185 m_evaluator = other.m_evaluator;
186 eigen_assert(m_evaluator->refCount() > 0);
187 m_evaluator->incrRefCount();
193 EIGEN_STRONG_INLINE Index rank()
const {
return m_evaluator->dimensions().size(); }
195 EIGEN_STRONG_INLINE Index dimension(Index n)
const {
return m_evaluator->dimensions()[n]; }
197 EIGEN_STRONG_INLINE
const Dimensions& dimensions()
const {
return m_evaluator->dimensions(); }
199 EIGEN_STRONG_INLINE Index size()
const {
return m_evaluator->dimensions().TotalSize(); }
201 EIGEN_STRONG_INLINE
const Scalar* data()
const {
return m_evaluator->data(); }
204 EIGEN_STRONG_INLINE
const Scalar operator()(Index index)
const
206 return m_evaluator->coeff(index);
209 template<
typename... IndexTypes> EIGEN_DEVICE_FUNC
210 EIGEN_STRONG_INLINE
const Scalar operator()(Index firstIndex, IndexTypes... otherIndices)
const
212 const std::size_t num_indices = (
sizeof...(otherIndices) + 1);
213 const array<Index, num_indices> indices{{firstIndex, otherIndices...}};
214 return coeff(indices);
216 template<
typename... IndexTypes> EIGEN_DEVICE_FUNC
217 EIGEN_STRONG_INLINE Scalar& coeffRef(Index firstIndex, IndexTypes... otherIndices)
219 const std::size_t num_indices = (
sizeof...(otherIndices) + 1);
220 const array<Index, num_indices> indices{{firstIndex, otherIndices...}};
221 return coeffRef(indices);
224 template <std::
size_t NumIndices> EIGEN_DEVICE_FUNC
225 EIGEN_STRONG_INLINE
const Scalar coeff(
const array<Index, NumIndices>& indices)
const
227 const Dimensions& dims = this->dimensions();
229 if (PlainObjectType::Options &
RowMajor) {
231 for (
size_t i = 1; i < NumIndices; ++i) {
232 index = index * dims[i] + indices[i];
235 index += indices[NumIndices-1];
236 for (
int i = NumIndices-2; i >= 0; --i) {
237 index = index * dims[i] + indices[i];
240 return m_evaluator->coeff(index);
242 template <std::
size_t NumIndices> EIGEN_DEVICE_FUNC
243 EIGEN_STRONG_INLINE Scalar& coeffRef(
const array<Index, NumIndices>& indices)
245 const Dimensions& dims = this->dimensions();
247 if (PlainObjectType::Options &
RowMajor) {
249 for (
size_t i = 1; i < NumIndices; ++i) {
250 index = index * dims[i] + indices[i];
253 index += indices[NumIndices-1];
254 for (
int i = NumIndices-2; i >= 0; --i) {
255 index = index * dims[i] + indices[i];
258 return m_evaluator->coeffRef(index);
262 EIGEN_STRONG_INLINE
const Scalar coeff(Index index)
const
264 return m_evaluator->coeff(index);
268 EIGEN_STRONG_INLINE Scalar& coeffRef(Index index)
270 return m_evaluator->coeffRef(index);
274 EIGEN_STRONG_INLINE
void unrefEvaluator() {
276 m_evaluator->decrRefCount();
277 if (m_evaluator->refCount() == 0) {
283 internal::TensorLazyBaseEvaluator<Dimensions, Scalar>* m_evaluator;
288 template<
typename Derived,
typename Device>
291 typedef typename Derived::Index
Index;
292 typedef typename Derived::Scalar Scalar;
293 typedef typename Derived::Scalar CoeffReturnType;
294 typedef typename PacketType<CoeffReturnType, Device>::type PacketReturnType;
295 typedef typename Derived::Dimensions Dimensions;
296 typedef StorageMemory<CoeffReturnType, Device> Storage;
297 typedef typename Storage::Type EvaluatorPointerType;
302 PacketAccess =
false,
304 PreferBlockAccess =
false,
310 typedef internal::TensorBlockNotImplemented TensorBlock;
313 EIGEN_STRONG_INLINE TensorEvaluator(
const TensorRef<Derived>& m,
const Device&)
317 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Dimensions& dimensions()
const {
return m_ref.dimensions(); }
319 EIGEN_STRONG_INLINE
bool evalSubExprsIfNeeded(EvaluatorPointerType) {
323 EIGEN_STRONG_INLINE
void cleanup() { }
325 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index)
const {
326 return m_ref.coeff(index);
329 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& coeffRef(Index index) {
330 return m_ref.coeffRef(index);
333 EIGEN_DEVICE_FUNC
const Scalar* data()
const {
return m_ref.data(); }
336 TensorRef<Derived> m_ref;
341 template<
typename Derived,
typename Device>
342 struct TensorEvaluator<TensorRef<Derived>, Device> :
public TensorEvaluator<const TensorRef<Derived>, Device>
344 typedef typename Derived::Index
Index;
345 typedef typename Derived::Scalar Scalar;
346 typedef typename Derived::Scalar CoeffReturnType;
347 typedef typename PacketType<CoeffReturnType, Device>::type PacketReturnType;
348 typedef typename Derived::Dimensions Dimensions;
350 typedef TensorEvaluator<const TensorRef<Derived>, Device> Base;
354 PacketAccess =
false,
356 PreferBlockAccess =
false,
361 typedef internal::TensorBlockNotImplemented TensorBlock;
364 EIGEN_STRONG_INLINE TensorEvaluator(TensorRef<Derived>& m,
const Device& d) : Base(m, d)
367 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& coeffRef(Index index) {
368 return this->m_ref.coeffRef(index);
The tensor base class.
Definition: TensorForwardDeclarations.h:58
A reference to a tensor expression The expression will be evaluated lazily (as much as possible).
Definition: TensorRef.h:127
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:31