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
104  // column major assumption
105  return operator()(row, 0);
106  }
107 
108  EIGEN_DEVICE_FUNC
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 {
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:509
SCALAR Scalar
Definition: bench_gemm.cpp:33
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void offsetBuffer(typename Tensor::Index offset)
#define EIGEN_STRONG_INLINE
Definition: Macros.h:494
constexpr int last(int, int result)
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
set noclip points set clip one set noclip two set bar set border lt lw set xdata set ydata set zdata set x2data set y2data set boxwidth set dummy y set format x g set format y g set format x2 g set format y2 g set format z g set angles radians set nogrid set key title set key left top Right noreverse box linetype linewidth samplen spacing width set nolabel set noarrow set nologscale set logscale x set set pointsize set encoding default set nopolar set noparametric set set set set surface set nocontour set clabel set mapping cartesian set nohidden3d set cntrparam order set cntrparam linear set cntrparam levels auto set cntrparam points set size set set xzeroaxis lt lw set x2zeroaxis lt lw set yzeroaxis lt lw set y2zeroaxis lt lw set tics in set ticslevel set tics set mxtics default set mytics default set mx2tics default set my2tics default set xtics border mirror norotate autofreq set ytics border mirror norotate autofreq set ztics border nomirror norotate autofreq set nox2tics set noy2tics set timestamp bottom norotate offset
Namespace containing all symbols from the Eigen library.
Definition: jet.h:637
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Tensor::PacketReturnType packet(typename Tensor::Index index) const
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(Index row) const
#define EIGEN_STATIC_ASSERT(CONDITION, MSG)
Definition: StaticAssert.h:124
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)
static char left
Scalar Scalar int size
Definition: benchVecAdd.cpp:17
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 CoeffLoader(const Tensor &tensor)
SimpleTensorContractionMapper< Scalar, Index, side, Tensor, nocontract_t, contract_t, 1, inner_dim_contiguous, Alignment > ParentMapper
constexpr int first(int i)
Implementation details for constexpr functions.
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)
m row(1)
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:579
int data[]
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:757
float * p
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
m col(1)
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
std::ptrdiff_t j
The tensor class.
Definition: Tensor.h:63


gtsam
Author(s):
autogenerated on Sat May 8 2021 02:45:17