Skip to content

Add DBDSVR: MRRR-based bidiagonal SVD (Golub-Kahan TGK) with DBDSDC safety fallback - #1361

Draft
saisuryadv wants to merge 2 commits into
Reference-LAPACK:masterfrom
saisuryadv:dbdsvr-mrrr-bidiagonal-svd
Draft

Add DBDSVR: MRRR-based bidiagonal SVD (Golub-Kahan TGK) with DBDSDC safety fallback#1361
saisuryadv wants to merge 2 commits into
Reference-LAPACK:masterfrom
saisuryadv:dbdsvr-mrrr-bidiagonal-svd

Conversation

@saisuryadv

Copy link
Copy Markdown

Add DBDSVR: an MRRR-based bidiagonal SVD driver

Summary

DBDSVR computes the SVD of an n-by-n bidiagonal matrix by the MRRR algorithm applied to the Golub-Kahan tridiagonal, with the same argument list as DBDSVDX (plus LWORK/LIWORK) and a built-in safety net: every output is audited for nonfiniteness and, on audit or nonzero INFO, inputs are restored and DBDSDC recomputes, with the execution path reported in IWORK(2) (1 native / 2 fallback-on-INFO / 3 fallback-on-audit). Motivation: DBDSVDX is 7-228x slower than DBDSVR on a 16-variety battery and returns unorthogonalized vectors with INFO=0 on clustered spectra (ratios to 2.2e14); DBDSDC remains the deflation-friendly workhorse, and DBDSVR complements it with the best worst-case time of the four solvers tested.

Integration pattern (mirrors the DBDSVDX integration)

  • SRC/: dbdsvr.f (driver), dbdsvdmr3.f, dbdtgk.f, dlar1v_tgk.f, dlarrf_tgk.f, dlarrv_tgk.f, dlarrb_tgk.f (bundled bisection renamed from DLARRB - its extended signature collides with SRC/dlarrb.f; linking the stock routine segfaults).
  • SRC/Makefile, SRC/CMakeLists.txt: DLASRC lists extended.
  • TESTING/EIG/dchkbd.f: tests 35-49, an exact programmatic mirror of the DBDSVDX tests 20-34 (RANGE='A','I','V' x residual, U/VT orthogonality, ordering, values-vs-vectors agreement).
  • TESTING/EIG/derrbd.f: 12 error-exit checks.

Validation on current master (svd.in)

  • All tests for DBD routines passed the threshold ( 14820 tests run)
  • All tests for DBD drivers passed the threshold ( 14820 tests run)
  • All tests for DBD routines passed the threshold ( 14820 tests run)
  • All tests for DBD drivers passed the threshold ( 14820 tests run)
  • All tests for DBD routines passed the threshold ( 14820 tests run)
  • All tests for DBD drivers passed the threshold ( 14820 tests run)
  • All tests for DBD routines passed the threshold ( 14820 tests run)
  • All tests for DBD drivers passed the threshold ( 14820 tests run)
  • All tests for DBD routines passed the threshold ( 14820 tests run)
  • All tests for DBD drivers passed the threshold ( 14820 tests run) - includes the 15 new DBDSVR tests across all sizes/types.
  • DBD routines passed the tests of the error exits ( 55 tests done) - includes the 12 new checks.

Accuracy on a harder 16-variety battery (separate DCHKBSVR harness)

Sizes 2-100, DBDT04/DORT01 in n.ulp units, threshold 20; identical 240-case RANGE='A' basis; DBDSVR/DBDSVDX additionally exercised on I/V modes:

Method n exact-0 share share > 20 p50 p90 p99 max
DBDSVR (ours) 240 6% 2.1% 0.20 6.38 25.76 30.20
DBDSDC 240 45% 0.0% 0.01 0.76 1.41 1.53
DBDSVDX 240 32% 0.0% 0.03 0.91 3.41 7.80
MR3GK (Willems & Lang) 240 44% 0.0% 0.02 1.66 4.65 14.50

DBDSVR: 1195/1200 residuals below threshold; the exceedances (max 30.2, i.e. <=1.6x threshold) are confined to Cholesky-lifted geometric spectra where the construction fuses ~80% of sigma into one 1e-13-tight cluster (child-representation selection in dlarrf_tgk; fix path = block factorizations, validated externally). DBDSVDX on the same battery fails variety 8 at up to 2.2e14 with INFO=0 in its I/V modes. Wilkinson-class zero-diagonal inputs route to fallback path 3 by design.

