diff options
author | Gael Guennebaud <g.gael@free.fr> | 2009-12-16 11:41:16 +0100 |
---|---|---|
committer | Gael Guennebaud <g.gael@free.fr> | 2009-12-16 11:41:16 +0100 |
commit | 6db6774c4685b997ab4343e5c5b4d48af84e45e7 (patch) | |
tree | 6e0a2bb73d959179b735a7cebb588cb72cdef570 | |
parent | 0d8ffe5240e4324a6ada046eeb2c2bb25b36af9a (diff) |
* fix aliasing checks when the lhs is also transposed. At the same time,
significantly simplify the code of these checks while extending them
to catch much more expressions!
* move the enabling/disabling of vectorized sin/cos to the architecture traits
-rw-r--r-- | Eigen/src/Array/Functors.h | 4 | ||||
-rw-r--r-- | Eigen/src/Core/Assign.h | 3 | ||||
-rw-r--r-- | Eigen/src/Core/MatrixBase.h | 23 | ||||
-rw-r--r-- | Eigen/src/Core/Transpose.h | 78 | ||||
-rw-r--r-- | Eigen/src/Core/arch/SSE/PacketMath.h | 4 | ||||
-rw-r--r-- | Eigen/src/Core/util/BlasUtil.h | 4 | ||||
-rw-r--r-- | test/adjoint.cpp | 8 |
7 files changed, 46 insertions, 78 deletions
diff --git a/Eigen/src/Array/Functors.h b/Eigen/src/Array/Functors.h index fd259f7bc..120c56cc1 100644 --- a/Eigen/src/Array/Functors.h +++ b/Eigen/src/Array/Functors.h @@ -87,7 +87,7 @@ struct ei_functor_traits<ei_scalar_cos_op<Scalar> > { enum { Cost = 5 * NumTraits<Scalar>::MulCost, - PacketAccess = ei_packet_traits<Scalar>::HasCos && EIGEN_FAST_MATH + PacketAccess = ei_packet_traits<Scalar>::HasCos }; }; @@ -109,7 +109,7 @@ struct ei_functor_traits<ei_scalar_sin_op<Scalar> > { enum { Cost = 5 * NumTraits<Scalar>::MulCost, - PacketAccess = ei_packet_traits<Scalar>::HasSin && EIGEN_FAST_MATH + PacketAccess = ei_packet_traits<Scalar>::HasSin }; }; diff --git a/Eigen/src/Core/Assign.h b/Eigen/src/Core/Assign.h index 00febdc5d..d544a6198 100644 --- a/Eigen/src/Core/Assign.h +++ b/Eigen/src/Core/Assign.h @@ -485,6 +485,9 @@ EIGEN_STRONG_INLINE Derived& MatrixBase<Derived> #ifdef EIGEN_DEBUG_ASSIGN ei_assign_traits<Derived, OtherDerived>::debug(); #endif +#ifndef EIGEN_NO_DEBUG + checkTransposeAliasing(other.derived()); +#endif return derived(); } diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h index 03d8d5f55..593108522 100644 --- a/Eigen/src/Core/MatrixBase.h +++ b/Eigen/src/Core/MatrixBase.h @@ -436,21 +436,12 @@ template<typename Derived> class MatrixBase void transposeInPlace(); const AdjointReturnType adjoint() const; void adjointInPlace(); - #ifndef EIGEN_NO_DEBUG - template<typename OtherDerived> - Derived& lazyAssign(const Transpose<OtherDerived>& other); - template<typename DerivedA, typename DerivedB> - Derived& lazyAssign(const CwiseBinaryOp<ei_scalar_sum_op<Scalar>,Transpose<DerivedA>,DerivedB>& other); - template<typename DerivedA, typename DerivedB> - Derived& lazyAssign(const CwiseBinaryOp<ei_scalar_sum_op<Scalar>,DerivedA,Transpose<DerivedB> >& other); - +#ifndef EIGEN_NO_DEBUG + protected: template<typename OtherDerived> - Derived& lazyAssign(const CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, Eigen::Transpose<OtherDerived> >& other); - template<typename DerivedA, typename DerivedB> - Derived& lazyAssign(const CwiseBinaryOp<ei_scalar_sum_op<Scalar>,CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, Eigen::Transpose<DerivedA> >,DerivedB>& other); - template<typename DerivedA, typename DerivedB> - Derived& lazyAssign(const CwiseBinaryOp<ei_scalar_sum_op<Scalar>,DerivedA,CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, Eigen::Transpose<DerivedB> > >& other); - #endif + void checkTransposeAliasing(const OtherDerived& other) const; + public: +#endif RowXpr row(int i); const RowXpr row(int i) const; @@ -638,7 +629,7 @@ template<typename Derived> class MatrixBase const CwiseBinaryOp<CustomBinaryOp, Derived, OtherDerived> binaryExpr(const MatrixBase<OtherDerived> &other, const CustomBinaryOp& func = CustomBinaryOp()) const; - + Scalar sum() const; Scalar mean() const; Scalar trace() const; @@ -818,7 +809,7 @@ template<typename Derived> class MatrixBase INVALID_MATRIXBASE_TEMPLATE_PARAMETERS) #endif } - + private: explicit MatrixBase(int); MatrixBase(int,int); diff --git a/Eigen/src/Core/Transpose.h b/Eigen/src/Core/Transpose.h index 79aef9fa7..796ec8573 100644 --- a/Eigen/src/Core/Transpose.h +++ b/Eigen/src/Core/Transpose.h @@ -268,13 +268,7 @@ inline void MatrixBase<Derived>::adjointInPlace() #ifndef EIGEN_NO_DEBUG -// The following is to detect aliasing problems in the following common cases: -// a = a.transpose() -// a = a.transpose() + X -// a = X + a.transpose() -// a = a.adjoint() -// a = a.adjoint() + X -// a = X + a.adjoint() +// The following is to detect aliasing problems in most common cases. template<typename T, int Access=ei_blas_traits<T>::ActualAccess> struct ei_extract_data_selector { @@ -294,63 +288,31 @@ template<typename T> typename T::Scalar* ei_extract_data(const T& m) return ei_extract_data_selector<T>::run(m); } -template<typename Derived> -template<typename OtherDerived> -Derived& MatrixBase<Derived>::lazyAssign(const Transpose<OtherDerived>& other) -{ - ei_assert(ei_extract_data(other) != ei_extract_data(derived()) - && "aliasing detected during tranposition, please use transposeInPlace()"); - return lazyAssign(static_cast<const MatrixBase<Transpose<OtherDerived> >& >(other)); -} - -template<typename Derived> -template<typename DerivedA, typename DerivedB> -Derived& MatrixBase<Derived>:: -lazyAssign(const CwiseBinaryOp<ei_scalar_sum_op<Scalar>,Transpose<DerivedA>,DerivedB>& other) -{ - ei_assert(ei_extract_data(derived()) != ei_extract_data(other.lhs()) - && "aliasing detected during tranposition, please evaluate your expression"); - return lazyAssign(static_cast<const MatrixBase<CwiseBinaryOp<ei_scalar_sum_op<Scalar>,Transpose<DerivedA>,DerivedB> >& >(other)); -} - -template<typename Derived> -template<typename DerivedA, typename DerivedB> -Derived& MatrixBase<Derived>:: -lazyAssign(const CwiseBinaryOp<ei_scalar_sum_op<Scalar>,DerivedA,Transpose<DerivedB> >& other) -{ - ei_assert(ei_extract_data(derived()) != ei_extract_data(other.rhs()) - && "aliasing detected during tranposition, please evaluate your expression"); - return lazyAssign(static_cast<const MatrixBase<CwiseBinaryOp<ei_scalar_sum_op<Scalar>,DerivedA,Transpose<DerivedB> > >& >(other)); -} - -template<typename Derived> -template<typename OtherDerived> Derived& -MatrixBase<Derived>:: -lazyAssign(const CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, Eigen::Transpose<OtherDerived> >& other) +template<typename Scalar, bool DestIsTranposed, typename OtherDerived> +struct ei_check_transpose_aliasing_selector { - ei_assert(ei_extract_data(other) != ei_extract_data(derived()) - && "aliasing detected during tranposition, please use adjointInPlace()"); - return lazyAssign(static_cast<const MatrixBase<CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, Eigen::Transpose<OtherDerived> > >& >(other)); -} + static bool run(const Scalar* dest, const OtherDerived& src) + { + return (ei_blas_traits<OtherDerived>::IsTransposed != DestIsTranposed) && (dest==ei_extract_data(src)); + } +}; -template<typename Derived> -template<typename DerivedA, typename DerivedB> -Derived& MatrixBase<Derived>:: -lazyAssign(const CwiseBinaryOp<ei_scalar_sum_op<Scalar>,CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, Eigen::Transpose<DerivedA> >,DerivedB>& other) +template<typename Scalar, bool DestIsTranposed, typename BinOp, typename DerivedA, typename DerivedB> +struct ei_check_transpose_aliasing_selector<Scalar,DestIsTranposed,CwiseBinaryOp<BinOp,DerivedA,DerivedB> > { - ei_assert(ei_extract_data(derived()) != ei_extract_data(other.lhs()) - && "aliasing detected during tranposition, please evaluate your expression"); - return lazyAssign(static_cast<const MatrixBase<CwiseBinaryOp<ei_scalar_sum_op<Scalar>,CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, Eigen::Transpose<DerivedA> >,DerivedB> >& >(other)); -} + static bool run(const Scalar* dest, const CwiseBinaryOp<BinOp,DerivedA,DerivedB>& src) + { + return ((ei_blas_traits<DerivedA>::IsTransposed != DestIsTranposed) && dest==ei_extract_data(src.lhs())) + || ((ei_blas_traits<DerivedB>::IsTransposed != DestIsTranposed) && dest==ei_extract_data(src.rhs())); + } +}; template<typename Derived> -template<typename DerivedA, typename DerivedB> -Derived& MatrixBase<Derived>:: -lazyAssign(const CwiseBinaryOp<ei_scalar_sum_op<Scalar>,DerivedA,CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, Eigen::Transpose<DerivedB> > >& other) +template<typename OtherDerived> +void MatrixBase<Derived>::checkTransposeAliasing(const OtherDerived& other) const { - ei_assert(ei_extract_data(derived()) != ei_extract_data(other.rhs()) - && "aliasing detected during tranposition, please evaluate your expression"); - return lazyAssign(static_cast<const MatrixBase<CwiseBinaryOp<ei_scalar_sum_op<Scalar>,DerivedA,CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, Eigen::Transpose<DerivedB> > > >& >(other)); + ei_assert((!ei_check_transpose_aliasing_selector<Scalar,ei_blas_traits<Derived>::IsTransposed,OtherDerived>::run(ei_extract_data(derived()), other)) + && "aliasing detected during tranposition, use transposeInPlace() or evaluate the rhs into a temporary using .eval()"); } #endif diff --git a/Eigen/src/Core/arch/SSE/PacketMath.h b/Eigen/src/Core/arch/SSE/PacketMath.h index 69f6979bd..dbdddb38d 100644 --- a/Eigen/src/Core/arch/SSE/PacketMath.h +++ b/Eigen/src/Core/arch/SSE/PacketMath.h @@ -58,8 +58,8 @@ template<> struct ei_packet_traits<float> : ei_default_packet_traits { typedef Packet4f type; enum {size=4}; enum { - HasSin = 1, - HasCos = 1, + HasSin = EIGEN_FAST_MATH, + HasCos = EIGEN_FAST_MATH, HasLog = 1, HasExp = 1, HasSqrt = 1 diff --git a/Eigen/src/Core/util/BlasUtil.h b/Eigen/src/Core/util/BlasUtil.h index a012a6e12..fa21ceebb 100644 --- a/Eigen/src/Core/util/BlasUtil.h +++ b/Eigen/src/Core/util/BlasUtil.h @@ -160,6 +160,7 @@ template<typename XprType> struct ei_blas_traits typedef XprType _ExtractType; enum { IsComplex = NumTraits<Scalar>::IsComplex, + IsTransposed = false, NeedToConjugate = false, ActualAccess = int(ei_traits<XprType>::Flags)&DirectAccessBit ? HasDirectAccess : NoDirectAccess }; @@ -227,6 +228,9 @@ struct ei_blas_traits<Transpose<NestedXpr> > ExtractType, typename ExtractType::PlainMatrixType >::ret DirectLinearAccessType; + enum { + IsTransposed = Base::IsTransposed ? 0 : 1 + }; static inline const ExtractType extract(const XprType& x) { return Base::extract(x._expression()); } static inline Scalar extractScalarFactor(const XprType& x) { return Base::extractScalarFactor(x._expression()); } }; diff --git a/test/adjoint.cpp b/test/adjoint.cpp index 344399257..b34112249 100644 --- a/test/adjoint.cpp +++ b/test/adjoint.cpp @@ -128,6 +128,14 @@ void test_adjoint() VERIFY_RAISES_ASSERT(a = a.adjoint()); VERIFY_RAISES_ASSERT(a = a.adjoint() + b); VERIFY_RAISES_ASSERT(a = b + a.adjoint()); + + // no assertion should be triggered for these cases: + a.transpose() = a.transpose(); + a.transpose() += a.transpose(); + a.transpose() += a.transpose() + b; + a.transpose() = a.adjoint(); + a.transpose() += a.adjoint(); + a.transpose() += a.adjoint() + b; } #endif } |