diff options
author | 2010-02-09 11:05:39 +0100 | |
---|---|---|
committer | 2010-02-09 11:05:39 +0100 | |
commit | 5686eca7b1017738a19a32ce0627249e56cfd3eb (patch) | |
tree | eae2f93d90cb58c7625334c3cb754b9c528754fe /Eigen/src/Core/products | |
parent | 0398e21198caaf7206851a9081033cddb0797d47 (diff) |
* fix multiple temporary copies for coeff based products
* introduce a lazy product version of the coefficient based implementation
=> flagged is not used anymore
=> small outer product are now lazy by default (aliasing is really unlikely for outer products)
Diffstat (limited to 'Eigen/src/Core/products')
-rw-r--r-- | Eigen/src/Core/products/CoeffBasedProduct.h (renamed from Eigen/src/Core/products/GeneralCoeffBased.h) | 60 |
1 files changed, 40 insertions, 20 deletions
diff --git a/Eigen/src/Core/products/GeneralCoeffBased.h b/Eigen/src/Core/products/CoeffBasedProduct.h index 0cca2d417..d947bfc58 100644 --- a/Eigen/src/Core/products/GeneralCoeffBased.h +++ b/Eigen/src/Core/products/CoeffBasedProduct.h @@ -23,11 +23,14 @@ // License and a copy of the GNU General Public License along with // Eigen. If not, see <http://www.gnu.org/licenses/>. -#ifndef EIGEN_GENERAL_UNROLLED_PRODUCT_H -#define EIGEN_GENERAL_UNROLLED_PRODUCT_H +#ifndef EIGEN_COEFFBASED_PRODUCT_H +#define EIGEN_COEFFBASED_PRODUCT_H /********************************************************************************* -* Specialization of GeneralProduct<> for products with small fixed sizes +* Coefficient based product implementation. +* It is designed for the following use cases: +* - small fixed sizes +* - lazy products *********************************************************************************/ /* Since the all the dimensions of the product are small, here we can rely @@ -42,8 +45,8 @@ struct ei_product_coeff_impl; template<int StorageOrder, int Index, typename Lhs, typename Rhs, typename PacketScalar, int LoadMode> struct ei_product_packet_impl; -template<typename LhsNested, typename RhsNested> -struct ei_traits<GeneralProduct<LhsNested,RhsNested,CoeffBasedProduct> > +template<typename LhsNested, typename RhsNested, int NestingFlags> +struct ei_traits<CoeffBasedProduct<LhsNested,RhsNested,NestingFlags> > { typedef DenseStorageMatrix DenseStorageType; typedef typename ei_cleantype<LhsNested>::type _LhsNested; @@ -79,14 +82,13 @@ struct ei_traits<GeneralProduct<LhsNested,RhsNested,CoeffBasedProduct> > RemovedBits = ~(EvalToRowMajor ? 0 : RowMajorBit), Flags = ((unsigned int)(LhsFlags | RhsFlags) & HereditaryBits & RemovedBits) - | EvalBeforeAssigningBit - | EvalBeforeNestingBit + | NestingFlags | (CanVectorizeLhs || CanVectorizeRhs ? PacketAccessBit : 0) | (LhsFlags & RhsFlags & AlignedBit), - CoeffReadCost = InnerSize == Dynamic ? Dynamic - : InnerSize * (NumTraits<Scalar>::MulCost + LhsCoeffReadCost + RhsCoeffReadCost) - + (InnerSize - 1) * NumTraits<Scalar>::AddCost, + CoeffReadCost = 1000,//InnerSize == Dynamic ? Dynamic +// : InnerSize * (NumTraits<Scalar>::MulCost + LhsCoeffReadCost + RhsCoeffReadCost) +// + (InnerSize - 1) * NumTraits<Scalar>::AddCost, /* CanVectorizeInner deserves special explanation. It does not affect the product flags. It is not used outside * of Product. If the Product itself is not a packet-access expression, there is still a chance that the inner @@ -98,25 +100,27 @@ struct ei_traits<GeneralProduct<LhsNested,RhsNested,CoeffBasedProduct> > }; }; -template<typename LhsNested, typename RhsNested> class GeneralProduct<LhsNested,RhsNested,CoeffBasedProduct> +template<typename LhsNested, typename RhsNested, int NestingFlags> +class CoeffBasedProduct : ei_no_assignment_operator, - public MatrixBase<GeneralProduct<LhsNested, RhsNested, CoeffBasedProduct> > + public MatrixBase<CoeffBasedProduct<LhsNested, RhsNested, NestingFlags> > { public: - typedef MatrixBase<GeneralProduct> Base; - EIGEN_DENSE_PUBLIC_INTERFACE(GeneralProduct) + typedef MatrixBase<CoeffBasedProduct> Base; + EIGEN_DENSE_PUBLIC_INTERFACE(CoeffBasedProduct) + typedef typename Base::PlainMatrixType PlainMatrixType; private: - typedef typename ei_traits<GeneralProduct>::_LhsNested _LhsNested; - typedef typename ei_traits<GeneralProduct>::_RhsNested _RhsNested; + typedef typename ei_traits<CoeffBasedProduct>::_LhsNested _LhsNested; + typedef typename ei_traits<CoeffBasedProduct>::_RhsNested _RhsNested; enum { PacketSize = ei_packet_traits<Scalar>::size, - InnerSize = ei_traits<GeneralProduct>::InnerSize, + InnerSize = ei_traits<CoeffBasedProduct>::InnerSize, Unroll = CoeffReadCost <= EIGEN_UNROLLING_LIMIT, - CanVectorizeInner = ei_traits<GeneralProduct>::CanVectorizeInner + CanVectorizeInner = ei_traits<CoeffBasedProduct>::CanVectorizeInner }; typedef ei_product_coeff_impl<CanVectorizeInner ? InnerVectorizedTraversal : DefaultTraversal, @@ -126,7 +130,7 @@ template<typename LhsNested, typename RhsNested> class GeneralProduct<LhsNested, public: template<typename Lhs, typename Rhs> - inline GeneralProduct(const Lhs& lhs, const Rhs& rhs) + inline CoeffBasedProduct(const Lhs& lhs, const Rhs& rhs) : m_lhs(lhs), m_rhs(rhs) { // we don't allow taking products of matrices of different real types, as that wouldn't be vectorizable. @@ -171,11 +175,27 @@ template<typename LhsNested, typename RhsNested> class GeneralProduct<LhsNested, return res; } + // Implicit convertion to the nested type (trigger the evaluation of the product) + operator const PlainMatrixType& () const + { + m_result = *this; + return m_result; + } + protected: const LhsNested m_lhs; const RhsNested m_rhs; + + mutable PlainMatrixType m_result; }; +// here we need to overload the nested rule for products +// such that the nested type is a const reference to a plain matrix +template<typename Lhs, typename Rhs, int N, typename PlainMatrixType> +struct ei_nested<CoeffBasedProduct<Lhs,Rhs,EvalBeforeNestingBit|EvalBeforeAssigningBit>, N, PlainMatrixType> +{ + typedef PlainMatrixType const& type; +}; /*************************************************************************** * Normal product .coeff() implementation (with meta-unrolling) @@ -386,4 +406,4 @@ struct ei_product_packet_impl<ColMajor, Dynamic, Lhs, Rhs, PacketScalar, LoadMod } }; -#endif // EIGEN_GENERAL_UNROLLED_PRODUCT_H +#endif // EIGEN_COEFFBASED_PRODUCT_H |