TensorFixedSize.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_FIXED_SIZE_H
11 #define EIGEN_CXX11_TENSOR_TENSOR_FIXED_SIZE_H
12 
13 #include "./InternalHeaderCheck.h"
14 
15 namespace Eigen {
16 
28 template<typename Scalar_, typename Dimensions_, int Options_, typename IndexType>
29 class TensorFixedSize : public TensorBase<TensorFixedSize<Scalar_, Dimensions_, Options_, IndexType> >
30 {
31  public:
34  typedef typename Eigen::internal::nested<Self>::type Nested;
35  typedef typename internal::traits<Self>::StorageKind StorageKind;
36  typedef typename internal::traits<Self>::Index Index;
37  typedef Scalar_ Scalar;
39  typedef typename Base::CoeffReturnType CoeffReturnType;
40 
41  static constexpr int Options = Options_;
42  static constexpr int Layout = Options_ & RowMajor ? RowMajor : ColMajor;
43 
44  enum {
45  IsAligned = bool(EIGEN_MAX_ALIGN_BYTES>0),
46  PacketAccess = (internal::packet_traits<Scalar>::size > 1),
47  BlockAccess = false,
49  CoordAccess = true,
50  RawAccess = true
51  };
52 
53  //===- Tensor block evaluation strategy (see TensorBlock.h) -------------===//
54  typedef internal::TensorBlockNotImplemented TensorBlock;
55  //===--------------------------------------------------------------------===//
56 
57  typedef Dimensions_ Dimensions;
58  static constexpr std::size_t NumIndices = Dimensions::count;
59 
60  protected:
62 
63  public:
64  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index rank() const { return NumIndices; }
65  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index dimension(std::size_t n) const { return m_storage.dimensions()[n]; }
66  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions dimensions() const { return m_storage.dimensions(); }
67  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index size() const { return m_storage.size(); }
68  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar *data() { return m_storage.data(); }
69  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar *data() const { return m_storage.data(); }
70 
71  // This makes EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
72  // work, because that uses base().coeffRef() - and we don't yet
73  // implement a similar class hierarchy
74  inline Self& base() { return *this; }
75  inline const Self& base() const { return *this; }
76 
77  template<typename... IndexTypes>
78  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar& coeff(Index firstIndex, IndexTypes... otherIndices) const
79  {
80  // The number of indices used to access a tensor coefficient must be equal to the rank of the tensor.
81  EIGEN_STATIC_ASSERT(sizeof...(otherIndices) + 1 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
82  return coeff(array<Index, NumIndices>{{firstIndex, otherIndices...}});
83  }
84 
86  EIGEN_STRONG_INLINE const Scalar& coeff(const array<Index, NumIndices>& indices) const
87  {
89  return m_storage.data()[linearizedIndex(indices)];
90  }
91 
93  EIGEN_STRONG_INLINE const Scalar& coeff(Index index) const
94  {
95  eigen_internal_assert(index >= 0 && index < size());
96  return m_storage.data()[index];
97  }
98 
100  EIGEN_STRONG_INLINE const Scalar& coeff() const
101  {
102  EIGEN_STATIC_ASSERT(NumIndices == 0, YOU_MADE_A_PROGRAMMING_MISTAKE);
103  return m_storage.data()[0];
104  }
105 
106 
107  template<typename... IndexTypes>
108  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& coeffRef(Index firstIndex, IndexTypes... otherIndices)
109  {
110  // The number of indices used to access a tensor coefficient must be equal to the rank of the tensor.
111  EIGEN_STATIC_ASSERT(sizeof...(otherIndices) + 1 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
112  return coeffRef(array<Index, NumIndices>{{firstIndex, otherIndices...}});
113  }
114 
116  EIGEN_STRONG_INLINE Scalar& coeffRef(const array<Index, NumIndices>& indices)
117  {
119  return m_storage.data()[linearizedIndex(indices)];
120  }
121 
123  EIGEN_STRONG_INLINE Scalar& coeffRef(Index index)
124  {
125  eigen_internal_assert(index >= 0 && index < size());
126  return m_storage.data()[index];
127  }
128 
130  EIGEN_STRONG_INLINE Scalar& coeffRef()
131  {
132  EIGEN_STATIC_ASSERT(NumIndices == 0, YOU_MADE_A_PROGRAMMING_MISTAKE);
133  return m_storage.data()[0];
134  }
135 
136  template<typename... IndexTypes>
137  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar& operator()(Index firstIndex, IndexTypes... otherIndices) const
138  {
139  // The number of indices used to access a tensor coefficient must be equal to the rank of the tensor.
140  EIGEN_STATIC_ASSERT(sizeof...(otherIndices) + 1 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
141  return this->operator()(array<Index, NumIndices>{{firstIndex, otherIndices...}});
142  }
143 
145  EIGEN_STRONG_INLINE const Scalar& operator()(const array<Index, NumIndices>& indices) const
146  {
147  eigen_assert(checkIndexRange(indices));
148  return coeff(indices);
149  }
150 
152  EIGEN_STRONG_INLINE const Scalar& operator()(Index index) const
153  {
154  eigen_internal_assert(index >= 0 && index < size());
155  return coeff(index);
156  }
157 
159  EIGEN_STRONG_INLINE const Scalar& operator()() const
160  {
161  EIGEN_STATIC_ASSERT(NumIndices == 0, YOU_MADE_A_PROGRAMMING_MISTAKE);
162  return coeff();
163  }
164 
166  EIGEN_STRONG_INLINE const Scalar& operator[](Index index) const
167  {
168  // The bracket operator is only for vectors, use the parenthesis operator instead.
169  EIGEN_STATIC_ASSERT(NumIndices == 1, YOU_MADE_A_PROGRAMMING_MISTAKE);
170  return coeff(index);
171  }
172 
173  template<typename... IndexTypes>
174  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& operator()(Index firstIndex, IndexTypes... otherIndices)
175  {
176  // The number of indices used to access a tensor coefficient must be equal to the rank of the tensor.
177  EIGEN_STATIC_ASSERT(sizeof...(otherIndices) + 1 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
178  return operator()(array<Index, NumIndices>{{firstIndex, otherIndices...}});
179  }
180 
182  EIGEN_STRONG_INLINE Scalar& operator()(const array<Index, NumIndices>& indices)
183  {
184  eigen_assert(checkIndexRange(indices));
185  return coeffRef(indices);
186  }
187 
189  EIGEN_STRONG_INLINE Scalar& operator()(Index index)
190  {
191  eigen_assert(index >= 0 && index < size());
192  return coeffRef(index);
193  }
194 
196  EIGEN_STRONG_INLINE Scalar& operator()()
197  {
198  EIGEN_STATIC_ASSERT(NumIndices == 0, YOU_MADE_A_PROGRAMMING_MISTAKE);
199  return coeffRef();
200  }
201 
203  EIGEN_STRONG_INLINE Scalar& operator[](Index index)
204  {
205  // The bracket operator is only for vectors, use the parenthesis operator instead
206  EIGEN_STATIC_ASSERT(NumIndices == 1, YOU_MADE_A_PROGRAMMING_MISTAKE)
207  return coeffRef(index);
208  }
209 
211  EIGEN_STRONG_INLINE TensorFixedSize()
212  : m_storage()
213  {
214  }
215 
217  EIGEN_STRONG_INLINE TensorFixedSize(const Self& other)
218  : Base(other), m_storage(other.m_storage)
219  {
220  }
221 
222  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorFixedSize(Self&& other)
223  : m_storage(other.m_storage)
224  {
225  }
226 
227  template<typename OtherDerived>
230  {
232  Assign assign(*this, other.derived());
233  internal::TensorExecutor<const Assign, DefaultDevice>::run(assign, DefaultDevice());
234  }
235  template<typename OtherDerived>
238  {
240  Assign assign(*this, other.derived());
241  internal::TensorExecutor<const Assign, DefaultDevice>::run(assign, DefaultDevice());
242  }
243 
244  // FIXME: check that the dimensions of other match the dimensions of *this.
245  // Unfortunately this isn't possible yet when the rhs is an expression.
247 
248 
249  protected:
251  EIGEN_STRONG_INLINE bool checkIndexRange(const array<Index, NumIndices>& /*indices*/) const
252  {
255  using internal::greater_equal_zero_op;
256  using internal::logical_and_op;
257  using internal::lesser_op;
258 
259  return true;
260  // check whether the indices are all >= 0
261  /* array_apply_and_reduce<logical_and_op, greater_equal_zero_op>(indices) &&
262  // check whether the indices fit in the dimensions
263  array_zip_and_reduce<logical_and_op, lesser_op>(indices, m_storage.dimensions());*/
264  }
265 
267  EIGEN_STRONG_INLINE Index linearizedIndex(const array<Index, NumIndices>& indices) const
268  {
269  if (Options&RowMajor) {
270  return m_storage.dimensions().IndexOfRowMajor(indices);
271  } else {
272  return m_storage.dimensions().IndexOfColMajor(indices);
273  }
274  }
275 };
276 
277 
278 } // end namespace Eigen
279 
280 #endif // EIGEN_CXX11_TENSOR_TENSOR_FIXED_SIZE_H
int n
#define eigen_internal_assert(x)
#define EIGEN_DEVICE_FUNC
#define eigen_assert(x)
#define EIGEN_STATIC_ASSERT(X, MSG)
#define EIGEN_TENSOR_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived)
Definition: TensorMacros.h:70
The tensor base class.
The fixed sized version of the tensor class.
Scalar & operator()(const array< Index, NumIndices > &indices)
Scalar & operator[](Index index)
const Dimensions dimensions() const
Index linearizedIndex(const array< Index, NumIndices > &indices) const
const Self & base() const
TensorBase< TensorFixedSize< Scalar_, Dimensions_, Options_, IndexType > > Base
TensorFixedSize(const Self &other)
TensorStorage< Scalar, Dimensions, Options > m_storage
Eigen::internal::nested< Self >::type Nested
TensorFixedSize(const TensorBase< OtherDerived, ReadOnlyAccessors > &other)
const Scalar & operator()(const array< Index, NumIndices > &indices) const
internal::TensorBlockNotImplemented TensorBlock
Scalar & operator()(Index index)
TensorFixedSize(Self &&other)
static constexpr std::size_t NumIndices
static constexpr int Options
TensorFixedSize(const TensorBase< OtherDerived, WriteAccessors > &other)
Base::CoeffReturnType CoeffReturnType
const Scalar & operator()() const
TensorFixedSize< Scalar_, Dimensions_, Options_, IndexType > Self
const Scalar & coeff() const
internal::traits< Self >::Index Index
Index dimension(std::size_t n) const
const Scalar & operator()(Index firstIndex, IndexTypes... otherIndices) const
Scalar & coeffRef(const array< Index, NumIndices > &indices)
internal::traits< Self >::StorageKind StorageKind
const Scalar & coeff(const array< Index, NumIndices > &indices) const
Scalar & coeffRef(Index firstIndex, IndexTypes... otherIndices)
const Scalar * data() const
bool checkIndexRange(const array< Index, NumIndices > &) const
NumTraits< Scalar >::Real RealScalar
Scalar & coeffRef(Index index)
const Scalar & operator[](Index index) const
const Scalar & operator()(Index index) const
const Scalar & coeff(Index index) const
const Scalar & coeff(Index firstIndex, IndexTypes... otherIndices) const
static constexpr int Layout
Scalar & operator()(Index firstIndex, IndexTypes... otherIndices)
const FixedDimensions dimensions() const
Definition: TensorStorage.h:61
DenseIndex size() const
Definition: TensorStorage.h:64
constexpr 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()))
constexpr 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()))
: TensorContractionSycl.h, provides various tensor contraction kernel for SYCL backend
std::array< T, N > array