TensorContractionMapper.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_CONTRACTION_MAPPER_H
11 #define EIGEN_CXX11_TENSOR_TENSOR_CONTRACTION_MAPPER_H
12 
13 namespace Eigen {
14 
15 namespace internal {
16 
17 enum {
18  Rhs = 0,
19  Lhs = 1
20 };
21 
22 /*
23  * Implementation of the Eigen blas_data_mapper class for tensors.
24  */
25 
26 template <typename Tensor, bool HasRawAccess> struct CoeffLoader {
27  enum {
28  DirectOffsets = false
29  };
30 
31  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE CoeffLoader(const Tensor& tensor) : m_tensor(tensor) { }
32 
33  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void offsetBuffer(typename Tensor::Index) {
34  eigen_assert(false && "unsupported");
35  }
36 
37  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE typename Tensor::Scalar coeff(typename Tensor::Index index) const { return m_tensor.coeff(index); }
38 
39  template<int LoadMode> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
40  typename Tensor::PacketReturnType packet(typename Tensor::Index index) const
41  {
42  return m_tensor.template packet<LoadMode>(index);
43  }
44 
45 
46  private:
48 };
49 
50 template <typename Tensor> struct CoeffLoader<Tensor, true> {
51  enum {
53  };
54 
55  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE CoeffLoader(const Tensor& tensor) : m_data(tensor.data()) {}
56 
57  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void offsetBuffer(typename Tensor::Index offset) {
58  m_data += offset;
59  }
60 
61  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE typename Tensor::Scalar coeff(typename Tensor::Index index) const { return loadConstant(m_data+index); }
62 
63  template<int LoadMode> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
64  typename Tensor::PacketReturnType packet(typename Tensor::Index index) const
65  {
66  return internal::ploadt_ro<typename Tensor::PacketReturnType, LoadMode>(m_data + index);
67  }
68  private:
69  typedef typename Tensor::Scalar Scalar;
70  const Scalar* m_data;
71 };
72 
73 template<typename Scalar, typename Index, int side,
74  typename Tensor,
75  typename nocontract_t, typename contract_t,
76  int packet_size, bool inner_dim_contiguous, int Alignment>
78  public:
79  EIGEN_DEVICE_FUNC
80  SimpleTensorContractionMapper(const Tensor& tensor,
81  const nocontract_t& nocontract_strides,
82  const nocontract_t& ij_strides,
83  const contract_t& contract_strides,
84  const contract_t& k_strides) :
85  m_tensor(tensor),
86  m_nocontract_strides(nocontract_strides),
87  m_ij_strides(ij_strides),
88  m_contract_strides(contract_strides),
89  m_k_strides(k_strides) { }
90 
91  enum {
93  };
94 
95  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void offsetBuffer(typename Tensor::Index offset) {
96  m_tensor.offsetBuffer(offset);
97  }
98 
99  EIGEN_DEVICE_FUNC
100  EIGEN_STRONG_INLINE void prefetch(Index /*i*/) { }
101 
102  EIGEN_DEVICE_FUNC
103  EIGEN_STRONG_INLINE Scalar operator()(Index row) const {
104  // column major assumption
105  return operator()(row, 0);
106  }
107 
108  EIGEN_DEVICE_FUNC
109  EIGEN_STRONG_INLINE Scalar operator()(Index row, Index col) const {
110  return m_tensor.coeff(computeIndex(row, col));
111  }
112 
113  EIGEN_DEVICE_FUNC
114  EIGEN_STRONG_INLINE Index computeIndex(Index row, Index col) const {
115  const bool left = (side == Lhs);
116  Index nocontract_val = left ? row : col;
117  Index linidx = 0;
118  for (int i = static_cast<int>(array_size<nocontract_t>::value) - 1; i > 0; i--) {
119  const Index idx = nocontract_val / m_ij_strides[i];
120  linidx += idx * m_nocontract_strides[i];
121  nocontract_val -= idx * m_ij_strides[i];
122  }
124  if (side == Lhs && inner_dim_contiguous) {
125  eigen_assert(m_nocontract_strides[0] == 1);
126  linidx += nocontract_val;
127  } else {
128  linidx += nocontract_val * m_nocontract_strides[0];
129  }
130  }
131 
132  Index contract_val = left ? col : row;
134  for (int i = static_cast<int>(array_size<contract_t>::value) - 1; i > 0; i--) {
135  const Index idx = contract_val / m_k_strides[i];
136  linidx += idx * m_contract_strides[i];
137  contract_val -= idx * m_k_strides[i];
138  }
139 
140  if (side == Rhs && inner_dim_contiguous) {
141  eigen_assert(m_contract_strides[0] == 1);
142  linidx += contract_val;
143  } else {
144  linidx += contract_val * m_contract_strides[0];
145  }
146  }
147 
148  return linidx;
149  }
150 
151  EIGEN_DEVICE_FUNC
152  EIGEN_STRONG_INLINE IndexPair<Index> computeIndexPair(Index row, Index col, const Index distance) const {
153  const bool left = (side == Lhs);
154  Index nocontract_val[2] = {left ? row : col, left ? row + distance : col};
155  Index linidx[2] = {0, 0};
157  for (int i = static_cast<int>(array_size<nocontract_t>::value) - 1; i > 0; i--) {
158  const Index idx0 = nocontract_val[0] / m_ij_strides[i];
159  const Index idx1 = nocontract_val[1] / m_ij_strides[i];
160  linidx[0] += idx0 * m_nocontract_strides[i];
161  linidx[1] += idx1 * m_nocontract_strides[i];
162  nocontract_val[0] -= idx0 * m_ij_strides[i];
163  nocontract_val[1] -= idx1 * m_ij_strides[i];
164  }
165  if (side == Lhs && inner_dim_contiguous) {
166  eigen_assert(m_nocontract_strides[0] == 1);
167  linidx[0] += nocontract_val[0];
168  linidx[1] += nocontract_val[1];
169  } else {
170  linidx[0] += nocontract_val[0] * m_nocontract_strides[0];
171  linidx[1] += nocontract_val[1] * m_nocontract_strides[0];
172  }
173  }
174 
175  Index contract_val[2] = {left ? col : row, left ? col : row + distance};
177  for (int i = static_cast<int>(array_size<contract_t>::value) - 1; i > 0; i--) {
178  const Index idx0 = contract_val[0] / m_k_strides[i];
179  const Index idx1 = contract_val[1] / m_k_strides[i];
180  linidx[0] += idx0 * m_contract_strides[i];
181  linidx[1] += idx1 * m_contract_strides[i];
182  contract_val[0] -= idx0 * m_k_strides[i];
183  contract_val[1] -= idx1 * m_k_strides[i];
184  }
185 
186  if (side == Rhs && inner_dim_contiguous) {
187  eigen_assert(m_contract_strides[0] == 1);
188  linidx[0] += contract_val[0];
189  linidx[1] += contract_val[1];
190  } else {
191  linidx[0] += contract_val[0] * m_contract_strides[0];
192  linidx[1] += contract_val[1] * m_contract_strides[0];
193  }
194  }
195  return IndexPair<Index>(linidx[0], linidx[1]);
196  }
197 
198  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Index firstAligned(Index size) const {
199  // Only claim alignment when we can compute the actual stride (ie when we're
200  // dealing with the lhs with inner_dim_contiguous. This is because the
201  // matrix-vector product relies on the stride when dealing with aligned inputs.
202  return (Alignment == Aligned) && (side == Lhs) && inner_dim_contiguous ? 0 : size;
203  }
204  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Index stride() const {
205  return ((side == Lhs) && inner_dim_contiguous && array_size<contract_t>::value > 0) ? m_contract_strides[0] : 1;
206  }
207 
208  protected:
210  const nocontract_t m_nocontract_strides;
211  const nocontract_t m_ij_strides;
212  const contract_t m_contract_strides;
213  const contract_t m_k_strides;
214 };
215 
216 
217 template<typename Scalar, typename Index, int side,
218  typename Tensor,
219  typename nocontract_t, typename contract_t,
220  int packet_size, bool inner_dim_contiguous,
221  bool inner_dim_reordered, int Alignment>
222 class BaseTensorContractionMapper : public SimpleTensorContractionMapper<Scalar, Index, side, Tensor, nocontract_t, contract_t, packet_size, inner_dim_contiguous, Alignment>
223 {
224  public:
226 
227  EIGEN_DEVICE_FUNC
228  BaseTensorContractionMapper(const Tensor& tensor,
229  const nocontract_t& nocontract_strides,
230  const nocontract_t& ij_strides,
231  const contract_t& contract_strides,
232  const contract_t& k_strides) :
233  ParentMapper(tensor, nocontract_strides, ij_strides, contract_strides, k_strides) { }
234 
235  typedef typename Tensor::PacketReturnType Packet;
237 
238  template <int AlignmentType>
239  EIGEN_DEVICE_FUNC
240  EIGEN_STRONG_INLINE Packet loadPacket(Index i, Index j) const {
241  // whole method makes column major assumption
242 
243  // don't need to add offsets for now (because operator handles that)
244  // current code assumes packet size must be a multiple of 2
245  EIGEN_STATIC_ASSERT(packet_size % 2 == 0, YOU_MADE_A_PROGRAMMING_MISTAKE);
246 
247  if (Tensor::PacketAccess && inner_dim_contiguous && !inner_dim_reordered) {
248  const Index index = this->computeIndex(i, j);
249  eigen_assert(this->computeIndex(i+packet_size-1, j) == index + packet_size-1);
250  return this->m_tensor.template packet<AlignmentType>(index);
251  }
252 
253  const IndexPair<Index> indexPair = this->computeIndexPair(i, j, packet_size - 1);
254  const Index first = indexPair.first;
255  const Index last = indexPair.second;
256 
257  // We can always do optimized packet reads from left hand side right now, because
258  // the vertical matrix dimension on the left hand side is never contracting.
259  // On the right hand side we need to check if the contracting dimensions may have
260  // been shuffled first.
261  if (Tensor::PacketAccess &&
262  (side == Lhs || internal::array_size<contract_t>::value <= 1 || !inner_dim_reordered) &&
263  (last - first) == (packet_size - 1)) {
264 
265  return this->m_tensor.template packet<AlignmentType>(first);
266  }
267 
268  EIGEN_ALIGN_MAX Scalar data[packet_size];
269 
270  data[0] = this->m_tensor.coeff(first);
271  for (Index k = 1; k < packet_size - 1; k += 2) {
272  const IndexPair<Index> internal_pair = this->computeIndexPair(i + k, j, 1);
273  data[k] = this->m_tensor.coeff(internal_pair.first);
274  data[k + 1] = this->m_tensor.coeff(internal_pair.second);
275  }
276  data[packet_size - 1] = this->m_tensor.coeff(last);
277 
278  return pload<Packet>(data);
279  }
280 
281  template <int AlignmentType>
282  EIGEN_DEVICE_FUNC
283  EIGEN_STRONG_INLINE HalfPacket loadHalfPacket(Index i, Index j) const {
284  // whole method makes column major assumption
285 
286  // don't need to add offsets for now (because operator handles that)
287  const Index half_packet_size = unpacket_traits<HalfPacket>::size;
288  if (half_packet_size == packet_size) {
289  return loadPacket<AlignmentType>(i, j);
290  }
291  EIGEN_ALIGN_MAX Scalar data[half_packet_size];
292  for (Index k = 0; k < half_packet_size; k++) {
293  data[k] = operator()(i + k, j);
294  }
295  return pload<HalfPacket>(data);
296  }
297 };
298 
299 
300 template<typename Scalar, typename Index, int side,
301  typename Tensor,
302  typename nocontract_t, typename contract_t,
303  bool inner_dim_contiguous,
304  bool inner_dim_reordered, int Alignment>
305 class BaseTensorContractionMapper<Scalar, Index, side, Tensor, nocontract_t, contract_t, 1, inner_dim_contiguous, inner_dim_reordered, Alignment> : public SimpleTensorContractionMapper<Scalar, Index, side, Tensor, nocontract_t, contract_t, 1, inner_dim_contiguous, Alignment>
306 {
307  public:
309 
310  EIGEN_DEVICE_FUNC
311  BaseTensorContractionMapper(const Tensor& tensor,
312  const nocontract_t& nocontract_strides,
313  const nocontract_t& ij_strides,
314  const contract_t& contract_strides,
315  const contract_t& k_strides) :
316  ParentMapper(tensor, nocontract_strides, ij_strides, contract_strides, k_strides) { }
317 
318  typedef typename Tensor::PacketReturnType Packet;
319  template <int> EIGEN_DEVICE_FUNC
320  EIGEN_STRONG_INLINE Packet loadPacket(Index i, Index j) const {
321  EIGEN_ALIGN_MAX Scalar data[1];
322  data[0] = this->m_tensor.coeff(this->computeIndex(i, j));
323  return pload<typename Tensor::PacketReturnType>(data);
324  }
325  template <int> EIGEN_DEVICE_FUNC
326  EIGEN_STRONG_INLINE Packet loadHalfPacket(Index i, Index j) const {
327  return loadPacket(i, j);
328  }
329 };
330 
331 
332 template<typename Scalar, typename Index, int side,
333  typename Tensor,
334  typename nocontract_t, typename contract_t,
335  int packet_size,
336  bool inner_dim_contiguous, bool inner_dim_reordered, int Alignment>
338  public:
339  typedef typename Tensor::PacketReturnType Packet;
341 
344  typedef Self LinearMapper;
345 
346  enum {
347  // We can use direct offsets iff the parent mapper supports then and we can compute the strides.
348  // TODO: we should also enable direct offsets for the Rhs case.
349  UseDirectOffsets = ParentMapper::DirectOffsets && (side == Lhs) && inner_dim_contiguous && (array_size<contract_t>::value > 0)
350  };
351 
352  EIGEN_DEVICE_FUNC TensorContractionSubMapper(const ParentMapper& base_mapper, Index vert_offset, Index horiz_offset)
353  : m_base_mapper(base_mapper), m_vert_offset(vert_offset), m_horiz_offset(horiz_offset) {
354  // Bake the offsets into the buffer used by the base mapper whenever possible. This avoids the need to recompute
355  // this offset every time we attempt to access a coefficient.
356  if (UseDirectOffsets) {
357  Index stride = m_base_mapper.stride();
358  m_base_mapper.offsetBuffer(vert_offset + horiz_offset * stride);
359  }
360  }
361 
362  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar operator()(Index i) const {
363  if (UseDirectOffsets) {
364  return m_base_mapper(i, 0);
365  }
366  return m_base_mapper(i + m_vert_offset, m_horiz_offset);
367  }
368  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar operator()(Index i, Index j) const {
369  if (UseDirectOffsets) {
370  return m_base_mapper(i, j);
371  }
372  return m_base_mapper(i + m_vert_offset, j + m_horiz_offset);
373  }
374 
375  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet loadPacket(Index i) const {
376  if (UseDirectOffsets) {
377  return m_base_mapper.template loadPacket<Alignment>(i, 0);
378  }
379  return m_base_mapper.template loadPacket<Alignment>(i + m_vert_offset, m_horiz_offset);
380  }
381  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet loadPacket(Index i, Index j) const {
382  if (UseDirectOffsets) {
383  return m_base_mapper.template loadPacket<Alignment>(i, j);
384  }
385  return m_base_mapper.template loadPacket<Alignment>(i + m_vert_offset, j + m_horiz_offset);
386  }
387 
388  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE HalfPacket loadHalfPacket(Index i) const {
389  if (UseDirectOffsets) {
390  return m_base_mapper.template loadHalfPacket<Alignment>(i, 0);
391  }
392  return m_base_mapper.template loadHalfPacket<Alignment>(i + m_vert_offset, m_horiz_offset);
393  }
394 
395  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void storePacket(Index i, Packet p) const {
396  if (UseDirectOffsets) {
397  m_base_mapper.storePacket(i, 0, p);
398  }
399  m_base_mapper.storePacket(i + m_vert_offset, m_horiz_offset, p);
400  }
401 
402  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE LinearMapper getLinearMapper(Index i, Index j) const {
403  if (UseDirectOffsets) {
404  return LinearMapper(m_base_mapper, i, j);
405  }
406  return LinearMapper(m_base_mapper, i + m_vert_offset, j + m_horiz_offset);
407  }
408 
409  template <typename PacketT, int AlignmentType>
410  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE PacketT load(Index i) const {
411  EIGEN_STATIC_ASSERT((internal::is_same<PacketT, Packet>::value), YOU_MADE_A_PROGRAMMING_MISTAKE);
412  const int ActualAlignment = (AlignmentType == Aligned) && (Alignment == Aligned) ? Aligned : Unaligned;
413  if (UseDirectOffsets) {
414  return m_base_mapper.template loadPacket<ActualAlignment>(i, 0);
415  }
416  return m_base_mapper.template loadPacket<ActualAlignment>(i + m_vert_offset, m_horiz_offset);
417  }
418 
419  template <typename Packet>
420  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool aligned(Index) const {
421  return false;
422  }
423 
424  private:
425  ParentMapper m_base_mapper;
426  const Index m_vert_offset;
427  const Index m_horiz_offset;
428 };
429 
430 
431 template<typename Scalar_, typename Index, int side,
432  typename Tensor,
433  typename nocontract_t, typename contract_t,
434  int packet_size,
435  bool inner_dim_contiguous, bool inner_dim_reordered, int Alignment>
437  : public BaseTensorContractionMapper<Scalar_, Index, side, Tensor, nocontract_t, contract_t, packet_size, inner_dim_contiguous, inner_dim_reordered, Alignment> {
438 
439  public:
440  typedef Scalar_ Scalar;
443  typedef SubMapper VectorMapper;
444 
445  EIGEN_DEVICE_FUNC TensorContractionInputMapper(const Tensor& tensor,
446  const nocontract_t& nocontract_strides,
447  const nocontract_t& ij_strides,
448  const contract_t& contract_strides,
449  const contract_t& k_strides)
450  : Base(tensor, nocontract_strides, ij_strides, contract_strides, k_strides) { }
451 
452  EIGEN_DEVICE_FUNC
453  EIGEN_STRONG_INLINE SubMapper getSubMapper(Index i, Index j) const {
454  return SubMapper(*this, i, j);
455  }
456 
457  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE VectorMapper getVectorMapper(Index i, Index j) const {
458  return VectorMapper(*this, i, j);
459  }
460 };
461 
462 
463 
464 } // end namespace internal
465 } // end namespace Eigen
466 
467 #endif // EIGEN_CXX11_TENSOR_TENSOR_CONTRACTION_MAPPER_H
TensorContractionSubMapper< Scalar, Index, side, Tensor, nocontract_t, contract_t, packet_size, inner_dim_contiguous, inner_dim_reordered, Alignment > SubMapper
#define EIGEN_ALWAYS_INLINE
Definition: Macros.h:507
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void offsetBuffer(typename Tensor::Index offset)
#define EIGEN_STRONG_INLINE
Definition: Macros.h:493
EIGEN_DEVICE_FUNC BaseTensorContractionMapper(const Tensor &tensor, const nocontract_t &nocontract_strides, const nocontract_t &ij_strides, const contract_t &contract_strides, const contract_t &k_strides)
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void storePacket(Index i, Packet p) const
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void offsetBuffer(typename Tensor::Index offset)
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Tensor::Scalar coeff(typename Tensor::Index index) const
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE SubMapper getSubMapper(Index i, Index j) const
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet loadPacket(Index i) const
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet loadPacket(Index i, Index j) const
Scalar_ Scalar
Definition: Tensor.h:71
Definition: LDLT.h:16
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Tensor::PacketReturnType packet(typename Tensor::Index index) const
static constexpr size_t size(Tuple< Args... > &)
Provides access to the number of elements in a tuple as a compile-time constant expression.
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(Index row) const
#define EIGEN_STATIC_ASSERT(CONDITION, MSG)
Definition: StaticAssert.h:122
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE LinearMapper getLinearMapper(Index i, Index j) const
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Index firstAligned(Index size) const
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(Index row, Index col) const
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar operator()(Index i) const
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index computeIndex(Index row, Index col) const
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE IndexPair< Index > computeIndexPair(Index row, Index col, const Index distance) const
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Tensor::Scalar coeff(typename Tensor::Index index) const
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void offsetBuffer(typename Tensor::Index)
EIGEN_DEVICE_FUNC TensorContractionInputMapper(const Tensor &tensor, const nocontract_t &nocontract_strides, const nocontract_t &ij_strides, const contract_t &contract_strides, const contract_t &k_strides)
EIGEN_DEVICE_FUNC BaseTensorContractionMapper(const Tensor &tensor, const nocontract_t &nocontract_strides, const nocontract_t &ij_strides, const contract_t &contract_strides, const contract_t &k_strides)
EIGEN_DEVICE_FUNC ColXpr col(Index i)
This is the const version of col().
Definition: BlockMethods.h:838
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE CoeffLoader(const Tensor &tensor)
SimpleTensorContractionMapper< Scalar, Index, side, Tensor, nocontract_t, contract_t, 1, inner_dim_contiguous, Alignment > ParentMapper
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool aligned(Index) const
EIGEN_DEVICE_FUNC SimpleTensorContractionMapper(const Tensor &tensor, const nocontract_t &nocontract_strides, const nocontract_t &ij_strides, const contract_t &contract_strides, const contract_t &k_strides)
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Index stride() const
TensorContractionSubMapper< Scalar, Index, side, Tensor, nocontract_t, contract_t, packet_size, inner_dim_contiguous, inner_dim_reordered, Alignment > Self
internal::traits< Self >::Index Index
Definition: Tensor.h:70
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:33
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Tensor::PacketReturnType packet(typename Tensor::Index index) const
#define eigen_assert(x)
Definition: Macros.h:577
EIGEN_DEVICE_FUNC RowXpr row(Index i)
This is the const version of row(). */.
Definition: BlockMethods.h:859
EIGEN_DEVICE_FUNC TensorContractionSubMapper(const ParentMapper &base_mapper, Index vert_offset, Index horiz_offset)
BaseTensorContractionMapper< Scalar, Index, side, Tensor, nocontract_t, contract_t, packet_size, inner_dim_contiguous, inner_dim_reordered, Alignment > ParentMapper
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar & coeff(const array< Index, NumIndices > &indices) const
Definition: Tensor.h:124
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void prefetch(Index)
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE VectorMapper getVectorMapper(Index i, Index j) const
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE HalfPacket loadHalfPacket(Index i) const
AlignmentType
Definition: Constants.h:227
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE PacketT load(Index i) const
BaseTensorContractionMapper< Scalar, Index, side, Tensor, nocontract_t, contract_t, packet_size, inner_dim_contiguous, inner_dim_reordered, Alignment > Base
#define EIGEN_ALIGN_MAX
Definition: Macros.h:755
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar operator()(Index i, Index j) const
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE HalfPacket loadHalfPacket(Index i, Index j) const
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE CoeffLoader(const Tensor &tensor)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet loadPacket(Index i, Index j) const
SimpleTensorContractionMapper< Scalar, Index, side, Tensor, nocontract_t, contract_t, packet_size, inner_dim_contiguous, Alignment > ParentMapper
CoeffLoader< Tensor, Tensor::RawAccess > m_tensor
The tensor class.
Definition: Tensor.h:63


hebiros
Author(s): Xavier Artache , Matthew Tesch
autogenerated on Thu Sep 3 2020 04:09:15