Add vector right-hand-side ldiv! dispatch - #47
Merged
ChrisRackauckas merged 1 commit intoAug 8, 2026
Conversation
Single right-hand sides previously fell through the catch-all to LinearAlgebra (BLAS trsv). The left-division paths already operate on transpose(A), and for a vector the required 1×n transposed form is just transpose(b) — no reshape, no allocation — so the vector methods forward into the same dispatch with M = 1, which runs the kernels' scalar row-remainder. Measured against trsv (min times, EPYC 7502/AVX2, Float64) that wins 1.2-3.3x up to n = 128 but loses once the triangle falls out of L2 (0.44x at n = 512), so solves above VECTOR_RHS_CUTOFF = 128 keep the LinearAlgebra path; above the cutoff the ratio is parity within noise. Motivated by SciML/LinearSolve.jl#1161: with this, single-vector RFLU backsolves can route both legs through TriangularSolve without the reshape trick measured there. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #47 +/- ##
==========================================
+ Coverage 94.62% 94.69% +0.07%
==========================================
Files 1 1
Lines 837 849 +12
==========================================
+ Hits 792 804 +12
Misses 45 45 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
ChrisRackauckas
marked this pull request as ready for review
August 8, 2026 10:44
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds first-class vector right-hand-side
ldiv!methods for all four wrapper types (2- and 3-arg,Valthread flag), prompted by the measurement in SciML/LinearSolve.jl#1161 that the TriangularSolve matrix kernels tie a hand-written scalar back-solve and beatgetrs!fornrhs == 1once the native upper kernel exists.Design
No reshape, no new kernel: the left-division paths already work on
transpose(A), and for a vectorbthe required 1×n transposed operand is justtranspose(b)— a stack immutable, so the whole path stays zero-allocation (areshape(b, :, 1)header would allocate). With M = 1 the drivers run their scalar row-remainder sweep.That sweep beats BLAS
trsvwhile the triangle is cache-resident but loses totrsv's blocked sweep beyond L2, so the methods defer toLinearAlgebraaboveVECTOR_RHS_CUTOFF = 128:(Without the cutoff the kernel path degrades to 0.44x at n = 512 — measured before adding it; the cutoff keeps every size at parity or better vs current behavior.)
Verification
TriangularSolve.jl | 149168 149168pass (Julia 1.12.4), Aqua + ambiguities clean. New testset sweeps n ∈ {1..500} straddling the cutoff, all four wrappers, bothValflags, 2-/3-arg, Float32/64, packed-lu!parent, and asserts zero allocations on the kernel path.which(TriangularSolve.ldiv!, (UpperTriangular{Float64,Matrix{Float64}}, Vector{Float64}, Val{false}))is the catch-all; with this PR it is a native method (and the n ≤ 128 timings above are the behavior change).trsvimproves with wider vectors, so the crossover should not move much upward).Reviewer notes
Float32-specific or derive it fromVectorizationBase.cache_sizeif you prefer.rdiv!with a vector is not added —LinearAlgebrahas no such method surface for triangular right-division, so there is nothing to mirror.🤖 Generated with Claude Code