mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-01-06 14:14:46 +08:00
Pulled latest update from trunk
This commit is contained in:
commit
faa2ff99c6
@ -329,6 +329,7 @@ template<> struct gemv_dense_selector<OnTheRight,ColMajor,false>
|
|||||||
template<typename Lhs, typename Rhs, typename Dest>
|
template<typename Lhs, typename Rhs, typename Dest>
|
||||||
static void run(const Lhs &lhs, const Rhs &rhs, Dest& dest, const typename Dest::Scalar& alpha)
|
static void run(const Lhs &lhs, const Rhs &rhs, Dest& dest, const typename Dest::Scalar& alpha)
|
||||||
{
|
{
|
||||||
|
EIGEN_STATIC_ASSERT((!nested_eval<Lhs,1>::Evaluate),EIGEN_INTERNAL_COMPILATION_ERROR_OR_YOU_MADE_A_PROGRAMMING_MISTAKE);
|
||||||
// TODO if rhs is large enough it might be beneficial to make sure that dest is sequentially stored in memory, otherwise use a temp
|
// TODO if rhs is large enough it might be beneficial to make sure that dest is sequentially stored in memory, otherwise use a temp
|
||||||
typename nested_eval<Rhs,1>::type actual_rhs(rhs);
|
typename nested_eval<Rhs,1>::type actual_rhs(rhs);
|
||||||
const Index size = rhs.rows();
|
const Index size = rhs.rows();
|
||||||
@ -342,6 +343,7 @@ template<> struct gemv_dense_selector<OnTheRight,RowMajor,false>
|
|||||||
template<typename Lhs, typename Rhs, typename Dest>
|
template<typename Lhs, typename Rhs, typename Dest>
|
||||||
static void run(const Lhs &lhs, const Rhs &rhs, Dest& dest, const typename Dest::Scalar& alpha)
|
static void run(const Lhs &lhs, const Rhs &rhs, Dest& dest, const typename Dest::Scalar& alpha)
|
||||||
{
|
{
|
||||||
|
EIGEN_STATIC_ASSERT((!nested_eval<Lhs,1>::Evaluate),EIGEN_INTERNAL_COMPILATION_ERROR_OR_YOU_MADE_A_PROGRAMMING_MISTAKE);
|
||||||
typename nested_eval<Rhs,Lhs::RowsAtCompileTime>::type actual_rhs(rhs);
|
typename nested_eval<Rhs,Lhs::RowsAtCompileTime>::type actual_rhs(rhs);
|
||||||
const Index rows = dest.rows();
|
const Index rows = dest.rows();
|
||||||
for(Index i=0; i<rows; ++i)
|
for(Index i=0; i<rows; ++i)
|
||||||
|
@ -366,17 +366,22 @@ template<typename Lhs, typename Rhs>
|
|||||||
struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,GemvProduct>
|
struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,GemvProduct>
|
||||||
: generic_product_impl_base<Lhs,Rhs,generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,GemvProduct> >
|
: generic_product_impl_base<Lhs,Rhs,generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,GemvProduct> >
|
||||||
{
|
{
|
||||||
|
typedef typename nested_eval<Lhs,1>::type LhsNested;
|
||||||
|
typedef typename nested_eval<Rhs,1>::type RhsNested;
|
||||||
typedef typename Product<Lhs,Rhs>::Scalar Scalar;
|
typedef typename Product<Lhs,Rhs>::Scalar Scalar;
|
||||||
enum { Side = Lhs::IsVectorAtCompileTime ? OnTheLeft : OnTheRight };
|
enum { Side = Lhs::IsVectorAtCompileTime ? OnTheLeft : OnTheRight };
|
||||||
typedef typename internal::conditional<int(Side)==OnTheRight,Lhs,Rhs>::type MatrixType;
|
typedef typename internal::remove_all<typename internal::conditional<int(Side)==OnTheRight,LhsNested,RhsNested>::type>::type MatrixType;
|
||||||
|
|
||||||
template<typename Dest>
|
template<typename Dest>
|
||||||
static EIGEN_STRONG_INLINE void scaleAndAddTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
|
static EIGEN_STRONG_INLINE void scaleAndAddTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
|
||||||
{
|
{
|
||||||
|
LhsNested actual_lhs(lhs);
|
||||||
|
RhsNested actual_rhs(rhs);
|
||||||
|
|
||||||
internal::gemv_dense_selector<Side,
|
internal::gemv_dense_selector<Side,
|
||||||
(int(MatrixType::Flags)&RowMajorBit) ? RowMajor : ColMajor,
|
(int(MatrixType::Flags)&RowMajorBit) ? RowMajor : ColMajor,
|
||||||
bool(internal::blas_traits<MatrixType>::HasUsableDirectAccess)
|
bool(internal::blas_traits<MatrixType>::HasUsableDirectAccess)
|
||||||
>::run(lhs, rhs, dst, alpha);
|
>::run(actual_lhs, actual_rhs, dst, alpha);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -173,6 +173,13 @@ template<typename Scalar, typename PacketType,typename IndexType>
|
|||||||
struct has_unary_operator<linspaced_op<Scalar,PacketType>,IndexType> { enum { value = 1}; };
|
struct has_unary_operator<linspaced_op<Scalar,PacketType>,IndexType> { enum { value = 1}; };
|
||||||
template<typename Scalar, typename PacketType,typename IndexType>
|
template<typename Scalar, typename PacketType,typename IndexType>
|
||||||
struct has_binary_operator<linspaced_op<Scalar,PacketType>,IndexType> { enum { value = 0}; };
|
struct has_binary_operator<linspaced_op<Scalar,PacketType>,IndexType> { enum { value = 0}; };
|
||||||
|
|
||||||
|
template<typename Scalar,typename IndexType>
|
||||||
|
struct has_nullary_operator<scalar_random_op<Scalar>,IndexType> { enum { value = 1}; };
|
||||||
|
template<typename Scalar,typename IndexType>
|
||||||
|
struct has_unary_operator<scalar_random_op<Scalar>,IndexType> { enum { value = 0}; };
|
||||||
|
template<typename Scalar,typename IndexType>
|
||||||
|
struct has_binary_operator<scalar_random_op<Scalar>,IndexType> { enum { value = 0}; };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
@ -445,15 +445,11 @@ template<typename T, int n, typename PlainObject = typename plain_object_eval<T>
|
|||||||
// Another solution could be to count the number of temps?
|
// Another solution could be to count the number of temps?
|
||||||
NAsInteger = n == Dynamic ? HugeCost : n,
|
NAsInteger = n == Dynamic ? HugeCost : n,
|
||||||
CostEval = (NAsInteger+1) * ScalarReadCost + CoeffReadCost,
|
CostEval = (NAsInteger+1) * ScalarReadCost + CoeffReadCost,
|
||||||
CostNoEval = NAsInteger * CoeffReadCost
|
CostNoEval = NAsInteger * CoeffReadCost,
|
||||||
|
Evaluate = (int(evaluator<T>::Flags) & EvalBeforeNestingBit) || (int(CostEval) < int(CostNoEval))
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef typename conditional<
|
typedef typename conditional<Evaluate, PlainObject, typename ref_selector<T>::type>::type type;
|
||||||
( (int(evaluator<T>::Flags) & EvalBeforeNestingBit) ||
|
|
||||||
(int(CostEval) < int(CostNoEval)) ),
|
|
||||||
PlainObject,
|
|
||||||
typename ref_selector<T>::type
|
|
||||||
>::type type;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -136,6 +136,10 @@ template<typename MatrixType> void product_notemporary(const MatrixType& m)
|
|||||||
VERIFY_EVALUATION_COUNT( rm3.noalias() -= (cv1) * (rv1 * m1), 1 );
|
VERIFY_EVALUATION_COUNT( rm3.noalias() -= (cv1) * (rv1 * m1), 1 );
|
||||||
VERIFY_EVALUATION_COUNT( rm3.noalias() = (m1*cv1) * (rv1 * m1), 2 );
|
VERIFY_EVALUATION_COUNT( rm3.noalias() = (m1*cv1) * (rv1 * m1), 2 );
|
||||||
VERIFY_EVALUATION_COUNT( rm3.noalias() += (m1*cv1) * (rv1 * m1), 2 );
|
VERIFY_EVALUATION_COUNT( rm3.noalias() += (m1*cv1) * (rv1 * m1), 2 );
|
||||||
|
|
||||||
|
// Check nested products
|
||||||
|
VERIFY_EVALUATION_COUNT( cvres.noalias() = m1.adjoint() * m1 * cv1, 1 );
|
||||||
|
VERIFY_EVALUATION_COUNT( rvres.noalias() = rv1 * (m1 * m2.adjoint()), 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_product_notemporary()
|
void test_product_notemporary()
|
||||||
|
Loading…
Reference in New Issue
Block a user