From 78bb80833708615c330659d9b64870b19185df37 Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Fri, 20 Jun 2014 15:39:38 +0200 Subject: [PATCH] 1- Introduce sub-evaluator types for unary, binary, product, and map expressions to ease specializing them. 2- Remove a lot of code which should not be there with evaluators, in particular coeff/packet methods implemented in the expressions. --- Eigen/src/Core/ArrayBase.h | 4 + Eigen/src/Core/ArrayWrapper.h | 2 + Eigen/src/Core/Block.h | 13 +- Eigen/src/Core/CoreEvaluators.h | 247 ++++++++++-------- Eigen/src/Core/CwiseBinaryOp.h | 30 ++- Eigen/src/Core/CwiseUnaryOp.h | 14 +- Eigen/src/Core/CwiseUnaryView.h | 9 +- Eigen/src/Core/DenseBase.h | 5 +- Eigen/src/Core/DenseCoeffsBase.h | 45 +++- Eigen/src/Core/Inverse.h | 9 +- Eigen/src/Core/Replicate.h | 1 + Eigen/src/Core/ReturnByValue.h | 28 ++ Eigen/src/Core/Reverse.h | 1 + Eigen/src/Core/Transpose.h | 30 ++- Eigen/src/Core/TriangularMatrix.h | 4 +- Eigen/src/Core/products/GeneralMatrixMatrix.h | 4 +- Eigen/src/Core/util/ForwardDeclarations.h | 4 +- Eigen/src/Core/util/XprHelper.h | 9 + 18 files changed, 300 insertions(+), 159 deletions(-) diff --git a/Eigen/src/Core/ArrayBase.h b/Eigen/src/Core/ArrayBase.h index d1c422836..f5bae6357 100644 --- a/Eigen/src/Core/ArrayBase.h +++ b/Eigen/src/Core/ArrayBase.h @@ -123,7 +123,11 @@ template class ArrayBase EIGEN_DEVICE_FUNC Derived& operator=(const ArrayBase& other) { +#ifndef EIGEN_TEST_EVALUATORS return internal::assign_selector::run(derived(), other.derived()); +#else + internal::call_assignment(derived(), other.derived()); +#endif } EIGEN_DEVICE_FUNC diff --git a/Eigen/src/Core/ArrayWrapper.h b/Eigen/src/Core/ArrayWrapper.h index 4bb648024..599d87f64 100644 --- a/Eigen/src/Core/ArrayWrapper.h +++ b/Eigen/src/Core/ArrayWrapper.h @@ -39,6 +39,7 @@ class ArrayWrapper : public ArrayBase > typedef ArrayBase Base; EIGEN_DENSE_PUBLIC_INTERFACE(ArrayWrapper) EIGEN_INHERIT_ASSIGNMENT_OPERATORS(ArrayWrapper) + typedef typename internal::remove_all::type NestedExpression; typedef typename internal::conditional< internal::is_lvalue::value, @@ -176,6 +177,7 @@ class MatrixWrapper : public MatrixBase > typedef MatrixBase > Base; EIGEN_DENSE_PUBLIC_INTERFACE(MatrixWrapper) EIGEN_INHERIT_ASSIGNMENT_OPERATORS(MatrixWrapper) + typedef typename internal::remove_all::type NestedExpression; typedef typename internal::conditional< internal::is_lvalue::value, diff --git a/Eigen/src/Core/Block.h b/Eigen/src/Core/Block.h index e0b24e199..ef6c143d3 100644 --- a/Eigen/src/Core/Block.h +++ b/Eigen/src/Core/Block.h @@ -344,6 +344,9 @@ class BlockImpl_dense : public MapBase > { typedef Block BlockType; + enum { + XprTypeIsRowMajor = (int(traits::Flags)&RowMajorBit) != 0 + }; public: typedef MapBase Base; @@ -354,9 +357,8 @@ class BlockImpl_dense */ EIGEN_DEVICE_FUNC inline BlockImpl_dense(XprType& xpr, Index i) - : Base(internal::const_cast_ptr(&xpr.coeffRef( - (BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0, - (BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0)), + : Base(xpr.data() + i * ( ((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && (!XprTypeIsRowMajor)) + || ((BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) && ( XprTypeIsRowMajor)) ? xpr.innerStride() : xpr.outerStride()), BlockRows==1 ? 1 : xpr.rows(), BlockCols==1 ? 1 : xpr.cols()), m_xpr(xpr) @@ -368,7 +370,8 @@ class BlockImpl_dense */ EIGEN_DEVICE_FUNC inline BlockImpl_dense(XprType& xpr, Index startRow, Index startCol) - : Base(internal::const_cast_ptr(&xpr.coeffRef(startRow,startCol))), m_xpr(xpr) + : Base(xpr.data()+xpr.innerStride()*(XprTypeIsRowMajor?startCol:startRow) + xpr.outerStride()*(XprTypeIsRowMajor?startRow:startCol)), + m_xpr(xpr) { init(); } @@ -379,7 +382,7 @@ class BlockImpl_dense inline BlockImpl_dense(XprType& xpr, Index startRow, Index startCol, Index blockRows, Index blockCols) - : Base(internal::const_cast_ptr(&xpr.coeffRef(startRow,startCol)), blockRows, blockCols), + : Base(xpr.data()+xpr.innerStride()*(XprTypeIsRowMajor?startCol:startRow) + xpr.outerStride()*(XprTypeIsRowMajor?startRow:startCol), blockRows, blockCols), m_xpr(xpr) { init(); diff --git a/Eigen/src/Core/CoreEvaluators.h b/Eigen/src/Core/CoreEvaluators.h index 47f50d548..f872b41e1 100644 --- a/Eigen/src/Core/CoreEvaluators.h +++ b/Eigen/src/Core/CoreEvaluators.h @@ -27,14 +27,6 @@ struct storage_kind_to_evaluator_kind { typedef IndexBased Kind; }; -// TODO to be moved to SparseCore: -/* -template<> -struct storage_kind_to_evaluator_kind { - typedef IteratorBased Kind -}; -*/ - // This class returns the evaluator shape from the expression storage kind. // It can be Dense, Sparse, Triangular, Diagonal, SelfAdjoint, Band, etc. template struct storage_kind_to_shape; @@ -45,22 +37,28 @@ struct storage_kind_to_shape { typedef DenseShape Shape; }; -// TODO to be moved to SparseCore: -/* -template<> -struct storage_kind_to_shape { - typedef SparseSpape Shape; -}; -*/ +// Evaluators have to be specialized with respect to various criteria such as: +// - storage/structure/shape +// - scalar type +// - etc. +// Therefore, we need specialization of evaluator providing additional template arguments for each kind of evaluators. +// We currently distinguish the following kind of evaluators: +// - unary_evaluator for expressions taking only one arguments (CwiseUnaryOp, CwiseUnaryView, Transpose, MatrixWrapper, ArrayWrapper, Reverse, Replicate) +// - binary_evaluator for expression taking two arguments (CwiseBinaryOp) +// - product_evaluator for linear algebra products (Product); special case of binary_evaluator because it requires additional tags for dispatching. +// - mapbase_evaluator for Map, Block, Ref +// - block_evaluator for Block (special dispatching to a mapbase_evaluator or unary_evaluator) - - template< typename T, - typename LhsKind = typename evaluator_traits::Kind, - typename RhsKind = typename evaluator_traits::Kind, + typename LhsKind = typename evaluator_traits::Kind, + typename RhsKind = typename evaluator_traits::Kind, typename LhsScalar = typename T::Lhs::Scalar, typename RhsScalar = typename T::Rhs::Scalar> struct binary_evaluator; +template< typename T, + typename Kind = typename evaluator_traits::Kind, + typename Scalar = typename T::Scalar> struct unary_evaluator; + // evaluator_traits contains traits for evaluator template @@ -80,15 +78,20 @@ struct evaluator_traits_base static const int AssumeAliasing = 0; }; +// Default evaluator traits template struct evaluator_traits : public evaluator_traits_base { }; -// expression class for evaluating nested expression to a temporary - -template -class EvalToTemp; + +// By default, we assume a unary expression: +template +struct evaluator : public unary_evaluator +{ + typedef unary_evaluator Base; + evaluator(const T& xpr) : Base(xpr) {} +}; // TODO: Think about const-correctness @@ -118,6 +121,8 @@ struct evaluator_base // // evaluator is a common base class for the // Matrix and Array evaluators. +// Here we directly specialize evaluator. This is not really a unary expression, and it is, by definition, dense, +// so no need for more sophisticated dispatching. template struct evaluator > @@ -245,81 +250,10 @@ struct evaluator > { } }; -// -------------------- EvalToTemp -------------------- - -template -struct traits > - : public traits -{ }; - -template -class EvalToTemp - : public dense_xpr_base >::type -{ - public: - - typedef typename dense_xpr_base::type Base; - EIGEN_GENERIC_PUBLIC_INTERFACE(EvalToTemp) - - EvalToTemp(const ArgType& arg) - : m_arg(arg) - { } - - const ArgType& arg() const - { - return m_arg; - } - - Index rows() const - { - return m_arg.rows(); - } - - Index cols() const - { - return m_arg.cols(); - } - - private: - const ArgType& m_arg; -}; - -template -struct evaluator > - : public evaluator::type -{ - typedef EvalToTemp XprType; - typedef typename ArgType::PlainObject PlainObject; - typedef typename evaluator::type Base; - - typedef evaluator type; - typedef evaluator nestedType; - - evaluator(const XprType& xpr) - : m_result(xpr.rows(), xpr.cols()) - { - ::new (static_cast(this)) Base(m_result); - // TODO we should simply do m_result(xpr.arg()); - call_dense_assignment_loop(m_result, xpr.arg()); - } - - // This constructor is used when nesting an EvalTo evaluator in another evaluator - evaluator(const ArgType& arg) - : m_result(arg.rows(), arg.cols()) - { - ::new (static_cast(this)) Base(m_result); - // TODO we should simply do m_result(xpr.arg()); - call_dense_assignment_loop(m_result, arg); - } - -protected: - PlainObject m_result; -}; - // -------------------- Transpose -------------------- template -struct evaluator > +struct unary_evaluator > : evaluator_base > { typedef Transpose XprType; @@ -329,7 +263,7 @@ struct evaluator > Flags = evaluator::Flags ^ RowMajorBit }; - evaluator(const XprType& t) : m_argImpl(t.nestedExpression()) {} + unary_evaluator(const XprType& t) : m_argImpl(t.nestedExpression()) {} typedef typename XprType::Index Index; typedef typename XprType::Scalar Scalar; @@ -386,6 +320,8 @@ protected: }; // -------------------- CwiseNullaryOp -------------------- +// Like Matrix and Array, this is not really a unary expression, so we directly specialize evaluator. +// Likewise, there is not need to more sophisticated dispatching here. template struct evaluator > @@ -441,7 +377,7 @@ protected: // -------------------- CwiseUnaryOp -------------------- template -struct evaluator > +struct unary_evaluator, IndexBased > : evaluator_base > { typedef CwiseUnaryOp XprType; @@ -454,7 +390,7 @@ struct evaluator > | (functor_traits::PacketAccess ? PacketAccessBit : 0)) }; - evaluator(const XprType& op) + unary_evaluator(const XprType& op) : m_functor(op.functor()), m_argImpl(op.nestedExpression()) { } @@ -492,8 +428,19 @@ protected: // -------------------- CwiseBinaryOp -------------------- +// this is a binary expression template struct evaluator > + : public binary_evaluator > +{ + typedef CwiseBinaryOp XprType; + typedef binary_evaluator > Base; + + evaluator(const XprType& xpr) : Base(xpr) {} +}; + +template +struct binary_evaluator > : evaluator_base > { typedef CwiseBinaryOp XprType; @@ -517,7 +464,7 @@ struct evaluator > Flags = (Flags0 & ~RowMajorBit) | (LhsFlags & RowMajorBit) }; - evaluator(const XprType& xpr) + binary_evaluator(const XprType& xpr) : m_functor(xpr.functor()), m_lhsImpl(xpr.lhs()), m_rhsImpl(xpr.rhs()) @@ -560,7 +507,7 @@ protected: // -------------------- CwiseUnaryView -------------------- template -struct evaluator > +struct unary_evaluator > : evaluator_base > { typedef CwiseUnaryView XprType; @@ -571,7 +518,7 @@ struct evaluator > Flags = (evaluator::Flags & (HereditaryBits | LinearAccessBit | DirectAccessBit)) }; - evaluator(const XprType& op) + unary_evaluator(const XprType& op) : m_unaryOp(op.functor()), m_argImpl(op.nestedExpression()) { } @@ -884,6 +831,7 @@ struct block_evaluator @@ -934,7 +882,7 @@ protected: // -------------------- Replicate -------------------- template -struct evaluator > +struct unary_evaluator > : evaluator_base > { typedef Replicate XprType; @@ -953,7 +901,7 @@ struct evaluator > Flags = (evaluator::Flags & HereditaryBits & ~RowMajorBit) | (traits::Flags & RowMajorBit) }; - evaluator(const XprType& replicate) + unary_evaluator(const XprType& replicate) : m_arg(replicate.nestedExpression()), m_argImpl(m_arg), m_rows(replicate.nestedExpression().rows()), @@ -1111,23 +1059,23 @@ protected: }; template -struct evaluator > +struct unary_evaluator > : evaluator_wrapper_base > { typedef MatrixWrapper XprType; - evaluator(const XprType& wrapper) + unary_evaluator(const XprType& wrapper) : evaluator_wrapper_base >(wrapper.nestedExpression()) { } }; template -struct evaluator > +struct unary_evaluator > : evaluator_wrapper_base > { typedef ArrayWrapper XprType; - evaluator(const XprType& wrapper) + unary_evaluator(const XprType& wrapper) : evaluator_wrapper_base >(wrapper.nestedExpression()) { } }; @@ -1139,7 +1087,7 @@ struct evaluator > template struct reverse_packet_cond; template -struct evaluator > +struct unary_evaluator > : evaluator_base > { typedef Reverse XprType; @@ -1173,7 +1121,7 @@ struct evaluator > }; typedef internal::reverse_packet_cond reverse_packet; - evaluator(const XprType& reverse) + unary_evaluator(const XprType& reverse) : m_argImpl(reverse.nestedExpression()), m_rows(ReverseRow ? reverse.nestedExpression().rows() : 0), m_cols(ReverseCol ? reverse.nestedExpression().cols() : 0) @@ -1292,6 +1240,87 @@ private: EIGEN_STRONG_INLINE Index colOffset() const { return m_index.value() > 0 ? m_index.value() : 0; } }; + + +//---------------------------------------------------------------------- +// deprecated code +//---------------------------------------------------------------------- + +// -------------------- EvalToTemp -------------------- + +// expression class for evaluating nested expression to a temporary + +template class EvalToTemp; + +template +struct traits > + : public traits +{ }; + +template +class EvalToTemp + : public dense_xpr_base >::type +{ + public: + + typedef typename dense_xpr_base::type Base; + EIGEN_GENERIC_PUBLIC_INTERFACE(EvalToTemp) + + EvalToTemp(const ArgType& arg) + : m_arg(arg) + { } + + const ArgType& arg() const + { + return m_arg; + } + + Index rows() const + { + return m_arg.rows(); + } + + Index cols() const + { + return m_arg.cols(); + } + + private: + const ArgType& m_arg; +}; + +template +struct evaluator > + : public evaluator::type +{ + typedef EvalToTemp XprType; + typedef typename ArgType::PlainObject PlainObject; + typedef typename evaluator::type Base; + + typedef evaluator type; + typedef evaluator nestedType; + + evaluator(const XprType& xpr) + : m_result(xpr.rows(), xpr.cols()) + { + ::new (static_cast(this)) Base(m_result); + // TODO we should simply do m_result(xpr.arg()); + call_dense_assignment_loop(m_result, xpr.arg()); + } + + // This constructor is used when nesting an EvalTo evaluator in another evaluator + evaluator(const ArgType& arg) + : m_result(arg.rows(), arg.cols()) + { + ::new (static_cast(this)) Base(m_result); + // TODO we should simply do m_result(xpr.arg()); + call_dense_assignment_loop(m_result, arg); + } + +protected: + PlainObject m_result; +}; + } // namespace internal } // end namespace Eigen diff --git a/Eigen/src/Core/CwiseBinaryOp.h b/Eigen/src/Core/CwiseBinaryOp.h index 07861dbc9..5e4fb147b 100644 --- a/Eigen/src/Core/CwiseBinaryOp.h +++ b/Eigen/src/Core/CwiseBinaryOp.h @@ -94,23 +94,26 @@ struct traits > template class CwiseBinaryOpImpl; -template +template class CwiseBinaryOp : internal::no_assignment_operator, public CwiseBinaryOpImpl< - BinaryOp, Lhs, Rhs, - typename internal::promote_storage_type::StorageKind, - typename internal::traits::StorageKind>::ret> + BinaryOp, LhsType, RhsType, + typename internal::promote_storage_type::StorageKind, + typename internal::traits::StorageKind>::ret> { public: + + typedef typename internal::remove_all::type Lhs; + typedef typename internal::remove_all::type Rhs; typedef typename CwiseBinaryOpImpl< - BinaryOp, Lhs, Rhs, - typename internal::promote_storage_type::StorageKind, + BinaryOp, LhsType, RhsType, + typename internal::promote_storage_type::StorageKind, typename internal::traits::StorageKind>::ret>::Base Base; EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseBinaryOp) - typedef typename internal::nested::type LhsNested; - typedef typename internal::nested::type RhsNested; + typedef typename internal::nested::type LhsNested; + typedef typename internal::nested::type RhsNested; typedef typename internal::remove_reference::type _LhsNested; typedef typename internal::remove_reference::type _RhsNested; @@ -157,6 +160,7 @@ class CwiseBinaryOp : internal::no_assignment_operator, const BinaryOp m_functor; }; +#ifndef EIGEN_TEST_EVALUATORS template class CwiseBinaryOpImpl : public internal::dense_xpr_base >::type @@ -195,6 +199,16 @@ class CwiseBinaryOpImpl derived().rhs().template packet(index)); } }; +#else +// Generic API dispatcher +template +class CwiseBinaryOpImpl + : public internal::generic_xpr_base >::type +{ +public: + typedef typename internal::generic_xpr_base >::type Base; +}; +#endif /** replaces \c *this by \c *this - \a other. * diff --git a/Eigen/src/Core/CwiseUnaryOp.h b/Eigen/src/Core/CwiseUnaryOp.h index af05a9108..098034a1e 100644 --- a/Eigen/src/Core/CwiseUnaryOp.h +++ b/Eigen/src/Core/CwiseUnaryOp.h @@ -67,6 +67,7 @@ class CwiseUnaryOp : internal::no_assignment_operator, typedef typename CwiseUnaryOpImpl::StorageKind>::Base Base; EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseUnaryOp) + typedef typename internal::remove_all::type NestedExpression; EIGEN_DEVICE_FUNC inline CwiseUnaryOp(const XprType& xpr, const UnaryOp& func = UnaryOp()) @@ -96,6 +97,7 @@ class CwiseUnaryOp : internal::no_assignment_operator, const UnaryOp m_functor; }; +#ifndef EIGEN_TEST_EVALUATORS // This is the generic implementation for dense storage. // It can be used for any expression types implementing the dense concept. template @@ -107,7 +109,7 @@ class CwiseUnaryOpImpl typedef CwiseUnaryOp Derived; typedef typename internal::dense_xpr_base >::type Base; EIGEN_DENSE_PUBLIC_INTERFACE(Derived) - + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar coeff(Index rowId, Index colId) const { @@ -133,6 +135,16 @@ class CwiseUnaryOpImpl return derived().functor().packetOp(derived().nestedExpression().template packet(index)); } }; +#else +// Generic API dispatcher +template +class CwiseUnaryOpImpl + : public internal::generic_xpr_base >::type +{ +public: + typedef typename internal::generic_xpr_base >::type Base; +}; +#endif } // end namespace Eigen diff --git a/Eigen/src/Core/CwiseUnaryView.h b/Eigen/src/Core/CwiseUnaryView.h index 9cdebb8e7..92b031e19 100644 --- a/Eigen/src/Core/CwiseUnaryView.h +++ b/Eigen/src/Core/CwiseUnaryView.h @@ -66,6 +66,7 @@ class CwiseUnaryView : public CwiseUnaryViewImpl::StorageKind>::Base Base; EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseUnaryView) + typedef typename internal::remove_all::type NestedExpression; inline CwiseUnaryView(const MatrixType& mat, const ViewOp& func = ViewOp()) : m_matrix(mat), m_functor(func) {} @@ -104,8 +105,8 @@ class CwiseUnaryViewImpl EIGEN_DENSE_PUBLIC_INTERFACE(Derived) EIGEN_INHERIT_ASSIGNMENT_OPERATORS(CwiseUnaryViewImpl) - inline Scalar* data() { return &coeffRef(0); } - inline const Scalar* data() const { return &coeff(0); } + inline Scalar* data() { return &(this->coeffRef(0)); } + inline const Scalar* data() const { return &(this->coeff(0)); } inline Index innerStride() const { @@ -116,6 +117,8 @@ class CwiseUnaryViewImpl { return derived().nestedExpression().outerStride() * sizeof(typename internal::traits::Scalar) / sizeof(Scalar); } + +#ifndef EIGEN_TEST_EVALUATORS EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col) const { @@ -136,6 +139,8 @@ class CwiseUnaryViewImpl { return derived().functor()(const_cast_derived().nestedExpression().coeffRef(index)); } + +#endif }; } // end namespace Eigen diff --git a/Eigen/src/Core/DenseBase.h b/Eigen/src/Core/DenseBase.h index f3c79aa31..624276240 100644 --- a/Eigen/src/Core/DenseBase.h +++ b/Eigen/src/Core/DenseBase.h @@ -74,6 +74,7 @@ template class DenseBase using Base::colIndexByOuterInner; using Base::coeff; using Base::coeffByOuterInner; +#ifndef EIGEN_TEST_EVALUATORS using Base::packet; using Base::packetByOuterInner; using Base::writePacket; @@ -84,6 +85,7 @@ template class DenseBase using Base::copyCoeffByOuterInner; using Base::copyPacket; using Base::copyPacketByOuterInner; +#endif using Base::operator(); using Base::operator[]; using Base::x; @@ -280,7 +282,8 @@ template class DenseBase Derived& operator=(const ReturnByValue& func); #ifndef EIGEN_PARSED_BY_DOXYGEN - /** Copies \a other into *this without evaluating other. \returns a reference to *this. */ + /** Copies \a other into *this without evaluating other. \returns a reference to *this. + * \deprecated */ template EIGEN_DEVICE_FUNC Derived& lazyAssign(const DenseBase& other); diff --git a/Eigen/src/Core/DenseCoeffsBase.h b/Eigen/src/Core/DenseCoeffsBase.h index efabb5e67..6f35a67ca 100644 --- a/Eigen/src/Core/DenseCoeffsBase.h +++ b/Eigen/src/Core/DenseCoeffsBase.h @@ -97,8 +97,12 @@ class DenseCoeffsBase : public EigenBase EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col) const { eigen_internal_assert(row >= 0 && row < rows() - && col >= 0 && col < cols()); + && col >= 0 && col < cols()); +#ifndef EIGEN_TEST_EVALUATORS return derived().coeff(row, col); +#else + return typename internal::evaluator::type(derived()).coeff(row,col); +#endif } EIGEN_DEVICE_FUNC @@ -117,7 +121,7 @@ class DenseCoeffsBase : public EigenBase { eigen_assert(row >= 0 && row < rows() && col >= 0 && col < cols()); - return derived().coeff(row, col); + return coeff(row, col); } /** Short version: don't use this function, use @@ -140,7 +144,11 @@ class DenseCoeffsBase : public EigenBase coeff(Index index) const { eigen_internal_assert(index >= 0 && index < size()); +#ifndef EIGEN_TEST_EVALUATORS return derived().coeff(index); +#else + return typename internal::evaluator::type(derived()).coeff(index); +#endif } @@ -161,7 +169,7 @@ class DenseCoeffsBase : public EigenBase THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD) #endif eigen_assert(index >= 0 && index < size()); - return derived().coeff(index); + return coeff(index); } /** \returns the coefficient at given index. @@ -179,7 +187,7 @@ class DenseCoeffsBase : public EigenBase operator()(Index index) const { eigen_assert(index >= 0 && index < size()); - return derived().coeff(index); + return coeff(index); } /** equivalent to operator[](0). */ @@ -219,9 +227,12 @@ class DenseCoeffsBase : public EigenBase template EIGEN_STRONG_INLINE PacketReturnType packet(Index row, Index col) const { - eigen_internal_assert(row >= 0 && row < rows() - && col >= 0 && col < cols()); + eigen_internal_assert(row >= 0 && row < rows() && col >= 0 && col < cols()); +#ifndef EIGEN_TEST_EVALUATORS return derived().template packet(row,col); +#else + return typename internal::evaluator::type(derived()).template packet(row,col); +#endif } @@ -247,7 +258,11 @@ class DenseCoeffsBase : public EigenBase EIGEN_STRONG_INLINE PacketReturnType packet(Index index) const { eigen_internal_assert(index >= 0 && index < size()); +#ifndef EIGEN_TEST_EVALUATORS return derived().template packet(index); +#else + return typename internal::evaluator::type(derived()).template packet(index); +#endif } protected: @@ -327,8 +342,12 @@ class DenseCoeffsBase : public DenseCoeffsBase= 0 && row < rows() - && col >= 0 && col < cols()); + && col >= 0 && col < cols()); +#ifndef EIGEN_TEST_EVALUATORS return derived().coeffRef(row, col); +#else + return typename internal::evaluator::type(derived()).coeffRef(row,col); +#endif } EIGEN_DEVICE_FUNC @@ -350,7 +369,7 @@ class DenseCoeffsBase : public DenseCoeffsBase= 0 && row < rows() && col >= 0 && col < cols()); - return derived().coeffRef(row, col); + return coeffRef(row, col); } @@ -374,7 +393,11 @@ class DenseCoeffsBase : public DenseCoeffsBase= 0 && index < size()); +#ifndef EIGEN_TEST_EVALUATORS return derived().coeffRef(index); +#else + return typename internal::evaluator::type(derived()).coeffRef(index); +#endif } /** \returns a reference to the coefficient at given index. @@ -393,7 +416,7 @@ class DenseCoeffsBase : public DenseCoeffsBase= 0 && index < size()); - return derived().coeffRef(index); + return coeffRef(index); } /** \returns a reference to the coefficient at given index. @@ -410,7 +433,7 @@ class DenseCoeffsBase : public DenseCoeffsBase= 0 && index < size()); - return derived().coeffRef(index); + return coeffRef(index); } /** equivalent to operator[](0). */ @@ -437,6 +460,7 @@ class DenseCoeffsBase : public DenseCoeffsBase : public DenseCoeffsBase(row, col, other); } #endif +#endif // EIGEN_TEST_EVALUATORS }; diff --git a/Eigen/src/Core/Inverse.h b/Eigen/src/Core/Inverse.h index 57eaf99f1..788d0664d 100644 --- a/Eigen/src/Core/Inverse.h +++ b/Eigen/src/Core/Inverse.h @@ -81,6 +81,7 @@ public: typedef MatrixBase Base; EIGEN_DENSE_PUBLIC_INTERFACE(Derived) + typedef typename internal::remove_all::type NestedExpression; private: @@ -101,19 +102,19 @@ namespace internal { * \sa class Inverse */ template -struct evaluator > +struct unary_evaluator > : public evaluator::PlainObject>::type { typedef Inverse InverseType; typedef typename InverseType::PlainObject PlainObject; typedef typename evaluator::type Base; - typedef evaluator type; - typedef evaluator nestedType; + typedef evaluator type; + typedef evaluator nestedType; enum { Flags = Base::Flags | EvalBeforeNestingBit }; - evaluator(const InverseType& inv_xpr) + unary_evaluator(const InverseType& inv_xpr) : m_result(inv_xpr.rows(), inv_xpr.cols()) { ::new (static_cast(this)) Base(m_result); diff --git a/Eigen/src/Core/Replicate.h b/Eigen/src/Core/Replicate.h index 2dff03ea3..e63f0d421 100644 --- a/Eigen/src/Core/Replicate.h +++ b/Eigen/src/Core/Replicate.h @@ -74,6 +74,7 @@ template class Replicate typedef typename internal::dense_xpr_base::type Base; EIGEN_DENSE_PUBLIC_INTERFACE(Replicate) + typedef typename internal::remove_all::type NestedExpression; template inline explicit Replicate(const OriginalMatrixType& a_matrix) diff --git a/Eigen/src/Core/ReturnByValue.h b/Eigen/src/Core/ReturnByValue.h index d63b96138..30ade1b75 100644 --- a/Eigen/src/Core/ReturnByValue.h +++ b/Eigen/src/Core/ReturnByValue.h @@ -92,6 +92,34 @@ Derived& DenseBase::operator=(const ReturnByValue& other) return derived(); } +#ifdef EIGEN_TEST_EVALUATORS +namespace internal { + +template +struct evaluator > + : public evaluator::ReturnType>::type +{ + typedef ReturnByValue XprType; + typedef typename internal::traits::ReturnType PlainObject; + typedef typename evaluator::type Base; + + typedef evaluator type; + typedef evaluator nestedType; + + evaluator(const XprType& xpr) + : m_result(xpr.rows(), xpr.cols()) + { + ::new (static_cast(this)) Base(m_result); + xpr.evalTo(m_result); + } + +protected: + PlainObject m_result; +}; + +} // end namespace internal +#endif + } // end namespace Eigen #endif // EIGEN_RETURNBYVALUE_H diff --git a/Eigen/src/Core/Reverse.h b/Eigen/src/Core/Reverse.h index 4969bb4fc..ceb6e4701 100644 --- a/Eigen/src/Core/Reverse.h +++ b/Eigen/src/Core/Reverse.h @@ -77,6 +77,7 @@ template class Reverse typedef typename internal::dense_xpr_base::type Base; EIGEN_DENSE_PUBLIC_INTERFACE(Reverse) + typedef typename internal::remove_all::type NestedExpression; using Base::IsRowMajor; // next line is necessary because otherwise const version of operator() diff --git a/Eigen/src/Core/Transpose.h b/Eigen/src/Core/Transpose.h index 079f21fd9..4b605dfd6 100644 --- a/Eigen/src/Core/Transpose.h +++ b/Eigen/src/Core/Transpose.h @@ -68,6 +68,7 @@ template class Transpose typedef typename TransposeImpl::StorageKind>::Base Base; EIGEN_GENERIC_PUBLIC_INTERFACE(Transpose) + typedef typename internal::remove_all::type NestedExpression; EIGEN_DEVICE_FUNC inline Transpose(MatrixType& a_matrix) : m_matrix(a_matrix) {} @@ -113,6 +114,7 @@ template class TransposeImpl public: typedef typename internal::TransposeImpl_base::type Base; + using Base::coeffRef; EIGEN_DENSE_PUBLIC_INTERFACE(Transpose) EIGEN_INHERIT_ASSIGNMENT_OPERATORS(TransposeImpl) @@ -127,6 +129,8 @@ template class TransposeImpl inline ScalarWithConstIfNotLvalue* data() { return derived().nestedExpression().data(); } inline const Scalar* data() const { return derived().nestedExpression().data(); } + +#ifndef EIGEN_TEST_EVALUATORS EIGEN_DEVICE_FUNC inline ScalarWithConstIfNotLvalue& coeffRef(Index rowId, Index colId) @@ -142,18 +146,6 @@ template class TransposeImpl return derived().nestedExpression().const_cast_derived().coeffRef(index); } - EIGEN_DEVICE_FUNC - inline const Scalar& coeffRef(Index rowId, Index colId) const - { - return derived().nestedExpression().coeffRef(colId, rowId); - } - - EIGEN_DEVICE_FUNC - inline const Scalar& coeffRef(Index index) const - { - return derived().nestedExpression().coeffRef(index); - } - EIGEN_DEVICE_FUNC inline CoeffReturnType coeff(Index rowId, Index colId) const { @@ -189,6 +181,20 @@ template class TransposeImpl { derived().nestedExpression().const_cast_derived().template writePacket(index, x); } +#endif + + // FIXME: shall we keep the const version of coeffRef? + EIGEN_DEVICE_FUNC + inline const Scalar& coeffRef(Index rowId, Index colId) const + { + return derived().nestedExpression().coeffRef(colId, rowId); + } + + EIGEN_DEVICE_FUNC + inline const Scalar& coeffRef(Index index) const + { + return derived().nestedExpression().coeffRef(index); + } }; /** \returns an expression of the transpose of *this. diff --git a/Eigen/src/Core/TriangularMatrix.h b/Eigen/src/Core/TriangularMatrix.h index 064e0e10d..180efdd62 100644 --- a/Eigen/src/Core/TriangularMatrix.h +++ b/Eigen/src/Core/TriangularMatrix.h @@ -1071,8 +1071,8 @@ struct evaluator_traits > static const int AssumeAliasing = 0; }; -template -struct evaluator, Kind, typename MatrixType::Scalar> +template +struct evaluator > : evaluator::type> { typedef TriangularView XprType; diff --git a/Eigen/src/Core/products/GeneralMatrixMatrix.h b/Eigen/src/Core/products/GeneralMatrixMatrix.h index 1726f98ed..b0a09216d 100644 --- a/Eigen/src/Core/products/GeneralMatrixMatrix.h +++ b/Eigen/src/Core/products/GeneralMatrixMatrix.h @@ -219,8 +219,8 @@ struct gemm_functor cols = m_rhs.cols(); Gemm::run(rows, cols, m_lhs.cols(), - /*(const Scalar*)*/&m_lhs.coeffRef(row,0), m_lhs.outerStride(), - /*(const Scalar*)*/&m_rhs.coeffRef(0,col), m_rhs.outerStride(), + &m_lhs.coeffRef(row,0), m_lhs.outerStride(), + &m_rhs.coeffRef(0,col), m_rhs.outerStride(), (Scalar*)&(m_dest.coeffRef(row,col)), m_dest.outerStride(), m_actualAlpha, m_blocking, info); } diff --git a/Eigen/src/Core/util/ForwardDeclarations.h b/Eigen/src/Core/util/ForwardDeclarations.h index 092ba758e..ead5de650 100644 --- a/Eigen/src/Core/util/ForwardDeclarations.h +++ b/Eigen/src/Core/util/ForwardDeclarations.h @@ -38,9 +38,7 @@ template struct accessors_level template struct evaluator_traits; -template< typename T, - typename Kind = typename evaluator_traits::Kind, - typename Scalar = typename T::Scalar> struct evaluator; +template< typename T> struct evaluator; } // end namespace internal diff --git a/Eigen/src/Core/util/XprHelper.h b/Eigen/src/Core/util/XprHelper.h index 0be5029c9..5407645c9 100644 --- a/Eigen/src/Core/util/XprHelper.h +++ b/Eigen/src/Core/util/XprHelper.h @@ -465,6 +465,15 @@ struct dense_xpr_base typedef ArrayBase type; }; +template::XprKind, typename StorageKind = typename traits::StorageKind> +struct generic_xpr_base; + +template +struct generic_xpr_base +{ + typedef typename dense_xpr_base::type type; +}; + /** \internal Helper base class to add a scalar multiple operator * overloads for complex types */ template