Make redux_vec_unroller more flexible regarding packet-type

This commit is contained in:
Gael Guennebaud 2018-10-09 23:30:41 +02:00
parent c0c3be26ed
commit bfa2a81a50

View File

@ -145,38 +145,36 @@ struct redux_novec_unroller<Func, Evaluator, Start, 0>
template<typename Func, typename Evaluator, int Start, int Length> template<typename Func, typename Evaluator, int Start, int Length>
struct redux_vec_unroller struct redux_vec_unroller
{ {
enum { template<typename PacketType>
PacketSize = redux_traits<Func, Evaluator>::PacketSize, EIGEN_DEVICE_FUNC
HalfLength = Length/2 static EIGEN_STRONG_INLINE PacketType run(const Evaluator &eval, const Func& func)
};
typedef typename Evaluator::Scalar Scalar;
typedef typename redux_traits<Func, Evaluator>::PacketType PacketScalar;
static EIGEN_STRONG_INLINE PacketScalar run(const Evaluator &eval, const Func& func)
{ {
enum {
PacketSize = unpacket_traits<PacketType>::size,
HalfLength = Length/2
};
return func.packetOp( return func.packetOp(
redux_vec_unroller<Func, Evaluator, Start, HalfLength>::run(eval,func), redux_vec_unroller<Func, Evaluator, Start, HalfLength>::template run<PacketType>(eval,func),
redux_vec_unroller<Func, Evaluator, Start+HalfLength, Length-HalfLength>::run(eval,func) ); redux_vec_unroller<Func, Evaluator, Start+HalfLength, Length-HalfLength>::template run<PacketType>(eval,func) );
} }
}; };
template<typename Func, typename Evaluator, int Start> template<typename Func, typename Evaluator, int Start>
struct redux_vec_unroller<Func, Evaluator, Start, 1> struct redux_vec_unroller<Func, Evaluator, Start, 1>
{ {
enum { template<typename PacketType>
index = Start * redux_traits<Func, Evaluator>::PacketSize, EIGEN_DEVICE_FUNC
outer = index / int(Evaluator::InnerSizeAtCompileTime), static EIGEN_STRONG_INLINE PacketType run(const Evaluator &eval, const Func&)
inner = index % int(Evaluator::InnerSizeAtCompileTime),
alignment = Evaluator::Alignment
};
typedef typename Evaluator::Scalar Scalar;
typedef typename redux_traits<Func, Evaluator>::PacketType PacketScalar;
static EIGEN_STRONG_INLINE PacketScalar run(const Evaluator &eval, const Func&)
{ {
return eval.template packetByOuterInner<alignment,PacketScalar>(outer, inner); enum {
PacketSize = unpacket_traits<PacketType>::size,
index = Start * PacketSize,
outer = index / int(Evaluator::InnerSizeAtCompileTime),
inner = index % int(Evaluator::InnerSizeAtCompileTime),
alignment = Evaluator::Alignment
};
return eval.template packetByOuterInner<alignment,PacketType>(outer, inner);
} }
}; };
@ -329,7 +327,7 @@ struct redux_impl<Func, Evaluator, LinearVectorizedTraversal, CompleteUnrolling>
{ {
typedef typename Evaluator::Scalar Scalar; typedef typename Evaluator::Scalar Scalar;
typedef typename redux_traits<Func, Evaluator>::PacketType PacketScalar; typedef typename redux_traits<Func, Evaluator>::PacketType PacketType;
enum { enum {
PacketSize = redux_traits<Func, Evaluator>::PacketSize, PacketSize = redux_traits<Func, Evaluator>::PacketSize,
Size = Evaluator::SizeAtCompileTime, Size = Evaluator::SizeAtCompileTime,
@ -343,7 +341,7 @@ struct redux_impl<Func, Evaluator, LinearVectorizedTraversal, CompleteUnrolling>
EIGEN_ONLY_USED_FOR_DEBUG(xpr) EIGEN_ONLY_USED_FOR_DEBUG(xpr)
eigen_assert(xpr.rows()>0 && xpr.cols()>0 && "you are using an empty matrix"); eigen_assert(xpr.rows()>0 && xpr.cols()>0 && "you are using an empty matrix");
if (VectorizedSize > 0) { if (VectorizedSize > 0) {
Scalar res = func.predux(redux_vec_unroller<Func, Evaluator, 0, Size / PacketSize>::run(eval,func)); Scalar res = func.predux(redux_vec_unroller<Func, Evaluator, 0, Size / PacketSize>::template run<PacketType>(eval,func));
if (VectorizedSize != Size) if (VectorizedSize != Size)
res = func(res,redux_novec_unroller<Func, Evaluator, VectorizedSize, Size-VectorizedSize>::run(eval,func)); res = func(res,redux_novec_unroller<Func, Evaluator, VectorizedSize, Size-VectorizedSize>::run(eval,func));
return res; return res;