mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-08-12 11:49:02 +08:00
Enable use of evaluators for noalias and lazyProduct, add conversion to scalar for inner products
This commit is contained in:
parent
f0b82c3ab9
commit
6c5e915e9a
@ -53,11 +53,7 @@ struct storage_kind_to_shape<Sparse> {
|
||||
};
|
||||
*/
|
||||
|
||||
template<typename T> struct evaluator_traits;
|
||||
|
||||
template< typename T,
|
||||
typename Kind = typename evaluator_traits<T>::Kind,
|
||||
typename Scalar = typename T::Scalar> struct evaluator;
|
||||
|
||||
template< typename T,
|
||||
typename LhsKind = typename evaluator_traits<typename T::Lhs>::Kind,
|
||||
|
@ -623,7 +623,7 @@ MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const
|
||||
|
||||
return Product<Derived, OtherDerived>(derived(), other.derived());
|
||||
}
|
||||
#else
|
||||
#else // EIGEN_TEST_EVALUATORS
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
inline const typename ProductReturnType<Derived, OtherDerived>::Type
|
||||
@ -653,9 +653,10 @@ MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const
|
||||
#endif
|
||||
return typename ProductReturnType<Derived,OtherDerived>::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<Derived>::operator*(const MatrixBase<OtherDerived> &other) const
|
||||
*
|
||||
* \sa operator*(const MatrixBase&)
|
||||
*/
|
||||
#ifdef EIGEN_TEST_EVALUATORS
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
const Product<Derived,OtherDerived,LazyProduct>
|
||||
MatrixBase<Derived>::lazyProduct(const MatrixBase<OtherDerived> &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,OtherDerived,LazyProduct>(derived(), other.derived());
|
||||
}
|
||||
#else // EIGEN_TEST_EVALUATORS
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
const typename LazyProductReturnType<Derived,OtherDerived>::Type
|
||||
@ -690,6 +716,7 @@ MatrixBase<Derived>::lazyProduct(const MatrixBase<OtherDerived> &other) const
|
||||
|
||||
return typename LazyProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived());
|
||||
}
|
||||
#endif // EIGEN_TEST_EVALUATORS
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
|
@ -199,7 +199,11 @@ template<typename Derived> class MatrixBase
|
||||
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
#ifdef EIGEN_TEST_EVALUATORS
|
||||
const Product<Derived,OtherDerived,LazyProduct>
|
||||
#else
|
||||
const typename LazyProductReturnType<Derived,OtherDerived>::Type
|
||||
#endif
|
||||
lazyProduct(const MatrixBase<OtherDerived> &other) const;
|
||||
|
||||
template<typename OtherDerived>
|
||||
|
@ -34,6 +34,33 @@ class NoAlias
|
||||
typedef typename ExpressionType::Scalar Scalar;
|
||||
|
||||
NoAlias(ExpressionType& expression) : m_expression(expression) {}
|
||||
|
||||
#ifdef EIGEN_TEST_EVALUATORS
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE ExpressionType& operator=(const StorageBase<OtherDerived>& other)
|
||||
{
|
||||
call_assignment(*this, other.derived(), internal::assign_op<Scalar>());
|
||||
return m_expression;
|
||||
}
|
||||
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE ExpressionType& operator+=(const StorageBase<OtherDerived>& other)
|
||||
{
|
||||
call_assignment(*this, other.derived(), internal::add_assign_op<Scalar>());
|
||||
return m_expression;
|
||||
}
|
||||
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE ExpressionType& operator-=(const StorageBase<OtherDerived>& other)
|
||||
{
|
||||
call_assignment(*this, other.derived(), internal::sub_assign_op<Scalar>());
|
||||
return m_expression;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/** Behaves like MatrixBase::lazyAssign(other)
|
||||
* \sa MatrixBase::lazyAssign() */
|
||||
@ -91,6 +118,8 @@ class NoAlias
|
||||
template<typename OtherDerived>
|
||||
ExpressionType& operator=(const ReturnByValue<OtherDerived>& func)
|
||||
{ return m_expression = func; }
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
|
@ -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<Product>::type(*this).coeff(0,0);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -209,12 +209,12 @@ struct dense_product_impl<Lhs,Rhs,GemmProduct> : dense_product_impl_base<Lhs,Rhs
|
||||
{
|
||||
typedef typename Product<Lhs,Rhs>::Scalar Scalar;
|
||||
|
||||
template<typename Dest>
|
||||
static void scaleAndAddTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
|
||||
{
|
||||
// TODO bypass GeneralProduct class
|
||||
GeneralProduct<Lhs, Rhs, GemmProduct>(lhs,rhs).scaleAndAddTo(dst, alpha);
|
||||
}
|
||||
// template<typename Dest>
|
||||
// static void scaleAndAddTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
|
||||
// {
|
||||
// // TODO bypass GeneralProduct class
|
||||
// GeneralProduct<Lhs, Rhs, GemmProduct>(lhs,rhs).scaleAndAddTo(dst, alpha);
|
||||
// }
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
@ -225,22 +225,28 @@ struct dense_product_impl<Lhs,Rhs,CoeffBasedProductMode>
|
||||
template<typename Dst>
|
||||
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<Scalar>());
|
||||
}
|
||||
|
||||
template<typename Dst>
|
||||
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<Scalar>());
|
||||
}
|
||||
|
||||
template<typename Dst>
|
||||
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<Scalar>());
|
||||
}
|
||||
|
||||
template<typename Dst>
|
||||
static inline void scaleAndAddTo(Dst& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
|
||||
{ dst += alpha * lazyprod(lhs,rhs); }
|
||||
// template<typename Dst>
|
||||
// static inline void scaleAndAddTo(Dst& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
|
||||
// { dst += alpha * lazyprod(lhs,rhs); }
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
@ -286,7 +292,7 @@ struct product_evaluator<Product<Lhs, Rhs, LazyProduct>, ProductTag, DenseShape,
|
||||
CoeffReadCost = traits<CoeffBasedProductType>::CoeffReadCost,
|
||||
Unroll = CoeffReadCost != Dynamic && CoeffReadCost <= EIGEN_UNROLLING_LIMIT,
|
||||
CanVectorizeInner = traits<CoeffBasedProductType>::CanVectorizeInner,
|
||||
Flags = CoeffBasedProductType::Flags
|
||||
Flags = traits<CoeffBasedProductType>::Flags
|
||||
};
|
||||
|
||||
typedef typename evaluator<Lhs>::type LhsEtorType;
|
||||
|
@ -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<CoeffBasedProduct<LhsNested,RhsNested,NestingFlags> >
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
#ifndef EIGEN_TEST_EVALUATORS
|
||||
|
||||
template<typename LhsNested, typename RhsNested, int NestingFlags>
|
||||
class CoeffBasedProduct
|
||||
: internal::no_assignment_operator,
|
||||
@ -447,6 +449,8 @@ struct product_packet_impl<ColMajor, Dynamic, Lhs, Rhs, Packet, LoadMode>
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
#endif // EIGEN_TEST_EVALUATORS
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_COEFFBASED_PRODUCT_H
|
||||
|
@ -36,6 +36,12 @@ template<typename Derived> struct accessors_level
|
||||
};
|
||||
};
|
||||
|
||||
template<typename T> struct evaluator_traits;
|
||||
|
||||
template< typename T,
|
||||
typename Kind = typename evaluator_traits<T>::Kind,
|
||||
typename Scalar = typename T::Scalar> struct evaluator;
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
template<typename T> struct NumTraits;
|
||||
|
@ -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
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user