mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-03-07 18:27:40 +08:00
First step toward the generalization of evaluators to triangular, sparse and other fancyness.
Remove product_tag template parameter to Product.
This commit is contained in:
parent
fb6e32a62f
commit
c15c65990f
@ -646,7 +646,7 @@ struct SparseShape {};
|
||||
// Based on the respective shapes of the destination and source,
|
||||
// the class AssignmentKind determine the kind of assignment mechanism.
|
||||
// AssignmentKind must define a Kind typedef.
|
||||
template<int DstShape, int SrcShape> struct AssignmentKind;
|
||||
template<typename DstShape, typename SrcShape> struct AssignmentKind;
|
||||
|
||||
// AssignmentKind<.,.>::Kind can be one of the following:
|
||||
struct Dense2Dense {};
|
||||
@ -655,9 +655,11 @@ template<int DstShape, int SrcShape> struct AssignmentKind;
|
||||
struct Sparse2Dense {};
|
||||
struct Sparse2Sparse {};
|
||||
|
||||
template<> struct AssignmentKind<Dense,Dense> { typedef Dense2Dense Kind; };
|
||||
|
||||
// This is the main assignment class
|
||||
template< typename DstXprType, typename SrcXprType, typename Functor,
|
||||
typename Kind = Dense2Dense,//AssignmentKind< evaluator<A>::Shape , evaluator<B>::Shape >::Kind,
|
||||
typename Kind = typename AssignmentKind< typename evaluator_traits<DstXprType>::Shape , typename evaluator_traits<SrcXprType>::Shape >::Kind,
|
||||
typename Scalar = typename DstXprType::Scalar>
|
||||
struct Assignment;
|
||||
|
||||
|
@ -14,20 +14,70 @@
|
||||
#define EIGEN_COREEVALUATORS_H
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<typename T> struct evaluator;
|
||||
struct IndexBased {};
|
||||
struct IteratorBased {};
|
||||
|
||||
// This class returns the evaluator kind from the expression storage kind.
|
||||
// Default assumes index based accessors
|
||||
template<typename StorageKind>
|
||||
struct storage_kind_to_evaluator_kind {
|
||||
typedef IndexBased Kind;
|
||||
};
|
||||
|
||||
// TODO to be moved to SparseCore:
|
||||
/*
|
||||
template<>
|
||||
struct storage_kind_to_evaluator_kind<Sparse> {
|
||||
typedef IteratorBased Kind
|
||||
};
|
||||
*/
|
||||
|
||||
// This class returns the evaluator shape from the expression storage kind.
|
||||
// It can be Dense, Sparse, Triangular, Diagonal, SelfAdjoint, Band, etc.
|
||||
template<typename StorageKind> struct storage_kind_to_shape;
|
||||
|
||||
|
||||
template<>
|
||||
struct storage_kind_to_shape<Dense> {
|
||||
typedef Dense Shape;
|
||||
};
|
||||
|
||||
// TODO to be moved to SparseCore:
|
||||
/*
|
||||
template<>
|
||||
struct storage_kind_to_shape<Sparse> {
|
||||
typedef Sparse Shape;
|
||||
};
|
||||
*/
|
||||
|
||||
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,
|
||||
typename RhsKind = typename evaluator_traits<typename T::Rhs>::Kind,
|
||||
typename LhsScalar = typename T::Lhs::Scalar,
|
||||
typename RhsScalar = typename T::Rhs::Scalar> struct binary_evaluator;
|
||||
|
||||
// evaluator_traits<T> contains traits for evaluator<T>
|
||||
|
||||
template<typename T>
|
||||
template<typename T>
|
||||
struct evaluator_traits_base
|
||||
{
|
||||
// TODO check whether these two indirections are really needed.
|
||||
// Basically, if nobody overwrite type and nestedType, then, they can be dropped
|
||||
typedef evaluator<T> type;
|
||||
typedef evaluator<T> nestedType;
|
||||
// typedef evaluator<T> type;
|
||||
// typedef evaluator<T> nestedType;
|
||||
|
||||
// by default, get evalautor kind and shape from storage
|
||||
typedef typename storage_kind_to_evaluator_kind<typename T::StorageKind>::Kind Kind;
|
||||
typedef typename storage_kind_to_shape<typename T::StorageKind>::Shape Shape;
|
||||
|
||||
// 1 if assignment A = B assumes aliasing when B is of type T and thus B needs to be evaluated into a
|
||||
// temporary; 0 if not.
|
||||
@ -58,8 +108,10 @@ struct evaluator<const T>
|
||||
template<typename ExpressionType>
|
||||
struct evaluator_base
|
||||
{
|
||||
typedef typename evaluator_traits<ExpressionType>::type type;
|
||||
typedef typename evaluator_traits<ExpressionType>::nestedType nestedType;
|
||||
// typedef typename evaluator_traits<ExpressionType>::type type;
|
||||
// typedef typename evaluator_traits<ExpressionType>::nestedType nestedType;
|
||||
typedef evaluator<ExpressionType> type;
|
||||
typedef evaluator<ExpressionType> nestedType;
|
||||
|
||||
typedef typename ExpressionType::Index Index;
|
||||
// TODO that's not very nice to have to propagate all these traits. They are currently only needed to handle outer,inner indices.
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
template<typename Lhs, typename Rhs, int Option, int ProductTag, typename StorageKind> class ProductImpl;
|
||||
template<typename Lhs, typename Rhs, int Option, typename StorageKind> class ProductImpl;
|
||||
|
||||
/** \class Product
|
||||
* \ingroup Core_Module
|
||||
@ -26,14 +26,13 @@ template<typename Lhs, typename Rhs, int Option, int ProductTag, typename Storag
|
||||
*
|
||||
* The other template parameters are:
|
||||
* \tparam Option can be DefaultProduct or LazyProduct
|
||||
* \tparam ProductTag can be InnerProduct, OuterProduct, GemvProduct, GemmProduct. It is used to ease expression manipulations.
|
||||
*
|
||||
*/
|
||||
|
||||
// Use ProductReturnType to get correct traits, in particular vectorization flags
|
||||
namespace internal {
|
||||
template<typename Lhs, typename Rhs, int Option, int ProductTag>
|
||||
struct traits<Product<Lhs, Rhs, Option, ProductTag> >
|
||||
template<typename Lhs, typename Rhs, int Option>
|
||||
struct traits<Product<Lhs, Rhs, Option> >
|
||||
: traits<typename ProductReturnType<Lhs, Rhs>::Type>
|
||||
{
|
||||
// We want A+B*C to be of type Product<Matrix, Sum> and not Product<Matrix, Matrix>
|
||||
@ -45,18 +44,23 @@ struct traits<Product<Lhs, Rhs, Option, ProductTag> >
|
||||
} // end namespace internal
|
||||
|
||||
|
||||
template<typename Lhs, typename Rhs, int Option, int ProductTag>
|
||||
class Product : public ProductImpl<Lhs,Rhs,Option,ProductTag,
|
||||
typename internal::promote_storage_type<typename internal::traits<Lhs>::StorageKind,
|
||||
typename internal::traits<Rhs>::StorageKind>::ret>
|
||||
template<typename _Lhs, typename _Rhs, int Option>
|
||||
class Product : public ProductImpl<_Lhs,_Rhs,Option,
|
||||
typename internal::promote_storage_type<typename internal::traits<_Lhs>::StorageKind,
|
||||
typename internal::traits<_Rhs>::StorageKind>::ret>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef _Lhs Lhs;
|
||||
typedef _Rhs Rhs;
|
||||
|
||||
typedef typename ProductImpl<
|
||||
Lhs, Rhs, Option, ProductTag,
|
||||
Lhs, Rhs, Option,
|
||||
typename internal::promote_storage_type<typename Lhs::StorageKind,
|
||||
typename Rhs::StorageKind>::ret>::Base Base;
|
||||
EIGEN_GENERIC_PUBLIC_INTERFACE(Product)
|
||||
|
||||
|
||||
|
||||
typedef typename Lhs::Nested LhsNested;
|
||||
typedef typename Rhs::Nested RhsNested;
|
||||
@ -82,13 +86,13 @@ class Product : public ProductImpl<Lhs,Rhs,Option,ProductTag,
|
||||
RhsNested m_rhs;
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs, int Option, int ProductTag>
|
||||
class ProductImpl<Lhs,Rhs,Option,ProductTag,Dense> : public internal::dense_xpr_base<Product<Lhs,Rhs,Option,ProductTag> >::type
|
||||
template<typename Lhs, typename Rhs, int Option>
|
||||
class ProductImpl<Lhs,Rhs,Option,Dense> : public internal::dense_xpr_base<Product<Lhs,Rhs,Option> >::type
|
||||
{
|
||||
typedef Product<Lhs, Rhs> Derived;
|
||||
public:
|
||||
|
||||
typedef typename internal::dense_xpr_base<Product<Lhs, Rhs, Option, ProductTag> >::type Base;
|
||||
typedef typename internal::dense_xpr_base<Product<Lhs, Rhs, Option> >::type Base;
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
|
||||
};
|
||||
|
||||
|
@ -16,7 +16,28 @@
|
||||
namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Like more general binary expressions, products need they own evaluator:
|
||||
template< typename T,
|
||||
int ProductTag = internal::product_tag<typename T::Lhs,typename T::Rhs>::ret,
|
||||
typename LhsShape = typename evaluator_traits<typename T::Lhs>::Shape,
|
||||
typename RhsShape = typename evaluator_traits<typename T::Rhs>::Shape,
|
||||
typename LhsScalar = typename T::Lhs::Scalar,
|
||||
typename RhsScalar = typename T::Rhs::Scalar
|
||||
> struct product_evaluator;
|
||||
|
||||
template<typename Lhs, typename Rhs, int Options>
|
||||
struct evaluator<Product<Lhs, Rhs, Options> >
|
||||
: public product_evaluator<Product<Lhs, Rhs, Options> >
|
||||
{
|
||||
typedef Product<Lhs, Rhs, Options> XprType;
|
||||
typedef product_evaluator<XprType> Base;
|
||||
|
||||
typedef evaluator type;
|
||||
typedef evaluator nestedType;
|
||||
|
||||
evaluator(const XprType& xpr) : Base(xpr) {}
|
||||
};
|
||||
|
||||
// Helper class to perform a dense product with the destination at hand.
|
||||
// Depending on the sizes of the factors, there are different evaluation strategies
|
||||
@ -27,17 +48,14 @@ struct dense_product_impl;
|
||||
|
||||
// The evaluator for default dense products creates a temporary and call dense_product_impl
|
||||
template<typename Lhs, typename Rhs, int ProductTag>
|
||||
struct evaluator<Product<Lhs, Rhs, DefaultProduct, ProductTag> >
|
||||
: public evaluator<typename Product<Lhs, Rhs, DefaultProduct, ProductTag>::PlainObject>::type
|
||||
struct product_evaluator<Product<Lhs, Rhs, DefaultProduct>, ProductTag, Dense, Dense, typename Lhs::Scalar, typename Rhs::Scalar>
|
||||
: public evaluator<typename Product<Lhs, Rhs, DefaultProduct>::PlainObject>::type
|
||||
{
|
||||
typedef Product<Lhs, Rhs, DefaultProduct, ProductTag> XprType;
|
||||
typedef Product<Lhs, Rhs, DefaultProduct> XprType;
|
||||
typedef typename XprType::PlainObject PlainObject;
|
||||
typedef typename evaluator<PlainObject>::type Base;
|
||||
|
||||
typedef evaluator type;
|
||||
typedef evaluator nestedType;
|
||||
|
||||
evaluator(const XprType& xpr)
|
||||
product_evaluator(const XprType& xpr)
|
||||
: m_result(xpr.rows(), xpr.cols())
|
||||
{
|
||||
::new (static_cast<Base*>(this)) Base(m_result);
|
||||
@ -199,13 +217,13 @@ template<int StorageOrder, int UnrollingIndex, typename Lhs, typename Rhs, typen
|
||||
struct etor_product_packet_impl;
|
||||
|
||||
template<typename Lhs, typename Rhs, int ProductTag>
|
||||
struct evaluator<Product<Lhs, Rhs, LazyProduct, ProductTag> >
|
||||
: evaluator_base<Product<Lhs, Rhs, LazyProduct, ProductTag> >
|
||||
struct product_evaluator<Product<Lhs, Rhs, LazyProduct>, ProductTag, Dense, Dense, typename Lhs::Scalar, typename Rhs::Scalar >
|
||||
: evaluator_base<Product<Lhs, Rhs, LazyProduct> >
|
||||
{
|
||||
typedef Product<Lhs, Rhs, LazyProduct, ProductTag> XprType;
|
||||
typedef Product<Lhs, Rhs, LazyProduct> XprType;
|
||||
typedef CoeffBasedProduct<Lhs, Rhs, 0> CoeffBasedProductType;
|
||||
|
||||
evaluator(const XprType& xpr)
|
||||
product_evaluator(const XprType& xpr)
|
||||
: m_lhsImpl(xpr.lhs()),
|
||||
m_rhsImpl(xpr.rhs()),
|
||||
m_innerDim(xpr.lhs().cols())
|
||||
|
@ -94,10 +94,7 @@ namespace internal {
|
||||
template<typename Lhs, typename Rhs> struct product_tag;
|
||||
}
|
||||
|
||||
template<typename Lhs, typename Rhs,
|
||||
int Option = DefaultProduct,
|
||||
int ProductTag = internal::product_tag<Lhs,Rhs>::ret
|
||||
> class Product;
|
||||
template<typename Lhs, typename Rhs, int Option = DefaultProduct> class Product;
|
||||
|
||||
template<typename Lhs, typename Rhs, int Mode> class GeneralProduct; // TODO deprecated
|
||||
template<typename Lhs, typename Rhs, int NestingFlags> class CoeffBasedProduct; // TODO deprecated
|
||||
|
Loading…
Reference in New Issue
Block a user