mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-02-11 18:00:51 +08:00
Evaluators: Implement linear traversal, better testing.
This commit is contained in:
parent
1b17a674dd
commit
b175bc464f
@ -78,8 +78,8 @@ public:
|
||||
enum {
|
||||
Traversal = int(MayInnerVectorize) ? int(InnerVectorizedTraversal)
|
||||
: int(MayLinearVectorize) ? int(LinearVectorizedTraversal)
|
||||
: int(MaySliceVectorize) ? int(DefaultTraversal) // int(SliceVectorizedTraversal)
|
||||
: int(MayLinearize) ? int(DefaultTraversal) // int(LinearTraversal)
|
||||
: int(MaySliceVectorize) ? int(SliceVectorizedTraversal)
|
||||
: int(MayLinearize) ? int(LinearTraversal)
|
||||
: int(DefaultTraversal),
|
||||
Vectorized = int(Traversal) == InnerVectorizedTraversal
|
||||
|| int(Traversal) == LinearVectorizedTraversal
|
||||
@ -264,12 +264,37 @@ struct copy_using_evaluator_impl<DstXprType, SrcXprType, InnerVectorizedTraversa
|
||||
}
|
||||
};
|
||||
|
||||
/***********************
|
||||
*** Linear traversal ***
|
||||
***********************/
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
struct copy_using_evaluator_impl<DstXprType, SrcXprType, LinearTraversal, NoUnrolling>
|
||||
{
|
||||
inline static void run(const 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.const_cast_derived());
|
||||
SrcEvaluatorType srcEvaluator(src);
|
||||
|
||||
const Index size = dst.size();
|
||||
for(Index i = 0; i < size; ++i)
|
||||
dstEvaluator.coeffRef(i) = srcEvaluator.coeff(i); // TODO: use copyCoeff ?
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Based on DenseBase::LazyAssign()
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
const DstXprType& copy_using_evaluator(const DstXprType& dst, const SrcXprType& src)
|
||||
{
|
||||
#ifdef EIGEN_DEBUG_ASSIGN
|
||||
internal::copy_using_evaluator_traits<DstXprType, SrcXprType>::debug();
|
||||
#endif
|
||||
copy_using_evaluator_impl<DstXprType, SrcXprType>::run(dst, src);
|
||||
return dst;
|
||||
}
|
||||
|
@ -60,11 +60,21 @@ struct evaluator_impl<Transpose<ExpressionType> >
|
||||
return m_argImpl.coeff(j, i);
|
||||
}
|
||||
|
||||
typename TransposeType::CoeffReturnType coeff(Index index) const
|
||||
{
|
||||
return m_argImpl.coeff(index);
|
||||
}
|
||||
|
||||
typename TransposeType::Scalar& coeffRef(Index i, Index j)
|
||||
{
|
||||
return m_argImpl.coeffRef(j, i);
|
||||
}
|
||||
|
||||
typename TransposeType::Scalar& coeffRef(Index index)
|
||||
{
|
||||
return m_argImpl.coeffRef(index);
|
||||
}
|
||||
|
||||
template<int LoadMode>
|
||||
const typename ExpressionType::PacketScalar packet(Index index) const
|
||||
{
|
||||
@ -79,12 +89,11 @@ struct evaluator_impl<Transpose<ExpressionType> >
|
||||
return m_argImpl.template packetByOuterInner<LoadMode>(outer, inner);
|
||||
}
|
||||
|
||||
// TODO: Is this function needed?
|
||||
// template<int StoreMode>
|
||||
// void writePacket(Index index, const typename ExpressionType::PacketScalar& x)
|
||||
// {
|
||||
// m_argImpl.template writePacket<StoreMode>(index, x);
|
||||
// }
|
||||
template<int StoreMode>
|
||||
void writePacket(Index index, const typename ExpressionType::PacketScalar& x)
|
||||
{
|
||||
m_argImpl.template writePacket<StoreMode>(index, x);
|
||||
}
|
||||
|
||||
template<int StoreMode>
|
||||
void writePacketByOuterInner(Index outer, Index inner, const typename ExpressionType::PacketScalar& x)
|
||||
@ -122,11 +131,21 @@ struct evaluator_impl<Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> >
|
||||
return m_matrix.coeff(i, j);
|
||||
}
|
||||
|
||||
typename MatrixType::CoeffReturnType coeff(Index index) const
|
||||
{
|
||||
return m_matrix.coeff(index);
|
||||
}
|
||||
|
||||
typename MatrixType::Scalar& coeffRef(Index i, Index j)
|
||||
{
|
||||
return m_matrix.const_cast_derived().coeffRef(i, j);
|
||||
}
|
||||
|
||||
typename MatrixType::Scalar& coeffRef(Index index)
|
||||
{
|
||||
return m_matrix.const_cast_derived().coeffRef(index);
|
||||
}
|
||||
|
||||
template<int LoadMode>
|
||||
typename MatrixType::PacketReturnType packet(Index index) const
|
||||
{
|
||||
@ -191,6 +210,11 @@ struct evaluator_impl<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> >
|
||||
return m_array.const_cast_derived().coeffRef(i, j);
|
||||
}
|
||||
|
||||
typename ArrayType::Scalar& coeffRef(Index index)
|
||||
{
|
||||
return m_array.const_cast_derived().coeffRef(index);
|
||||
}
|
||||
|
||||
template<int LoadMode>
|
||||
typename ArrayType::PacketReturnType packet(Index index) const
|
||||
{
|
||||
@ -243,6 +267,11 @@ struct evaluator_impl<CwiseNullaryOp<NullaryOp,PlainObjectType> >
|
||||
return m_nullaryOp.coeff(i, j);
|
||||
}
|
||||
|
||||
typename NullaryOpType::CoeffReturnType coeff(Index index) const
|
||||
{
|
||||
return m_nullaryOp.coeff(index);
|
||||
}
|
||||
|
||||
template<int LoadMode>
|
||||
typename NullaryOpType::PacketScalar packet(Index index) const
|
||||
{
|
||||
@ -269,6 +298,11 @@ struct evaluator_impl<CwiseUnaryOp<UnaryOp, ArgType> >
|
||||
return m_unaryOp.functor()(m_argImpl.coeff(i, j));
|
||||
}
|
||||
|
||||
typename UnaryOpType::CoeffReturnType coeff(Index index) const
|
||||
{
|
||||
return m_unaryOp.functor()(m_argImpl.coeff(index));
|
||||
}
|
||||
|
||||
template<int LoadMode>
|
||||
typename UnaryOpType::PacketScalar packet(Index index) const
|
||||
{
|
||||
@ -309,6 +343,11 @@ struct evaluator_impl<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
|
||||
return m_binaryOp.functor()(m_lhsImpl.coeff(i, j), m_rhsImpl.coeff(i, j));
|
||||
}
|
||||
|
||||
typename BinaryOpType::CoeffReturnType coeff(Index index) const
|
||||
{
|
||||
return m_binaryOp.functor()(m_lhsImpl.coeff(index), m_rhsImpl.coeff(index));
|
||||
}
|
||||
|
||||
template<int LoadMode>
|
||||
typename BinaryOpType::PacketScalar packet(Index index) const
|
||||
{
|
||||
@ -316,6 +355,20 @@ struct evaluator_impl<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
|
||||
m_rhsImpl.template packet<LoadMode>(index));
|
||||
}
|
||||
|
||||
template<int LoadMode>
|
||||
typename BinaryOpType::PacketScalar packet(Index row, Index col) const
|
||||
{
|
||||
return m_binaryOp.functor().packetOp(m_lhsImpl.template packet<LoadMode>(row, col),
|
||||
m_rhsImpl.template packet<LoadMode>(row, col));
|
||||
}
|
||||
|
||||
template<int LoadMode>
|
||||
typename BinaryOpType::PacketScalar packetByOuterInner(Index outer, Index inner) const
|
||||
{
|
||||
return packet<LoadMode>(m_lhsImpl.rowIndexByOuterInner(outer, inner),
|
||||
m_lhsImpl.colIndexByOuterInner(outer, inner));
|
||||
}
|
||||
|
||||
protected:
|
||||
const BinaryOpType& m_binaryOp;
|
||||
typename evaluator<Lhs>::type m_lhsImpl;
|
||||
|
@ -89,4 +89,40 @@ void test_evaluators()
|
||||
ArrayXXd arr1(6,6), arr2(6,6);
|
||||
VERIFY_IS_APPROX_EVALUATOR(arr1, ArrayXXd::Constant(6,6, 3.0));
|
||||
VERIFY_IS_APPROX_EVALUATOR(arr2, arr1);
|
||||
|
||||
// test direct traversal
|
||||
Matrix3f m3;
|
||||
Array33f a3;
|
||||
VERIFY_IS_APPROX_EVALUATOR(m3, Matrix3f::Identity()); // matrix, nullary
|
||||
// TODO: find a way to test direct traversal with array
|
||||
VERIFY_IS_APPROX_EVALUATOR(m3.transpose(), Matrix3f::Identity().transpose()); // transpose
|
||||
VERIFY_IS_APPROX_EVALUATOR(m3, 2 * Matrix3f::Identity()); // unary
|
||||
VERIFY_IS_APPROX_EVALUATOR(m3, Matrix3f::Identity() + m3); // binary
|
||||
|
||||
// test linear traversal
|
||||
VERIFY_IS_APPROX_EVALUATOR(m3, Matrix3f::Zero()); // matrix, nullary
|
||||
VERIFY_IS_APPROX_EVALUATOR(a3, Array33f::Zero()); // array
|
||||
VERIFY_IS_APPROX_EVALUATOR(m3.transpose(), Matrix3f::Zero().transpose()); // transpose
|
||||
VERIFY_IS_APPROX_EVALUATOR(m3, 2 * Matrix3f::Zero()); // unary
|
||||
VERIFY_IS_APPROX_EVALUATOR(m3, Matrix3f::Zero() + m3); // binary
|
||||
|
||||
// test inner vectorization
|
||||
Matrix4f m4, m4src = Matrix4f::Random();
|
||||
Array44f a4, a4src = Matrix4f::Random();
|
||||
VERIFY_IS_APPROX_EVALUATOR(m4, m4src); // matrix
|
||||
VERIFY_IS_APPROX_EVALUATOR(a4, a4src); // array
|
||||
VERIFY_IS_APPROX_EVALUATOR(m4.transpose(), m4src.transpose()); // transpose
|
||||
// TODO: find out why Matrix4f::Zero() does not allow inner vectorization
|
||||
VERIFY_IS_APPROX_EVALUATOR(m4, 2 * m4src); // unary
|
||||
VERIFY_IS_APPROX_EVALUATOR(m4, m4src + m4src); // binary
|
||||
|
||||
// test linear vectorization
|
||||
MatrixXf mX(6,6), mXsrc = MatrixXf::Random(6,6);
|
||||
ArrayXXf aX(6,6), aXsrc = MatrixXf::Random(6,6);
|
||||
VERIFY_IS_APPROX_EVALUATOR(mX, mXsrc); // matrix
|
||||
VERIFY_IS_APPROX_EVALUATOR(aX, aXsrc); // array
|
||||
VERIFY_IS_APPROX_EVALUATOR(mX.transpose(), mXsrc.transpose()); // transpose
|
||||
VERIFY_IS_APPROX_EVALUATOR(mX, MatrixXf::Zero(6,6)); // nullary
|
||||
VERIFY_IS_APPROX_EVALUATOR(mX, 2 * mXsrc); // unary
|
||||
VERIFY_IS_APPROX_EVALUATOR(mX, mXsrc + mXsrc); // binary
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user