13#ifndef EIGEN_COREEVALUATORS_H
14#define EIGEN_COREEVALUATORS_H
17#include "./InternalHeaderCheck.h"
25template <
typename StorageKind>
26struct storage_kind_to_evaluator_kind {
27 using Kind = IndexBased;
32template <
typename StorageKind>
33struct storage_kind_to_shape;
36struct storage_kind_to_shape<Dense> {
37 using Shape = DenseShape;
40struct storage_kind_to_shape<SolverStorage> {
41 using Shape = SolverShape;
44struct storage_kind_to_shape<PermutationStorage> {
45 using Shape = PermutationShape;
48struct storage_kind_to_shape<TranspositionsStorage> {
49 using Shape = TranspositionsShape;
67template <typename T, typename Arg1Kind = typename evaluator_traits<typename T::Arg1>::Kind,
68 typename Arg2Kind =
typename evaluator_traits<typename T::Arg2>::Kind,
69 typename Arg3Kind =
typename evaluator_traits<typename T::Arg3>::Kind,
70 typename Arg1Scalar =
typename traits<typename T::Arg1>::Scalar,
71 typename Arg2Scalar =
typename traits<typename T::Arg2>::Scalar,
72 typename Arg3Scalar =
typename traits<typename T::Arg3>::Scalar>
73struct ternary_evaluator;
75template <typename T, typename LhsKind = typename evaluator_traits<typename T::Lhs>::Kind,
76 typename RhsKind =
typename evaluator_traits<typename T::Rhs>::Kind,
77 typename LhsScalar =
typename traits<typename T::Lhs>::Scalar,
78 typename RhsScalar =
typename traits<typename T::Rhs>::Scalar>
79struct binary_evaluator;
81template <typename T, typename Kind = typename evaluator_traits<typename T::NestedExpression>::Kind,
82 typename Scalar =
typename T::Scalar>
83struct unary_evaluator;
88struct evaluator_traits_base {
90 using Kind =
typename storage_kind_to_evaluator_kind<typename traits<T>::StorageKind>::Kind;
91 using Shape =
typename storage_kind_to_shape<typename traits<T>::StorageKind>::Shape;
96struct evaluator_traits :
public evaluator_traits_base<T> {};
98template <typename T, typename Shape = typename evaluator_traits<T>::Shape>
99struct evaluator_assume_aliasing : std::false_type {};
103struct evaluator :
public unary_evaluator<T> {
104 using Base = unary_evaluator<T>;
105 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE
explicit evaluator(
const T& xpr) : Base(xpr) {}
110struct evaluator<const T> : evaluator<T> {
111 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE
explicit evaluator(
const T& xpr) : evaluator<T>(xpr) {}
116template <
typename ExpressionType>
117struct evaluator_base {
120 using ExpressionTraits = traits<ExpressionType>;
122 enum { Alignment = 0 };
125 EIGEN_DEVICE_FUNC
constexpr evaluator_base() =
default;
127 evaluator_base(
const evaluator_base&) =
delete;
128 evaluator_base& operator=(
const evaluator_base&) =
delete;
139template <
typename Scalar,
int OuterStr
ide>
140class plainobjectbase_evaluator_data {
142 EIGEN_DEVICE_FUNC
constexpr plainobjectbase_evaluator_data(
const Scalar* ptr, Index outerStride) : data(ptr) {
143 EIGEN_UNUSED_VARIABLE(outerStride);
144 eigen_internal_assert(outerStride == OuterStride);
146 EIGEN_DEVICE_FUNC
constexpr Index outerStride() const noexcept {
return OuterStride; }
150template <
typename Scalar>
151class plainobjectbase_evaluator_data<Scalar, Dynamic> {
153 EIGEN_DEVICE_FUNC
constexpr plainobjectbase_evaluator_data(
const Scalar* ptr, Index outerStride)
154 : data(ptr), m_outerStride(outerStride) {}
155 EIGEN_DEVICE_FUNC
constexpr Index outerStride()
const {
return m_outerStride; }
162template <
typename Derived>
163struct evaluator<PlainObjectBase<Derived>> : evaluator_base<Derived> {
164 using PlainObjectType = PlainObjectBase<Derived>;
165 using Scalar =
typename PlainObjectType::Scalar;
166 using CoeffReturnType =
typename PlainObjectType::CoeffReturnType;
169 IsRowMajor = PlainObjectType::IsRowMajor,
170 IsVectorAtCompileTime = PlainObjectType::IsVectorAtCompileTime,
171 RowsAtCompileTime = PlainObjectType::RowsAtCompileTime,
172 ColsAtCompileTime = PlainObjectType::ColsAtCompileTime,
174 CoeffReadCost = NumTraits<Scalar>::ReadCost,
175 Flags = traits<Derived>::EvaluatorFlags,
176 Alignment = traits<Derived>::Alignment
180 OuterStrideAtCompileTime = IsVectorAtCompileTime ? 0
181 : int(IsRowMajor) ? ColsAtCompileTime
185 EIGEN_DEVICE_FUNC
constexpr evaluator() : m_d(0, OuterStrideAtCompileTime) {
186 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
189 EIGEN_DEVICE_FUNC
constexpr explicit evaluator(
const PlainObjectType& m)
190 : m_d(m.data(), IsVectorAtCompileTime ? 0 : m.outerStride()) {
191 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
194 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
constexpr CoeffReturnType coeff(Index row, Index col)
const {
195 return coeff(getIndex(row, col));
198 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
constexpr CoeffReturnType coeff(Index index)
const {
return m_d.data[index]; }
200 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
constexpr Scalar& coeffRef(Index row, Index col) {
201 return coeffRef(getIndex(row, col));
204 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
constexpr Scalar& coeffRef(Index index) {
205 return const_cast<Scalar*
>(m_d.data)[index];
208 template <
int LoadMode,
typename PacketType>
209 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packet(Index row, Index col)
const {
210 return packet<LoadMode, PacketType>(getIndex(row, col));
213 template <
int LoadMode,
typename PacketType>
214 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packet(Index index)
const {
215 return ploadt<PacketType, LoadMode>(m_d.data + index);
218 template <
int StoreMode,
typename PacketType>
219 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void writePacket(Index row, Index col,
const PacketType& x) {
220 writePacket<StoreMode, PacketType>(getIndex(row, col), x);
223 template <
int StoreMode,
typename PacketType>
224 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void writePacket(Index index,
const PacketType& x) {
225 pstoret<Scalar, PacketType, StoreMode>(
const_cast<Scalar*
>(m_d.data) + index, x);
228 template <
int LoadMode,
typename PacketType>
229 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packetSegment(Index row, Index col, Index begin, Index count)
const {
230 return packetSegment<LoadMode, PacketType>(getIndex(row, col), begin, count);
233 template <
int LoadMode,
typename PacketType>
234 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packetSegment(Index index, Index begin, Index count)
const {
235 return ploadtSegment<PacketType, LoadMode>(m_d.data + index, begin, count);
238 template <
int StoreMode,
typename PacketType>
239 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void writePacketSegment(Index row, Index col,
const PacketType& x, Index begin,
241 writePacketSegment<StoreMode, PacketType>(getIndex(row, col), x, begin, count);
244 template <
int StoreMode,
typename PacketType>
245 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void writePacketSegment(Index index,
const PacketType& x, Index begin,
247 pstoretSegment<Scalar, PacketType, StoreMode>(
const_cast<Scalar*
>(m_d.data) + index, x, begin, count);
251 plainobjectbase_evaluator_data<Scalar, OuterStrideAtCompileTime> m_d;
254 EIGEN_DEVICE_FUNC
constexpr Index getIndex(Index row, Index col)
const {
255 return IsRowMajor ? row * m_d.outerStride() + col : row + col * m_d.outerStride();
259template <
typename Scalar,
int Rows,
int Cols,
int Options,
int MaxRows,
int MaxCols>
260struct evaluator<Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols>>
261 : evaluator<PlainObjectBase<Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols>>> {
262 using XprType = Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols>;
264 EIGEN_DEVICE_FUNC
constexpr evaluator() =
default;
266 EIGEN_DEVICE_FUNC
constexpr explicit evaluator(
const XprType& m) : evaluator<PlainObjectBase<XprType>>(m) {}
269template <
typename Scalar,
int Rows,
int Cols,
int Options,
int MaxRows,
int MaxCols>
270struct evaluator<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols>>
271 : evaluator<PlainObjectBase<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols>>> {
272 using XprType = Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols>;
274 EIGEN_DEVICE_FUNC
constexpr evaluator() =
default;
276 EIGEN_DEVICE_FUNC
constexpr explicit evaluator(
const XprType& m) : evaluator<PlainObjectBase<XprType>>(m) {}
281template <
typename ArgType>
282struct unary_evaluator<Transpose<ArgType>, IndexBased> : evaluator_base<Transpose<ArgType>> {
283 using XprType = Transpose<ArgType>;
286 CoeffReadCost = evaluator<ArgType>::CoeffReadCost,
288 Alignment = evaluator<ArgType>::Alignment
291 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE
explicit unary_evaluator(
const XprType& t)
292 : m_argImpl(t.nestedExpression()) {}
294 using Scalar =
typename XprType::Scalar;
295 using CoeffReturnType =
typename XprType::CoeffReturnType;
297 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col)
const {
298 return m_argImpl.coeff(col, row);
301 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index)
const {
302 return m_argImpl.coeff(index);
305 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col) {
306 return m_argImpl.coeffRef(col, row);
309 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE
typename XprType::Scalar& coeffRef(Index index) {
310 return m_argImpl.coeffRef(index);
313 template <
int LoadMode,
typename PacketType>
314 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packet(Index row, Index col)
const {
315 return m_argImpl.template packet<LoadMode, PacketType>(col, row);
318 template <
int LoadMode,
typename PacketType>
319 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packet(Index index)
const {
320 return m_argImpl.template packet<LoadMode, PacketType>(index);
323 template <
int StoreMode,
typename PacketType>
324 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void writePacket(Index row, Index col,
const PacketType& x) {
325 m_argImpl.template writePacket<StoreMode, PacketType>(col, row, x);
328 template <
int StoreMode,
typename PacketType>
329 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void writePacket(Index index,
const PacketType& x) {
330 m_argImpl.template writePacket<StoreMode, PacketType>(index, x);
333 template <
int LoadMode,
typename PacketType>
334 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packetSegment(Index row, Index col, Index begin, Index count)
const {
335 return m_argImpl.template packetSegment<LoadMode, PacketType>(col, row, begin, count);
338 template <
int LoadMode,
typename PacketType>
339 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packetSegment(Index index, Index begin, Index count)
const {
340 return m_argImpl.template packetSegment<LoadMode, PacketType>(index, begin, count);
343 template <
int StoreMode,
typename PacketType>
344 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void writePacketSegment(Index row, Index col,
const PacketType& x, Index begin,
346 m_argImpl.template writePacketSegment<StoreMode, PacketType>(col, row, x, begin, count);
349 template <
int StoreMode,
typename PacketType>
350 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void writePacketSegment(Index index,
const PacketType& x, Index begin,
352 m_argImpl.template writePacketSegment<StoreMode, PacketType>(index, x, begin, count);
356 evaluator<ArgType> m_argImpl;
363template <typename Scalar, typename NullaryOp, bool has_nullary = has_nullary_operator<NullaryOp>::value,
364 bool has_unary = has_unary_operator<NullaryOp>::value,
365 bool has_binary = has_binary_operator<NullaryOp>::value>
366struct nullary_wrapper {
367 template <
typename IndexType>
368 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE Scalar operator()(
const NullaryOp& op, IndexType i,
372 template <
typename IndexType>
373 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE Scalar operator()(
const NullaryOp& op, IndexType i)
const {
377 template <
typename T,
typename IndexType>
378 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T packetOp(
const NullaryOp& op, IndexType i, IndexType j)
const {
379 return op.template packetOp<T>(i, j);
381 template <
typename T,
typename IndexType>
382 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T packetOp(
const NullaryOp& op, IndexType i)
const {
383 return op.template packetOp<T>(i);
387template <
typename Scalar,
typename NullaryOp>
388struct nullary_wrapper<Scalar, NullaryOp, true, false, false> {
389 template <
typename IndexType>
390 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE Scalar operator()(
const NullaryOp& op, IndexType = 0,
391 IndexType = 0)
const {
394 template <
typename T,
typename IndexType>
395 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T packetOp(
const NullaryOp& op, IndexType = 0, IndexType = 0)
const {
396 return op.template packetOp<T>();
400template <
typename Scalar,
typename NullaryOp>
401struct nullary_wrapper<Scalar, NullaryOp, false, false, true> {
402 template <
typename IndexType>
403 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE Scalar operator()(
const NullaryOp& op, IndexType i,
404 IndexType j = 0)
const {
407 template <
typename T,
typename IndexType>
408 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T packetOp(
const NullaryOp& op, IndexType i, IndexType j = 0)
const {
409 return op.template packetOp<T>(i, j);
416template <
typename Scalar,
typename NullaryOp>
417struct nullary_wrapper<Scalar, NullaryOp, false, true, false> {
418 template <
typename IndexType>
419 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE Scalar operator()(
const NullaryOp& op, IndexType i,
421 eigen_assert(i == 0 || j == 0);
424 template <
typename T,
typename IndexType>
425 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T packetOp(
const NullaryOp& op, IndexType i, IndexType j)
const {
426 eigen_assert(i == 0 || j == 0);
427 return op.template packetOp<T>(i + j);
430 template <
typename IndexType>
431 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE Scalar operator()(
const NullaryOp& op, IndexType i)
const {
434 template <
typename T,
typename IndexType>
435 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T packetOp(
const NullaryOp& op, IndexType i)
const {
436 return op.template packetOp<T>(i);
440template <
typename Scalar,
typename NullaryOp>
441struct nullary_wrapper<Scalar, NullaryOp, false, false, false> {};
443template <
typename NullaryOp,
typename PlainObjectType>
444struct evaluator<CwiseNullaryOp<NullaryOp, PlainObjectType>>
445 : evaluator_base<CwiseNullaryOp<NullaryOp, PlainObjectType>> {
446 using XprType = CwiseNullaryOp<NullaryOp, PlainObjectType>;
447 using PlainObjectTypeCleaned = remove_all_t<PlainObjectType>;
450 CoeffReadCost = functor_traits<NullaryOp>::Cost,
452 Flags = (evaluator<PlainObjectTypeCleaned>::Flags &
453 (HereditaryBits | (functor_has_linear_access<NullaryOp>::value ?
LinearAccessBit : 0) |
456 Alignment = AlignedMax
459 EIGEN_DEVICE_FUNC
constexpr explicit evaluator(
const XprType& n) : m_functor(n.functor()), m_wrapper() {
460 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
463 using CoeffReturnType =
typename XprType::CoeffReturnType;
465 template <
typename IndexType>
466 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE CoeffReturnType coeff(IndexType row, IndexType col)
const {
467 return m_wrapper(m_functor, row, col);
470 template <
typename IndexType>
471 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE CoeffReturnType coeff(IndexType index)
const {
472 return m_wrapper(m_functor, index);
475 template <
int LoadMode,
typename PacketType,
typename IndexType>
476 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packet(IndexType row, IndexType col)
const {
477 return m_wrapper.template packetOp<PacketType>(m_functor, row, col);
480 template <
int LoadMode,
typename PacketType,
typename IndexType>
481 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packet(IndexType index)
const {
482 return m_wrapper.template packetOp<PacketType>(m_functor, index);
485 template <
int LoadMode,
typename PacketType,
typename IndexType>
486 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packetSegment(IndexType row, IndexType col, Index ,
488 return packet<LoadMode, PacketType, IndexType>(row, col);
491 template <
int LoadMode,
typename PacketType,
typename IndexType>
492 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packetSegment(IndexType index, Index ,
494 return packet<LoadMode, PacketType, IndexType>(index);
498 const NullaryOp m_functor;
499 const nullary_wrapper<CoeffReturnType, NullaryOp> m_wrapper;
504template <
typename UnaryOp,
typename ArgType>
505struct unary_evaluator<CwiseUnaryOp<UnaryOp, ArgType>, IndexBased> : evaluator_base<CwiseUnaryOp<UnaryOp, ArgType>> {
506 using XprType = CwiseUnaryOp<UnaryOp, ArgType>;
509 CoeffReadCost = int(evaluator<ArgType>::CoeffReadCost) + int(functor_traits<UnaryOp>::Cost),
511 Flags = evaluator<ArgType>::Flags &
513 Alignment = evaluator<ArgType>::Alignment
516 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE
explicit unary_evaluator(
const XprType& op) : m_d(op) {
517 EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<UnaryOp>::Cost);
518 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
521 using CoeffReturnType =
typename XprType::CoeffReturnType;
523 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col)
const {
524 return m_d.func()(m_d.argImpl.coeff(row, col));
527 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index)
const {
528 return m_d.func()(m_d.argImpl.coeff(index));
531 template <
int LoadMode,
typename PacketType>
532 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packet(Index row, Index col)
const {
533 return m_d.func().packetOp(m_d.argImpl.template packet<LoadMode, PacketType>(row, col));
536 template <
int LoadMode,
typename PacketType>
537 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packet(Index index)
const {
538 return m_d.func().packetOp(m_d.argImpl.template packet<LoadMode, PacketType>(index));
541 template <
int LoadMode,
typename PacketType>
542 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packetSegment(Index row, Index col, Index begin, Index count)
const {
543 return m_d.func().packetOp(m_d.argImpl.template packetSegment<LoadMode, PacketType>(row, col, begin, count));
546 template <
int LoadMode,
typename PacketType>
547 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packetSegment(Index index, Index begin, Index count)
const {
548 return m_d.func().packetOp(m_d.argImpl.template packetSegment<LoadMode, PacketType>(index, begin, count));
554 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE Data(
const XprType& xpr)
555 : op(xpr.functor()), argImpl(xpr.nestedExpression()) {}
556 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE
const UnaryOp& func()
const {
return op; }
558 evaluator<ArgType> argImpl;
566template <
typename SrcType,
typename DstType,
typename ArgType>
567struct unary_evaluator<CwiseUnaryOp<core_cast_op<SrcType, DstType>, ArgType>, IndexBased> {
568 using CastOp = core_cast_op<SrcType, DstType>;
569 using XprType = CwiseUnaryOp<CastOp, ArgType>;
572 using SrcPacketType =
typename packet_traits<SrcType>::type;
573 static constexpr int SrcPacketSize = unpacket_traits<SrcPacketType>::size;
574 static constexpr int SrcPacketBytes = SrcPacketSize *
sizeof(SrcType);
577 CoeffReadCost = int(evaluator<ArgType>::CoeffReadCost) + int(functor_traits<CastOp>::Cost),
578 PacketAccess = functor_traits<CastOp>::PacketAccess,
581 IsRowMajor = (evaluator<ArgType>::Flags &
RowMajorBit),
582 Alignment = evaluator<ArgType>::Alignment
585 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE
explicit unary_evaluator(
const XprType& xpr)
586 : m_argImpl(xpr.nestedExpression()), m_rows(xpr.rows()), m_cols(xpr.cols()) {
587 EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<CastOp>::Cost);
588 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
591 template <
typename DstPacketType>
592 using AltSrcScalarOp = std::enable_if_t<(unpacket_traits<DstPacketType>::size < SrcPacketSize &&
593 !find_packet_by_size<SrcType, unpacket_traits<DstPacketType>::size>::value),
595 template <
typename DstPacketType>
596 using SrcPacketArgs1 =
597 std::enable_if_t<(find_packet_by_size<SrcType, unpacket_traits<DstPacketType>::size>::value),
bool>;
598 template <
typename DstPacketType>
599 using SrcPacketArgs2 = std::enable_if_t<(unpacket_traits<DstPacketType>::size) == (2 * SrcPacketSize),
bool>;
600 template <
typename DstPacketType>
601 using SrcPacketArgs4 = std::enable_if_t<(unpacket_traits<DstPacketType>::size) == (4 * SrcPacketSize),
bool>;
602 template <
typename DstPacketType>
603 using SrcPacketArgs8 = std::enable_if_t<(unpacket_traits<DstPacketType>::size) == (8 * SrcPacketSize),
bool>;
605 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
bool check_array_bounds(Index row, Index col, Index begin, Index count)
const {
606 return IsRowMajor ? (col + count + begin <= cols()) : (row + count + begin <= rows());
608 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
bool check_array_bounds(Index index, Index begin, Index count)
const {
609 return index + count + begin <= size();
612 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE SrcType srcCoeff(Index row, Index col, Index offset)
const {
613 Index actualRow = IsRowMajor ? row : row + offset;
614 Index actualCol = IsRowMajor ? col + offset : col;
615 return m_argImpl.coeff(actualRow, actualCol);
617 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE SrcType srcCoeff(Index index, Index offset)
const {
618 Index actualIndex = index + offset;
619 return m_argImpl.coeff(actualIndex);
622 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE DstType coeff(Index row, Index col)
const {
623 return cast<SrcType, DstType>(srcCoeff(row, col, 0));
625 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE DstType coeff(Index index)
const {
626 return cast<SrcType, DstType>(srcCoeff(index, 0));
629 template <
int LoadMode,
typename PacketType = SrcPacketType>
630 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType srcPacket(Index row, Index col, Index offset)
const {
631 constexpr int PacketSize = unpacket_traits<PacketType>::size;
632 Index packetOffset = offset * PacketSize;
633 Index actualRow = IsRowMajor ? row : row + packetOffset;
634 Index actualCol = IsRowMajor ? col + packetOffset : col;
635 eigen_assert(check_array_bounds(actualRow, actualCol, 0, PacketSize) &&
"Array index out of bounds");
636 return m_argImpl.template packet<LoadMode, PacketType>(actualRow, actualCol);
638 template <
int LoadMode,
typename PacketType = SrcPacketType>
639 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType srcPacket(Index index, Index offset)
const {
640 constexpr int PacketSize = unpacket_traits<PacketType>::size;
641 Index packetOffset = offset * PacketSize;
642 Index actualIndex = index + packetOffset;
643 eigen_assert(check_array_bounds(actualIndex, 0, PacketSize) &&
"Array index out of bounds");
644 return m_argImpl.template packet<LoadMode, PacketType>(actualIndex);
646 template <
int LoadMode,
typename PacketType = SrcPacketType>
647 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType srcPacketSegment(Index row, Index col, Index begin, Index count,
648 Index offset)
const {
649 constexpr int PacketSize = unpacket_traits<PacketType>::size;
650 Index packetOffset = offset * PacketSize;
651 Index actualRow = IsRowMajor ? row : row + packetOffset;
652 Index actualCol = IsRowMajor ? col + packetOffset : col;
653 eigen_assert(check_array_bounds(actualRow, actualCol, begin, count) &&
"Array index out of bounds");
654 return m_argImpl.template packetSegment<LoadMode, PacketType>(actualRow, actualCol, begin, count);
656 template <
int LoadMode,
typename PacketType = SrcPacketType>
657 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType srcPacketSegment(Index index, Index begin, Index count,
658 Index offset)
const {
659 constexpr int PacketSize = unpacket_traits<PacketType>::size;
660 Index packetOffset = offset * PacketSize;
661 Index actualIndex = index + packetOffset;
662 eigen_assert(check_array_bounds(actualIndex, begin, count) &&
"Array index out of bounds");
663 return m_argImpl.template packetSegment<LoadMode, PacketType>(actualIndex, begin, count);
666 template <
int NumPackets,
int LoadMode,
typename PacketType = SrcPacketType>
667 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketBlock<PacketType, NumPackets> srcPacketSegmentHelper(Index row, Index col,
670 constexpr int SrcLoadMode = plain_enum_min(SrcPacketBytes, LoadMode);
671 PacketBlock<PacketType, NumPackets> packets;
672 for (Index i = 0; i < NumPackets; i++) packets.packet[i] = pzero(PacketType());
673 Index offset = begin / SrcPacketSize;
674 Index actualBegin = begin % SrcPacketSize;
675 for (; offset < NumPackets; offset++) {
676 Index actualCount = numext::mini(SrcPacketSize - actualBegin, count);
677 packets.packet[offset] = srcPacketSegment<SrcLoadMode>(row, col, actualBegin, actualCount, offset);
678 if (count == actualCount)
break;
680 count -= actualCount;
684 template <
int NumPackets,
int LoadMode,
typename PacketType = SrcPacketType>
685 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketBlock<PacketType, NumPackets> srcPacketSegmentHelper(Index index,
688 constexpr int SrcLoadMode = plain_enum_min(SrcPacketBytes, LoadMode);
689 PacketBlock<PacketType, NumPackets> packets;
690 for (Index i = 0; i < NumPackets; i++) packets.packet[i] = pzero(PacketType());
691 Index offset = begin / SrcPacketSize;
692 Index actualBegin = begin % SrcPacketSize;
693 for (; offset < NumPackets; offset++) {
694 Index actualCount = numext::mini(SrcPacketSize - actualBegin, count);
695 packets.packet[offset] = srcPacketSegment<SrcLoadMode>(index, actualBegin, actualCount, offset);
696 if (count == actualCount)
break;
698 count -= actualCount;
708 template <
int LoadMode,
typename DstPacketType, AltSrcScalarOp<DstPacketType> = true>
709 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DstPacketType packet(Index row, Index col)
const {
710 constexpr int DstPacketSize = unpacket_traits<DstPacketType>::size;
711 constexpr int SrcBytesIncrement = DstPacketSize *
sizeof(SrcType);
712 constexpr int SrcLoadMode = plain_enum_min(SrcBytesIncrement, LoadMode);
713 return pcast<SrcPacketType, DstPacketType>(srcPacketSegment<SrcLoadMode>(row, col, 0, DstPacketSize, 0));
716 template <
int LoadMode,
typename DstPacketType, SrcPacketArgs1<DstPacketType> = true>
717 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DstPacketType packet(Index row, Index col)
const {
718 constexpr int DstPacketSize = unpacket_traits<DstPacketType>::size;
719 using SizedSrcPacketType =
typename find_packet_by_size<SrcType, DstPacketSize>::type;
720 constexpr int SrcBytesIncrement = DstPacketSize *
sizeof(SrcType);
721 constexpr int SrcLoadMode = plain_enum_min(SrcBytesIncrement, LoadMode);
722 return pcast<SizedSrcPacketType, DstPacketType>(srcPacket<SrcLoadMode, SizedSrcPacketType>(row, col, 0));
725 template <
int LoadMode,
typename DstPacketType, SrcPacketArgs2<DstPacketType> = true>
726 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DstPacketType packet(Index row, Index col)
const {
727 constexpr int SrcLoadMode = plain_enum_min(SrcPacketBytes, LoadMode);
728 return pcast<SrcPacketType, DstPacketType>(srcPacket<SrcLoadMode>(row, col, 0),
729 srcPacket<SrcLoadMode>(row, col, 1));
732 template <
int LoadMode,
typename DstPacketType, SrcPacketArgs4<DstPacketType> = true>
733 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DstPacketType packet(Index row, Index col)
const {
734 constexpr int SrcLoadMode = plain_enum_min(SrcPacketBytes, LoadMode);
735 return pcast<SrcPacketType, DstPacketType>(srcPacket<SrcLoadMode>(row, col, 0), srcPacket<SrcLoadMode>(row, col, 1),
736 srcPacket<SrcLoadMode>(row, col, 2),
737 srcPacket<SrcLoadMode>(row, col, 3));
740 template <
int LoadMode,
typename DstPacketType, SrcPacketArgs8<DstPacketType> = true>
741 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DstPacketType packet(Index row, Index col)
const {
742 constexpr int SrcLoadMode = plain_enum_min(SrcPacketBytes, LoadMode);
743 return pcast<SrcPacketType, DstPacketType>(
744 srcPacket<SrcLoadMode>(row, col, 0), srcPacket<SrcLoadMode>(row, col, 1), srcPacket<SrcLoadMode>(row, col, 2),
745 srcPacket<SrcLoadMode>(row, col, 3), srcPacket<SrcLoadMode>(row, col, 4), srcPacket<SrcLoadMode>(row, col, 5),
746 srcPacket<SrcLoadMode>(row, col, 6), srcPacket<SrcLoadMode>(row, col, 7));
750 template <
int LoadMode,
typename DstPacketType, AltSrcScalarOp<DstPacketType> = true>
751 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DstPacketType packetSegment(Index row, Index col, Index begin,
753 constexpr int DstPacketSize = unpacket_traits<DstPacketType>::size;
754 constexpr int SrcBytesIncrement = DstPacketSize *
sizeof(SrcType);
755 constexpr int SrcLoadMode = plain_enum_min(SrcBytesIncrement, LoadMode);
756 return pcast<SrcPacketType, DstPacketType>(srcPacketSegment<SrcLoadMode>(row, col, begin, count, 0));
759 template <
int LoadMode,
typename DstPacketType, SrcPacketArgs1<DstPacketType> = true>
760 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DstPacketType packetSegment(Index row, Index col, Index begin,
762 constexpr int DstPacketSize = unpacket_traits<DstPacketType>::size;
763 using SizedSrcPacketType =
typename find_packet_by_size<SrcType, DstPacketSize>::type;
764 constexpr int SrcBytesIncrement = DstPacketSize *
sizeof(SrcType);
765 constexpr int SrcLoadMode = plain_enum_min(SrcBytesIncrement, LoadMode);
766 return pcast<SizedSrcPacketType, DstPacketType>(
767 srcPacketSegment<SrcLoadMode, SizedSrcPacketType>(row, col, begin, count, 0));
770 template <
int LoadMode,
typename DstPacketType, SrcPacketArgs2<DstPacketType> = true>
771 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DstPacketType packetSegment(Index row, Index col, Index begin,
773 constexpr int NumPackets = 2;
774 constexpr int SrcLoadMode = plain_enum_min(SrcPacketBytes, LoadMode);
775 PacketBlock<SrcPacketType, NumPackets> packets =
776 srcPacketSegmentHelper<NumPackets, SrcLoadMode>(row, col, begin, count);
777 return pcast<SrcPacketType, DstPacketType>(packets.packet[0], packets.packet[1]);
780 template <
int LoadMode,
typename DstPacketType, SrcPacketArgs4<DstPacketType> = true>
781 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DstPacketType packetSegment(Index row, Index col, Index begin,
783 constexpr int NumPackets = 4;
784 constexpr int SrcLoadMode = plain_enum_min(SrcPacketBytes, LoadMode);
785 PacketBlock<SrcPacketType, NumPackets> packets =
786 srcPacketSegmentHelper<NumPackets, SrcLoadMode>(row, col, begin, count);
787 return pcast<SrcPacketType, DstPacketType>(packets.packet[0], packets.packet[1], packets.packet[2],
791 template <
int LoadMode,
typename DstPacketType, SrcPacketArgs8<DstPacketType> = true>
792 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DstPacketType packetSegment(Index row, Index col, Index begin,
794 constexpr int NumPackets = 8;
795 constexpr int SrcLoadMode = plain_enum_min(SrcPacketBytes, LoadMode);
796 PacketBlock<SrcPacketType, NumPackets> packets =
797 srcPacketSegmentHelper<NumPackets, SrcLoadMode>(row, col, begin, count);
798 return pcast<SrcPacketType, DstPacketType>(packets.packet[0], packets.packet[1], packets.packet[2],
799 packets.packet[3], packets.packet[4], packets.packet[5],
800 packets.packet[6], packets.packet[7]);
804 template <
int LoadMode,
typename DstPacketType, AltSrcScalarOp<DstPacketType> = true>
805 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DstPacketType packet(Index index)
const {
806 constexpr int DstPacketSize = unpacket_traits<DstPacketType>::size;
807 constexpr int SrcBytesIncrement = DstPacketSize *
sizeof(SrcType);
808 constexpr int SrcLoadMode = plain_enum_min(SrcBytesIncrement, LoadMode);
809 return pcast<SrcPacketType, DstPacketType>(srcPacketSegment<SrcLoadMode>(index, 0, DstPacketSize, 0));
811 template <
int LoadMode,
typename DstPacketType, SrcPacketArgs1<DstPacketType> = true>
812 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DstPacketType packet(Index index)
const {
813 constexpr int DstPacketSize = unpacket_traits<DstPacketType>::size;
814 using SizedSrcPacketType =
typename find_packet_by_size<SrcType, DstPacketSize>::type;
815 constexpr int SrcBytesIncrement = DstPacketSize *
sizeof(SrcType);
816 constexpr int SrcLoadMode = plain_enum_min(SrcBytesIncrement, LoadMode);
817 return pcast<SizedSrcPacketType, DstPacketType>(srcPacket<SrcLoadMode, SizedSrcPacketType>(index, 0));
819 template <
int LoadMode,
typename DstPacketType, SrcPacketArgs2<DstPacketType> = true>
820 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DstPacketType packet(Index index)
const {
821 constexpr int SrcLoadMode = plain_enum_min(SrcPacketBytes, LoadMode);
822 return pcast<SrcPacketType, DstPacketType>(srcPacket<SrcLoadMode>(index, 0), srcPacket<SrcLoadMode>(index, 1));
824 template <
int LoadMode,
typename DstPacketType, SrcPacketArgs4<DstPacketType> = true>
825 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DstPacketType packet(Index index)
const {
826 constexpr int SrcLoadMode = plain_enum_min(SrcPacketBytes, LoadMode);
827 return pcast<SrcPacketType, DstPacketType>(srcPacket<SrcLoadMode>(index, 0), srcPacket<SrcLoadMode>(index, 1),
828 srcPacket<SrcLoadMode>(index, 2), srcPacket<SrcLoadMode>(index, 3));
830 template <
int LoadMode,
typename DstPacketType, SrcPacketArgs8<DstPacketType> = true>
831 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DstPacketType packet(Index index)
const {
832 constexpr int SrcLoadMode = plain_enum_min(SrcPacketBytes, LoadMode);
833 return pcast<SrcPacketType, DstPacketType>(srcPacket<SrcLoadMode>(index, 0), srcPacket<SrcLoadMode>(index, 1),
834 srcPacket<SrcLoadMode>(index, 2), srcPacket<SrcLoadMode>(index, 3),
835 srcPacket<SrcLoadMode>(index, 4), srcPacket<SrcLoadMode>(index, 5),
836 srcPacket<SrcLoadMode>(index, 6), srcPacket<SrcLoadMode>(index, 7));
840 template <
int LoadMode,
typename DstPacketType, AltSrcScalarOp<DstPacketType> = true>
841 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DstPacketType packetSegment(Index index, Index begin, Index count)
const {
842 constexpr int DstPacketSize = unpacket_traits<DstPacketType>::size;
843 constexpr int SrcBytesIncrement = DstPacketSize *
sizeof(SrcType);
844 constexpr int SrcLoadMode = plain_enum_min(SrcBytesIncrement, LoadMode);
845 return pcast<SrcPacketType, DstPacketType>(srcPacketSegment<SrcLoadMode>(index, begin, count, 0));
848 template <
int LoadMode,
typename DstPacketType, SrcPacketArgs1<DstPacketType> = true>
849 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DstPacketType packetSegment(Index index, Index begin, Index count)
const {
850 constexpr int DstPacketSize = unpacket_traits<DstPacketType>::size;
851 using SizedSrcPacketType =
typename find_packet_by_size<SrcType, DstPacketSize>::type;
852 constexpr int SrcBytesIncrement = DstPacketSize *
sizeof(SrcType);
853 constexpr int SrcLoadMode = plain_enum_min(SrcBytesIncrement, LoadMode);
854 return pcast<SizedSrcPacketType, DstPacketType>(
855 srcPacketSegment<SrcLoadMode, SizedSrcPacketType>(index, begin, count, 0));
858 template <
int LoadMode,
typename DstPacketType, SrcPacketArgs2<DstPacketType> = true>
859 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DstPacketType packetSegment(Index index, Index begin, Index count)
const {
860 constexpr int NumPackets = 2;
861 constexpr int SrcLoadMode = plain_enum_min(SrcPacketBytes, LoadMode);
862 PacketBlock<SrcPacketType, NumPackets> packets =
863 srcPacketSegmentHelper<NumPackets, SrcLoadMode>(index, begin, count);
864 return pcast<SrcPacketType, DstPacketType>(packets.packet[0], packets.packet[1]);
867 template <
int LoadMode,
typename DstPacketType, SrcPacketArgs4<DstPacketType> = true>
868 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DstPacketType packetSegment(Index index, Index begin, Index count)
const {
869 constexpr int NumPackets = 4;
870 constexpr int SrcLoadMode = plain_enum_min(SrcPacketBytes, LoadMode);
871 PacketBlock<SrcPacketType, NumPackets> packets =
872 srcPacketSegmentHelper<NumPackets, SrcLoadMode>(index, begin, count);
873 return pcast<SrcPacketType, DstPacketType>(packets.packet[0], packets.packet[1], packets.packet[2],
877 template <
int LoadMode,
typename DstPacketType, SrcPacketArgs8<DstPacketType> = true>
878 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DstPacketType packetSegment(Index index, Index begin, Index count)
const {
879 constexpr int NumPackets = 8;
880 constexpr int SrcLoadMode = plain_enum_min(SrcPacketBytes, LoadMode);
881 PacketBlock<SrcPacketType, NumPackets> packets =
882 srcPacketSegmentHelper<NumPackets, SrcLoadMode>(index, begin, count);
883 return pcast<SrcPacketType, DstPacketType>(packets.packet[0], packets.packet[1], packets.packet[2],
884 packets.packet[3], packets.packet[4], packets.packet[5],
885 packets.packet[6], packets.packet[7]);
888 constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index rows()
const {
return m_rows; }
889 constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index cols()
const {
return m_cols; }
890 constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index size()
const {
return m_rows * m_cols; }
893 const evaluator<ArgType> m_argImpl;
894 const variable_if_dynamic<Index, XprType::RowsAtCompileTime> m_rows;
895 const variable_if_dynamic<Index, XprType::ColsAtCompileTime> m_cols;
901template <
typename TernaryOp,
typename Arg1,
typename Arg2,
typename Arg3>
902struct evaluator<CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3>>
903 :
public ternary_evaluator<CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3>> {
904 using XprType = CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3>;
905 using Base = ternary_evaluator<CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3>>;
907 EIGEN_DEVICE_FUNC
constexpr explicit evaluator(
const XprType& xpr) : Base(xpr) {}
910template <
typename TernaryOp,
typename Arg1,
typename Arg2,
typename Arg3>
911struct ternary_evaluator<CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3>, IndexBased, IndexBased>
912 : evaluator_base<CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3>> {
913 using XprType = CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3>;
916 CoeffReadCost = int(evaluator<Arg1>::CoeffReadCost) + int(evaluator<Arg2>::CoeffReadCost) +
917 int(evaluator<Arg3>::CoeffReadCost) + int(functor_traits<TernaryOp>::Cost),
919 Arg1Flags = evaluator<Arg1>::Flags,
920 Arg2Flags = evaluator<Arg2>::Flags,
921 Arg3Flags = evaluator<Arg3>::Flags,
922 SameType = std::is_same<typename Arg1::Scalar, typename Arg2::Scalar>::value &&
923 std::is_same<typename Arg1::Scalar, typename Arg3::Scalar>::value,
926 Flags0 = (int(Arg1Flags) | int(Arg2Flags) | int(Arg3Flags)) &
928 (
int(Arg1Flags) &
int(Arg2Flags) &
int(Arg3Flags) &
930 (functor_traits<TernaryOp>::PacketAccess && StorageOrdersAgree && SameType ?
PacketAccessBit : 0)))),
931 Flags = (Flags0 & ~RowMajorBit) | (Arg1Flags &
RowMajorBit),
932 Alignment = plain_enum_min(plain_enum_min(evaluator<Arg1>::Alignment, evaluator<Arg2>::Alignment),
933 evaluator<Arg3>::Alignment)
936 EIGEN_DEVICE_FUNC
constexpr explicit ternary_evaluator(
const XprType& xpr) : m_d(xpr) {
937 EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<TernaryOp>::Cost);
938 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
941 using CoeffReturnType =
typename XprType::CoeffReturnType;
943 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col)
const {
944 return m_d.func()(m_d.arg1Impl.coeff(row, col), m_d.arg2Impl.coeff(row, col), m_d.arg3Impl.coeff(row, col));
947 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index)
const {
948 return m_d.func()(m_d.arg1Impl.coeff(index), m_d.arg2Impl.coeff(index), m_d.arg3Impl.coeff(index));
951 template <
int LoadMode,
typename PacketType>
952 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packet(Index row, Index col)
const {
953 return m_d.func().packetOp(m_d.arg1Impl.template packet<LoadMode, PacketType>(row, col),
954 m_d.arg2Impl.template packet<LoadMode, PacketType>(row, col),
955 m_d.arg3Impl.template packet<LoadMode, PacketType>(row, col));
958 template <
int LoadMode,
typename PacketType>
959 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packet(Index index)
const {
960 return m_d.func().packetOp(m_d.arg1Impl.template packet<LoadMode, PacketType>(index),
961 m_d.arg2Impl.template packet<LoadMode, PacketType>(index),
962 m_d.arg3Impl.template packet<LoadMode, PacketType>(index));
965 template <
int LoadMode,
typename PacketType>
966 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packetSegment(Index row, Index col, Index begin, Index count)
const {
967 return m_d.func().packetOp(m_d.arg1Impl.template packetSegment<LoadMode, PacketType>(row, col, begin, count),
968 m_d.arg2Impl.template packetSegment<LoadMode, PacketType>(row, col, begin, count),
969 m_d.arg3Impl.template packetSegment<LoadMode, PacketType>(row, col, begin, count));
972 template <
int LoadMode,
typename PacketType>
973 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packetSegment(Index index, Index begin, Index count)
const {
974 return m_d.func().packetOp(m_d.arg1Impl.template packetSegment<LoadMode, PacketType>(index, begin, count),
975 m_d.arg2Impl.template packetSegment<LoadMode, PacketType>(index, begin, count),
976 m_d.arg3Impl.template packetSegment<LoadMode, PacketType>(index, begin, count));
982 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE Data(
const XprType& xpr)
983 : op(xpr.functor()), arg1Impl(xpr.arg1()), arg2Impl(xpr.arg2()), arg3Impl(xpr.arg3()) {}
984 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE
const TernaryOp& func()
const {
return op; }
986 evaluator<Arg1> arg1Impl;
987 evaluator<Arg2> arg2Impl;
988 evaluator<Arg3> arg3Impl;
994template <
typename Arg1,
typename Arg2,
typename Scalar,
typename CmpLhsType,
typename CmpRhsType, ComparisonName cmp>
995struct scalar_boolean_select_spec {
996 using DummyTernaryOp = scalar_boolean_select_op<Scalar, Scalar, bool>;
997 using DummyArg3 = CwiseBinaryOp<scalar_cmp_op<Scalar, Scalar, cmp, false>, CmpLhsType, CmpRhsType>;
998 using DummyXprType = CwiseTernaryOp<DummyTernaryOp, Arg1, Arg2, DummyArg3>;
1000 using PacketTernaryOp = scalar_boolean_select_op<Scalar, Scalar, Scalar>;
1001 using PacketArg3 = CwiseBinaryOp<scalar_cmp_op<Scalar, Scalar, cmp, true>, CmpLhsType, CmpRhsType>;
1002 using PacketXprType = CwiseTernaryOp<PacketTernaryOp, Arg1, Arg2, PacketArg3>;
1006 static constexpr bool UseTyped = (ternary_evaluator<PacketXprType>::Flags &
PacketAccessBit) != 0;
1007 using Arg3 = std::conditional_t<UseTyped, PacketArg3, DummyArg3>;
1008 using XprType = std::conditional_t<UseTyped, PacketXprType, DummyXprType>;
1010 using Base = ternary_evaluator<XprType>;
1012 EIGEN_DEVICE_FUNC
constexpr static const DummyXprType& expression(
const DummyXprType& xpr, std::false_type) {
1016 EIGEN_DEVICE_FUNC
constexpr static XprType expression(
const DummyXprType& xpr, std::true_type) {
1017 return XprType(xpr.arg1(), xpr.arg2(), Arg3(xpr.arg3().lhs(), xpr.arg3().rhs()));
1022template <
typename Arg1,
typename Arg2,
typename Scalar,
typename CmpLhsType,
typename CmpRhsType, ComparisonName cmp>
1023struct evaluator<CwiseTernaryOp<scalar_boolean_select_op<Scalar, Scalar, bool>, Arg1, Arg2,
1024 CwiseBinaryOp<scalar_cmp_op<Scalar, Scalar, cmp, false>, CmpLhsType, CmpRhsType>>>
1025 :
public scalar_boolean_select_spec<Arg1, Arg2, Scalar, CmpLhsType, CmpRhsType, cmp>::Base {
1026 using Helper = scalar_boolean_select_spec<Arg1, Arg2, Scalar, CmpLhsType, CmpRhsType, cmp>;
1027 using Base =
typename Helper::Base;
1028 using DummyXprType =
typename Helper::DummyXprType;
1030 EIGEN_DEVICE_FUNC
constexpr explicit evaluator(
const DummyXprType& xpr)
1031 : Base(Helper::expression(xpr, bool_constant<Helper::UseTyped>())) {}
1037template <
typename BinaryOp,
typename Lhs,
typename Rhs>
1038struct evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs>> :
public binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs>> {
1039 using XprType = CwiseBinaryOp<BinaryOp, Lhs, Rhs>;
1040 using Base = binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs>>;
1042 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE
explicit evaluator(
const XprType& xpr) : Base(xpr) {}
1045template <
typename BinaryOp,
typename Lhs,
typename Rhs>
1046struct binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs>, IndexBased, IndexBased>
1047 : evaluator_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs>> {
1048 using XprType = CwiseBinaryOp<BinaryOp, Lhs, Rhs>;
1052 int(evaluator<Lhs>::CoeffReadCost) + int(evaluator<Rhs>::CoeffReadCost) + int(functor_traits<BinaryOp>::Cost),
1054 LhsFlags = evaluator<Lhs>::Flags,
1055 RhsFlags = evaluator<Rhs>::Flags,
1056 SameType = std::is_same<typename Lhs::Scalar, typename Rhs::Scalar>::value,
1058 Flags0 = (int(LhsFlags) | int(RhsFlags)) &
1060 (
int(LhsFlags) &
int(RhsFlags) &
1062 (functor_traits<BinaryOp>::PacketAccess && StorageOrdersAgree && SameType ?
PacketAccessBit : 0)))),
1063 Flags = (Flags0 & ~RowMajorBit) | (LhsFlags &
RowMajorBit),
1064 Alignment = plain_enum_min(evaluator<Lhs>::Alignment, evaluator<Rhs>::Alignment)
1067 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE
explicit binary_evaluator(
const XprType& xpr) : m_d(xpr) {
1068 EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<BinaryOp>::Cost);
1069 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
1072 using CoeffReturnType =
typename XprType::CoeffReturnType;
1074 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col)
const {
1075 return m_d.func()(m_d.lhsImpl.coeff(row, col), m_d.rhsImpl.coeff(row, col));
1078 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index)
const {
1079 return m_d.func()(m_d.lhsImpl.coeff(index), m_d.rhsImpl.coeff(index));
1082 template <
int LoadMode,
typename PacketType>
1083 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packet(Index row, Index col)
const {
1084 return m_d.func().packetOp(m_d.lhsImpl.template packet<LoadMode, PacketType>(row, col),
1085 m_d.rhsImpl.template packet<LoadMode, PacketType>(row, col));
1088 template <
int LoadMode,
typename PacketType>
1089 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packet(Index index)
const {
1090 return m_d.func().packetOp(m_d.lhsImpl.template packet<LoadMode, PacketType>(index),
1091 m_d.rhsImpl.template packet<LoadMode, PacketType>(index));
1094 template <
int LoadMode,
typename PacketType>
1095 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packetSegment(Index row, Index col, Index begin, Index count)
const {
1096 return m_d.func().packetOp(m_d.lhsImpl.template packetSegment<LoadMode, PacketType>(row, col, begin, count),
1097 m_d.rhsImpl.template packetSegment<LoadMode, PacketType>(row, col, begin, count));
1100 template <
int LoadMode,
typename PacketType>
1101 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packetSegment(Index index, Index begin, Index count)
const {
1102 return m_d.func().packetOp(m_d.lhsImpl.template packetSegment<LoadMode, PacketType>(index, begin, count),
1103 m_d.rhsImpl.template packetSegment<LoadMode, PacketType>(index, begin, count));
1109 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE Data(
const XprType& xpr)
1110 : op(xpr.functor()), lhsImpl(xpr.lhs()), rhsImpl(xpr.rhs()) {}
1111 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE
const BinaryOp& func()
const {
return op; }
1113 evaluator<Lhs> lhsImpl;
1114 evaluator<Rhs> rhsImpl;
1122template <
typename UnaryOp,
typename ArgType,
typename Str
ideType>
1123struct unary_evaluator<CwiseUnaryView<UnaryOp, ArgType, StrideType>, IndexBased>
1124 : evaluator_base<CwiseUnaryView<UnaryOp, ArgType, StrideType>> {
1125 using XprType = CwiseUnaryView<UnaryOp, ArgType, StrideType>;
1128 CoeffReadCost = int(evaluator<ArgType>::CoeffReadCost) + int(functor_traits<UnaryOp>::Cost),
1135 EIGEN_DEVICE_FUNC
constexpr explicit unary_evaluator(
const XprType& op) : m_d(op) {
1136 EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<UnaryOp>::Cost);
1137 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
1140 using Scalar =
typename XprType::Scalar;
1141 using CoeffReturnType =
typename XprType::CoeffReturnType;
1143 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col)
const {
1144 return m_d.func()(m_d.argImpl.coeff(row, col));
1147 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index)
const {
1148 return m_d.func()(m_d.argImpl.coeff(index));
1151 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col) {
1152 return m_d.func()(m_d.argImpl.coeffRef(row, col));
1155 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE Scalar& coeffRef(Index index) {
1156 return m_d.func()(m_d.argImpl.coeffRef(index));
1162 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE Data(
const XprType& xpr)
1163 : op(xpr.functor()), argImpl(xpr.nestedExpression()) {}
1164 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE
const UnaryOp& func()
const {
return op; }
1166 evaluator<ArgType> argImpl;
1174template <
typename XprType,
int Component,
1175 bool Vectorizable = bool(traits<typename XprType::NestedExpression>::Flags &
DirectAccessBit) &&
1176 inner_stride_at_compile_time<typename XprType::NestedExpression>::value == 1 &&
1177 (std::is_same<typename XprType::Scalar, float>::value ||
1178 std::is_same<typename XprType::Scalar, double>::value) &&
1179 packet_traits<typename XprType::Scalar>::Vectorizable &&
1180 std::is_same<
typename XprType::Scalar,
typename unpacket_traits<
typename packet_traits<
1181 typename XprType::Scalar>::type>::type>::value>
1182struct complex_component_evaluator : unary_evaluator<XprType> {
1183 using Base = unary_evaluator<XprType>;
1184 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE
explicit complex_component_evaluator(
const XprType& xpr)
1188template <
typename XprType,
int Component>
1189struct complex_component_evaluator<XprType, Component, true> : unary_evaluator<XprType> {
1190 using Base = unary_evaluator<XprType>;
1191 using Scalar =
typename XprType::Scalar;
1194 using NestedXpr =
typename XprType::NestedExpression;
1196 static constexpr unsigned int Flags = (Base::Flags & ~DirectAccessBit) |
PacketAccessBit;
1197 static constexpr int Alignment = 0;
1199 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE
explicit complex_component_evaluator(
const XprType& xpr)
1201 m_data(reinterpret_cast<const Scalar*>(xpr.nestedExpression().data())),
1202 m_outerStride(xpr.nestedExpression().outerStride()) {}
1204 template <
int LoadMode,
typename PacketType>
1205 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packet(Index index)
const {
1206 return pgather<Scalar, PacketType>(m_data + 2 * index + Component, 2);
1209 template <
int LoadMode,
typename PacketType>
1210 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packet(Index row, Index col)
const {
1211 const Index index = XprType::IsRowMajor ? row * m_outerStride.value() + col : col * m_outerStride.value() + row;
1212 return packet<LoadMode, PacketType>(index);
1215 template <
int LoadMode,
typename PacketType>
1216 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packetSegment(Index index, Index begin, Index count)
const {
1217 Scalar values[unpacket_traits<PacketType>::size] = {};
1218 for (Index i = begin; i < begin + count; ++i) values[i] = Base::coeff(index + i);
1219 return ploadu<PacketType>(values);
1222 template <
int LoadMode,
typename PacketType>
1223 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packetSegment(Index row, Index col, Index begin, Index count)
const {
1224 Scalar values[unpacket_traits<PacketType>::size] = {};
1225 for (Index i = begin; i < begin + count; ++i)
1226 values[i] = Base::coeff(row + (XprType::IsRowMajor ? 0 : i), col + (XprType::IsRowMajor ? i : 0));
1227 return ploadu<PacketType>(values);
1231 const Scalar* m_data;
1232 const variable_if_dynamic<Index, outer_stride_at_compile_time<NestedXpr>::value> m_outerStride;
1235template <
typename Real,
typename ArgType>
1236struct evaluator<CwiseUnaryOp<scalar_real_op<std::complex<Real>>, ArgType>>
1237 : complex_component_evaluator<CwiseUnaryOp<scalar_real_op<std::complex<Real>>, ArgType>, 0> {
1238 using XprType = CwiseUnaryOp<scalar_real_op<std::complex<Real>>, ArgType>;
1239 using Base = complex_component_evaluator<XprType, 0>;
1240 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE
explicit evaluator(
const XprType& xpr) : Base(xpr) {}
1244template <
typename Real,
typename ArgType>
1245struct evaluator<const CwiseUnaryView<scalar_real_ref_op<std::complex<Real>>, ArgType, Stride<0, 0>>>
1246 : complex_component_evaluator<CwiseUnaryView<scalar_real_ref_op<std::complex<Real>>, ArgType, Stride<0, 0>>, 0> {
1247 using XprType = CwiseUnaryView<scalar_real_ref_op<std::complex<Real>>, ArgType, Stride<0, 0>>;
1248 using Base = complex_component_evaluator<XprType, 0>;
1249 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE
explicit evaluator(
const XprType& xpr) : Base(xpr) {}
1252template <
typename Real,
typename ArgType>
1253struct evaluator<CwiseUnaryOp<scalar_imag_op<std::complex<Real>>, ArgType>>
1254 : complex_component_evaluator<CwiseUnaryOp<scalar_imag_op<std::complex<Real>>, ArgType>, 1> {
1255 using XprType = CwiseUnaryOp<scalar_imag_op<std::complex<Real>>, ArgType>;
1256 using Base = complex_component_evaluator<XprType, 1>;
1257 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE
explicit evaluator(
const XprType& xpr) : Base(xpr) {}
1260template <
typename Real,
typename ArgType>
1261struct evaluator<const CwiseUnaryView<scalar_imag_ref_op<std::complex<Real>>, ArgType, Stride<0, 0>>>
1262 : complex_component_evaluator<CwiseUnaryView<scalar_imag_ref_op<std::complex<Real>>, ArgType, Stride<0, 0>>, 1> {
1263 using XprType = CwiseUnaryView<scalar_imag_ref_op<std::complex<Real>>, ArgType, Stride<0, 0>>;
1264 using Base = complex_component_evaluator<XprType, 1>;
1265 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE
explicit evaluator(
const XprType& xpr) : Base(xpr) {}
1272template <
typename Derived,
typename PlainObjectType>
1273struct mapbase_evaluator;
1275template <
typename Derived,
typename PlainObjectType>
1276struct mapbase_evaluator : evaluator_base<Derived> {
1277 using XprType = Derived;
1278 using PointerType =
typename XprType::PointerType;
1279 using Scalar =
typename XprType::Scalar;
1280 using CoeffReturnType =
typename XprType::CoeffReturnType;
1283 IsRowMajor = XprType::IsRowMajor,
1284 ColsAtCompileTime = XprType::ColsAtCompileTime,
1285 CoeffReadCost = NumTraits<Scalar>::ReadCost
1288 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE
explicit mapbase_evaluator(
const XprType& map)
1289 : m_data(const_cast<PointerType>(map.data())),
1290 m_innerStride(map.innerStride()),
1291 m_outerStride(map.outerStride()) {
1292 EIGEN_STATIC_ASSERT(check_implication((evaluator<Derived>::Flags &
PacketAccessBit) != 0,
1293 inner_stride_at_compile_time<Derived>::value == 1),
1294 PACKET_ACCESS_REQUIRES_TO_HAVE_INNER_STRIDE_FIXED_TO_1);
1295 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
1298 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col)
const {
1299 return m_data[col * colStride() + row * rowStride()];
1302 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index)
const {
1303 return m_data[index * m_innerStride.value()];
1306 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col) {
1307 return m_data[col * colStride() + row * rowStride()];
1310 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE Scalar& coeffRef(Index index) {
1311 return m_data[index * m_innerStride.value()];
1314 template <
int LoadMode,
typename PacketType>
1315 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packet(Index row, Index col)
const {
1316 PointerType ptr = m_data + row * rowStride() + col * colStride();
1317 return ploadt<PacketType, LoadMode>(ptr);
1320 template <
int LoadMode,
typename PacketType>
1321 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packet(Index index)
const {
1322 return ploadt<PacketType, LoadMode>(m_data + index * m_innerStride.value());
1325 template <
int StoreMode,
typename PacketType>
1326 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void writePacket(Index row, Index col,
const PacketType& x) {
1327 PointerType ptr = m_data + row * rowStride() + col * colStride();
1328 pstoret<Scalar, PacketType, StoreMode>(ptr, x);
1331 template <
int StoreMode,
typename PacketType>
1332 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void writePacket(Index index,
const PacketType& x) {
1333 pstoret<Scalar, PacketType, StoreMode>(m_data + index * m_innerStride.value(), x);
1336 template <
int LoadMode,
typename PacketType>
1337 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packetSegment(Index row, Index col, Index begin, Index count)
const {
1338 PointerType ptr = m_data + row * rowStride() + col * colStride();
1339 return ploadtSegment<PacketType, LoadMode>(ptr, begin, count);
1342 template <
int LoadMode,
typename PacketType>
1343 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packetSegment(Index index, Index begin, Index count)
const {
1344 return ploadtSegment<PacketType, LoadMode>(m_data + index * m_innerStride.value(), begin, count);
1347 template <
int StoreMode,
typename PacketType>
1348 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void writePacketSegment(Index row, Index col,
const PacketType& x, Index begin,
1350 PointerType ptr = m_data + row * rowStride() + col * colStride();
1351 pstoretSegment<Scalar, PacketType, StoreMode>(ptr, x, begin, count);
1354 template <
int StoreMode,
typename PacketType>
1355 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void writePacketSegment(Index index,
const PacketType& x, Index begin,
1357 pstoretSegment<Scalar, PacketType, StoreMode>(m_data + index * m_innerStride.value(), x, begin, count);
1361 EIGEN_DEVICE_FUNC
constexpr Index rowStride() const noexcept {
1362 return XprType::IsRowMajor ? m_outerStride.value() : m_innerStride.value();
1364 EIGEN_DEVICE_FUNC
constexpr Index colStride() const noexcept {
1365 return XprType::IsRowMajor ? m_innerStride.value() : m_outerStride.value();
1369 const variable_if_dynamic<Index, XprType::InnerStrideAtCompileTime> m_innerStride;
1370 const variable_if_dynamic<Index, XprType::OuterStrideAtCompileTime> m_outerStride;
1373template <
typename PlainObjectType,
int MapOptions,
typename Str
ideType>
1374struct evaluator<Map<PlainObjectType, MapOptions, StrideType>>
1375 :
public mapbase_evaluator<Map<PlainObjectType, MapOptions, StrideType>, PlainObjectType> {
1376 using XprType = Map<PlainObjectType, MapOptions, StrideType>;
1377 using Scalar =
typename XprType::Scalar;
1379 using PacketScalar =
typename packet_traits<Scalar>::type;
1382 InnerStrideAtCompileTime = StrideType::InnerStrideAtCompileTime == 0
1383 ? int(PlainObjectType::InnerStrideAtCompileTime)
1384 : int(StrideType::InnerStrideAtCompileTime),
1385 OuterStrideAtCompileTime = StrideType::OuterStrideAtCompileTime == 0
1386 ? int(PlainObjectType::OuterStrideAtCompileTime)
1387 : int(StrideType::OuterStrideAtCompileTime),
1388 HasNoInnerStride = InnerStrideAtCompileTime == 1,
1389 HasNoOuterStride = StrideType::OuterStrideAtCompileTime == 0,
1390 HasNoStride = HasNoInnerStride && HasNoOuterStride,
1391 IsDynamicSize = PlainObjectType::SizeAtCompileTime == Dynamic,
1393 PacketAccessMask = bool(HasNoInnerStride) ? ~int(0) : ~int(
PacketAccessBit),
1395 bool(HasNoStride) || bool(PlainObjectType::IsVectorAtCompileTime) ? ~int(0) : ~int(
LinearAccessBit),
1396 Flags = int(evaluator<PlainObjectType>::Flags) & (LinearAccessMask & PacketAccessMask),
1398 Alignment = int(MapOptions) & int(AlignedMask)
1401 EIGEN_DEVICE_FUNC
constexpr explicit evaluator(
const XprType& map)
1402 : mapbase_evaluator<XprType, PlainObjectType>(map) {}
1407template <
typename PlainObjectType,
int RefOptions,
typename Str
ideType>
1408struct evaluator<Ref<PlainObjectType, RefOptions, StrideType>>
1409 :
public mapbase_evaluator<Ref<PlainObjectType, RefOptions, StrideType>, PlainObjectType> {
1410 using XprType = Ref<PlainObjectType, RefOptions, StrideType>;
1413 Flags = evaluator<Map<PlainObjectType, RefOptions, StrideType>>::Flags,
1414 Alignment = evaluator<Map<PlainObjectType, RefOptions, StrideType>>::Alignment
1417 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE
explicit evaluator(
const XprType& ref)
1418 : mapbase_evaluator<XprType, PlainObjectType>(ref) {}
1423template <
typename ArgType,
int BlockRows,
int BlockCols,
bool InnerPanel,
1424 bool HasDirectAccess = has_direct_access<ArgType>::value && bool(evaluator<ArgType>::Flags &
DirectAccessBit)>
1425struct block_evaluator;
1427template <
typename ArgType,
int BlockRows,
int BlockCols,
bool InnerPanel>
1428struct evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel>>
1429 : block_evaluator<ArgType, BlockRows, BlockCols, InnerPanel> {
1430 using XprType = Block<ArgType, BlockRows, BlockCols, InnerPanel>;
1431 using Scalar =
typename XprType::Scalar;
1433 using PacketScalar =
typename packet_traits<Scalar>::type;
1436 CoeffReadCost = evaluator<ArgType>::CoeffReadCost,
1438 RowsAtCompileTime = traits<XprType>::RowsAtCompileTime,
1439 ColsAtCompileTime = traits<XprType>::ColsAtCompileTime,
1440 MaxRowsAtCompileTime = traits<XprType>::MaxRowsAtCompileTime,
1441 MaxColsAtCompileTime = traits<XprType>::MaxColsAtCompileTime,
1443 ArgTypeIsRowMajor = (int(evaluator<ArgType>::Flags) &
RowMajorBit) != 0,
1444 IsRowMajor = (MaxRowsAtCompileTime == 1 && MaxColsAtCompileTime != 1) ? 1
1445 : (MaxColsAtCompileTime == 1 && MaxRowsAtCompileTime != 1) ? 0
1446 : ArgTypeIsRowMajor,
1447 HasSameStorageOrderAsArgType = (IsRowMajor == ArgTypeIsRowMajor),
1448 InnerSize = IsRowMajor ? int(ColsAtCompileTime) : int(RowsAtCompileTime),
1449 InnerStrideAtCompileTime = HasSameStorageOrderAsArgType ? int(inner_stride_at_compile_time<ArgType>::value)
1450 : int(outer_stride_at_compile_time<ArgType>::value),
1451 OuterStrideAtCompileTime = HasSameStorageOrderAsArgType ? int(outer_stride_at_compile_time<ArgType>::value)
1452 : int(inner_stride_at_compile_time<ArgType>::value),
1454 MaskPacketAccessBit = (InnerStrideAtCompileTime == 1 ||
1455 (!(evaluator<ArgType>::Flags &
DirectAccessBit) && HasSameStorageOrderAsArgType))
1459 FlagsLinearAccessBit = (RowsAtCompileTime == 1 || ColsAtCompileTime == 1 ||
1465 Flags = Flags0 | FlagsLinearAccessBit | FlagsRowMajorBit,
1467 PacketAlignment = unpacket_traits<PacketScalar>::alignment,
1468 Alignment0 = (InnerPanel && (OuterStrideAtCompileTime != Dynamic) && (OuterStrideAtCompileTime != 0) &&
1469 (((OuterStrideAtCompileTime * int(sizeof(Scalar))) % int(PacketAlignment)) == 0))
1470 ? int(PacketAlignment)
1472 Alignment = plain_enum_min(evaluator<ArgType>::Alignment, Alignment0)
1474 using block_evaluator_type = block_evaluator<ArgType, BlockRows, BlockCols, InnerPanel>;
1475 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE
explicit evaluator(
const XprType& block)
1476 : block_evaluator_type(block) {
1477 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
1482template <
typename ArgType,
int BlockRows,
int BlockCols,
bool InnerPanel>
1483struct block_evaluator<ArgType, BlockRows, BlockCols, InnerPanel, false>
1484 : unary_evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel>> {
1485 using XprType = Block<ArgType, BlockRows, BlockCols, InnerPanel>;
1487 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE
explicit block_evaluator(
const XprType& block)
1488 : unary_evaluator<XprType>(block) {}
1491template <
typename ArgType,
int BlockRows,
int BlockCols,
bool InnerPanel>
1492struct unary_evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel>, IndexBased>
1493 : evaluator_base<Block<ArgType, BlockRows, BlockCols, InnerPanel>> {
1494 using XprType = Block<ArgType, BlockRows, BlockCols, InnerPanel>;
1496 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE
explicit unary_evaluator(
const XprType& block)
1497 : m_argImpl(block.nestedExpression()),
1498 m_startRow(block.startRow()),
1499 m_startCol(block.startCol()),
1500 m_linear_offset(ForwardLinearAccess
1501 ? (ArgType::IsRowMajor
1502 ? block.startRow() * block.nestedExpression().cols() + block.startCol()
1503 : block.startCol() * block.nestedExpression().rows() + block.startRow())
1506 using Scalar =
typename XprType::Scalar;
1507 using CoeffReturnType =
typename XprType::CoeffReturnType;
1510 RowsAtCompileTime = XprType::RowsAtCompileTime,
1511 ForwardLinearAccess = (InnerPanel || int(XprType::IsRowMajor) == int(ArgType::IsRowMajor)) &&
1512 bool(evaluator<ArgType>::Flags & LinearAccessBit)
1515 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col)
const {
1516 return m_argImpl.coeff(m_startRow.value() + row, m_startCol.value() + col);
1519 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index)
const {
1520 return linear_coeff_impl(index, bool_constant<ForwardLinearAccess>());
1523 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col) {
1524 return m_argImpl.coeffRef(m_startRow.value() + row, m_startCol.value() + col);
1527 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE Scalar& coeffRef(Index index) {
1528 return linear_coeffRef_impl(index, bool_constant<ForwardLinearAccess>());
1531 template <
int LoadMode,
typename PacketType>
1532 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packet(Index row, Index col)
const {
1533 return m_argImpl.template packet<LoadMode, PacketType>(m_startRow.value() + row, m_startCol.value() + col);
1536 template <
int LoadMode,
typename PacketType>
1537 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packet(Index index)
const {
1538 EIGEN_IF_CONSTEXPR (ForwardLinearAccess)
1539 return m_argImpl.template packet<LoadMode, PacketType>(m_linear_offset.value() + index);
1541 return packet<LoadMode, PacketType>(RowsAtCompileTime == 1 ? 0 : index, RowsAtCompileTime == 1 ? index : 0);
1544 template <
int StoreMode,
typename PacketType>
1545 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void writePacket(Index row, Index col,
const PacketType& x) {
1546 return m_argImpl.template writePacket<StoreMode, PacketType>(m_startRow.value() + row, m_startCol.value() + col, x);
1549 template <
int StoreMode,
typename PacketType>
1550 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void writePacket(Index index,
const PacketType& x) {
1551 EIGEN_IF_CONSTEXPR (ForwardLinearAccess)
1552 return m_argImpl.template writePacket<StoreMode, PacketType>(m_linear_offset.value() + index, x);
1554 return writePacket<StoreMode, PacketType>(RowsAtCompileTime == 1 ? 0 : index, RowsAtCompileTime == 1 ? index : 0,
1558 template <
int LoadMode,
typename PacketType>
1559 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packetSegment(Index row, Index col, Index begin, Index count)
const {
1560 return m_argImpl.template packetSegment<LoadMode, PacketType>(m_startRow.value() + row, m_startCol.value() + col,
1564 template <
int LoadMode,
typename PacketType>
1565 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packetSegment(Index index, Index begin, Index count)
const {
1566 EIGEN_IF_CONSTEXPR (ForwardLinearAccess)
1567 return m_argImpl.template packetSegment<LoadMode, PacketType>(m_linear_offset.value() + index, begin, count);
1569 return packetSegment<LoadMode, PacketType>(RowsAtCompileTime == 1 ? 0 : index, RowsAtCompileTime == 1 ? index : 0,
1573 template <
int StoreMode,
typename PacketType>
1574 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void writePacketSegment(Index row, Index col,
const PacketType& x, Index begin,
1576 return m_argImpl.template writePacketSegment<StoreMode, PacketType>(m_startRow.value() + row,
1577 m_startCol.value() + col, x, begin, count);
1580 template <
int StoreMode,
typename PacketType>
1581 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void writePacketSegment(Index index,
const PacketType& x, Index begin,
1583 EIGEN_IF_CONSTEXPR (ForwardLinearAccess)
1584 return m_argImpl.template writePacketSegment<StoreMode, PacketType>(m_linear_offset.value() + index, x, begin,
1587 return writePacketSegment<StoreMode, PacketType>(RowsAtCompileTime == 1 ? 0 : index,
1588 RowsAtCompileTime == 1 ? index : 0, x, begin, count);
1592 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE CoeffReturnType
1593 linear_coeff_impl(Index index, std::true_type )
const {
1594 return m_argImpl.coeff(m_linear_offset.value() + index);
1596 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE CoeffReturnType
1597 linear_coeff_impl(Index index, std::false_type )
const {
1598 return coeff(RowsAtCompileTime == 1 ? 0 : index, RowsAtCompileTime == 1 ? index : 0);
1601 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE Scalar& linear_coeffRef_impl(
1602 Index index, std::true_type ) {
1603 return m_argImpl.coeffRef(m_linear_offset.value() + index);
1605 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE Scalar& linear_coeffRef_impl(
1606 Index index, std::false_type ) {
1607 return coeffRef(RowsAtCompileTime == 1 ? 0 : index, RowsAtCompileTime == 1 ? index : 0);
1610 evaluator<ArgType> m_argImpl;
1611 const variable_if_dynamic<Index, (ArgType::RowsAtCompileTime == 1 && BlockRows == 1) ? 0 : Dynamic> m_startRow;
1612 const variable_if_dynamic<Index, (ArgType::ColsAtCompileTime == 1 && BlockCols == 1) ? 0 : Dynamic> m_startCol;
1613 const variable_if_dynamic<Index, ForwardLinearAccess ? Dynamic : 0> m_linear_offset;
1619template <
typename ArgType,
int BlockRows,
int BlockCols,
bool InnerPanel>
1620struct block_evaluator<ArgType, BlockRows, BlockCols, InnerPanel, true>
1621 : mapbase_evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel>,
1622 typename Block<ArgType, BlockRows, BlockCols, InnerPanel>::PlainObject> {
1623 using XprType = Block<ArgType, BlockRows, BlockCols, InnerPanel>;
1624 using Scalar =
typename XprType::Scalar;
1626 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE
explicit block_evaluator(
const XprType& block)
1627 : mapbase_evaluator<XprType, typename XprType::PlainObject>(block) {
1628 eigen_internal_assert((internal::is_constant_evaluated() ||
1629 (std::uintptr_t(block.data()) % plain_enum_max(1, evaluator<XprType>::Alignment)) == 0) &&
1630 "data is not aligned");
1636template <
typename ArgType,
int RowFactor,
int ColFactor>
1637struct unary_evaluator<Replicate<ArgType, RowFactor, ColFactor>>
1638 : evaluator_base<Replicate<ArgType, RowFactor, ColFactor>> {
1639 using XprType = Replicate<ArgType, RowFactor, ColFactor>;
1640 using CoeffReturnType =
typename XprType::CoeffReturnType;
1641 enum { Factor = (RowFactor == Dynamic || ColFactor == Dynamic) ? Dynamic : RowFactor * ColFactor };
1642 using ArgTypeNested =
typename nested_eval<ArgType, Factor>::type;
1643 using ArgTypeNestedCleaned = remove_all_t<ArgTypeNested>;
1646 CoeffReadCost = evaluator<ArgTypeNestedCleaned>::CoeffReadCost,
1647 LinearAccessMask = XprType::IsVectorAtCompileTime ?
LinearAccessBit : 0,
1653 InnerFactor = traits<XprType>::IsRowMajor ? ColFactor : RowFactor,
1655 Flags = (evaluator<ArgTypeNestedCleaned>::Flags & (HereditaryBits | LinearAccessMask | MaskPacketAccessBit) &
1657 (traits<XprType>::Flags & RowMajorBit),
1659 Alignment = evaluator<ArgTypeNestedCleaned>::Alignment
1662 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE
explicit unary_evaluator(
const XprType& replicate)
1663 : m_arg(replicate.nestedExpression()),
1665 m_rows(replicate.nestedExpression().rows()),
1666 m_cols(replicate.nestedExpression().cols()) {}
1668 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col)
const {
1670 const Index actual_row = traits<XprType>::RowsAtCompileTime == 1 ? 0 : RowFactor == 1 ? row : row % m_rows.value();
1671 const Index actual_col = traits<XprType>::ColsAtCompileTime == 1 ? 0 : ColFactor == 1 ? col : col % m_cols.value();
1673 return m_argImpl.coeff(actual_row, actual_col);
1676 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index)
const {
1678 const Index actual_index = traits<XprType>::RowsAtCompileTime == 1
1679 ? (ColFactor == 1 ? index : index % m_cols.value())
1680 : (RowFactor == 1 ? index : index % m_rows.value());
1682 return m_argImpl.coeff(actual_index);
1685 template <
int LoadMode,
typename PacketType>
1686 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packet(Index row, Index col)
const {
1687 const Index actual_row = traits<XprType>::RowsAtCompileTime == 1 ? 0 : RowFactor == 1 ? row : row % m_rows.value();
1688 const Index actual_col = traits<XprType>::ColsAtCompileTime == 1 ? 0 : ColFactor == 1 ? col : col % m_cols.value();
1690 return m_argImpl.template packet<LoadMode, PacketType>(actual_row, actual_col);
1693 template <
int LoadMode,
typename PacketType>
1694 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packet(Index index)
const {
1695 const Index actual_index = traits<XprType>::RowsAtCompileTime == 1
1696 ? (ColFactor == 1 ? index : index % m_cols.value())
1697 : (RowFactor == 1 ? index : index % m_rows.value());
1699 return m_argImpl.template packet<LoadMode, PacketType>(actual_index);
1702 template <
int LoadMode,
typename PacketType>
1703 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packetSegment(Index row, Index col, Index begin, Index count)
const {
1704 const Index actual_row = traits<XprType>::RowsAtCompileTime == 1 ? 0 : RowFactor == 1 ? row : row % m_rows.value();
1705 const Index actual_col = traits<XprType>::ColsAtCompileTime == 1 ? 0 : ColFactor == 1 ? col : col % m_cols.value();
1707 return m_argImpl.template packetSegment<LoadMode, PacketType>(actual_row, actual_col, begin, count);
1710 template <
int LoadMode,
typename PacketType>
1711 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packetSegment(Index index, Index begin, Index count)
const {
1712 const Index actual_index = traits<XprType>::RowsAtCompileTime == 1
1713 ? (ColFactor == 1 ? index : index % m_cols.value())
1714 : (RowFactor == 1 ? index : index % m_rows.value());
1716 return m_argImpl.template packetSegment<LoadMode, PacketType>(actual_index, begin, count);
1720 ArgTypeNested m_arg;
1721 evaluator<ArgTypeNestedCleaned> m_argImpl;
1722 const variable_if_dynamic<Index, ArgType::RowsAtCompileTime> m_rows;
1723 const variable_if_dynamic<Index, ArgType::ColsAtCompileTime> m_cols;
1731template <
typename XprType>
1732struct evaluator_wrapper_base : evaluator_base<XprType> {
1733 using ArgType = remove_all_t<typename XprType::NestedExpressionType>;
1735 CoeffReadCost = evaluator<ArgType>::CoeffReadCost,
1736 Flags = evaluator<ArgType>::Flags,
1737 Alignment = evaluator<ArgType>::Alignment
1740 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
explicit evaluator_wrapper_base(
const ArgType& arg) : m_argImpl(arg) {}
1742 using Scalar =
typename ArgType::Scalar;
1743 using CoeffReturnType =
typename ArgType::CoeffReturnType;
1745 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col)
const {
1746 return m_argImpl.coeff(row, col);
1749 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index)
const {
1750 return m_argImpl.coeff(index);
1753 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col) {
1754 return m_argImpl.coeffRef(row, col);
1757 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE Scalar& coeffRef(Index index) {
return m_argImpl.coeffRef(index); }
1759 template <
int LoadMode,
typename PacketType>
1760 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packet(Index row, Index col)
const {
1761 return m_argImpl.template packet<LoadMode, PacketType>(row, col);
1764 template <
int LoadMode,
typename PacketType>
1765 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packet(Index index)
const {
1766 return m_argImpl.template packet<LoadMode, PacketType>(index);
1769 template <
int StoreMode,
typename PacketType>
1770 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void writePacket(Index row, Index col,
const PacketType& x) {
1771 m_argImpl.template writePacket<StoreMode>(row, col, x);
1774 template <
int StoreMode,
typename PacketType>
1775 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void writePacket(Index index,
const PacketType& x) {
1776 m_argImpl.template writePacket<StoreMode>(index, x);
1779 template <
int LoadMode,
typename PacketType>
1780 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packetSegment(Index row, Index col, Index begin, Index count)
const {
1781 return m_argImpl.template packetSegment<LoadMode, PacketType>(row, col, begin, count);
1784 template <
int LoadMode,
typename PacketType>
1785 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packetSegment(Index index, Index begin, Index count)
const {
1786 return m_argImpl.template packetSegment<LoadMode, PacketType>(index, begin, count);
1789 template <
int StoreMode,
typename PacketType>
1790 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void writePacketSegment(Index row, Index col,
const PacketType& x, Index begin,
1792 m_argImpl.template writePacketSegment<StoreMode>(row, col, x, begin, count);
1795 template <
int StoreMode,
typename PacketType>
1796 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void writePacketSegment(Index index,
const PacketType& x, Index begin,
1798 m_argImpl.template writePacketSegment<StoreMode>(index, x, begin, count);
1802 evaluator<ArgType> m_argImpl;
1805template <
typename TArgType>
1806struct unary_evaluator<MatrixWrapper<TArgType>> : evaluator_wrapper_base<MatrixWrapper<TArgType>> {
1807 using XprType = MatrixWrapper<TArgType>;
1809 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE
explicit unary_evaluator(
const XprType& wrapper)
1810 : evaluator_wrapper_base<MatrixWrapper<TArgType>>(wrapper.nestedExpression()) {}
1813template <
typename TArgType>
1814struct unary_evaluator<ArrayWrapper<TArgType>> : evaluator_wrapper_base<ArrayWrapper<TArgType>> {
1815 using XprType = ArrayWrapper<TArgType>;
1817 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE
explicit unary_evaluator(
const XprType& wrapper)
1818 : evaluator_wrapper_base<ArrayWrapper<TArgType>>(wrapper.nestedExpression()) {}
1824template <
typename PacketType,
bool ReversePacket>
1825struct reverse_packet_cond;
1827template <
typename ArgType,
int Direction>
1828struct unary_evaluator<Reverse<ArgType, Direction>> : evaluator_base<Reverse<ArgType, Direction>> {
1829 using XprType = Reverse<ArgType, Direction>;
1830 using Scalar =
typename XprType::Scalar;
1831 using CoeffReturnType =
typename XprType::CoeffReturnType;
1834 IsRowMajor = XprType::IsRowMajor,
1835 IsColMajor = !IsRowMajor,
1836 ReverseRow = (Direction ==
Vertical) || (Direction == BothDirections),
1837 ReverseCol = (Direction ==
Horizontal) || (Direction == BothDirections),
1838 ReversePacket = (Direction ==
BothDirections) || ((Direction == Vertical) && IsColMajor) ||
1841 CoeffReadCost = evaluator<ArgType>::CoeffReadCost,
1845 Flags0 = evaluator<ArgType>::Flags,
1847 ((Direction == BothDirections) && (
int(Flags0) & PacketAccessBit)) ||
1848 ((ReverseRow && XprType::ColsAtCompileTime == 1) || (ReverseCol && XprType::RowsAtCompileTime == 1))
1852 Flags = int(Flags0) & (HereditaryBits |
PacketAccessBit | LinearAccess),
1857 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE
explicit unary_evaluator(
const XprType& reverse)
1858 : m_argImpl(reverse.nestedExpression()),
1859 m_rows(ReverseRow ? reverse.nestedExpression().rows() : 1),
1860 m_cols(ReverseCol ? reverse.nestedExpression().cols() : 1) {}
1862 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col)
const {
1863 return m_argImpl.coeff(ReverseRow ? m_rows.value() - row - 1 : row, ReverseCol ? m_cols.value() - col - 1 : col);
1866 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index)
const {
1867 return m_argImpl.coeff(m_rows.value() * m_cols.value() - index - 1);
1870 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col) {
1871 return m_argImpl.coeffRef(ReverseRow ? m_rows.value() - row - 1 : row, ReverseCol ? m_cols.value() - col - 1 : col);
1874 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE Scalar& coeffRef(Index index) {
1875 return m_argImpl.coeffRef(m_rows.value() * m_cols.value() - index - 1);
1878 template <
int LoadMode,
typename PacketType>
1879 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packet(Index row, Index col)
const {
1880 static constexpr int PacketSize = unpacket_traits<PacketType>::size;
1881 static constexpr int OffsetRow = ReverseRow && IsColMajor ? PacketSize : 1;
1882 static constexpr int OffsetCol = ReverseCol && IsRowMajor ? PacketSize : 1;
1883 using reverse_packet = reverse_packet_cond<PacketType, ReversePacket>;
1885 Index actualRow = ReverseRow ? m_rows.value() - row - OffsetRow : row;
1886 Index actualCol = ReverseCol ? m_cols.value() - col - OffsetCol : col;
1888 return reverse_packet::run(m_argImpl.template packet<LoadMode, PacketType>(actualRow, actualCol));
1891 template <
int LoadMode,
typename PacketType>
1892 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packet(Index index)
const {
1893 static constexpr int PacketSize = unpacket_traits<PacketType>::size;
1895 Index actualIndex = m_rows.value() * m_cols.value() - index - PacketSize;
1897 return preverse(m_argImpl.template packet<LoadMode, PacketType>(actualIndex));
1900 template <
int LoadMode,
typename PacketType>
1901 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void writePacket(Index row, Index col,
const PacketType& x) {
1902 static constexpr int PacketSize = unpacket_traits<PacketType>::size;
1903 static constexpr int OffsetRow = ReverseRow && IsColMajor ? PacketSize : 1;
1904 static constexpr int OffsetCol = ReverseCol && IsRowMajor ? PacketSize : 1;
1905 using reverse_packet = reverse_packet_cond<PacketType, ReversePacket>;
1907 Index actualRow = ReverseRow ? m_rows.value() - row - OffsetRow : row;
1908 Index actualCol = ReverseCol ? m_cols.value() - col - OffsetCol : col;
1910 m_argImpl.template writePacket<LoadMode>(actualRow, actualCol, reverse_packet::run(x));
1913 template <
int LoadMode,
typename PacketType>
1914 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void writePacket(Index index,
const PacketType& x) {
1915 static constexpr int PacketSize = unpacket_traits<PacketType>::size;
1917 Index actualIndex = m_rows.value() * m_cols.value() - index - PacketSize;
1919 m_argImpl.template writePacket<LoadMode>(actualIndex, preverse(x));
1922 template <
int LoadMode,
typename PacketType>
1923 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packetSegment(Index row, Index col, Index begin, Index count)
const {
1924 static constexpr int PacketSize = unpacket_traits<PacketType>::size;
1925 static constexpr int OffsetRow = ReverseRow && IsColMajor ? PacketSize : 1;
1926 static constexpr int OffsetCol = ReverseCol && IsRowMajor ? PacketSize : 1;
1927 using reverse_packet = reverse_packet_cond<PacketType, ReversePacket>;
1929 Index actualRow = ReverseRow ? m_rows.value() - row - OffsetRow : row;
1930 Index actualCol = ReverseCol ? m_cols.value() - col - OffsetCol : col;
1931 Index actualBegin = ReversePacket ? (PacketSize - count - begin) : begin;
1933 return reverse_packet::run(
1934 m_argImpl.template packetSegment<LoadMode, PacketType>(actualRow, actualCol, actualBegin, count));
1937 template <
int LoadMode,
typename PacketType>
1938 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packetSegment(Index index, Index begin, Index count)
const {
1939 static constexpr int PacketSize = unpacket_traits<PacketType>::size;
1941 Index actualIndex = m_rows.value() * m_cols.value() - index - PacketSize;
1942 Index actualBegin = PacketSize - count - begin;
1944 return preverse(m_argImpl.template packetSegment<LoadMode, PacketType>(actualIndex, actualBegin, count));
1947 template <
int LoadMode,
typename PacketType>
1948 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void writePacketSegment(Index row, Index col,
const PacketType& x, Index begin,
1950 static constexpr int PacketSize = unpacket_traits<PacketType>::size;
1951 static constexpr int OffsetRow = ReverseRow && IsColMajor ? PacketSize : 1;
1952 static constexpr int OffsetCol = ReverseCol && IsRowMajor ? PacketSize : 1;
1953 using reverse_packet = reverse_packet_cond<PacketType, ReversePacket>;
1955 Index actualRow = ReverseRow ? m_rows.value() - row - OffsetRow : row;
1956 Index actualCol = ReverseCol ? m_cols.value() - col - OffsetCol : col;
1957 Index actualBegin = ReversePacket ? (PacketSize - count - begin) : begin;
1959 m_argImpl.template writePacketSegment<LoadMode>(actualRow, actualCol, reverse_packet::run(x), actualBegin, count);
1962 template <
int LoadMode,
typename PacketType>
1963 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void writePacketSegment(Index index,
const PacketType& x, Index begin,
1965 static constexpr int PacketSize = unpacket_traits<PacketType>::size;
1967 Index actualIndex = m_rows.value() * m_cols.value() - index - PacketSize;
1968 Index actualBegin = PacketSize - count - begin;
1970 m_argImpl.template writePacketSegment<LoadMode>(actualIndex, preverse(x), actualBegin, count);
1974 evaluator<ArgType> m_argImpl;
1978 const variable_if_dynamic<Index, ReverseRow ? ArgType::RowsAtCompileTime : 1> m_rows;
1979 const variable_if_dynamic<Index, ReverseCol ? ArgType::ColsAtCompileTime : 1> m_cols;
1984template <
typename ArgType,
int DiagIndex>
1985struct evaluator<Diagonal<ArgType, DiagIndex>> : evaluator_base<Diagonal<ArgType, DiagIndex>> {
1986 using XprType = Diagonal<ArgType, DiagIndex>;
1989 CoeffReadCost = evaluator<ArgType>::CoeffReadCost,
1991 Flags =
static_cast<unsigned int>(evaluator<ArgType>::Flags & (HereditaryBits |
DirectAccessBit) & ~RowMajorBit) |
1997 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE
explicit evaluator(
const XprType& diagonal)
1998 : m_argImpl(diagonal.nestedExpression()), m_index(diagonal.index()) {}
2000 using Scalar =
typename XprType::Scalar;
2001 using CoeffReturnType =
typename XprType::CoeffReturnType;
2003 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index)
const {
2004 return m_argImpl.coeff(row + rowOffset(), row + colOffset());
2007 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index)
const {
2008 return m_argImpl.coeff(index + rowOffset(), index + colOffset());
2011 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index) {
2012 return m_argImpl.coeffRef(row + rowOffset(), row + colOffset());
2015 EIGEN_DEVICE_FUNC
constexpr EIGEN_STRONG_INLINE Scalar& coeffRef(Index index) {
2016 return m_argImpl.coeffRef(index + rowOffset(), index + colOffset());
2020 evaluator<ArgType> m_argImpl;
2021 const variable_if_dynamicindex<Index, XprType::DiagIndex> m_index;
2024 EIGEN_DEVICE_FUNC
constexpr Index rowOffset()
const {
return m_index.value() > 0 ? 0 : -m_index.value(); }
2025 EIGEN_DEVICE_FUNC
constexpr Index colOffset()
const {
return m_index.value() > 0 ? m_index.value() : 0; }
2036template <
typename ArgType>
2039template <
typename ArgType>
2040struct traits<EvalToTemp<ArgType>> :
public traits<ArgType> {};
2042template <
typename ArgType>
2043class EvalToTemp :
public dense_xpr_base<EvalToTemp<ArgType>>::type {
2045 using Base =
typename dense_xpr_base<EvalToTemp>::type;
2046 EIGEN_GENERIC_PUBLIC_INTERFACE(EvalToTemp)
2048 explicit EvalToTemp(
const ArgType& arg) : m_arg(arg) {}
2050 const ArgType& arg()
const {
return m_arg; }
2052 constexpr Index rows() const noexcept {
return m_arg.rows(); }
2054 constexpr Index cols() const noexcept {
return m_arg.cols(); }
2057 const ArgType& m_arg;
2060template <
typename ArgType>
2061struct evaluator<EvalToTemp<ArgType>> :
public evaluator<typename ArgType::PlainObject> {
2062 using XprType = EvalToTemp<ArgType>;
2063 using PlainObject =
typename ArgType::PlainObject;
2064 using Base = evaluator<PlainObject>;
2066 EIGEN_DEVICE_FUNC
constexpr explicit evaluator(
const XprType& xpr) : m_result(xpr.arg()) {
2067 internal::construct_at<Base>(
this, m_result);
2071 EIGEN_DEVICE_FUNC
constexpr evaluator(
const ArgType& arg) : m_result(arg) {
2072 internal::construct_at<Base>(
this, m_result);
2076 PlainObject m_result;
@ BothDirections
Definition Constants.h:273
@ Horizontal
Definition Constants.h:270
@ Vertical
Definition Constants.h:267
constexpr unsigned int ActualPacketAccessBit
Definition Constants.h:109
constexpr unsigned int PacketAccessBit
Definition Constants.h:98
constexpr unsigned int DirectAccessBit
Definition Constants.h:160
constexpr unsigned int EvalBeforeNestingBit
Definition Constants.h:75
constexpr unsigned int LinearAccessBit
Definition Constants.h:134
constexpr unsigned int RowMajorBit
Definition Constants.h:71