diff options
-rw-r--r-- | Eigen/src/Core/AssignEvaluator.h | 6 | ||||
-rw-r--r-- | Eigen/src/Core/CoreEvaluators.h | 66 | ||||
-rw-r--r-- | Eigen/src/Core/Product.h | 28 | ||||
-rw-r--r-- | Eigen/src/Core/ProductEvaluators.h | 40 | ||||
-rw-r--r-- | Eigen/src/Core/util/ForwardDeclarations.h | 5 |
5 files changed, 109 insertions, 36 deletions
diff --git a/Eigen/src/Core/AssignEvaluator.h b/Eigen/src/Core/AssignEvaluator.h index 99ae3f89d..2f18cbc95 100644 --- a/Eigen/src/Core/AssignEvaluator.h +++ b/Eigen/src/Core/AssignEvaluator.h @@ -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; diff --git a/Eigen/src/Core/CoreEvaluators.h b/Eigen/src/Core/CoreEvaluators.h index c63ff8acd..9460e675f 100644 --- a/Eigen/src/Core/CoreEvaluators.h +++ b/Eigen/src/Core/CoreEvaluators.h @@ -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. diff --git a/Eigen/src/Core/Product.h b/Eigen/src/Core/Product.h index 52586e5c0..970d257a5 100644 --- a/Eigen/src/Core/Product.h +++ b/Eigen/src/Core/Product.h @@ -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) }; diff --git a/Eigen/src/Core/ProductEvaluators.h b/Eigen/src/Core/ProductEvaluators.h index 9f5f6eb0c..e3a893651 100644 --- a/Eigen/src/Core/ProductEvaluators.h +++ b/Eigen/src/Core/ProductEvaluators.h @@ -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()) diff --git a/Eigen/src/Core/util/ForwardDeclarations.h b/Eigen/src/Core/util/ForwardDeclarations.h index 459422524..776eac587 100644 --- a/Eigen/src/Core/util/ForwardDeclarations.h +++ b/Eigen/src/Core/util/ForwardDeclarations.h @@ -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 |