Skip to content

Extract R before constructing Q in Householder QR/LQ - #267

Draft
lkdvos wants to merge 2 commits into
mainfrom
ld-qr
Draft

Extract R before constructing Q in Householder QR/LQ#267
lkdvos wants to merge 2 commits into
mainfrom
ld-qr

Conversation

@lkdvos

@lkdvos lkdvos commented Aug 12, 2026

Copy link
Copy Markdown
Member

ormqr (unmqr!) requires a workspace of ~2·m·n elements whose size can only be queried through a 32-bit integer, and cuSOLVER exposes no 64-bit variant.
Past m ≈ 35000 the query itself returns CUSOLVER_STATUS_INVALID_VALUE, so qr_compact/qr_full on a large CuMatrix cannot construct Q at all.

orgqr (ungqr!) needs no workspace and measured 1.15–1.5× faster at every size tested on my GPU — but it generates Q in the array holding the reflectors, which the old order (construct Q, then copy R out of the packed A) could not combine with returning R.
Note that the old order was there for the blocked version reasons, which is not on the GPU anyways and still exists for that reason.

qr_householder!/lq_householder! extract R/L before constructing Q.
An inplace Q (Q === A) therefore now combines with computing R/L and with positive = true; only blocksize = 1, a tall (wide) A, and R/L not aliasing A remain required. The blocked path still constructs Q first, since R doubles as workspace for T there.

CUSOLVER now always constructs Q with ungqr!. LAPACK keeps unmqr!, where the comparison is mixed (unmqr! up to 6× faster for small/skinny, ungqr! up to 1.9× faster from ~2000 up). qr_null keeps unmqr! regardless: N holds the trailing columns of Q, which orgqr cannot generate.

Also fixed: LQ gauge fixing ran even with positive = false when L was not computed; Native/GLA silently returned garbage for Q === A.

🤖 Generated with Claude Code

lkdvos and others added 2 commits August 12, 2026 10:47
cuSOLVER's `ormqr` needs a workspace of ~2*m*n elements whose size can only be
queried through a 32-bit integer, so it becomes unusable past m ~ 35000. `orgqr`
needs no workspace and is faster, but generates Q in the array holding the
reflectors, which the old order (construct Q, then copy R out of the packed A)
could not combine with returning R.

Extracting R/L first lifts the restrictions on an inplace Q (`Q === A`): it now
combines with computing R/L and with `positive = true`. The blocked path keeps
constructing Q first, as R doubles as workspace for T there. The CUSOLVER driver
now always constructs Q with `ungqr!`.

Also fixes LQ gauge fixing running with `positive = false` when L is not
computed, and makes the Native and GLA drivers reject `Q === A` instead of
silently returning garbage.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
They are no longer used now that the CUSOLVER driver always constructs Q with
`ungqr!`. Inline the ungqr!-based Q construction into `_qr_buildQ!`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@lkdvos
lkdvos force-pushed the ld-qr branch 2 times, most recently from cc06e89 to e164200 Compare August 12, 2026 14:48
@codecov

codecov Bot commented Aug 13, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.87755% with 3 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
ext/MatrixAlgebraKitGenericLinearAlgebraExt.jl 50.00% 1 Missing ⚠️
src/implementations/lq.jl 94.44% 1 Missing ⚠️
src/implementations/qr.jl 96.42% 1 Missing ⚠️
Files with missing lines Coverage Δ
...MatrixAlgebraKitCUDAExt/MatrixAlgebraKitCUDAExt.jl 82.08% <100.00%> (+0.27%) ⬆️
src/interface/decompositions.jl 76.19% <ø> (ø)
ext/MatrixAlgebraKitGenericLinearAlgebraExt.jl 85.96% <50.00%> (-1.31%) ⬇️
src/implementations/lq.jl 95.52% <94.44%> (-0.22%) ⬇️
src/implementations/qr.jl 93.16% <96.42%> (+0.10%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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.

1 participant