From 1eaef93021b4437a55d80ad59c513bcc5d128e9b Mon Sep 17 00:00:00 2001 From: ChrisRackauckas-Claude Date: Fri, 3 Jul 2026 12:37:35 -0400 Subject: [PATCH] Fix PureKLU both-Dual dispatch stolen by the b-only opt-out DualBLinearProblem's A slot is `Union{Number, AbstractArray}`, which a Dual-eltype A also matches, so `DualLinearProblem <: DualBLinearProblem`. The b-only PureKLU opt-out introduced in #1069 is more specific in the alg argument than the general dual-path `init`, so both-Dual PureKLU problems were routed to a plain `LinearCache` and `solve!` then failed with a FieldError on `dual_linear_cache` (test/Core/forwarddiff_overloads.jl "PureKLU direct dual path reuses inner LinearCache"). Add a more-specific `DualLinearProblem` method restoring the direct dual path; the mixed-type ldiv! only covers primal A. Co-Authored-By: Chris Rackauckas Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01EYp371jx6LurezUDhKcYRh --- ext/LinearSolveForwardDiffExt.jl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ext/LinearSolveForwardDiffExt.jl b/ext/LinearSolveForwardDiffExt.jl index a88cfd2b7..03d73a871 100644 --- a/ext/LinearSolveForwardDiffExt.jl +++ b/ext/LinearSolveForwardDiffExt.jl @@ -299,6 +299,14 @@ function SciMLBase.init(prob::DualBLinearProblem, alg::PureKLUFactorization, arg return __init(prob, alg, args...; kwargs...) end +# DualBLinearProblem's A slot is `Union{Number, AbstractArray}`, which a Dual-eltype A +# also matches, so the b-only opt-out above would otherwise capture both-Dual problems +# (`DualLinearProblem <: DualBLinearProblem`). Restore the direct dual path for them: a +# Dual A needs the DualLinearCache machinery, the mixed-type ldiv! only covers primal A. +function SciMLBase.init(prob::DualLinearProblem, alg::PureKLUFactorization, args...; kwargs...) + return __dual_init(prob, alg, args...; kwargs...) +end + # NOTE: Removed the runtime conditional for DefaultLinearSolver that checked for # GenericLUFactorization. Now always use __dual_init for type stability. function SciMLBase.init(prob::DualAbstractLinearProblem, alg::DefaultLinearSolver, args...; kwargs...)