mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-08-13 04:09:10 +08:00
Implement A.noalias() = B * C without temporaries
* Wrap expression inside EvalToTemp in copy_using_evaluators() if we assume aliasing for that expression (that is, for products) * Remove temporary kludge of evaluating expression to temporary in AllAtOnce traversal * Implement EvalToTemp expression object
This commit is contained in:
parent
d0b873822f
commit
746378868a
@ -617,12 +617,8 @@ struct copy_using_evaluator_impl<DstXprType, SrcXprType, AllAtOnceTraversal, NoU
|
|||||||
SrcEvaluatorType srcEvaluator(src);
|
SrcEvaluatorType srcEvaluator(src);
|
||||||
|
|
||||||
// Evaluate rhs in temporary to prevent aliasing problems in a = a * a;
|
// Evaluate rhs in temporary to prevent aliasing problems in a = a * a;
|
||||||
// TODO: Be smarter about this
|
|
||||||
// TODO: Do not pass the xpr object to evalTo()
|
// TODO: Do not pass the xpr object to evalTo()
|
||||||
typename DstXprType::PlainObject tmp;
|
srcEvaluator.evalTo(dstEvaluator, dst);
|
||||||
typename evaluator<typename DstXprType::PlainObject>::type tmpEvaluator(tmp);
|
|
||||||
srcEvaluator.evalTo(tmpEvaluator, tmp);
|
|
||||||
copy_using_evaluator(dst, tmp);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -640,11 +636,33 @@ const DstXprType& copy_using_evaluator(const NoAlias<DstXprType, StorageBase>& d
|
|||||||
return noalias_copy_using_evaluator(dst.expression(), src.derived());
|
return noalias_copy_using_evaluator(dst.expression(), src.derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename XprType, int AssumeAliasing = evaluator_traits<XprType>::AssumeAliasing>
|
||||||
|
struct AddEvalIfAssumingAliasing;
|
||||||
|
|
||||||
|
template<typename XprType>
|
||||||
|
struct AddEvalIfAssumingAliasing<XprType, 0>
|
||||||
|
{
|
||||||
|
static const XprType& run(const XprType& xpr)
|
||||||
|
{
|
||||||
|
return xpr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename XprType>
|
||||||
|
struct AddEvalIfAssumingAliasing<XprType, 1>
|
||||||
|
{
|
||||||
|
static const EvalToTemp<XprType> run(const XprType& xpr)
|
||||||
|
{
|
||||||
|
return EvalToTemp<XprType>(xpr);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<typename DstXprType, typename SrcXprType>
|
template<typename DstXprType, typename SrcXprType>
|
||||||
EIGEN_STRONG_INLINE
|
EIGEN_STRONG_INLINE
|
||||||
const DstXprType& copy_using_evaluator(const EigenBase<DstXprType>& dst, const EigenBase<SrcXprType>& src)
|
const DstXprType& copy_using_evaluator(const EigenBase<DstXprType>& dst, const EigenBase<SrcXprType>& src)
|
||||||
{
|
{
|
||||||
return noalias_copy_using_evaluator(dst.const_cast_derived(), src.derived());
|
return noalias_copy_using_evaluator(dst.const_cast_derived(),
|
||||||
|
AddEvalIfAssumingAliasing<SrcXprType>::run(src.derived()));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename DstXprType, typename SrcXprType>
|
template<typename DstXprType, typename SrcXprType>
|
||||||
|
@ -40,6 +40,10 @@ struct evaluator_traits
|
|||||||
// 1 if evaluator_impl<T>::evalTo() exists
|
// 1 if evaluator_impl<T>::evalTo() exists
|
||||||
// 0 if evaluator_impl<T> allows coefficient-based access
|
// 0 if evaluator_impl<T> allows coefficient-based access
|
||||||
static const int HasEvalTo = 0;
|
static const int HasEvalTo = 0;
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
static const int AssumeAliasing = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// expression class for evaluating nested expression to a temporary
|
// expression class for evaluating nested expression to a temporary
|
||||||
@ -245,17 +249,62 @@ struct evaluator_impl<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> >
|
|||||||
|
|
||||||
// -------------------- EvalToTemp --------------------
|
// -------------------- EvalToTemp --------------------
|
||||||
|
|
||||||
|
template<typename ArgType>
|
||||||
|
struct traits<EvalToTemp<ArgType> >
|
||||||
|
: public traits<ArgType>
|
||||||
|
{ };
|
||||||
|
|
||||||
|
template<typename ArgType>
|
||||||
|
class EvalToTemp
|
||||||
|
: public dense_xpr_base<EvalToTemp<ArgType> >::type
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef typename dense_xpr_base<EvalToTemp>::type Base;
|
||||||
|
EIGEN_GENERIC_PUBLIC_INTERFACE(EvalToTemp)
|
||||||
|
|
||||||
|
EvalToTemp(const ArgType& arg)
|
||||||
|
: m_arg(arg)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
const ArgType& arg() const
|
||||||
|
{
|
||||||
|
return m_arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
Index rows() const
|
||||||
|
{
|
||||||
|
return m_arg.rows();
|
||||||
|
}
|
||||||
|
|
||||||
|
Index cols() const
|
||||||
|
{
|
||||||
|
return m_arg.cols();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const ArgType& m_arg;
|
||||||
|
};
|
||||||
|
|
||||||
template<typename ArgType>
|
template<typename ArgType>
|
||||||
struct evaluator_impl<EvalToTemp<ArgType> >
|
struct evaluator_impl<EvalToTemp<ArgType> >
|
||||||
: evaluator_impl<typename ArgType::PlainObject>
|
: evaluator_impl<typename ArgType::PlainObject>
|
||||||
{
|
{
|
||||||
|
typedef EvalToTemp<ArgType> XprType;
|
||||||
typedef typename ArgType::PlainObject PlainObject;
|
typedef typename ArgType::PlainObject PlainObject;
|
||||||
typedef evaluator_impl<PlainObject> BaseType;
|
typedef evaluator_impl<PlainObject> BaseType;
|
||||||
|
|
||||||
|
evaluator_impl(const XprType& xpr)
|
||||||
|
: BaseType(m_result)
|
||||||
|
{
|
||||||
|
noalias_copy_using_evaluator(m_result, xpr.arg());
|
||||||
|
};
|
||||||
|
|
||||||
|
// this constructor is used when nesting an EvalTo evaluator in another evaluator
|
||||||
evaluator_impl(const ArgType& arg)
|
evaluator_impl(const ArgType& arg)
|
||||||
: BaseType(m_result)
|
: BaseType(m_result)
|
||||||
{
|
{
|
||||||
copy_using_evaluator(m_result, arg);
|
noalias_copy_using_evaluator(m_result, arg);
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -56,7 +56,9 @@ struct product_evaluator_traits_dispatcher;
|
|||||||
template<typename Lhs, typename Rhs>
|
template<typename Lhs, typename Rhs>
|
||||||
struct evaluator_traits<Product<Lhs, Rhs> >
|
struct evaluator_traits<Product<Lhs, Rhs> >
|
||||||
: product_evaluator_traits_dispatcher<Product<Lhs, Rhs>, typename ProductReturnType<Lhs, Rhs>::Type>
|
: product_evaluator_traits_dispatcher<Product<Lhs, Rhs>, typename ProductReturnType<Lhs, Rhs>::Type>
|
||||||
{ };
|
{
|
||||||
|
static const int AssumeAliasing = 1;
|
||||||
|
};
|
||||||
|
|
||||||
// Case 1: Evaluate all at once
|
// Case 1: Evaluate all at once
|
||||||
//
|
//
|
||||||
|
Loading…
x
Reference in New Issue
Block a user