diff --git a/Eigen/Core b/Eigen/Core index 722a49030..468ae0c76 100644 --- a/Eigen/Core +++ b/Eigen/Core @@ -311,6 +311,14 @@ using std::ptrdiff_t; #include "src/Core/MatrixBase.h" #include "src/Core/EigenBase.h" +#ifdef EIGEN_ENABLE_EVALUATORS +#include "src/Core/functors/AssignmentFunctors.h" +#include "src/Core/Product.h" +#include "src/Core/CoreEvaluators.h" +#include "src/Core/AssignEvaluator.h" +#include "src/Core/ProductEvaluators.h" +#endif + #ifndef EIGEN_PARSED_BY_DOXYGEN // work around Doxygen bug triggered by Assign.h r814874 // at least confirmed with Doxygen 1.5.5 and 1.5.6 #include "src/Core/Assign.h" @@ -382,14 +390,6 @@ using std::ptrdiff_t; #include "src/Core/Reverse.h" #include "src/Core/ArrayWrapper.h" -#ifdef EIGEN_ENABLE_EVALUATORS -#include "src/Core/functors/AssignmentFunctors.h" -#include "src/Core/Product.h" -#include "src/Core/CoreEvaluators.h" -#include "src/Core/AssignEvaluator.h" -#include "src/Core/ProductEvaluators.h" -#endif - #ifdef EIGEN_USE_BLAS #include "src/Core/products/GeneralMatrixMatrix_MKL.h" #include "src/Core/products/GeneralMatrixVector_MKL.h" diff --git a/Eigen/src/Core/Assign.h b/Eigen/src/Core/Assign.h index 906adcf82..c0b4bbfe0 100644 --- a/Eigen/src/Core/Assign.h +++ b/Eigen/src/Core/Assign.h @@ -504,12 +504,27 @@ EIGEN_STRONG_INLINE Derived& DenseBase EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Derived,OtherDerived) EIGEN_STATIC_ASSERT(SameType,YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) +#ifdef EIGEN_TEST_EVALUATORS + +#ifdef EIGEN_DEBUG_ASSIGN + internal::copy_using_evaluator_traits::debug(); +#endif + eigen_assert(rows() == other.rows() && cols() == other.cols()); +// internal::copy_using_evaluator_impl::Traversal) +// : int(InvalidTraversal)>::run(derived(),other.derived()); + internal::call_dense_assignment_loop(derived(),other.derived()); + +#else // EIGEN_TEST_EVALUATORS + #ifdef EIGEN_DEBUG_ASSIGN internal::assign_traits::debug(); #endif eigen_assert(rows() == other.rows() && cols() == other.cols()); - internal::assign_impl::Traversal) - : int(InvalidTraversal)>::run(derived(),other.derived()); + internal::assign_impl::Traversal) + : int(InvalidTraversal)>::run(derived(),other.derived()); + +#endif // EIGEN_TEST_EVALUATORS + #ifndef EIGEN_NO_DEBUG checkTransposeAliasing(other.derived()); #endif diff --git a/Eigen/src/Core/GeneralProduct.h b/Eigen/src/Core/GeneralProduct.h index 9d7d18427..e3a165ac6 100644 --- a/Eigen/src/Core/GeneralProduct.h +++ b/Eigen/src/Core/GeneralProduct.h @@ -566,6 +566,39 @@ template<> struct gemv_selector * \sa lazyProduct(), operator*=(const MatrixBase&), Cwise::operator*() */ #ifndef __CUDACC__ + +#ifdef EIGEN_TEST_EVALUATORS +template +template +inline const Product +MatrixBase::operator*(const MatrixBase &other) const +{ + // A note regarding the function declaration: In MSVC, this function will sometimes + // not be inlined since DenseStorage is an unwindable object for dynamic + // matrices and product types are holding a member to store the result. + // Thus it does not help tagging this function with EIGEN_STRONG_INLINE. + enum { + ProductIsValid = Derived::ColsAtCompileTime==Dynamic + || OtherDerived::RowsAtCompileTime==Dynamic + || int(Derived::ColsAtCompileTime)==int(OtherDerived::RowsAtCompileTime), + AreVectors = Derived::IsVectorAtCompileTime && OtherDerived::IsVectorAtCompileTime, + SameSizes = EIGEN_PREDICATE_SAME_MATRIX_SIZE(Derived,OtherDerived) + }; + // note to the lost user: + // * for a dot product use: v1.dot(v2) + // * for a coeff-wise product use: v1.cwiseProduct(v2) + EIGEN_STATIC_ASSERT(ProductIsValid || !(AreVectors && SameSizes), + INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS) + EIGEN_STATIC_ASSERT(ProductIsValid || !(SameSizes && !AreVectors), + INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION) + EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, INVALID_MATRIX_PRODUCT) +#ifdef EIGEN_DEBUG_PRODUCT + internal::product_type::debug(); +#endif + + return Product(derived(), other.derived()); +} +#else template template inline const typename ProductReturnType::Type @@ -595,6 +628,8 @@ MatrixBase::operator*(const MatrixBase &other) const #endif return typename ProductReturnType::Type(derived(), other.derived()); } +#endif + #endif /** \returns an expression of the matrix product of \c *this and \a other without implicit evaluation. * diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h index e77b49627..61798317e 100644 --- a/Eigen/src/Core/MatrixBase.h +++ b/Eigen/src/Core/MatrixBase.h @@ -184,9 +184,17 @@ template class MatrixBase operator*(const MatrixBase &other) const { return this->lazyProduct(other); } #else + +#ifdef EIGEN_TEST_EVALUATORS + template + const Product + operator*(const MatrixBase &other) const; +#else template const typename ProductReturnType::Type operator*(const MatrixBase &other) const; +#endif + #endif template diff --git a/Eigen/src/Core/Product.h b/Eigen/src/Core/Product.h index 3a08c027c..5d3789be7 100644 --- a/Eigen/src/Core/Product.h +++ b/Eigen/src/Core/Product.h @@ -36,7 +36,7 @@ struct traits > // We want A+B*C to be of type Product and not Product // TODO: This flag should eventually go in a separate evaluator traits class enum { - Flags = traits::Type>::Flags & ~EvalBeforeNestingBit + Flags = traits::Type>::Flags & ~(EvalBeforeNestingBit | DirectAccessBit) }; }; } // end namespace internal diff --git a/Eigen/src/Core/util/ForwardDeclarations.h b/Eigen/src/Core/util/ForwardDeclarations.h index dd0c18ad3..0a2144c69 100644 --- a/Eigen/src/Core/util/ForwardDeclarations.h +++ b/Eigen/src/Core/util/ForwardDeclarations.h @@ -89,6 +89,7 @@ template class CwiseUnaryView; template class CwiseBinaryOp; template class SelfCwiseBinaryOp; template class ProductBase; +template class Product; template class GeneralProduct; template class CoeffBasedProduct; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 5b9e92f01..04cb11d60 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -126,6 +126,13 @@ endif(TEST_LIB) set_property(GLOBAL PROPERTY EIGEN_CURRENT_SUBPROJECT "Official") add_custom_target(BuildOfficial) +option(EIGEN_TEST_EVALUATORS "Enable work in progress evaluators" OFF) + add_definitions("-DEIGEN_TEST_EVALUATORS=1") + add_definitions("-DEIGEN_ENABLE_EVALUATORS=1") +if(EIGEN_TEST_EVALUATORS) + +endif(EIGEN_TEST_EVALUATORS) + ei_add_test(meta) ei_add_test(sizeof) ei_add_test(dynalloc) diff --git a/test/main.h b/test/main.h index c889fa6c5..9dd8bc535 100644 --- a/test/main.h +++ b/test/main.h @@ -271,7 +271,13 @@ inline bool test_isApproxOrLessThan(const long double& a, const long double& b) template inline bool test_isApprox(const Type1& a, const Type2& b) { +#ifdef EIGEN_TEST_EVALUATORS + typename internal::eval::type a_eval(a); + typename internal::eval::type b_eval(b); + return a_eval.isApprox(b_eval, test_precision()); +#else return a.isApprox(b, test_precision()); +#endif } // The idea behind this function is to compare the two scalars a and b where