mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Fix row-skipping bug in general_matrix_vector_product::run_small_cols
libeigen/eigen!2276
This commit is contained in:
committed by
Rasmus Munk Larsen
parent
81550faea4
commit
4387e32481
@@ -652,17 +652,20 @@ general_matrix_vector_product<Index, LhsScalar, LhsMapper, RowMajor, ConjugateLh
|
||||
const Index n2 = rows - 1;
|
||||
|
||||
Index i = 0;
|
||||
for (; i < n8; i += 8)
|
||||
for (; i < n8; i += 8) {
|
||||
process_rows_small_cols<8>(i, cols, lhs, rhs, res, resIncr, alpha, halfColBlockEnd, quarterColBlockEnd);
|
||||
if (i < n4) {
|
||||
}
|
||||
// Process remaining groups of 4 rows in case n8 was 0.
|
||||
for (; i < n4; i += 4) {
|
||||
process_rows_small_cols<4>(i, cols, lhs, rhs, res, resIncr, alpha, halfColBlockEnd, quarterColBlockEnd);
|
||||
i += 4;
|
||||
}
|
||||
if (i < n2) {
|
||||
process_rows_small_cols<2>(i, cols, lhs, rhs, res, resIncr, alpha, halfColBlockEnd, quarterColBlockEnd);
|
||||
i += 2;
|
||||
}
|
||||
if (i < rows) process_rows_small_cols<1>(i, cols, lhs, rhs, res, resIncr, alpha, halfColBlockEnd, quarterColBlockEnd);
|
||||
if (i < rows) {
|
||||
process_rows_small_cols<1>(i, cols, lhs, rhs, res, resIncr, alpha, halfColBlockEnd, quarterColBlockEnd);
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
@@ -130,6 +130,28 @@ void bug_gemv_rowmajor_large_stride() {
|
||||
}
|
||||
}
|
||||
|
||||
// Regression test for row-major GEMV run_small_cols bug.
|
||||
// When cols is small (e.g., 2), and loop variables (like n8) are 0 due
|
||||
// to row or stride limits, the remainder loops previously used `if` checks
|
||||
// like `if (i < n4)`. This incorrectly skips rows if multiple remainder
|
||||
// blocks are needed (e.g., 9 rows).
|
||||
template <int>
|
||||
void bug_gemv_run_small_cols() {
|
||||
const int rows = 9; // > 8, covers 8-row loop step but tests remainder cleanup
|
||||
const int cols = 2; // triggers run_small_cols (cols < PacketSize)
|
||||
const int stride = 5000; // 5000 * sizeof(double) > 32000, forces n8 = 0
|
||||
|
||||
Matrix<double, Dynamic, Dynamic, RowMajor> A_full(rows, stride);
|
||||
A_full.setRandom();
|
||||
auto A = A_full.leftCols(cols);
|
||||
|
||||
VectorXd x = VectorXd::Random(cols);
|
||||
VectorXd y = A * x;
|
||||
VectorXd y_ref = A.eval() * x; // No stride.
|
||||
|
||||
VERIFY_IS_APPROX(y, y_ref);
|
||||
}
|
||||
|
||||
template <int>
|
||||
void bug_1622() {
|
||||
typedef Matrix<double, 2, -1, 0, 2, -1> Mat2X;
|
||||
@@ -175,6 +197,7 @@ EIGEN_DECLARE_TEST(product_large) {
|
||||
|
||||
CALL_SUBTEST_6(product_large_regressions<0>());
|
||||
CALL_SUBTEST_6(bug_gemv_rowmajor_large_stride<0>());
|
||||
CALL_SUBTEST_6(bug_gemv_run_small_cols<0>());
|
||||
|
||||
// Regression test for bug 714:
|
||||
#if defined EIGEN_HAS_OPENMP
|
||||
|
||||
Reference in New Issue
Block a user