mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-08-12 19:59:05 +08:00
Enable use of evaluators for noalias and lazyProduct, add conversion to scalar for inner products
This commit is contained in:
parent
f0b82c3ab9
commit
6c5e915e9a
@ -53,11 +53,7 @@ struct storage_kind_to_shape<Sparse> {
|
|||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template<typename T> struct evaluator_traits;
|
|
||||||
|
|
||||||
template< typename T,
|
|
||||||
typename Kind = typename evaluator_traits<T>::Kind,
|
|
||||||
typename Scalar = typename T::Scalar> struct evaluator;
|
|
||||||
|
|
||||||
template< typename T,
|
template< typename T,
|
||||||
typename LhsKind = typename evaluator_traits<typename T::Lhs>::Kind,
|
typename LhsKind = typename evaluator_traits<typename T::Lhs>::Kind,
|
||||||
|
@ -623,7 +623,7 @@ MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const
|
|||||||
|
|
||||||
return Product<Derived, OtherDerived>(derived(), other.derived());
|
return Product<Derived, OtherDerived>(derived(), other.derived());
|
||||||
}
|
}
|
||||||
#else
|
#else // EIGEN_TEST_EVALUATORS
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
inline const typename ProductReturnType<Derived, OtherDerived>::Type
|
inline const typename ProductReturnType<Derived, OtherDerived>::Type
|
||||||
@ -653,9 +653,10 @@ MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const
|
|||||||
#endif
|
#endif
|
||||||
return typename ProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived());
|
return typename ProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived());
|
||||||
}
|
}
|
||||||
#endif
|
#endif // EIGEN_TEST_EVALUATORS
|
||||||
|
|
||||||
|
#endif // __CUDACC__
|
||||||
|
|
||||||
#endif
|
|
||||||
/** \returns an expression of the matrix product of \c *this and \a other without implicit evaluation.
|
/** \returns an expression of the matrix product of \c *this and \a other without implicit evaluation.
|
||||||
*
|
*
|
||||||
* The returned product will behave like any other expressions: the coefficients of the product will be
|
* The returned product will behave like any other expressions: the coefficients of the product will be
|
||||||
@ -667,6 +668,31 @@ MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const
|
|||||||
*
|
*
|
||||||
* \sa operator*(const MatrixBase&)
|
* \sa operator*(const MatrixBase&)
|
||||||
*/
|
*/
|
||||||
|
#ifdef EIGEN_TEST_EVALUATORS
|
||||||
|
template<typename Derived>
|
||||||
|
template<typename OtherDerived>
|
||||||
|
const Product<Derived,OtherDerived,LazyProduct>
|
||||||
|
MatrixBase<Derived>::lazyProduct(const MatrixBase<OtherDerived> &other) const
|
||||||
|
{
|
||||||
|
enum {
|
||||||
|
ProductIsValid = Derived::ColsAtCompileTime==Dynamic
|
||||||
|
|| OtherDerived::RowsAtCompileTime==Dynamic
|
||||||
|
|| int(Derived::ColsAtCompileTime)==int(OtherDerived::RowsAtCompileTime),
|
||||||
|
AreVectors = Derived::IsVectorAtCompileTime && OtherDerived::IsVectorAtCompileTime,
|
||||||
|
SameSizes = EIGEN_PREDICATE_SAME_MATRIX_SIZE(Derived,OtherDerived)
|
||||||
|
};
|
||||||
|
// note to the lost user:
|
||||||
|
// * for a dot product use: v1.dot(v2)
|
||||||
|
// * for a coeff-wise product use: v1.cwiseProduct(v2)
|
||||||
|
EIGEN_STATIC_ASSERT(ProductIsValid || !(AreVectors && SameSizes),
|
||||||
|
INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS)
|
||||||
|
EIGEN_STATIC_ASSERT(ProductIsValid || !(SameSizes && !AreVectors),
|
||||||
|
INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION)
|
||||||
|
EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, INVALID_MATRIX_PRODUCT)
|
||||||
|
|
||||||
|
return Product<Derived,OtherDerived,LazyProduct>(derived(), other.derived());
|
||||||
|
}
|
||||||
|
#else // EIGEN_TEST_EVALUATORS
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
const typename LazyProductReturnType<Derived,OtherDerived>::Type
|
const typename LazyProductReturnType<Derived,OtherDerived>::Type
|
||||||
@ -690,6 +716,7 @@ MatrixBase<Derived>::lazyProduct(const MatrixBase<OtherDerived> &other) const
|
|||||||
|
|
||||||
return typename LazyProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived());
|
return typename LazyProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived());
|
||||||
}
|
}
|
||||||
|
#endif // EIGEN_TEST_EVALUATORS
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
|
@ -199,7 +199,11 @@ template<typename Derived> class MatrixBase
|
|||||||
|
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
|
#ifdef EIGEN_TEST_EVALUATORS
|
||||||
|
const Product<Derived,OtherDerived,LazyProduct>
|
||||||
|
#else
|
||||||
const typename LazyProductReturnType<Derived,OtherDerived>::Type
|
const typename LazyProductReturnType<Derived,OtherDerived>::Type
|
||||||
|
#endif
|
||||||
lazyProduct(const MatrixBase<OtherDerived> &other) const;
|
lazyProduct(const MatrixBase<OtherDerived> &other) const;
|
||||||
|
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
|
@ -34,6 +34,33 @@ class NoAlias
|
|||||||
typedef typename ExpressionType::Scalar Scalar;
|
typedef typename ExpressionType::Scalar Scalar;
|
||||||
|
|
||||||
NoAlias(ExpressionType& expression) : m_expression(expression) {}
|
NoAlias(ExpressionType& expression) : m_expression(expression) {}
|
||||||
|
|
||||||
|
#ifdef EIGEN_TEST_EVALUATORS
|
||||||
|
template<typename OtherDerived>
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
EIGEN_STRONG_INLINE ExpressionType& operator=(const StorageBase<OtherDerived>& other)
|
||||||
|
{
|
||||||
|
call_assignment(*this, other.derived(), internal::assign_op<Scalar>());
|
||||||
|
return m_expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename OtherDerived>
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
EIGEN_STRONG_INLINE ExpressionType& operator+=(const StorageBase<OtherDerived>& other)
|
||||||
|
{
|
||||||
|
call_assignment(*this, other.derived(), internal::add_assign_op<Scalar>());
|
||||||
|
return m_expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename OtherDerived>
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
EIGEN_STRONG_INLINE ExpressionType& operator-=(const StorageBase<OtherDerived>& other)
|
||||||
|
{
|
||||||
|
call_assignment(*this, other.derived(), internal::sub_assign_op<Scalar>());
|
||||||
|
return m_expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
/** Behaves like MatrixBase::lazyAssign(other)
|
/** Behaves like MatrixBase::lazyAssign(other)
|
||||||
* \sa MatrixBase::lazyAssign() */
|
* \sa MatrixBase::lazyAssign() */
|
||||||
@ -91,6 +118,8 @@ class NoAlias
|
|||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
ExpressionType& operator=(const ReturnByValue<OtherDerived>& func)
|
ExpressionType& operator=(const ReturnByValue<OtherDerived>& func)
|
||||||
{ return m_expression = func; }
|
{ return m_expression = func; }
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
|
@ -79,6 +79,12 @@ class Product : public ProductImpl<_Lhs,_Rhs,Option,
|
|||||||
|
|
||||||
const LhsNestedCleaned& lhs() const { return m_lhs; }
|
const LhsNestedCleaned& lhs() const { return m_lhs; }
|
||||||
const RhsNestedCleaned& rhs() const { return m_rhs; }
|
const RhsNestedCleaned& rhs() const { return m_rhs; }
|
||||||
|
|
||||||
|
/** Convertion to scalar for inner-products */
|
||||||
|
operator const Scalar() const {
|
||||||
|
EIGEN_STATIC_ASSERT(SizeAtCompileTime==1, IMPLICIT_CONVERSION_TO_SCALAR_IS_FOR_INNER_PRODUCT_ONLY);
|
||||||
|
return typename internal::evaluator<Product>::type(*this).coeff(0,0);
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -209,12 +209,12 @@ struct dense_product_impl<Lhs,Rhs,GemmProduct> : dense_product_impl_base<Lhs,Rhs
|
|||||||
{
|
{
|
||||||
typedef typename Product<Lhs,Rhs>::Scalar Scalar;
|
typedef typename Product<Lhs,Rhs>::Scalar Scalar;
|
||||||
|
|
||||||
template<typename Dest>
|
// template<typename Dest>
|
||||||
static void scaleAndAddTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
|
// static void scaleAndAddTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
|
||||||
{
|
// {
|
||||||
// TODO bypass GeneralProduct class
|
// // TODO bypass GeneralProduct class
|
||||||
GeneralProduct<Lhs, Rhs, GemmProduct>(lhs,rhs).scaleAndAddTo(dst, alpha);
|
// GeneralProduct<Lhs, Rhs, GemmProduct>(lhs,rhs).scaleAndAddTo(dst, alpha);
|
||||||
}
|
// }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs>
|
template<typename Lhs, typename Rhs>
|
||||||
@ -225,22 +225,28 @@ struct dense_product_impl<Lhs,Rhs,CoeffBasedProductMode>
|
|||||||
template<typename Dst>
|
template<typename Dst>
|
||||||
static inline void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
static inline void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
||||||
{
|
{
|
||||||
// TODO: use the following instead of calling call_assignment
|
// TODO: use the following instead of calling call_assignment, same for the other methods
|
||||||
// dst = lazyprod(lhs,rhs);
|
// dst = lazyprod(lhs,rhs);
|
||||||
call_assignment(dst, lazyprod(lhs,rhs), internal::assign_op<Scalar>());
|
call_assignment(dst, lazyprod(lhs,rhs), internal::assign_op<Scalar>());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Dst>
|
template<typename Dst>
|
||||||
static inline void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
static inline void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
||||||
{ dst += lazyprod(lhs,rhs); }
|
{
|
||||||
|
// dst += lazyprod(lhs,rhs);
|
||||||
|
call_assignment(dst, lazyprod(lhs,rhs), internal::add_assign_op<Scalar>());
|
||||||
|
}
|
||||||
|
|
||||||
template<typename Dst>
|
template<typename Dst>
|
||||||
static inline void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
static inline void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
||||||
{ dst -= lazyprod(lhs,rhs); }
|
{
|
||||||
|
// dst -= lazyprod(lhs,rhs);
|
||||||
|
call_assignment(dst, lazyprod(lhs,rhs), internal::sub_assign_op<Scalar>());
|
||||||
|
}
|
||||||
|
|
||||||
template<typename Dst>
|
// template<typename Dst>
|
||||||
static inline void scaleAndAddTo(Dst& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
|
// static inline void scaleAndAddTo(Dst& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
|
||||||
{ dst += alpha * lazyprod(lhs,rhs); }
|
// { dst += alpha * lazyprod(lhs,rhs); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs>
|
template<typename Lhs, typename Rhs>
|
||||||
@ -286,7 +292,7 @@ struct product_evaluator<Product<Lhs, Rhs, LazyProduct>, ProductTag, DenseShape,
|
|||||||
CoeffReadCost = traits<CoeffBasedProductType>::CoeffReadCost,
|
CoeffReadCost = traits<CoeffBasedProductType>::CoeffReadCost,
|
||||||
Unroll = CoeffReadCost != Dynamic && CoeffReadCost <= EIGEN_UNROLLING_LIMIT,
|
Unroll = CoeffReadCost != Dynamic && CoeffReadCost <= EIGEN_UNROLLING_LIMIT,
|
||||||
CanVectorizeInner = traits<CoeffBasedProductType>::CanVectorizeInner,
|
CanVectorizeInner = traits<CoeffBasedProductType>::CanVectorizeInner,
|
||||||
Flags = CoeffBasedProductType::Flags
|
Flags = traits<CoeffBasedProductType>::Flags
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef typename evaluator<Lhs>::type LhsEtorType;
|
typedef typename evaluator<Lhs>::type LhsEtorType;
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
namespace Eigen {
|
namespace Eigen {
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
/*********************************************************************************
|
/*********************************************************************************
|
||||||
* Coefficient based product implementation.
|
* Coefficient based product implementation.
|
||||||
* It is designed for the following use cases:
|
* It is designed for the following use cases:
|
||||||
@ -110,6 +110,8 @@ struct traits<CoeffBasedProduct<LhsNested,RhsNested,NestingFlags> >
|
|||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
|
#ifndef EIGEN_TEST_EVALUATORS
|
||||||
|
|
||||||
template<typename LhsNested, typename RhsNested, int NestingFlags>
|
template<typename LhsNested, typename RhsNested, int NestingFlags>
|
||||||
class CoeffBasedProduct
|
class CoeffBasedProduct
|
||||||
: internal::no_assignment_operator,
|
: internal::no_assignment_operator,
|
||||||
@ -447,6 +449,8 @@ struct product_packet_impl<ColMajor, Dynamic, Lhs, Rhs, Packet, LoadMode>
|
|||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
|
#endif // EIGEN_TEST_EVALUATORS
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
#endif // EIGEN_COEFFBASED_PRODUCT_H
|
#endif // EIGEN_COEFFBASED_PRODUCT_H
|
||||||
|
@ -36,6 +36,12 @@ template<typename Derived> struct accessors_level
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T> struct evaluator_traits;
|
||||||
|
|
||||||
|
template< typename T,
|
||||||
|
typename Kind = typename evaluator_traits<T>::Kind,
|
||||||
|
typename Scalar = typename T::Scalar> struct evaluator;
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
template<typename T> struct NumTraits;
|
template<typename T> struct NumTraits;
|
||||||
|
@ -90,7 +90,8 @@
|
|||||||
YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED,
|
YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED,
|
||||||
THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE,
|
THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE,
|
||||||
THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH,
|
THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH,
|
||||||
OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG
|
OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG,
|
||||||
|
IMPLICIT_CONVERSION_TO_SCALAR_IS_FOR_INNER_PRODUCT_ONLY
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -66,6 +66,8 @@ namespace Eigen
|
|||||||
static bool g_has_set_repeat, g_has_set_seed;
|
static bool g_has_set_repeat, g_has_set_seed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define TRACK std::cerr << __FILE__ << " " << __LINE__ << std::endl
|
||||||
|
|
||||||
#define EI_PP_MAKE_STRING2(S) #S
|
#define EI_PP_MAKE_STRING2(S) #S
|
||||||
#define EI_PP_MAKE_STRING(S) EI_PP_MAKE_STRING2(S)
|
#define EI_PP_MAKE_STRING(S) EI_PP_MAKE_STRING2(S)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user