Add an option to test evaluators globally

This commit is contained in:
Gael Guennebaud 2013-11-07 16:38:14 +01:00
parent 57327cc2d5
commit 76c230a84d
8 changed files with 83 additions and 11 deletions

View File

@ -311,6 +311,14 @@ using std::ptrdiff_t;
#include "src/Core/MatrixBase.h" #include "src/Core/MatrixBase.h"
#include "src/Core/EigenBase.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 #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 // at least confirmed with Doxygen 1.5.5 and 1.5.6
#include "src/Core/Assign.h" #include "src/Core/Assign.h"
@ -382,14 +390,6 @@ using std::ptrdiff_t;
#include "src/Core/Reverse.h" #include "src/Core/Reverse.h"
#include "src/Core/ArrayWrapper.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 #ifdef EIGEN_USE_BLAS
#include "src/Core/products/GeneralMatrixMatrix_MKL.h" #include "src/Core/products/GeneralMatrixMatrix_MKL.h"
#include "src/Core/products/GeneralMatrixVector_MKL.h" #include "src/Core/products/GeneralMatrixVector_MKL.h"

View File

@ -504,12 +504,27 @@ EIGEN_STRONG_INLINE Derived& DenseBase<Derived>
EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Derived,OtherDerived) 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) 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<Derived, OtherDerived>::debug();
#endif
eigen_assert(rows() == other.rows() && cols() == other.cols());
// internal::copy_using_evaluator_impl<Derived, OtherDerived, int(SameType) ? int(internal::copy_using_evaluator_traits<Derived, OtherDerived>::Traversal)
// : int(InvalidTraversal)>::run(derived(),other.derived());
internal::call_dense_assignment_loop(derived(),other.derived());
#else // EIGEN_TEST_EVALUATORS
#ifdef EIGEN_DEBUG_ASSIGN #ifdef EIGEN_DEBUG_ASSIGN
internal::assign_traits<Derived, OtherDerived>::debug(); internal::assign_traits<Derived, OtherDerived>::debug();
#endif #endif
eigen_assert(rows() == other.rows() && cols() == other.cols()); eigen_assert(rows() == other.rows() && cols() == other.cols());
internal::assign_impl<Derived, OtherDerived, int(SameType) ? int(internal::assign_traits<Derived, OtherDerived>::Traversal) internal::assign_impl<Derived, OtherDerived, int(SameType) ? int(internal::copy_using_evaluator_traits<Derived, OtherDerived>::Traversal)
: int(InvalidTraversal)>::run(derived(),other.derived()); : int(InvalidTraversal)>::run(derived(),other.derived());
#endif // EIGEN_TEST_EVALUATORS
#ifndef EIGEN_NO_DEBUG #ifndef EIGEN_NO_DEBUG
checkTransposeAliasing(other.derived()); checkTransposeAliasing(other.derived());
#endif #endif

View File

