From 3011dc94efcabf609ce4bd766fa0461c4f17b5e3 Mon Sep 17 00:00:00 2001 From: Benoit Steiner Date: Mon, 28 Nov 2016 09:00:31 -0800 Subject: [PATCH 1/5] Call internal::array_prod to compute the total size of the tensor. --- unsupported/test/cxx11_tensor_fixed_size.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unsupported/test/cxx11_tensor_fixed_size.cpp b/unsupported/test/cxx11_tensor_fixed_size.cpp index 4c660de65..e6274f8eb 100644 --- a/unsupported/test/cxx11_tensor_fixed_size.cpp +++ b/unsupported/test/cxx11_tensor_fixed_size.cpp @@ -21,7 +21,7 @@ static void test_0d() TensorFixedSize, RowMajor> scalar2; VERIFY_IS_EQUAL(scalar1.rank(), 0); VERIFY_IS_EQUAL(scalar1.size(), 1); - VERIFY_IS_EQUAL(array_prod(scalar1.dimensions()), 1); + VERIFY_IS_EQUAL(internal::array_prod(scalar1.dimensions()), 1); scalar1() = 7.0; scalar2() = 13.0; From ab4ef5e66e33dd585bed2207c7c53948e30b2875 Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Wed, 30 Nov 2016 17:37:53 +0100 Subject: [PATCH 2/5] bug #1351: fix compilation of random with old compilers --- Eigen/src/Core/functors/NullaryFunctors.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Eigen/src/Core/functors/NullaryFunctors.h b/Eigen/src/Core/functors/NullaryFunctors.h index 0000ea1f1..70efec3ec 100644 --- a/Eigen/src/Core/functors/NullaryFunctors.h +++ b/Eigen/src/Core/functors/NullaryFunctors.h @@ -173,6 +173,13 @@ template struct has_unary_operator,IndexType> { enum { value = 1}; }; template struct has_binary_operator,IndexType> { enum { value = 0}; }; + +template +struct has_nullary_operator,IndexType> { enum { value = 1}; }; +template +struct has_unary_operator,IndexType> { enum { value = 0}; }; +template +struct has_binary_operator,IndexType> { enum { value = 0}; }; #endif } // end namespace internal From c927af60edbf7dd859fc8057151e40b0fe2de661 Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Wed, 30 Nov 2016 17:59:13 +0100 Subject: [PATCH 3/5] Fix a performance regression in (mat*mat)*vec for which mat*mat was evaluated multiple times. --- Eigen/src/Core/GeneralProduct.h | 2 ++ Eigen/src/Core/ProductEvaluators.h | 9 +++++++-- Eigen/src/Core/util/XprHelper.h | 10 +++------- test/product_notemporary.cpp | 4 ++++ 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/Eigen/src/Core/GeneralProduct.h b/Eigen/src/Core/GeneralProduct.h index 0cc2d08e2..8d87cab1f 100644 --- a/Eigen/src/Core/GeneralProduct.h +++ b/Eigen/src/Core/GeneralProduct.h @@ -329,6 +329,7 @@ template<> struct gemv_dense_selector template static void run(const Lhs &lhs, const Rhs &rhs, Dest& dest, const typename Dest::Scalar& alpha) { + EIGEN_STATIC_ASSERT((!nested_eval::Evaluate),EIGEN_INTERNAL_COMPILATION_ERROR_OR_YOU_MADE_A_PROGRAMMING_MISTAKE); // TODO if rhs is large enough it might be beneficial to make sure that dest is sequentially stored in memory, otherwise use a temp typename nested_eval::type actual_rhs(rhs); const Index size = rhs.rows(); @@ -342,6 +343,7 @@ template<> struct gemv_dense_selector template static void run(const Lhs &lhs, const Rhs &rhs, Dest& dest, const typename Dest::Scalar& alpha) { + EIGEN_STATIC_ASSERT((!nested_eval::Evaluate),EIGEN_INTERNAL_COMPILATION_ERROR_OR_YOU_MADE_A_PROGRAMMING_MISTAKE); typename nested_eval::type actual_rhs(rhs); const Index rows = dest.rows(); for(Index i=0; i struct generic_product_impl : generic_product_impl_base > { + typedef typename nested_eval::type LhsNested; + typedef typename nested_eval::type RhsNested; typedef typename Product::Scalar Scalar; enum { Side = Lhs::IsVectorAtCompileTime ? OnTheLeft : OnTheRight }; - typedef typename internal::conditional::type MatrixType; + typedef typename internal::remove_all::type>::type MatrixType; template static EIGEN_STRONG_INLINE void scaleAndAddTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha) { + LhsNested actual_lhs(lhs); + RhsNested actual_rhs(rhs); + internal::gemv_dense_selector::HasUsableDirectAccess) - >::run(lhs, rhs, dst, alpha); + >::run(actual_lhs, actual_rhs, dst, alpha); } }; diff --git a/Eigen/src/Core/util/XprHelper.h b/Eigen/src/Core/util/XprHelper.h index 7cfa2c49f..efd179b35 100644 --- a/Eigen/src/Core/util/XprHelper.h +++ b/Eigen/src/Core/util/XprHelper.h @@ -445,15 +445,11 @@ template // Another solution could be to count the number of temps? NAsInteger = n == Dynamic ? HugeCost : n, CostEval = (NAsInteger+1) * ScalarReadCost + CoeffReadCost, - CostNoEval = NAsInteger * CoeffReadCost + CostNoEval = NAsInteger * CoeffReadCost, + Evaluate = (int(evaluator::Flags) & EvalBeforeNestingBit) || (int(CostEval) < int(CostNoEval)) }; - typedef typename conditional< - ( (int(evaluator::Flags) & EvalBeforeNestingBit) || - (int(CostEval) < int(CostNoEval)) ), - PlainObject, - typename ref_selector::type - >::type type; + typedef typename conditional::type>::type type; }; template diff --git a/test/product_notemporary.cpp b/test/product_notemporary.cpp index 2bb19a681..8bf71b4f2 100644 --- a/test/product_notemporary.cpp +++ b/test/product_notemporary.cpp @@ -136,6 +136,10 @@ template void product_notemporary(const MatrixType& m) VERIFY_EVALUATION_COUNT( rm3.noalias() -= (cv1) * (rv1 * m1), 1 ); VERIFY_EVALUATION_COUNT( rm3.noalias() = (m1*cv1) * (rv1 * m1), 2 ); VERIFY_EVALUATION_COUNT( rm3.noalias() += (m1*cv1) * (rv1 * m1), 2 ); + + // Check nested products + VERIFY_EVALUATION_COUNT( cvres.noalias() = m1.adjoint() * m1 * cv1, 1 ); + VERIFY_EVALUATION_COUNT( rvres.noalias() = rv1 * (m1 * m2.adjoint()), 1 ); } void test_product_notemporary() From df3da0780d26f479dbb21dae5ae4bf2ab701595e Mon Sep 17 00:00:00 2001 From: Benoit Steiner Date: Wed, 30 Nov 2016 09:30:12 -0800 Subject: [PATCH 4/5] Updated customIndices2Array to handle various index sizes. --- unsupported/Eigen/CXX11/src/Tensor/TensorMeta.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorMeta.h b/unsupported/Eigen/CXX11/src/Tensor/TensorMeta.h index 615559d44..25ce471f9 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorMeta.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorMeta.h @@ -168,12 +168,12 @@ template struct IndexPair { #ifdef EIGEN_HAS_SFINAE namespace internal { - template + template EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE array customIndices2Array(IndexType& idx, numeric_list) { return { idx[Is]... }; } - template + template EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE array customIndices2Array(IndexType&, numeric_list) { return array(); From 8df272af8889bf01d800a83d64c17e19dd291744 Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Wed, 30 Nov 2016 22:21:33 +0100 Subject: [PATCH 5/5] Fix slection of product implementation for dynamic size matrices with fixed max size. --- Eigen/src/Core/GeneralProduct.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Eigen/src/Core/GeneralProduct.h b/Eigen/src/Core/GeneralProduct.h index 8d87cab1f..f62ecfcbe 100644 --- a/Eigen/src/Core/GeneralProduct.h +++ b/Eigen/src/Core/GeneralProduct.h @@ -25,7 +25,8 @@ template struct product_type_selector; template struct product_size_category { enum { is_large = MaxSize == Dynamic || - Size >= EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD, + Size >= EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD || + (Size==Dynamic && MaxSize>=EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD), value = is_large ? Large : Size == 1 ? 1 : Small