Tensor.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 // Copyright (C) 2013 Christian Seiler <christian@iwakd.de>
6 //
7 // This Source Code Form is subject to the terms of the Mozilla
8 // Public License v. 2.0. If a copy of the MPL was not distributed
9 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 
11 #ifndef EIGEN_CXX11_TENSOR_TENSOR_H
12 #define EIGEN_CXX11_TENSOR_TENSOR_H
13 
14 // IWYU pragma: private
15 #include "./InternalHeaderCheck.h"
16 
17 namespace Eigen {
18 
67 template <typename Scalar_, int NumIndices_, int Options_, typename IndexType_>
68 class Tensor : public TensorBase<Tensor<Scalar_, NumIndices_, Options_, IndexType_> > {
69  public:
75  typedef Scalar_ Scalar;
78 
79  enum { IsAligned = (EIGEN_MAX_ALIGN_BYTES > 0) && !(Options_ & DontAlign), CoordAccess = true, RawAccess = true };
80 
81  static constexpr int Layout = Options_ & RowMajor ? RowMajor : ColMajor;
82  static constexpr int Options = Options_;
83  static constexpr int NumIndices = NumIndices_;
85 
86  protected:
88 
89  template <typename CustomIndices>
90  struct isOfNormalIndex {
93  static const bool value = is_array | is_int;
94  };
95 
96  public:
97  // Metadata
104 
105  // This makes EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
106  // work, because that uses base().coeffRef() - and we don't yet
107  // implement a similar class hierarchy
108  inline Self& base() { return *this; }
109  inline const Self& base() const { return *this; }
110 
111  template <typename... IndexTypes>
113  IndexTypes... otherIndices) const {
114  // The number of indices used to access a tensor coefficient must be equal to the rank of the tensor.
115  EIGEN_STATIC_ASSERT(sizeof...(otherIndices) + 2 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
116  return coeff(array<Index, NumIndices>{{firstIndex, secondIndex, otherIndices...}});
117  }
118 
119  // normal indices
122  return m_storage.data()[linearizedIndex(indices)];
123  }
124 
125  // custom indices
126  template <typename CustomIndices, EIGEN_SFINAE_ENABLE_IF(!(isOfNormalIndex<CustomIndices>::value))>
127  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar& coeff(CustomIndices& indices) const {
128  return coeff(internal::customIndices2Array<Index, NumIndices>(indices));
129  }
130 
132  EIGEN_STATIC_ASSERT(NumIndices == 0, YOU_MADE_A_PROGRAMMING_MISTAKE);
133  return m_storage.data()[0];
134  }
135 
137  eigen_internal_assert(index >= 0 && index < size());
138  return m_storage.data()[index];
139  }
140 
141  template <typename... IndexTypes>
142  inline Scalar& coeffRef(Index firstIndex, Index secondIndex, IndexTypes... otherIndices) {
143  // The number of indices used to access a tensor coefficient must be equal to the rank of the tensor.
144  EIGEN_STATIC_ASSERT(sizeof...(otherIndices) + 2 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
145  return coeffRef(array<Index, NumIndices>{{firstIndex, secondIndex, otherIndices...}});
146  }
147 
148  // normal indices
151  return m_storage.data()[linearizedIndex(indices)];
152  }
153 
154  // custom indices
155  template <typename CustomIndices, EIGEN_SFINAE_ENABLE_IF(!(isOfNormalIndex<CustomIndices>::value))>
157  return coeffRef(internal::customIndices2Array<Index, NumIndices>(indices));
158  }
159 
161  EIGEN_STATIC_ASSERT(NumIndices == 0, YOU_MADE_A_PROGRAMMING_MISTAKE);
162  return m_storage.data()[0];
163  }
164 
166  eigen_internal_assert(index >= 0 && index < size());
167  return m_storage.data()[index];
168  }
169 
170  template <typename... IndexTypes>
171  inline const Scalar& operator()(Index firstIndex, Index secondIndex, IndexTypes... otherIndices) const {
172  // The number of indices used to access a tensor coefficient must be equal to the rank of the tensor.
173  EIGEN_STATIC_ASSERT(sizeof...(otherIndices) + 2 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
174  return this->operator()(array<Index, NumIndices>{{firstIndex, secondIndex, otherIndices...}});
175  }
176 
177  // custom indices
178  template <typename CustomIndices, EIGEN_SFINAE_ENABLE_IF(!(isOfNormalIndex<CustomIndices>::value))>
179  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar& operator()(CustomIndices& indices) const {
180  return coeff(internal::customIndices2Array<Index, NumIndices>(indices));
181  }
182 
183  // normal indices
185  return coeff(indices);
186  }
187 
189  eigen_internal_assert(index >= 0 && index < size());
190  return coeff(index);
191  }
192 
194  EIGEN_STATIC_ASSERT(NumIndices == 0, YOU_MADE_A_PROGRAMMING_MISTAKE);
195  return coeff();
196  }
197 
199  // The bracket operator is only for vectors, use the parenthesis operator instead.
200  EIGEN_STATIC_ASSERT(NumIndices == 1, YOU_MADE_A_PROGRAMMING_MISTAKE);
201  return coeff(index);
202  }
203 
204  template <typename... IndexTypes>
205  inline Scalar& operator()(Index firstIndex, Index secondIndex, IndexTypes... otherIndices) {
206  // The number of indices used to access a tensor coefficient must be equal to the rank of the tensor.
207  EIGEN_STATIC_ASSERT(sizeof...(otherIndices) + 2 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
208  return operator()(array<Index, NumIndices>{{firstIndex, secondIndex, otherIndices...}});
209  }
210 
211  // normal indices
213  return coeffRef(indices);
214  }
215 
216  // custom indices
217  template <typename CustomIndices, EIGEN_SFINAE_ENABLE_IF(!(isOfNormalIndex<CustomIndices>::value))>
219  return coeffRef(internal::customIndices2Array<Index, NumIndices>(indices));
220  }
221 
223  eigen_assert(index >= 0 && index < size());
224  return coeffRef(index);
225  }
226 
228  EIGEN_STATIC_ASSERT(NumIndices == 0, YOU_MADE_A_PROGRAMMING_MISTAKE);
229  return coeffRef();
230  }
231 
233  // The bracket operator is only for vectors, use the parenthesis operator instead
234  EIGEN_STATIC_ASSERT(NumIndices == 1, YOU_MADE_A_PROGRAMMING_MISTAKE)
235  return coeffRef(index);
236  }
237 
239 
241 
242  template <typename... IndexTypes>
243  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Tensor(Index firstDimension, IndexTypes... otherDimensions)
244  : m_storage(firstDimension, otherDimensions...) {
245  // The number of dimensions used to construct a tensor must be equal to the rank of the tensor.
246  EIGEN_STATIC_ASSERT(sizeof...(otherDimensions) + 1 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
247  }
248 
253  }
254 
255  template <typename OtherDerived>
257  EIGEN_STATIC_ASSERT(OtherDerived::NumDimensions == Base::NumDimensions, Number_of_dimensions_must_match)
259  Assign assign(*this, other.derived());
262  }
263 
264  template <typename OtherDerived>
266  EIGEN_STATIC_ASSERT(OtherDerived::NumDimensions == Base::NumDimensions, Number_of_dimensions_must_match)
268  Assign assign(*this, other.derived());
271  }
272 
275  m_storage = std::move(other.m_storage);
276  return *this;
277  }
278 
281  Assign assign(*this, other);
284  return *this;
285  }
286  template <typename OtherDerived>
289  Assign assign(*this, other);
292  return *this;
293  }
294 
295  template <typename... IndexTypes>
296  EIGEN_DEVICE_FUNC void resize(Index firstDimension, IndexTypes... otherDimensions) {
297  // The number of dimensions used to resize a tensor must be equal to the rank of the tensor.
298  EIGEN_STATIC_ASSERT(sizeof...(otherDimensions) + 1 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
299  resize(array<Index, NumIndices>{{firstDimension, otherDimensions...}});
300  }
301 
304 #ifndef EIGEN_NO_DEBUG
305  Index size = Index(1);
306  for (int i = 0; i < NumIndices; i++) {
308  size *= dimensions[i];
309  }
310 #else
312 #endif
313 
314 #ifdef EIGEN_INITIALIZE_COEFFS
315  bool size_changed = size != this->size();
316  m_storage.resize(size, dimensions);
318 #else
319  m_storage.resize(size, dimensions);
320 #endif
321  }
322 
324  EIGEN_STATIC_ASSERT(NumIndices == 0, YOU_MADE_A_PROGRAMMING_MISTAKE);
325  // Nothing to do: rank 0 tensors have fixed size
326  }
327 
328  template <typename FirstType, typename... OtherTypes>
331  for (int i = 0; i < NumIndices; ++i) {
332  dims[i] = static_cast<Index>(dimensions[i]);
333  }
334  resize(dims);
335  }
336 
338  template <typename CustomDimension, EIGEN_SFINAE_ENABLE_IF(!(isOfNormalIndex<CustomDimension>::value))>
340  resize(internal::customIndices2Array<Index, NumIndices>(dimensions));
341  }
342 
343  template <typename std::ptrdiff_t... Indices>
346  for (int i = 0; i < NumIndices; ++i) {
347  dims[i] = static_cast<Index>(dimensions[i]);
348  }
349  resize(dims);
350  }
351 
352 #ifdef EIGEN_TENSOR_PLUGIN
353 #include EIGEN_TENSOR_PLUGIN
354 #endif
355 
356  protected:
357  bool checkIndexRange(const array<Index, NumIndices>& indices) const {
361  using internal::lesser_op;
363 
364  return
365  // check whether the indices are all >= 0
366  array_apply_and_reduce<logical_and_op, greater_equal_zero_op>(indices) &&
367  // check whether the indices fit in the dimensions
368  array_zip_and_reduce<logical_and_op, lesser_op>(indices, m_storage.dimensions());
369  }
370 
372  if (Options & RowMajor) {
373  return m_storage.dimensions().IndexOfRowMajor(indices);
374  } else {
375  return m_storage.dimensions().IndexOfColMajor(indices);
376  }
377  }
378 };
379 
380 } // end namespace Eigen
381 
382 #endif // EIGEN_CXX11_TENSOR_TENSOR_H
int i
Definition: BiCGSTAB_step_by_step.cpp:9
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
#define EIGEN_MAX_ALIGN_BYTES
Definition: ConfigureVectorization.h:163
#define eigen_internal_assert(x)
Definition: Macros.h:916
#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_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
Definition: PlainObjectBase.h:24
#define EIGEN_STATIC_ASSERT(X, MSG)
Definition: StaticAssert.h:26
Definition: TensorAssign.h:57
The tensor base class.
Definition: TensorBase.h:1026
static constexpr int NumDimensions
Definition: TensorBase.h:1033
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived & derived()
Definition: TensorBase.h:1220
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DenseIndex size() const
Definition: TensorStorage.h:58
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const FixedDimensions dimensions() const
Definition: TensorStorage.h:56
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T * data()
Definition: TensorStorage.h:53
The tensor class.
Definition: Tensor.h:68
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Tensor(const Self &other)
Definition: Tensor.h:240
TensorStorage< Scalar, Dimensions, Options > m_storage
Definition: Tensor.h:87
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar & operator()(const array< Index, NumIndices > &indices)
Definition: Tensor.h:212
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Tensor & operator=(const Tensor &other)
Definition: Tensor.h:279
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar & operator[](Index index) const
Definition: Tensor.h:198
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar * data() const
Definition: Tensor.h:103
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar & coeff(Index index) const
Definition: Tensor.h:136
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar & operator[](Index index)
Definition: Tensor.h:232
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Tensor(Self &&other)
Definition: Tensor.h:273
const Scalar & operator()(Index firstIndex, Index secondIndex, IndexTypes... otherIndices) const
Definition: Tensor.h:171
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Tensor(Index firstDimension, IndexTypes... otherDimensions)
Definition: Tensor.h:243
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Tensor()
Definition: Tensor.h:238
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions & dimensions() const
Definition: Tensor.h:100
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar & operator()()
Definition: Tensor.h:227
DSizes< Index, NumIndices_ > Dimensions
Definition: Tensor.h:84
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Tensor & operator=(const OtherDerived &other)
Definition: Tensor.h:287
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar & operator()(CustomIndices &indices)
Definition: Tensor.h:218
Self & base()
Definition: Tensor.h:108
EIGEN_DEVICE_FUNC void resize(const Sizes< Indices... > &dimensions)
Definition: Tensor.h:344
const Self & base() const
Definition: Tensor.h:109
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar & coeff(Index firstIndex, Index secondIndex, IndexTypes... otherIndices) const
Definition: Tensor.h:112
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index linearizedIndex(const array< Index, NumIndices > &indices) const
Definition: Tensor.h:371
EIGEN_DEVICE_FUNC void resize(const array< Index, NumIndices > &dimensions)
Definition: Tensor.h:303
EIGEN_DEVICE_FUNC void resize(const Eigen::IndexList< FirstType, OtherTypes... > &dimensions)
Definition: Tensor.h:329
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar & coeffRef(const array< Index, NumIndices > &indices)
Definition: Tensor.h:149
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar & coeffRef(Index index)
Definition: Tensor.h:165
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Tensor(const array< Index, NumIndices > &dimensions)
Definition: Tensor.h:250
EIGEN_DEVICE_FUNC void resize(Index firstDimension, IndexTypes... otherDimensions)
Definition: Tensor.h:296
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar & coeff(const array< Index, NumIndices > &indices) const
Definition: Tensor.h:120
Base::CoeffReturnType CoeffReturnType
Definition: Tensor.h:77
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar & coeff(CustomIndices &indices) const
Definition: Tensor.h:127
bool checkIndexRange(const array< Index, NumIndices > &indices) const
Definition: Tensor.h:357
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar & operator()(const array< Index, NumIndices > &indices) const
Definition: Tensor.h:184
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index size() const
Definition: Tensor.h:101
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar & operator()(CustomIndices &indices) const
Definition: Tensor.h:179
Scalar & operator()(Index firstIndex, Index secondIndex, IndexTypes... otherIndices)
Definition: Tensor.h:205
static constexpr int Layout
Definition: Tensor.h:81
static constexpr int NumIndices
Definition: Tensor.h:83
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Tensor(const TensorBase< OtherDerived, WriteAccessors > &other)
Definition: Tensor.h:265
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar & coeffRef(CustomIndices &indices)
Definition: Tensor.h:156
Scalar & coeffRef(Index firstIndex, Index secondIndex, IndexTypes... otherIndices)
Definition: Tensor.h:142
TensorBase< Tensor< Scalar_, NumIndices_, Options_, IndexType_ > > Base
Definition: Tensor.h:71
Tensor< Scalar_, NumIndices_, Options_, IndexType_ > Self
Definition: Tensor.h:70
EIGEN_DEVICE_FUNC void resize()
Definition: Tensor.h:323
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar & operator()(Index index)
Definition: Tensor.h:222
NumTraits< Scalar >::Real RealScalar
Definition: Tensor.h:76
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index dimension(std::size_t n) const
Definition: Tensor.h:99
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void resize(CustomDimension &dimensions)
Definition: Tensor.h:339
Scalar_ Scalar
Definition: Tensor.h:75
internal::traits< Self >::Index Index
Definition: Tensor.h:74
Eigen::internal::nested< Self >::type Nested
Definition: Tensor.h:72
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Tensor(const TensorBase< OtherDerived, ReadOnlyAccessors > &other)
Definition: Tensor.h:256
static constexpr int Options
Definition: Tensor.h:82
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar & coeffRef()
Definition: Tensor.h:160
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar * data()
Definition: Tensor.h:102
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar & coeff() const
Definition: Tensor.h:131
internal::traits< Self >::StorageKind StorageKind
Definition: Tensor.h:73
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index rank() const
Definition: Tensor.h:98
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Tensor & operator=(Self &&other)
Definition: Tensor.h:274
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar & operator()(Index index) const
Definition: Tensor.h:188
@ CoordAccess
Definition: Tensor.h:79
@ IsAligned
Definition: Tensor.h:79
@ RawAccess
Definition: Tensor.h:79
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar & operator()() const
Definition: Tensor.h:193
static EIGEN_STRONG_INLINE void run(const Expression &expr, const Device &device=DefaultDevice())
Definition: TensorExecutor.h:92
@ ColMajor
Definition: Constants.h:318
@ DontAlign
Definition: Constants.h:324
@ RowMajor
Definition: Constants.h:320
constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE auto array_prod(const array< T, N > &arr) -> decltype(array_reduce< product_op, T, N >(arr, static_cast< T >(1)))
Definition: MoreMeta.h:497
constexpr EIGEN_STRONG_INLINE auto array_zip_and_reduce(array< A, N > a, array< B, N > b) -> decltype(h_array_zip_and_reduce< Reducer, Op, A, B, N >(a, b, typename gen_numeric_list< int, N >::type()))
Definition: MoreMeta.h:536
constexpr EIGEN_STRONG_INLINE auto array_apply_and_reduce(array< A, N > a) -> decltype(h_array_apply_and_reduce< Reducer, Op, A, N >(a, typename gen_numeric_list< int, N >::type()))
Definition: MoreMeta.h:564
Namespace containing all symbols from the Eigen library.
Definition: bench_norm.cpp:70
std::array< T, N > array
Definition: EmulateArray.h:231
Definition: Eigen_Colamd.h:49
Definition: TensorDimensions.h:161
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DenseIndex IndexOfColMajor(const array< DenseIndex, NumDims > &indices) const
Definition: TensorDimensions.h:230
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DenseIndex IndexOfRowMajor(const array< DenseIndex, NumDims > &indices) const
Definition: TensorDimensions.h:234
Definition: TensorDeviceDefault.h:19
Definition: TensorIndexList.h:271
Holds information about the various numeric (i.e. scalar) types allowed by Eigen.
Definition: NumTraits.h:217
Definition: TensorDimensions.h:85
A cost model used to limit the number of threads used for evaluating tensor expression.
Definition: TensorEvaluator.h:31
Definition: Tensor.h:90
static const bool is_int
Definition: Tensor.h:92
static const bool is_array
Definition: Tensor.h:91
static const bool value
Definition: Tensor.h:93
Definition: MoreMeta.h:422
Definition: TensorMeta.h:271
Definition: MoreMeta.h:383
Definition: MoreMeta.h:358
ref_selector< T >::type type
Definition: TensorTraits.h:153
Definition: ForwardDeclarations.h:21
void run(const string &dir_name, LinearSolver *linear_solver_pt, const unsigned nel_1d, bool mess_up_order)
Definition: two_d_poisson_compare_solvers.cc:317