10 #ifndef EIGEN_CXX11_TENSOR_TENSOR_CONTRACTION_MAPPER_H 11 #define EIGEN_CXX11_TENSOR_TENSOR_CONTRACTION_MAPPER_H 26 template <
typename Tensor,
bool HasRawAccess>
struct CoeffLoader {
42 return m_tensor.template packet<LoadMode>(index);
66 return internal::ploadt_ro<typename Tensor::PacketReturnType, LoadMode>(m_data + index);
75 typename nocontract_t,
typename contract_t,
76 int packet_size,
bool inner_dim_contiguous,
int Alignment>
81 const nocontract_t& nocontract_strides,
82 const nocontract_t& ij_strides,
83 const contract_t& contract_strides,
84 const contract_t& k_strides) :
86 m_nocontract_strides(nocontract_strides),
87 m_ij_strides(ij_strides),
88 m_contract_strides(contract_strides),
89 m_k_strides(k_strides) { }
105 return operator()(row, 0);
115 const bool left = (side ==
Lhs);
116 Index nocontract_val = left ? row :
col;
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];
124 if (side ==
Lhs && inner_dim_contiguous) {
126 linidx += nocontract_val;
128 linidx += nocontract_val * m_nocontract_strides[0];
132 Index contract_val = left ? col :
row;
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];
140 if (side ==
Rhs && inner_dim_contiguous) {
142 linidx += contract_val;
144 linidx += contract_val * m_contract_strides[0];
153 const bool left = (side ==
Lhs);
154 Index nocontract_val[2] = {left ? row :
col, left ? row + distance : col};
155 Index linidx[2] = {0, 0};
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];
165 if (side ==
Lhs && inner_dim_contiguous) {
167 linidx[0] += nocontract_val[0];
168 linidx[1] += nocontract_val[1];
170 linidx[0] += nocontract_val[0] * m_nocontract_strides[0];
171 linidx[1] += nocontract_val[1] * m_nocontract_strides[0];
175 Index contract_val[2] = {left ? col :
row, left ? col : row + distance};
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];
186 if (side ==
Rhs && inner_dim_contiguous) {
188 linidx[0] += contract_val[0];
189 linidx[1] += contract_val[1];
191 linidx[0] += contract_val[0] * m_contract_strides[0];
192 linidx[1] += contract_val[1] * m_contract_strides[0];
202 return (Alignment ==
Aligned) && (side ==
Lhs) && inner_dim_contiguous ? 0 : size;
217 template<
typename Scalar,
typename Index,
int side,
219 typename nocontract_t,
typename contract_t,
220 int packet_size,
bool inner_dim_contiguous,
221 bool inner_dim_reordered,
int Alignment>
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) { }
235 typedef typename Tensor::PacketReturnType
Packet;
238 template <
int AlignmentType>
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);
253 const IndexPair<Index> indexPair = this->computeIndexPair(i, j, packet_size - 1);
254 const Index
first = indexPair.first;
255 const Index
last = indexPair.second;
261 if (Tensor::PacketAccess &&
263 (last - first) == (packet_size - 1)) {
271 for (Index k = 1; k < packet_size - 1; k += 2) {
278 return pload<Packet>(
data);
281 template <
int AlignmentType>
288 if (half_packet_size == packet_size) {
289 return loadPacket<AlignmentType>(
i,
j);
292 for (Index k = 0; k < half_packet_size; k++) {
293 data[k] = operator()(i + k, j);
295 return pload<HalfPacket>(
data);
300 template<
typename Scalar,
typename Index,
int side,
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>
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) { }
318 typedef typename Tensor::PacketReturnType
Packet;
319 template <
int> EIGEN_DEVICE_FUNC
323 return pload<typename Tensor::PacketReturnType>(
data);
325 template <
int> EIGEN_DEVICE_FUNC
327 return loadPacket(i, j);
332 template<
typename Scalar,
typename Index,
int side,
334 typename nocontract_t,
typename contract_t,
336 bool inner_dim_contiguous,
bool inner_dim_reordered,
int Alignment>
339 typedef typename Tensor::PacketReturnType
Packet;
353 : m_base_mapper(base_mapper), m_vert_offset(vert_offset), m_horiz_offset(horiz_offset) {
356 if (UseDirectOffsets) {
357 Index stride = m_base_mapper.stride();
358 m_base_mapper.offsetBuffer(vert_offset + horiz_offset * stride);
363 if (UseDirectOffsets) {
364 return m_base_mapper(i, 0);
366 return m_base_mapper(i + m_vert_offset, m_horiz_offset);
369 if (UseDirectOffsets) {
370 return m_base_mapper(i, j);
372 return m_base_mapper(i + m_vert_offset, j + m_horiz_offset);
376 if (UseDirectOffsets) {
377 return m_base_mapper.template loadPacket<Alignment>(
i, 0);
379 return m_base_mapper.template loadPacket<Alignment>(i + m_vert_offset, m_horiz_offset);
382 if (UseDirectOffsets) {
383 return m_base_mapper.template loadPacket<Alignment>(
i,
j);
385 return m_base_mapper.template loadPacket<Alignment>(i + m_vert_offset, j + m_horiz_offset);
389 if (UseDirectOffsets) {
390 return m_base_mapper.template loadHalfPacket<Alignment>(
i, 0);
392 return m_base_mapper.template loadHalfPacket<Alignment>(i + m_vert_offset, m_horiz_offset);
396 if (UseDirectOffsets) {
397 m_base_mapper.storePacket(i, 0, p);
399 m_base_mapper.storePacket(i + m_vert_offset, m_horiz_offset, p);
403 if (UseDirectOffsets) {
404 return LinearMapper(m_base_mapper, i, j);
406 return LinearMapper(m_base_mapper, i + m_vert_offset, j + m_horiz_offset);
409 template <
typename PacketT,
int AlignmentType>
413 if (UseDirectOffsets) {
414 return m_base_mapper.template loadPacket<ActualAlignment>(
i, 0);
416 return m_base_mapper.template loadPacket<ActualAlignment>(i + m_vert_offset, m_horiz_offset);
419 template <
typename Packet>
431 template<
typename Scalar_,
typename Index,
int side,
433 typename nocontract_t,
typename contract_t,
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> {
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) { }
454 return SubMapper(*
this, i, j);
458 return VectorMapper(*
this, i, j);
467 #endif // EIGEN_CXX11_TENSOR_TENSOR_CONTRACTION_MAPPER_H
#define EIGEN_ALWAYS_INLINE
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void offsetBuffer(typename Tensor::Index offset)
#define EIGEN_STRONG_INLINE
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
const contract_t m_k_strides
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet loadPacket(Index i) const
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet loadPacket(Index i, Index j) const
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet loadHalfPacket(Index i, Index j) const
Tensor::PacketReturnType Packet
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.
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)
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)
const Index m_vert_offset
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)
const contract_t m_contract_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
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Tensor::PacketReturnType packet(typename Tensor::Index index) const
unpacket_traits< Packet >::half HalfPacket
ParentMapper m_base_mapper
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
Tensor::PacketReturnType Packet
Tensor::PacketReturnType Packet
const nocontract_t m_nocontract_strides
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar & coeff(const array< Index, NumIndices > &indices) const
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void prefetch(Index)
const Index m_horiz_offset
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet loadPacket(Index i, Index j) const
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE HalfPacket loadHalfPacket(Index i) const
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE PacketT load(Index i) const
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)
const nocontract_t m_ij_strides
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
unpacket_traits< Packet >::half HalfPacket