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/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"

View File

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

View File

@ -566,6 +566,39 @@ template<> struct gemv_selector<OnTheRight,RowMajor,false>
* \sa lazyProduct(), operator*=(const MatrixBase&), Cwise::operator*()
*/
#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 OtherDerived>
inline const typename ProductReturnType<Derived, OtherDerived>::Type
@ -595,6 +628,8 @@ MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const
#endif
return typename ProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived());
}
#endif
#endif
/** \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
{ return this->lazyProduct(other); }
#else
#ifdef EIGEN_TEST_EVALUATORS
template<typename OtherDerived>
const Product<Derived,OtherDerived>
operator*(const MatrixBase<OtherDerived> &other) const;
#else
template<typename OtherDerived>
const typename ProductReturnType<Derived,OtherDerived>::Type
operator*(const MatrixBase<OtherDerived> &other) const;
#endif
#endif
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>
// TODO: This flag should eventually go in a separate evaluator traits class
enum {
Flags = traits<typename ProductReturnType<Lhs, Rhs>::Type>::Flags & ~EvalBeforeNestingBit
Flags = traits<typename ProductReturnType<Lhs, Rhs>::Type>::Flags & ~(EvalBeforeNestingBit | DirectAccessBit)
};
};
} // 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 BinOp, typename Lhs, typename Rhs> class SelfCwiseBinaryOp;
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 NestingFlags> class CoeffBasedProduct;

View File

@ -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)

View File

@ -271,7 +271,13 @@ inline bool test_isApproxOrLessThan(const long double& a, const long double& b)
template<typename Type1, typename Type2>
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>());
#endif
}
// The idea behind this function is to compare the two scalars a and b where