aboutsummaryrefslogtreecommitdiffhomepage
path: root/Eigen/src/Core/GeneralProduct.h
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2016-12-02 22:41:26 +0100
committerGravatar Gael Guennebaud <g.gael@free.fr>2016-12-02 22:41:26 +0100
commit66f65ccc364034150bdc47333e05ebbde29825e5 (patch)
tree4f2f2fe0e896bbc9d7b727285c715b616f21786a /Eigen/src/Core/GeneralProduct.h
parentfe696022ec2f1a743047d1666f0ef8a92c865f2b (diff)
Ease compiler job to generate clean and efficient code in mat*vec.
Diffstat (limited to 'Eigen/src/Core/GeneralProduct.h')
-rw-r--r--Eigen/src/Core/GeneralProduct.h83
1 files changed, 49 insertions, 34 deletions
diff --git a/Eigen/src/Core/GeneralProduct.h b/Eigen/src/Core/GeneralProduct.h
index f62ecfcbe..0f16cd8e3 100644
--- a/Eigen/src/Core/GeneralProduct.h
+++ b/Eigen/src/Core/GeneralProduct.h
@@ -224,50 +224,65 @@ template<> struct gemv_dense_selector<OnTheRight,ColMajor,true>
// on, the other hand it is good for the cache to pack the vector anyways...
EvalToDestAtCompileTime = (ActualDest::InnerStrideAtCompileTime==1),
ComplexByReal = (NumTraits<LhsScalar>::IsComplex) && (!NumTraits<RhsScalar>::IsComplex),
- MightCannotUseDest = (ActualDest::InnerStrideAtCompileTime!=1) || ComplexByReal
+ MightCannotUseDest = (!EvalToDestAtCompileTime) || ComplexByReal
};
- gemv_static_vector_if<ResScalar,ActualDest::SizeAtCompileTime,ActualDest::MaxSizeAtCompileTime,MightCannotUseDest> static_dest;
+ typedef const_blas_data_mapper<LhsScalar,Index,ColMajor> LhsMapper;
+ typedef const_blas_data_mapper<RhsScalar,Index,RowMajor> RhsMapper;
+ RhsScalar compatibleAlpha = get_factor<ResScalar,RhsScalar>::run(actualAlpha);
- const bool alphaIsCompatible = (!ComplexByReal) || (numext::imag(actualAlpha)==RealScalar(0));
- const bool evalToDest = EvalToDestAtCompileTime && alphaIsCompatible;
+ if(!MightCannotUseDest)
+ {
+ // shortcut if we are sure to be able to use dest directly,
+ // this ease the compiler to generate cleaner and more optimzized code for most common cases
+ general_matrix_vector_product
+ <Index,LhsScalar,LhsMapper,ColMajor,LhsBlasTraits::NeedToConjugate,RhsScalar,RhsMapper,RhsBlasTraits::NeedToConjugate>::run(
+ actualLhs.rows(), actualLhs.cols(),
+ LhsMapper(actualLhs.data(), actualLhs.outerStride()),
+ RhsMapper(actualRhs.data(), actualRhs.innerStride()),
+ dest.data(), 1,
+ compatibleAlpha);
+ }
+ else
+ {
+ gemv_static_vector_if<ResScalar,ActualDest::SizeAtCompileTime,ActualDest::MaxSizeAtCompileTime,MightCannotUseDest> static_dest;
- RhsScalar compatibleAlpha = get_factor<ResScalar,RhsScalar>::run(actualAlpha);
+ const bool alphaIsCompatible = (!ComplexByReal) || (numext::imag(actualAlpha)==RealScalar(0));
+ const bool evalToDest = EvalToDestAtCompileTime && alphaIsCompatible;
- ei_declare_aligned_stack_constructed_variable(ResScalar,actualDestPtr,dest.size(),
- evalToDest ? dest.data() : static_dest.data());
+ ei_declare_aligned_stack_constructed_variable(ResScalar,actualDestPtr,dest.size(),
+ evalToDest ? dest.data() : static_dest.data());
- if(!evalToDest)
- {
- #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
- Index size = dest.size();
- EIGEN_DENSE_STORAGE_CTOR_PLUGIN
- #endif
- if(!alphaIsCompatible)
+ if(!evalToDest)
{
- MappedDest(actualDestPtr, dest.size()).setZero();
- compatibleAlpha = RhsScalar(1);
+ #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
+ Index size = dest.size();
+ EIGEN_DENSE_STORAGE_CTOR_PLUGIN
+ #endif
+ if(!alphaIsCompatible)
+ {
+ MappedDest(actualDestPtr, dest.size()).setZero();
+ compatibleAlpha = RhsScalar(1);
+ }
+ else
+ MappedDest(actualDestPtr, dest.size()) = dest;
}
- else
- MappedDest(actualDestPtr, dest.size()) = dest;
- }
- typedef const_blas_data_mapper<LhsScalar,Index,ColMajor> LhsMapper;
- typedef const_blas_data_mapper<RhsScalar,Index,RowMajor> RhsMapper;
- general_matrix_vector_product
- <Index,LhsScalar,LhsMapper,ColMajor,LhsBlasTraits::NeedToConjugate,RhsScalar,RhsMapper,RhsBlasTraits::NeedToConjugate>::run(
- actualLhs.rows(), actualLhs.cols(),
- LhsMapper(actualLhs.data(), actualLhs.outerStride()),
- RhsMapper(actualRhs.data(), actualRhs.innerStride()),
- actualDestPtr, 1,
- compatibleAlpha);
+ general_matrix_vector_product
+ <Index,LhsScalar,LhsMapper,ColMajor,LhsBlasTraits::NeedToConjugate,RhsScalar,RhsMapper,RhsBlasTraits::NeedToConjugate>::run(
+ actualLhs.rows(), actualLhs.cols(),
+ LhsMapper(actualLhs.data(), actualLhs.outerStride()),
+ RhsMapper(actualRhs.data(), actualRhs.innerStride()),
+ actualDestPtr, 1,
+ compatibleAlpha);
- if (!evalToDest)
- {
- if(!alphaIsCompatible)
- dest.matrix() += actualAlpha * MappedDest(actualDestPtr, dest.size());
- else
- dest = MappedDest(actualDestPtr, dest.size());
+ if (!evalToDest)
+ {
+ if(!alphaIsCompatible)
+ dest.matrix() += actualAlpha * MappedDest(actualDestPtr, dest.size());
+ else
+ dest = MappedDest(actualDestPtr, dest.size());
+ }
}
}
};