Implement eval-at-once in evaluator.

- Add evaluator_traits with HasEvalTo flag, which is true if evaluator
  has evalTo() function.
- Add AllAtOnce traversal, which calls evalTo() in evaluator.
- If source evaluator in copy_using_evaluator has HasEvalTo set, then
  use AllAtOnce traversal.
This commit is contained in:
Jitse Niesen 2012-06-29 13:32:12 +01:00
parent c1eb820e50
commit 2393ceb380
3 changed files with 44 additions and 9 deletions

View File

@ -38,7 +38,6 @@ namespace internal {
***************************************************************************/ ***************************************************************************/
// copy_using_evaluator_traits is based on assign_traits // copy_using_evaluator_traits is based on assign_traits
// (actually, it's identical)
template <typename Derived, typename OtherDerived> template <typename Derived, typename OtherDerived>
struct copy_using_evaluator_traits struct copy_using_evaluator_traits
@ -48,7 +47,8 @@ public:
DstIsAligned = Derived::Flags & AlignedBit, DstIsAligned = Derived::Flags & AlignedBit,
DstHasDirectAccess = Derived::Flags & DirectAccessBit, DstHasDirectAccess = Derived::Flags & DirectAccessBit,
SrcIsAligned = OtherDerived::Flags & AlignedBit, SrcIsAligned = OtherDerived::Flags & AlignedBit,
JointAlignment = bool(DstIsAligned) && bool(SrcIsAligned) ? Aligned : Unaligned JointAlignment = bool(DstIsAligned) && bool(SrcIsAligned) ? Aligned : Unaligned,
SrcEvalBeforeAssign = (evaluator_traits<OtherDerived>::HasEvalTo == 1)
}; };
private: private:
@ -83,11 +83,12 @@ private:
public: public:
enum { enum {
Traversal = int(MayInnerVectorize) ? int(InnerVectorizedTraversal) Traversal = int(SrcEvalBeforeAssign) ? int(AllAtOnceTraversal)
: int(MayLinearVectorize) ? int(LinearVectorizedTraversal) : int(MayInnerVectorize) ? int(InnerVectorizedTraversal)
: int(MaySliceVectorize) ? int(SliceVectorizedTraversal) : int(MayLinearVectorize) ? int(LinearVectorizedTraversal)
: int(MayLinearize) ? int(LinearTraversal) : int(MaySliceVectorize) ? int(SliceVectorizedTraversal)
: int(DefaultTraversal), : int(MayLinearize) ? int(LinearTraversal)
: int(DefaultTraversal),
Vectorized = int(Traversal) == InnerVectorizedTraversal Vectorized = int(Traversal) == InnerVectorizedTraversal
|| int(Traversal) == LinearVectorizedTraversal || int(Traversal) == LinearVectorizedTraversal
|| int(Traversal) == SliceVectorizedTraversal || int(Traversal) == SliceVectorizedTraversal
@ -599,6 +600,26 @@ struct copy_using_evaluator_impl<DstXprType, SrcXprType, SliceVectorizedTraversa
} }
}; };
/****************************
*** All-at-once traversal ***
****************************/
template<typename DstXprType, typename SrcXprType>
struct copy_using_evaluator_impl<DstXprType, SrcXprType, AllAtOnceTraversal, NoUnrolling>
{
inline static void run(DstXprType &dst, const SrcXprType &src)
{
typedef typename evaluator<DstXprType>::type DstEvaluatorType;
typedef typename evaluator<SrcXprType>::type SrcEvaluatorType;
typedef typename DstXprType::Index Index;
DstEvaluatorType dstEvaluator(dst);
SrcEvaluatorType srcEvaluator(src);
srcEvaluator.evalTo(dstEvaluator);
}
};
/*************************************************************************** /***************************************************************************
* Part 4 : Entry points * Part 4 : Entry points
***************************************************************************/ ***************************************************************************/

View File

@ -31,7 +31,19 @@
namespace Eigen { namespace Eigen {
namespace internal { namespace internal {
// evaluator_traits<T> contains traits for evaluator_impl<T>
template<typename T>
struct evaluator_traits
{
// 1 if evaluator_impl<T>::evalTo() exists
// 0 if evaluator_impl<T> allows coefficient-based access
static const int HasEvalTo = 0;
};
// evaluator<T>::type is type of evaluator for T
template<typename T> template<typename T>
struct evaluator_impl {}; struct evaluator_impl {};

View File

@ -242,7 +242,9 @@ enum {
* scalar loops to handle the unaligned boundaries */ * scalar loops to handle the unaligned boundaries */
SliceVectorizedTraversal, SliceVectorizedTraversal,
/** \internal Special case to properly handle incompatible scalar types or other defecting cases*/ /** \internal Special case to properly handle incompatible scalar types or other defecting cases*/
InvalidTraversal InvalidTraversal,
/** \internal Evaluate all entries at once */
AllAtOnceTraversal
}; };
/** \internal \ingroup enums /** \internal \ingroup enums