Performance (same battery; ratios are the reliable objects)

N=2000, ms per call (unpinned VM; median 39% absolute drift measured, 11% on ratios; a pinned EPYC 9454 confirms all rankings and reaches 65x over DBDSDC on Clement at n=3000):

Ty Variety DBDSVR (ours) DBDSDC DBDSVDX MR3GK (Willems & Lang)
1 zero 39.0 3.1 12.3 5.1
2 identity 50.7 6.4 16.5 5.2
3 arith bidiag 296.5 3,451.0† 27,200.0† 8,691.4†
4 geom bidiag 255.6 206.3 23,634.0† 2,968.5†
5 log-dist 88.8 41.2 25,042.0† 287.6
6 arith tri-chol 700.7 1,665.4† 8,585.4† 8,102.7†
7 geom tri-chol 1,124.1† 177.8 19,765.0† 3,276.3†
8 clust tri-chol 85.3 35.0 18.4 17.0
9 arith sqrt-ovfl 278.3 3,715.1† 27,154.0† 8,899.9†
10 arith sqrt-unfl 352.0 3,466.9† 28,675.0† 8,537.3†
11 arith diag 75.5 6.1 15.4 5.0
12 geom diag 72.2 5.9 16.0 5.0
13 clust diag 59.4 6.3 15.0 5.0
14 diag sqrt-ovfl 74.0 7.5 16.3 5.0
15 diag sqrt-unfl 70.7 5.8 19.6 5.0
16 SPD geom-chol 830.6 292.2 20,374.0† 4,169.3†

Pooled t/n^2 percentiles over 80 (variety, size) cases:

Method p25 p50 p75 p90 max
DBDSVR (ours) 8.6 18.7 63.8 176.5 281.0
DBDSDC 1.6 4.9 83.9 288.3 928.8
DBDSVDX 5.7 390.4 1,389.9 5,139.6 7,168.8
MR3GK (Willems & Lang) 1.3 38.8 1,237.0 1,955.9 2,241.7

DBDSVR wins exactly the deflation-free spectra (9.8-13.4x over DBDSDC at n=2000), concedes the deflation-friendly ones (2.2-6.3x), has the smallest maximum of any solver, and the best suite total (2.9x over DBDSDC at n=2000, growing with n).

Known limitations / review questions

Double precision only (SBDSVR to follow); RANGE='I'/'V' currently post-filters a full computation (index pushdown into dlarrv_tgk is the planned follow-up); the two clustered-spectrum exceedance classes above; LAPACKE bindings not included; the fallback introduces a dependency on DBDSDC.

…afety fallback

Same argument list as DBDSVDX plus LWORK/LIWORK. Engine: dqds values,
MRRR vector tree adapted from the DSTEGR lineage (dlarrv/dlar1v/dlarrf
_tgk variants), bundled bounded-progress bisection renamed DLARRB_TGK
to avoid the signature collision with SRC/dlarrb.f. Wrapper audits all
outputs for nonfiniteness and falls back to DBDSDC on audit or error,
reporting the path in IWORK(2).
Tests 35-49 mirror the DBDSVDX tests 20-34 (RANGE='A','I','V' x
residual, U/VT orthogonality, ordering, values-vs-vectors agreement).
derrbd gains 12 corresponding error-exit checks. svd.in on master:
all DBD ratios pass the threshold; error exits 55/55.
@mgates3

mgates3 commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator

Interesting approach to an SVD with MRRR.

I think names bdsvr and bdsvdmr3 are confusing. If users are looking for an SVD with MRRR, they will likely find the low-level bdsvdmr3 and could miss that the high-level bdsvr is even an SVD. The archaic 6-char limit produced some inscrutable abbreviations; let's not perpetuate the trend. (Note confusion with gesvj and gejsv, which have rather unfortunate names; gesvdj or gesvd_jacobi would be better.)

I'm not sure the best way to distinguish them, but I think both should start bdsvd. I would probably use something like bdsvdmr3 for the high-level driver (currently bdsvr) and bdsvdmr3_work for the low-level computational routine (currently bdsvdmr3). There's not really an LAPACK naming convention for high-level vs. low-level routines. Or bdsvdmrrr or bdsvd_mrrr; the 3 saves only 1 char and is less recognizable.

If the "classic" SVD with MRRR -- which has had numerical stability issues, hence never made it to LAPACK -- were ever added to LAPACK, would it replace these names, or how would it be distinguished? Something to consider.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants