Opt PureKLU and RFLU out of split dual AD path#1023
Open
ChrisRackauckas wants to merge 4 commits into
Open
Conversation
This was referenced Jun 9, 2026
ChrisRackauckas
commented
Jun 9, 2026
ChrisRackauckas-Claude
pushed a commit
to ChrisRackauckas-Claude/LinearSolve.jl
that referenced
this pull request
Jun 10, 2026
Per review on SciML#1005 (matching SciML#1023): SpecializingFactorizations has generic-element fallbacks, so SpecializedLUFactorization and SpecializedQRFactorization solve Dual-number problems directly via _use_direct_dual_solve instead of the primal/partials splitting path. The split-path math is square-only, so this also makes the QR least-squares solver correct for Dual rectangular systems. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
This was referenced Jun 10, 2026
Two fixes for the direct dual opt-out path:
1. PureKLUFactorization's sparse init_cacheval methods were restricted to
Float64/ComplexF64 eltypes, so Dual-eltype sparse matrices fell through
to the nothing fallback and solve! crashed on cacheval.nzval. PureKLU's
kernels are pure Julia and generic over Union{Real, Complex}, so widen
the specializations accordingly.
2. The direct dual path built its inner problem from dual_A/dual_b as
stored, but when only A carries duals b is a plain array, and __init
takes the solution eltype from b, so the dual solution could not be
stored (MethodError: no method matching Float64(::Dual)). This also
affected the pre-existing GenericLUFactorization opt-out. Promote b to
the cache's dual type in _solve_direct_dual!, and only take the direct
path when A itself carries duals: with duals just in b, the split path
(one primal factorization + partials back-solves) is strictly cheaper
and works for all algorithms.
Adds test coverage for the duals-only-in-A and duals-only-in-b cases for
GenericLUFactorization, RFLUFactorization, and PureKLUFactorization.
Co-authored-by: Chris Rackauckas (Claude) <accounts@chrisrackauckas.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
ChrisRackauckas
added a commit
that referenced
this pull request
Jun 10, 2026
* Add SpecializingFactorizations.jl package extension Wraps SpecializingFactorizations.jl as two opt-in LinearSolve algorithms: - SpecializedLUFactorization: type-stable, structure-detecting dense LU-style solver for square systems (diagonal/bidiagonal/tridiagonal/ banded/triangular/symmetric specializations behind one workspace type). - SpecializedQRFactorization: rank-revealing, never-throwing dense QR least-squares solver for rectangular / rank-deficient systems (minimum-norm least-squares == pinv(A)*b). Both are AbstractDenseFactorization subtypes gated behind a weakdep extension (ext/LinearSolveSpecializingFactorizationsExt.jl), implementing init_cacheval + SciMLBase.solve! with cache reuse via specializinglu!/ specializingqr!. Added a focused test set (extension load + solve + caching across LU/QR, structured, complex, float32, overdetermined, and rank-deficient cases) wired into the Core test group. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> * Opt SpecializedLU/QR out of the split dual AD path Per review on #1005 (matching #1023): SpecializingFactorizations has generic-element fallbacks, so SpecializedLUFactorization and SpecializedQRFactorization solve Dual-number problems directly via _use_direct_dual_solve instead of the primal/partials splitting path. The split-path math is square-only, so this also makes the QR least-squares solver correct for Dual rectangular systems. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> * Fix typos-check name and document Specialized LU/QR in solvers.md Rename the Float32 test variable solf (flagged by typos as a misspelling of solve) to sol32, and add SpecializedLUFactorization / SpecializedQRFactorization to the docs solver list so the Documenter missing-docs check covers them. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> * Load SpecializingFactorizations in resolve.jl re-solve sweep resolve.jl enumerates every AbstractDenseFactorization subtype, so the new SpecializedLU/QRFactorization hit the generic do_factorization fallback when their extension is not loaded. Load the package (already a test dep) so both algorithms go through the extension and get re-solve coverage. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> * Retrigger CI (tests/detect runner-infra failure, no steps ran) Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> --------- Co-authored-by: ChrisRackauckas-Claude <accounts@chrisrackauckas.com>
Contributor
|
Rebased onto current |
ChrisRackauckas
added a commit
that referenced
this pull request
Jun 14, 2026
* Opt PureKLU and RFLU out of split dual AD path * Update forwarddiff_overloads.jl * Apply suggestion from @ChrisRackauckas * Fix direct dual solve path for PureKLU and non-dual b (#1024) Two fixes for the direct dual opt-out path: 1. PureKLUFactorization's sparse init_cacheval methods were restricted to Float64/ComplexF64 eltypes, so Dual-eltype sparse matrices fell through to the nothing fallback and solve! crashed on cacheval.nzval. PureKLU's kernels are pure Julia and generic over Union{Real, Complex}, so widen the specializations accordingly. 2. The direct dual path built its inner problem from dual_A/dual_b as stored, but when only A carries duals b is a plain array, and __init takes the solution eltype from b, so the dual solution could not be stored (MethodError: no method matching Float64(::Dual)). This also affected the pre-existing GenericLUFactorization opt-out. Promote b to the cache's dual type in _solve_direct_dual!, and only take the direct path when A itself carries duals: with duals just in b, the split path (one primal factorization + partials back-solves) is strictly cheaper and works for all algorithms. Adds test coverage for the duals-only-in-A and duals-only-in-b cases for GenericLUFactorization, RFLUFactorization, and PureKLUFactorization. Co-authored-by: Chris Rackauckas (Claude) <accounts@chrisrackauckas.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> * Drop redundant PureKLU init_cacheval widening (subsumed by #1037) The original PR widened the `{T, Int64}` / `{T, Int32}` PureKLU `init_cacheval` methods from `Union{Float64, ComplexF64}` to `Union{Real, Complex}` to let ForwardDiff duals dispatch on the direct dual solve path. After rebasing onto main, that is unnecessary: #1037 ("Default to PureKLU for generic-eltype sparse LU") added a catch-all `where {T <: Number, Ti <: Integer}` method that already builds the correct empty cache for any number eltype (duals included). The widened specializations only duplicated it, so revert that file to main. Verified: test/core/forwarddiff_overloads.jl (incl. the PureKLU sparse-dual cases) passes with this file unchanged from main. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> --------- Co-authored-by: Christopher Rackauckas <accounts@chrisrackauckas.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
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.
No description provided.