mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Evaluators: add Block evaluator as dumb wrapper, add slice vectorization.
This commit is contained in:
@@ -289,6 +289,64 @@ struct copy_using_evaluator_impl<DstXprType, SrcXprType, LinearTraversal, NoUnro
|
||||
}
|
||||
};
|
||||
|
||||
/**************************
|
||||
*** Slice vectorization ***
|
||||
***************************/
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
struct copy_using_evaluator_impl<DstXprType, SrcXprType, SliceVectorizedTraversal, 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);
|
||||
|
||||
typedef packet_traits<typename DstXprType::Scalar> PacketTraits;
|
||||
enum {
|
||||
packetSize = PacketTraits::size,
|
||||
alignable = PacketTraits::AlignedOnScalar,
|
||||
dstAlignment = alignable ? Aligned : int(assign_traits<DstXprType,SrcXprType>::DstIsAligned) ,
|
||||
srcAlignment = assign_traits<DstXprType,SrcXprType>::JointAlignment
|
||||
};
|
||||
const Index packetAlignedMask = packetSize - 1;
|
||||
const Index innerSize = dst.innerSize();
|
||||
const Index outerSize = dst.outerSize();
|
||||
const Index alignedStep = alignable ? (packetSize - dst.outerStride() % packetSize) & packetAlignedMask : 0;
|
||||
Index alignedStart = ((!alignable) || assign_traits<DstXprType,SrcXprType>::DstIsAligned) ? 0
|
||||
: first_aligned(&dstEvaluator.coeffRef(0,0), innerSize);
|
||||
|
||||
for(Index outer = 0; outer < outerSize; ++outer)
|
||||
{
|
||||
const Index alignedEnd = alignedStart + ((innerSize-alignedStart) & ~packetAlignedMask);
|
||||
// do the non-vectorizable part of the assignment
|
||||
for(Index inner = 0; inner<alignedStart ; ++inner) {
|
||||
Index row = dst.rowIndexByOuterInner(outer, inner);
|
||||
Index col = dst.colIndexByOuterInner(outer, inner);
|
||||
dstEvaluator.coeffRef(row, col) = srcEvaluator.coeff(row, col);
|
||||
}
|
||||
|
||||
// do the vectorizable part of the assignment
|
||||
for(Index inner = alignedStart; inner<alignedEnd; inner+=packetSize) {
|
||||
Index row = dst.rowIndexByOuterInner(outer, inner);
|
||||
Index col = dst.colIndexByOuterInner(outer, inner);
|
||||
dstEvaluator.template writePacket<dstAlignment>(row, col, srcEvaluator.template packet<srcAlignment>(row, col));
|
||||
}
|
||||
|
||||
// do the non-vectorizable part of the assignment
|
||||
for(Index inner = alignedEnd; inner<innerSize ; ++inner) {
|
||||
Index row = dst.rowIndexByOuterInner(outer, inner);
|
||||
Index col = dst.colIndexByOuterInner(outer, inner);
|
||||
dstEvaluator.coeffRef(row, col) = srcEvaluator.coeff(row, col);
|
||||
}
|
||||
|
||||
alignedStart = std::min<Index>((alignedStart+alignedStep)%packetSize, innerSize);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Based on DenseBase::LazyAssign()
|
||||
|
||||
|
||||
@@ -368,6 +368,73 @@ protected:
|
||||
PlainObject m_result;
|
||||
};
|
||||
|
||||
// -------------------- Block --------------------
|
||||
//
|
||||
// This evaluator is implemented as a dumb wrapper around Block expression class.
|
||||
// TODO: Make this a real evaluator
|
||||
|
||||
template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, bool HasDirectAccess>
|
||||
struct evaluator_impl<Block<XprType, BlockRows, BlockCols, InnerPanel, HasDirectAccess> >
|
||||
{
|
||||
typedef Block<XprType, BlockRows, BlockCols, InnerPanel, HasDirectAccess> BlockType;
|
||||
evaluator_impl(const BlockType& block) : m_block(block) { }
|
||||
|
||||
typedef typename BlockType::Index Index;
|
||||
typedef typename BlockType::Scalar Scalar;
|
||||
typedef typename BlockType::CoeffReturnType CoeffReturnType;
|
||||
typedef typename BlockType::PacketScalar PacketScalar;
|
||||
typedef typename BlockType::PacketReturnType PacketReturnType;
|
||||
|
||||
|
||||
CoeffReturnType coeff(Index i, Index j) const
|
||||
{
|
||||
return m_block.coeff(i,j);
|
||||
}
|
||||
|
||||
CoeffReturnType coeff(Index index) const
|
||||
{
|
||||
return m_block.coeff(index);
|
||||
}
|
||||
|
||||
Scalar& coeffRef(Index i, Index j)
|
||||
{
|
||||
return m_block.const_cast_derived().coeffRef(i,j);
|
||||
}
|
||||
|
||||
Scalar& coeffRef(Index index)
|
||||
{
|
||||
return m_block.const_cast_derived().coeffRef(index);
|
||||
}
|
||||
|
||||
template<int LoadMode>
|
||||
PacketReturnType packet(Index row, Index col) const
|
||||
{
|
||||
return m_block.template packet<LoadMode>(row, col);
|
||||
}
|
||||
|
||||
template<int LoadMode>
|
||||
PacketReturnType packet(Index index) const
|
||||
{
|
||||
return m_block.template packet<LoadMode>(index);
|
||||
}
|
||||
|
||||
template<int StoreMode>
|
||||
void writePacket(Index row, Index col, const PacketScalar& x)
|
||||
{
|
||||
m_block.const_cast_derived().template writePacket<StoreMode>(row, col, x);
|
||||
}
|
||||
|
||||
template<int StoreMode>
|
||||
void writePacket(Index index, const PacketScalar& x)
|
||||
{
|
||||
m_block.const_cast_derived().template writePacket<StoreMode>(index, x);
|
||||
}
|
||||
|
||||
protected:
|
||||
const BlockType& m_block;
|
||||
};
|
||||
|
||||
|
||||
} // namespace internal
|
||||
|
||||
#endif // EIGEN_COREEVALUATORS_H
|
||||
|
||||
Reference in New Issue
Block a user