@ -566,6 +566,39 @@ template<> struct gemv_selector<OnTheRight,RowMajor,false>
* \sa lazyProduct(), operator*=(const MatrixBase&), Cwise::operator*() * \sa lazyProduct(), operator*=(const MatrixBase&), Cwise::operator*()
*/ */
#ifndef __CUDACC__ #ifndef __CUDACC__
#ifdef EIGEN_TEST_EVALUATORS
template<typename Derived>
template<typename OtherDerived>
inline const Product<Derived, OtherDerived>
MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &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<Derived,OtherDerived>::debug();
#endif
return Product<Derived, OtherDerived>(derived(), other.derived());
}
#else
template<typename Derived> template<typename Derived>
template<typename OtherDerived> template<typename OtherDerived>
inline const typename ProductReturnType<Derived, OtherDerived>::Type inline const typename ProductReturnType<Derived, OtherDerived>::Type
@ -595,6 +628,8 @@ MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const
#endif #endif
return typename ProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived()); return typename ProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived());
} }
#endif
#endif #endif
/** \returns an expression of the matrix product of \c *this and \a other without implicit evaluation. /** \returns an expression of the matrix product of \c *this and \a other without implicit evaluation.
* *

View File

@ -184,9 +184,17 @@ template<typename Derived> class MatrixBase
operator*(const MatrixBase<OtherDerived> &other) const operator*(const MatrixBase<OtherDerived> &other) const
{ return this->lazyProduct(other); } { return this->lazyProduct(other); }
#else #else
#ifdef EIGEN_TEST_EVALUATORS
template<typename OtherDerived>
const Product<Derived,OtherDerived>
operator*(const MatrixBase<OtherDerived> &other) const;
#else
template<typename OtherDerived> template<typename OtherDerived>
const typename ProductReturnType<Derived,OtherDerived>::Type const typename ProductReturnType<Derived,OtherDerived>::Type
operator*(const MatrixBase<OtherDerived> &other) const; operator*(const MatrixBase<OtherDerived> &other) const;
#endif
#endif #endif
template<typename OtherDerived> template<typename OtherDerived>

View File

@ -36,7 +36,7 @@ struct traits<Product<Lhs, Rhs> >
// We want A+B*C to be of type Product<Matrix, Sum> and not Product<Matrix, Matrix> // We want A+B*C to be of type Product<Matrix, Sum> and not Product<Matrix, Matrix>
// TODO: This flag should eventually go in a separate evaluator traits class // TODO: This flag should eventually go in a separate evaluator traits class
enum { enum {
Flags = traits<typename ProductReturnType<Lhs, Rhs>::Type>::Flags & ~EvalBeforeNestingBit Flags = traits<typename ProductReturnType<Lhs, Rhs>::Type>::Flags & ~(EvalBeforeNestingBit | DirectAccessBit)
}; };
}; };
} // end namespace internal } // end namespace internal

View File

@ -89,6 +89,7 @@ template<typename ViewOp, typename MatrixType> class CwiseUnaryView;
template<typename BinaryOp, typename Lhs, typename Rhs> class CwiseBinaryOp; template<typename BinaryOp, typename Lhs, typename Rhs> class CwiseBinaryOp;
template<typename BinOp, typename Lhs, typename Rhs> class SelfCwiseBinaryOp; template<typename BinOp, typename Lhs, typename Rhs> class SelfCwiseBinaryOp;
template<typename Derived, typename Lhs, typename Rhs> class ProductBase; template<typename Derived, typename Lhs, typename Rhs> class ProductBase;
template<typename Lhs, typename Rhs> class Product;
template<typename Lhs, typename Rhs, int Mode> class GeneralProduct; template<typename Lhs, typename Rhs, int Mode> class GeneralProduct;
template<typename Lhs, typename Rhs, int NestingFlags> class CoeffBasedProduct; template<typename Lhs, typename Rhs, int NestingFlags> class CoeffBasedProduct;

View File

@ -126,6 +126,13 @@ endif(TEST_LIB)
set_property(GLOBAL PROPERTY EIGEN_CURRENT_SUBPROJECT "Official") set_property(GLOBAL PROPERTY EIGEN_CURRENT_SUBPROJECT "Official")
add_custom_target(BuildOfficial) 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(meta)
ei_add_test(sizeof) ei_add_test(sizeof)
ei_add_test(dynalloc) ei_add_test(dynalloc)

View File

@ -271,7 +271,13 @@ inline bool test_isApproxOrLessThan(const long double& a, const long double& b)
template<typename Type1, typename Type2> template<typename Type1, typename Type2>
inline bool test_isApprox(const Type1& a, const Type2& b) inline bool test_isApprox(const Type1& a, const Type2& b)
{ {
#ifdef EIGEN_TEST_EVALUATORS
typename internal::eval<Type1>::type a_eval(a);
typename internal::eval<Type2>::type b_eval(b);
return a_eval.isApprox(b_eval, test_precision<typename Type1::Scalar>());
#else
return a.isApprox(b, test_precision<typename Type1::Scalar>()); return a.isApprox(b, test_precision<typename Type1::Scalar>());
#endif
} }
// The idea behind this function is to compare the two scalars a and b where // The idea behind this function is to compare the two scalars a and b where