From 98ca58b02c1363aedb27c18e4a7ccc3344fefec4 Mon Sep 17 00:00:00 2001 From: Rasmus Munk Larsen Date: Wed, 24 Feb 2021 14:12:27 -0800 Subject: [PATCH 1/3] Cast anonymous enums to int when used in expressions. --- Eigen/src/Core/AssignEvaluator.h | 2 +- Eigen/src/Core/PlainObjectBase.h | 4 ++-- Eigen/src/Core/ProductEvaluators.h | 8 ++++---- Eigen/src/Geometry/Transform.h | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Eigen/src/Core/AssignEvaluator.h b/Eigen/src/Core/AssignEvaluator.h index 47ccf6242..508f17de9 100644 --- a/Eigen/src/Core/AssignEvaluator.h +++ b/Eigen/src/Core/AssignEvaluator.h @@ -450,7 +450,7 @@ struct dense_assignment_loop::size, - alignedSize = (size/packetSize)*packetSize }; + alignedSize = (int(size)/packetSize)*packetSize }; copy_using_evaluator_innervec_CompleteUnrolling::run(kernel); copy_using_evaluator_DefaultTraversal_CompleteUnrolling::run(kernel); diff --git a/Eigen/src/Core/PlainObjectBase.h b/Eigen/src/Core/PlainObjectBase.h index f2c7b8c48..595a6c13f 100644 --- a/Eigen/src/Core/PlainObjectBase.h +++ b/Eigen/src/Core/PlainObjectBase.h @@ -975,8 +975,8 @@ class PlainObjectBase : public internal::dense_xpr_base::type EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void _check_template_params() { - EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, (Options&RowMajor)==RowMajor) - && EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, (Options&RowMajor)==0) + EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, (int(Options)&RowMajor)==RowMajor) + && EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, (int(Options)&RowMajor)==0) && ((RowsAtCompileTime == Dynamic) || (RowsAtCompileTime >= 0)) && ((ColsAtCompileTime == Dynamic) || (ColsAtCompileTime >= 0)) && ((MaxRowsAtCompileTime == Dynamic) || (MaxRowsAtCompileTime >= 0)) diff --git a/Eigen/src/Core/ProductEvaluators.h b/Eigen/src/Core/ProductEvaluators.h index 079189a10..b766e1a1d 100644 --- a/Eigen/src/Core/ProductEvaluators.h +++ b/Eigen/src/Core/ProductEvaluators.h @@ -549,7 +549,7 @@ struct product_evaluator, ProductTag, DenseShape, RhsCoeffReadCost = RhsEtorType::CoeffReadCost, CoeffReadCost = InnerSize==0 ? NumTraits::ReadCost : InnerSize == Dynamic ? HugeCost - : InnerSize * (NumTraits::MulCost + LhsCoeffReadCost + RhsCoeffReadCost) + : InnerSize * (NumTraits::MulCost + int(LhsCoeffReadCost) + int(RhsCoeffReadCost)) + (InnerSize - 1) * NumTraits::AddCost, Unroll = CoeffReadCost <= EIGEN_UNROLLING_LIMIT, @@ -576,7 +576,7 @@ struct product_evaluator, ProductTag, DenseShape, : (MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0 : (bool(RhsRowMajor) && !CanVectorizeLhs), - Flags = ((unsigned int)(LhsFlags | RhsFlags) & HereditaryBits & ~RowMajorBit) + Flags = ((int(LhsFlags) | int(RhsFlags)) & HereditaryBits & ~RowMajorBit) | (EvalToRowMajor ? RowMajorBit : 0) // TODO enable vectorization for mixed types | (SameType && (CanVectorizeLhs || CanVectorizeRhs) ? PacketAccessBit : 0) @@ -597,8 +597,8 @@ struct product_evaluator, ProductTag, DenseShape, CanVectorizeInner = SameType && LhsRowMajor && (!RhsRowMajor) - && (LhsFlags & RhsFlags & ActualPacketAccessBit) - && (InnerSize % packet_traits::size == 0) + && (int(LhsFlags) & int(RhsFlags) & ActualPacketAccessBit) + && (int(InnerSize) % packet_traits::size == 0) }; EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CoeffReturnType coeff(Index row, Index col) const diff --git a/Eigen/src/Geometry/Transform.h b/Eigen/src/Geometry/Transform.h index 7d258c01d..1cb1d2f17 100644 --- a/Eigen/src/Geometry/Transform.h +++ b/Eigen/src/Geometry/Transform.h @@ -223,9 +223,9 @@ public: /** type of the matrix used to represent the linear part of the transformation */ typedef Matrix LinearMatrixType; /** type of read/write reference to the linear part of the transformation */ - typedef Block LinearPart; + typedef Block LinearPart; /** type of read reference to the linear part of the transformation */ - typedef const Block ConstLinearPart; + typedef const Block ConstLinearPart; /** type of read/write reference to the affine part of the transformation */ typedef typename internal::conditional Date: Wed, 24 Feb 2021 15:58:23 -0800 Subject: [PATCH 2/3] Remove unused function scalar_cmp_with_cast. --- Eigen/src/Core/functors/BinaryFunctors.h | 105 ----------------------- 1 file changed, 105 deletions(-) diff --git a/Eigen/src/Core/functors/BinaryFunctors.h b/Eigen/src/Core/functors/BinaryFunctors.h index 271608123..a182b4b74 100644 --- a/Eigen/src/Core/functors/BinaryFunctors.h +++ b/Eigen/src/Core/functors/BinaryFunctors.h @@ -265,111 +265,6 @@ struct scalar_cmp_op : binary_op_base struct scalar_cmp_with_cast_op; - -template -struct functor_traits > { - enum { - Cost = (NumTraits::AddCost+NumTraits::AddCost)/2, - PacketAccess = internal::is_same::value && packet_traits::HasCmp - }; -}; - -template -struct scalar_cmp_with_cast_op : binary_op_base -{ - typedef typename ScalarBinaryOpTraits::ReturnType result_type; - EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_with_cast_op) - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { - if(a==b) return static_cast(1); - else return static_cast(0); - } - template - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const - { return internal::pselect(internal::pcmp_eq(a,b), internal::pset1(static_cast(1)), internal::pzero(a)); } -}; -template -struct scalar_cmp_with_cast_op : binary_op_base -{ - typedef typename ScalarBinaryOpTraits::ReturnType result_type; - EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_with_cast_op) - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { - if(a(1); - else return static_cast(0); - } - template - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const - { return internal::pselect(internal::pcmp_lt(a,b), internal::pset1(static_cast(1)), internal::pzero(a)); } -}; -template -struct scalar_cmp_with_cast_op : binary_op_base -{ - typedef typename ScalarBinaryOpTraits::ReturnType result_type; - EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_with_cast_op) - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { - if(a<=b) return static_cast(1); - else return static_cast(0); - } - template - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const - { return internal::pselect(internal::pcmp_le(a,b), internal::pset1(static_cast(1)), internal::pzero(a)); } -}; -template -struct scalar_cmp_with_cast_op : binary_op_base -{ - typedef typename ScalarBinaryOpTraits::ReturnType result_type; - EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_with_cast_op) - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { - if(a>b) return static_cast(1); - else return static_cast(0); - } - template - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const - { return internal::pselect(internal::pcmp_le(a,b), internal::pzero(a), internal::pset1(static_cast(1))); } -}; -template -struct scalar_cmp_with_cast_op : binary_op_base -{ - typedef typename ScalarBinaryOpTraits::ReturnType result_type; - EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_with_cast_op) - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { - if(a>=b) return static_cast(1); - else return static_cast(0); - } - template - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const - { return internal::pselect(internal::pcmp_lt(a,b), internal::pzero(a), internal::pset1(static_cast(1))); } -}; -template -struct scalar_cmp_with_cast_op : binary_op_base -{ - typedef typename ScalarBinaryOpTraits::ReturnType result_type; - EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_with_cast_op) - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { - if(a<=b || b<=a) return static_cast(0); - else return static_cast(1); - } - template - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const - { return internal::pselect(por(internal::pcmp_le(a,b), internal::pcmp_le(b,a)), internal::pzero(a), internal::pset1(static_cast(1))); } -}; -template -struct scalar_cmp_with_cast_op : binary_op_base -{ - typedef typename ScalarBinaryOpTraits::ReturnType result_type; - EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_with_cast_op) - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { - if(a!=b) return static_cast(1); - else return static_cast(0); - } - template - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const - { return internal::pselect(internal::pcmp_eq(a,b), internal::pzero(a), internal::pset1(static_cast(1))); } -}; - /** \internal * \brief Template functor to compute the hypot of two \b positive \b and \b real scalars * From 0065f9d3225def945333ca33da0b020a95ce8c36 Mon Sep 17 00:00:00 2001 From: Rasmus Munk Larsen Date: Wed, 24 Feb 2021 17:49:20 -0800 Subject: [PATCH 3/3] Make it possible to specify NaN propagation strategy for maxCoeff/minCoeff reductions. --- Eigen/src/Core/DenseBase.h | 5 +++++ Eigen/src/Core/Redux.h | 30 ++++++++++++++++++++++++++++++ test/array_cwise.cpp | 14 ++++++++++++++ 3 files changed, 49 insertions(+) diff --git a/Eigen/src/Core/DenseBase.h b/Eigen/src/Core/DenseBase.h index 767a8e274..c83a3fcc6 100644 --- a/Eigen/src/Core/DenseBase.h +++ b/Eigen/src/Core/DenseBase.h @@ -452,6 +452,11 @@ template class DenseBase EIGEN_DEVICE_FUNC typename internal::traits::Scalar minCoeff() const; EIGEN_DEVICE_FUNC typename internal::traits::Scalar maxCoeff() const; + template + EIGEN_DEVICE_FUNC typename internal::traits::Scalar minCoeff() const; + template + EIGEN_DEVICE_FUNC typename internal::traits::Scalar maxCoeff() const; + template EIGEN_DEVICE_FUNC typename internal::traits::Scalar minCoeff(IndexType* row, IndexType* col) const; template EIGEN_DEVICE_FUNC diff --git a/Eigen/src/Core/Redux.h b/Eigen/src/Core/Redux.h index 2eef5abc5..4e5affc43 100644 --- a/Eigen/src/Core/Redux.h +++ b/Eigen/src/Core/Redux.h @@ -429,6 +429,21 @@ DenseBase::minCoeff() const return derived().redux(Eigen::internal::scalar_min_op()); } +/** \returns the minimum of all coefficients of \c *this. + * In case \c *this contains NaN, NaNPropagation determines the behavior: + * NaNPropagation == PropagateFast : undefined + * NaNPropagation == PropagateNaN : result is NaN + * NaNPropagation == PropagateNumbers : result is minimum of elements that are not NaN + * \warning the matrix must be not empty, otherwise an assertion is triggered. + */ +template +template +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename internal::traits::Scalar +DenseBase::minCoeff() const +{ + return derived().redux(Eigen::internal::scalar_min_op()); +} + /** \returns the maximum of all coefficients of \c *this. * \warning the matrix must be not empty, otherwise an assertion is triggered. * \warning the result is undefined if \c *this contains NaN. @@ -440,6 +455,21 @@ DenseBase::maxCoeff() const return derived().redux(Eigen::internal::scalar_max_op()); } +/** \returns the maximum of all coefficients of \c *this. + * In case \c *this contains NaN, NaNPropagation determines the behavior: + * NaNPropagation == PropagateFast : undefined + * NaNPropagation == PropagateNaN : result is NaN + * NaNPropagation == PropagateNumbers : result is maximum of elements that are not NaN + * \warning the matrix must be not empty, otherwise an assertion is triggered. + */ +template +template +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename internal::traits::Scalar +DenseBase::maxCoeff() const +{ + return derived().redux(Eigen::internal::scalar_max_op()); +} + /** \returns the sum of all coefficients of \c *this * * If \c *this is empty, then the value 0 is returned. diff --git a/test/array_cwise.cpp b/test/array_cwise.cpp index 7f7e44f89..92abf6968 100644 --- a/test/array_cwise.cpp +++ b/test/array_cwise.cpp @@ -610,6 +610,20 @@ template void min_max(const ArrayType& m) VERIFY_IS_APPROX(ArrayType::Constant(rows,cols, maxM1), (m1.max)( maxM1)); VERIFY_IS_APPROX(m1, (m1.max)( minM1)); + + // min/max with various NaN propagation options. + if (m1.size() > 1 && !NumTraits::IsInteger) { + m1(0,0) = std::numeric_limits::quiet_NaN(); + maxM1 = m1.template maxCoeff(); + minM1 = m1.template minCoeff(); + VERIFY((numext::isnan)(maxM1)); + VERIFY((numext::isnan)(minM1)); + + maxM1 = m1.template maxCoeff(); + minM1 = m1.template minCoeff(); + VERIFY(!(numext::isnan)(maxM1)); + VERIFY(!(numext::isnan)(minM1)); + } } EIGEN_DECLARE_TEST(array_cwise)