diff --git a/Eigen/src/Core/CoreEvaluators.h b/Eigen/src/Core/CoreEvaluators.h index 961b56e55..faf5aedb5 100644 --- a/Eigen/src/Core/CoreEvaluators.h +++ b/Eigen/src/Core/CoreEvaluators.h @@ -53,11 +53,7 @@ struct storage_kind_to_shape { }; */ -template struct evaluator_traits; -template< typename T, - typename Kind = typename evaluator_traits::Kind, - typename Scalar = typename T::Scalar> struct evaluator; template< typename T, typename LhsKind = typename evaluator_traits::Kind, diff --git a/Eigen/src/Core/GeneralProduct.h b/Eigen/src/Core/GeneralProduct.h index c9ab63782..675f6ee8d 100644 --- a/Eigen/src/Core/GeneralProduct.h +++ b/Eigen/src/Core/GeneralProduct.h @@ -623,7 +623,7 @@ MatrixBase::operator*(const MatrixBase &other) const return Product(derived(), other.derived()); } -#else +#else // EIGEN_TEST_EVALUATORS template template inline const typename ProductReturnType::Type @@ -653,9 +653,10 @@ MatrixBase::operator*(const MatrixBase &other) const #endif return typename ProductReturnType::Type(derived(), other.derived()); } -#endif +#endif // EIGEN_TEST_EVALUATORS + +#endif // __CUDACC__ -#endif /** \returns an expression of the matrix product of \c *this and \a other without implicit evaluation. * * The returned product will behave like any other expressions: the coefficients of the product will be @@ -667,6 +668,31 @@ MatrixBase::operator*(const MatrixBase &other) const * * \sa operator*(const MatrixBase&) */ +#ifdef EIGEN_TEST_EVALUATORS +template +template +const Product +MatrixBase::lazyProduct(const MatrixBase &other) const +{ + 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) + + return Product(derived(), other.derived()); +} +#else // EIGEN_TEST_EVALUATORS template template const typename LazyProductReturnType::Type @@ -690,6 +716,7 @@ MatrixBase::lazyProduct(const MatrixBase &other) const return typename LazyProductReturnType::Type(derived(), other.derived()); } +#endif // EIGEN_TEST_EVALUATORS } // end namespace Eigen diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h index 61798317e..37e7408a4 100644 --- a/Eigen/src/Core/MatrixBase.h +++ b/Eigen/src/Core/MatrixBase.h @@ -199,7 +199,11 @@ template class MatrixBase template EIGEN_DEVICE_FUNC +#ifdef EIGEN_TEST_EVALUATORS + const Product +#else const typename LazyProductReturnType::Type +#endif lazyProduct(const MatrixBase &other) const; template diff --git a/Eigen/src/Core/NoAlias.h b/Eigen/src/Core/NoAlias.h index 65117a806..6ac525336 100644 --- a/Eigen/src/Core/NoAlias.h +++ b/Eigen/src/Core/NoAlias.h @@ -34,6 +34,33 @@ class NoAlias typedef typename ExpressionType::Scalar Scalar; NoAlias(ExpressionType& expression) : m_expression(expression) {} + +#ifdef EIGEN_TEST_EVALUATORS + template + EIGEN_DEVICE_FUNC + EIGEN_STRONG_INLINE ExpressionType& operator=(const StorageBase& other) + { + call_assignment(*this, other.derived(), internal::assign_op()); + return m_expression; + } + + template + EIGEN_DEVICE_FUNC + EIGEN_STRONG_INLINE ExpressionType& operator+=(const StorageBase& other) + { + call_assignment(*this, other.derived(), internal::add_assign_op()); + return m_expression; + } + + template + EIGEN_DEVICE_FUNC + EIGEN_STRONG_INLINE ExpressionType& operator-=(const StorageBase& other) + { + call_assignment(*this, other.derived(), internal::sub_assign_op()); + return m_expression; + } + +#else /** Behaves like MatrixBase::lazyAssign(other) * \sa MatrixBase::lazyAssign() */ @@ -91,6 +118,8 @@ class NoAlias template ExpressionType& operator=(const ReturnByValue& func) { return m_expression = func; } +#endif + #endif EIGEN_DEVICE_FUNC diff --git a/Eigen/src/Core/Product.h b/Eigen/src/Core/Product.h index 3b8fd7d9a..b37fd2ff7 100644 --- a/Eigen/src/Core/Product.h +++ b/Eigen/src/Core/Product.h @@ -79,6 +79,12 @@ class Product : public ProductImpl<_Lhs,_Rhs,Option, const LhsNestedCleaned& lhs() const { return m_lhs; } const RhsNestedCleaned& rhs() const { return m_rhs; } + + /** Convertion to scalar for inner-products */ + operator const Scalar() const { + EIGEN_STATIC_ASSERT(SizeAtCompileTime==1, IMPLICIT_CONVERSION_TO_SCALAR_IS_FOR_INNER_PRODUCT_ONLY); + return typename internal::evaluator::type(*this).coeff(0,0); + } protected: diff --git a/Eigen/src/Core/ProductEvaluators.h b/Eigen/src/Core/ProductEvaluators.h index d0dba1644..5dd480cad 100644 --- a/Eigen/src/Core/ProductEvaluators.h +++ b/Eigen/src/Core/ProductEvaluators.h @@ -209,12 +209,12 @@ struct dense_product_impl : dense_product_impl_base::Scalar Scalar; - template - static void scaleAndAddTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha) - { - // TODO bypass GeneralProduct class - GeneralProduct(lhs,rhs).scaleAndAddTo(dst, alpha); - } +// template +// static void scaleAndAddTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha) +// { +// // TODO bypass GeneralProduct class +// GeneralProduct(lhs,rhs).scaleAndAddTo(dst, alpha); +// } }; template @@ -225,22 +225,28 @@ struct dense_product_impl template static inline void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) { - // TODO: use the following instead of calling call_assignment + // TODO: use the following instead of calling call_assignment, same for the other methods // dst = lazyprod(lhs,rhs); call_assignment(dst, lazyprod(lhs,rhs), internal::assign_op()); } template static inline void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) - { dst += lazyprod(lhs,rhs); } + { + // dst += lazyprod(lhs,rhs); + call_assignment(dst, lazyprod(lhs,rhs), internal::add_assign_op()); + } template static inline void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) - { dst -= lazyprod(lhs,rhs); } + { + // dst -= lazyprod(lhs,rhs); + call_assignment(dst, lazyprod(lhs,rhs), internal::sub_assign_op()); + } - template - static inline void scaleAndAddTo(Dst& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha) - { dst += alpha * lazyprod(lhs,rhs); } +// template +// static inline void scaleAndAddTo(Dst& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha) +// { dst += alpha * lazyprod(lhs,rhs); } }; template @@ -286,7 +292,7 @@ struct product_evaluator, ProductTag, DenseShape, CoeffReadCost = traits::CoeffReadCost, Unroll = CoeffReadCost != Dynamic && CoeffReadCost <= EIGEN_UNROLLING_LIMIT, CanVectorizeInner = traits::CanVectorizeInner, - Flags = CoeffBasedProductType::Flags + Flags = traits::Flags }; typedef typename evaluator::type LhsEtorType; diff --git a/Eigen/src/Core/products/CoeffBasedProduct.h b/Eigen/src/Core/products/CoeffBasedProduct.h index 637513132..c987a30b0 100644 --- a/Eigen/src/Core/products/CoeffBasedProduct.h +++ b/Eigen/src/Core/products/CoeffBasedProduct.h @@ -14,7 +14,7 @@ namespace Eigen { namespace internal { - + /********************************************************************************* * Coefficient based product implementation. * It is designed for the following use cases: @@ -110,6 +110,8 @@ struct traits > } // end namespace internal +#ifndef EIGEN_TEST_EVALUATORS + template class CoeffBasedProduct : internal::no_assignment_operator, @@ -447,6 +449,8 @@ struct product_packet_impl } // end namespace internal +#endif // EIGEN_TEST_EVALUATORS + } // end namespace Eigen #endif // EIGEN_COEFFBASED_PRODUCT_H diff --git a/Eigen/src/Core/util/ForwardDeclarations.h b/Eigen/src/Core/util/ForwardDeclarations.h index 776eac587..3bc151229 100644 --- a/Eigen/src/Core/util/ForwardDeclarations.h +++ b/Eigen/src/Core/util/ForwardDeclarations.h @@ -36,6 +36,12 @@ template struct accessors_level }; }; +template struct evaluator_traits; + +template< typename T, + typename Kind = typename evaluator_traits::Kind, + typename Scalar = typename T::Scalar> struct evaluator; + } // end namespace internal template struct NumTraits; diff --git a/Eigen/src/Core/util/StaticAssert.h b/Eigen/src/Core/util/StaticAssert.h index 8872c5b64..b9b1ee02a 100644 --- a/Eigen/src/Core/util/StaticAssert.h +++ b/Eigen/src/Core/util/StaticAssert.h @@ -90,7 +90,8 @@ YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED, THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE, THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH, - OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG + OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG, + IMPLICIT_CONVERSION_TO_SCALAR_IS_FOR_INNER_PRODUCT_ONLY }; }; diff --git a/test/main.h b/test/main.h index 9dd8bc535..dda451a40 100644 --- a/test/main.h +++ b/test/main.h @@ -66,6 +66,8 @@ namespace Eigen static bool g_has_set_repeat, g_has_set_seed; } +#define TRACK std::cerr << __FILE__ << " " << __LINE__ << std::endl + #define EI_PP_MAKE_STRING2(S) #S #define EI_PP_MAKE_STRING(S) EI_PP_MAKE_STRING2(S)