mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
merge
This commit is contained in:
@@ -272,7 +272,7 @@ ptranspose(PacketBlock<Packet2cf,2>& kernel) {
|
||||
}
|
||||
|
||||
//---------- double ----------
|
||||
#if EIGEN_ARCH_ARM64
|
||||
#if EIGEN_ARCH_ARM64 && !EIGEN_APPLE_DOUBLE_NEON_BUG
|
||||
|
||||
static uint64x2_t p2ul_CONJ_XOR = EIGEN_INIT_NEON_PACKET2(0x0, 0x8000000000000000);
|
||||
|
||||
|
||||
@@ -55,6 +55,34 @@ struct functor_traits<scalar_abs_op<Scalar> >
|
||||
};
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the score of a scalar, to chose a pivot
|
||||
*
|
||||
* \sa class CwiseUnaryOp
|
||||
*/
|
||||
template<typename Scalar> struct scalar_score_coeff_op : scalar_abs_op<Scalar>
|
||||
{
|
||||
typedef void Score_is_abs;
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct functor_traits<scalar_score_coeff_op<Scalar> > : functor_traits<scalar_abs_op<Scalar> > {};
|
||||
|
||||
/* Avoid recomputing abs when we know the score and they are the same. Not a true Eigen functor. */
|
||||
template<typename Scalar, typename=void> struct abs_knowing_score
|
||||
{
|
||||
EIGEN_EMPTY_STRUCT_CTOR(abs_knowing_score)
|
||||
typedef typename NumTraits<Scalar>::Real result_type;
|
||||
template<typename Score>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a, const Score&) const { using std::abs; return abs(a); }
|
||||
};
|
||||
template<typename Scalar> struct abs_knowing_score<Scalar, typename scalar_score_coeff_op<Scalar>::Score_is_abs>
|
||||
{
|
||||
EIGEN_EMPTY_STRUCT_CTOR(abs_knowing_score)
|
||||
typedef typename NumTraits<Scalar>::Real result_type;
|
||||
template<typename Scal>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const Scal&, const result_type& a) const { return a; }
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the squared absolute value of a scalar
|
||||
*
|
||||
|
||||
@@ -86,19 +86,21 @@ void computeProductBlockingSizes(Index& k, Index& m, Index& n, Index num_threads
|
||||
typedef gebp_traits<LhsScalar,RhsScalar> Traits;
|
||||
|
||||
#ifdef EIGEN_TEST_SPECIFIC_BLOCKING_SIZES
|
||||
EIGEN_UNUSED_VARIABLE(num_threads);
|
||||
enum {
|
||||
kr = 8,
|
||||
mr = Traits::mr,
|
||||
nr = Traits::nr
|
||||
};
|
||||
k = std::min<Index>(k, EIGEN_TEST_SPECIFIC_BLOCKING_SIZE_K);
|
||||
if (k > kr) k -= k % kr;
|
||||
m = std::min<Index>(m, EIGEN_TEST_SPECIFIC_BLOCKING_SIZE_M);
|
||||
if (m > mr) m -= m % mr;
|
||||
n = std::min<Index>(n, EIGEN_TEST_SPECIFIC_BLOCKING_SIZE_N);
|
||||
if (n > nr) n -= n % nr;
|
||||
return;
|
||||
if (EIGEN_TEST_SPECIFIC_BLOCKING_SIZES) {
|
||||
EIGEN_UNUSED_VARIABLE(num_threads);
|
||||
enum {
|
||||
kr = 8,
|
||||
mr = Traits::mr,
|
||||
nr = Traits::nr
|
||||
};
|
||||
k = std::min<Index>(k, EIGEN_TEST_SPECIFIC_BLOCKING_SIZE_K);
|
||||
if (k > kr) k -= k % kr;
|
||||
m = std::min<Index>(m, EIGEN_TEST_SPECIFIC_BLOCKING_SIZE_M);
|
||||
if (m > mr) m -= m % mr;
|
||||
n = std::min<Index>(n, EIGEN_TEST_SPECIFIC_BLOCKING_SIZE_N);
|
||||
if (n > nr) n -= n % nr;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Explanations:
|
||||
@@ -1479,17 +1481,17 @@ void gebp_kernel<LhsScalar,RhsScalar,Index,DataMapper,mr,nr,ConjugateLhs,Conjuga
|
||||
|
||||
for(Index k=0; k<peeled_kc; k+=pk)
|
||||
{
|
||||
EIGEN_ASM_COMMENT("begin gebp micro kernel 2pX1");
|
||||
EIGEN_ASM_COMMENT("begin gebp micro kernel 1pX1");
|
||||
RhsPacket B_0;
|
||||
|
||||
#define EIGEN_GEBGP_ONESTEP(K) \
|
||||
do { \
|
||||
EIGEN_ASM_COMMENT("begin step of gebp micro kernel 2pX1"); \
|
||||
EIGEN_ASM_COMMENT("begin step of gebp micro kernel 1pX1"); \
|
||||
EIGEN_ASM_COMMENT("Note: these asm comments work around bug 935!"); \
|
||||
traits.loadLhs(&blA[(0+1*K)*LhsProgress], A0); \
|
||||
traits.loadRhs(&blB[(0+K)*RhsProgress], B_0); \
|
||||
traits.madd(A0, B_0, C0, B_0); \
|
||||
EIGEN_ASM_COMMENT("end step of gebp micro kernel 2pX1"); \
|
||||
EIGEN_ASM_COMMENT("end step of gebp micro kernel 1pX1"); \
|
||||
} while(false);
|
||||
|
||||
EIGEN_GEBGP_ONESTEP(0);
|
||||
@@ -1504,7 +1506,7 @@ void gebp_kernel<LhsScalar,RhsScalar,Index,DataMapper,mr,nr,ConjugateLhs,Conjuga
|
||||
blB += pk*RhsProgress;
|
||||
blA += pk*1*Traits::LhsProgress;
|
||||
|
||||
EIGEN_ASM_COMMENT("end gebp micro kernel 2pX1");
|
||||
EIGEN_ASM_COMMENT("end gebp micro kernel 1pX1");
|
||||
}
|
||||
|
||||
// process remaining peeled loop
|
||||
|
||||
@@ -459,14 +459,16 @@ FullPivLU<MatrixType>& FullPivLU<MatrixType>::compute(const MatrixType& matrix)
|
||||
|
||||
// biggest coefficient in the remaining bottom-right corner (starting at row k, col k)
|
||||
Index row_of_biggest_in_corner, col_of_biggest_in_corner;
|
||||
RealScalar biggest_in_corner;
|
||||
typedef internal::scalar_score_coeff_op<Scalar> Scoring;
|
||||
typedef typename Scoring::result_type Score;
|
||||
Score biggest_in_corner;
|
||||
biggest_in_corner = m_lu.bottomRightCorner(rows-k, cols-k)
|
||||
.cwiseAbs()
|
||||
.unaryExpr(Scoring())
|
||||
.maxCoeff(&row_of_biggest_in_corner, &col_of_biggest_in_corner);
|
||||
row_of_biggest_in_corner += k; // correct the values! since they were computed in the corner,
|
||||
col_of_biggest_in_corner += k; // need to add k to them.
|
||||
|
||||
if(biggest_in_corner==RealScalar(0))
|
||||
if(biggest_in_corner==Score(0))
|
||||
{
|
||||
// before exiting, make sure to initialize the still uninitialized transpositions
|
||||
// in a sane state without destroying what we already have.
|
||||
@@ -479,7 +481,8 @@ FullPivLU<MatrixType>& FullPivLU<MatrixType>::compute(const MatrixType& matrix)
|
||||
break;
|
||||
}
|
||||
|
||||
if(biggest_in_corner > m_maxpivot) m_maxpivot = biggest_in_corner;
|
||||
RealScalar abs_pivot = internal::abs_knowing_score<Scalar>()(m_lu(row_of_biggest_in_corner, col_of_biggest_in_corner), biggest_in_corner);
|
||||
if(abs_pivot > m_maxpivot) m_maxpivot = abs_pivot;
|
||||
|
||||
// Now that we've found the pivot, we need to apply the row/col swaps to
|
||||
// bring it to the location (k,k).
|
||||
|
||||
@@ -275,6 +275,8 @@ struct partial_lu_impl
|
||||
*/
|
||||
static Index unblocked_lu(MatrixType& lu, PivIndex* row_transpositions, PivIndex& nb_transpositions)
|
||||
{
|
||||
typedef scalar_score_coeff_op<Scalar> Scoring;
|
||||
typedef typename Scoring::result_type Score;
|
||||
const Index rows = lu.rows();
|
||||
const Index cols = lu.cols();
|
||||
const Index size = (std::min)(rows,cols);
|
||||
@@ -286,13 +288,13 @@ struct partial_lu_impl
|
||||
Index rcols = cols-k-1;
|
||||
|
||||
Index row_of_biggest_in_col;
|
||||
RealScalar biggest_in_corner
|
||||
= lu.col(k).tail(rows-k).cwiseAbs().maxCoeff(&row_of_biggest_in_col);
|
||||
Score biggest_in_corner
|
||||
= lu.col(k).tail(rows-k).unaryExpr(Scoring()).maxCoeff(&row_of_biggest_in_col);
|
||||
row_of_biggest_in_col += k;
|
||||
|
||||
row_transpositions[k] = PivIndex(row_of_biggest_in_col);
|
||||
|
||||
if(biggest_in_corner != RealScalar(0))
|
||||
if(biggest_in_corner != Score(0))
|
||||
{
|
||||
if(k != row_of_biggest_in_col)
|
||||
{
|
||||
|
||||
@@ -443,13 +443,15 @@ FullPivHouseholderQR<MatrixType>& FullPivHouseholderQR<MatrixType>::compute(cons
|
||||
for (Index k = 0; k < size; ++k)
|
||||
{
|
||||
Index row_of_biggest_in_corner, col_of_biggest_in_corner;
|
||||
RealScalar biggest_in_corner;
|
||||
typedef internal::scalar_score_coeff_op<Scalar> Scoring;
|
||||
typedef typename Scoring::result_type Score;
|
||||
|
||||
biggest_in_corner = m_qr.bottomRightCorner(rows-k, cols-k)
|
||||
.cwiseAbs()
|
||||
.maxCoeff(&row_of_biggest_in_corner, &col_of_biggest_in_corner);
|
||||
Score score = m_qr.bottomRightCorner(rows-k, cols-k)
|
||||
.unaryExpr(Scoring())
|
||||
.maxCoeff(&row_of_biggest_in_corner, &col_of_biggest_in_corner);
|
||||
row_of_biggest_in_corner += k;
|
||||
col_of_biggest_in_corner += k;
|
||||
RealScalar biggest_in_corner = internal::abs_knowing_score<Scalar>()(m_qr(row_of_biggest_in_corner, col_of_biggest_in_corner), score);
|
||||
if(k==0) biggest = biggest_in_corner;
|
||||
|
||||
// if the corner is negligible, then we have less than full rank, and we can finish early
|
||||
|
||||
Reference in New Issue
Block a user