Commit fd8271c
Bound the UMFPACK-backed sparse cachevals to the eltypes UMFPACK has (#1122)
`init(LinearProblem(A, b), nothing)` throws for a Float32 sparse matrix on
main:
defaultalg(...) = DefaultLinearSolver(DefaultAlgorithmChoice.KLUFactorization, ...)
init(...) = MethodError: no method matching
SparseArrays.UMFPACK.UmfpackLU(::SparseMatrixCSC{Float32, Int64})
Note the algorithm that throws is not the one selected. `_init_default_cacheval`
(src/default.jl, @generated) emits an unconditional `init_cacheval` for every
slot - only the three Krylov slots are guarded - so a too-permissive
`init_cacheval` on an *unselected* algorithm still breaks `init`. KLU is
chosen; the `LUFactorization` slot is built first and throws.
`LUFactorization`'s and `UMFPACKFactorization`'s sparse cachevals are bounded
by `BLASELTYPES = Union{Float32, Float64, ComplexF32, ComplexF64}`, but
UMFPACK's `UmfpackLU` exists only for Float64/ComplexF64 (SuiteSparse's
`UMFVTypes`), so the bound is too wide by exactly Float32/ComplexF32. KLU
already does this correctly with `T <: KLU.KLUTypes`.
Bound them to a local `UMFPACKELTYPES` instead. The additional `BLASELTYPES`
method is not redundant: the old methods' `is_cusparse(A)` branch is the only
`LUFactorization`+CuSparse `init_cacheval` in the tree, so narrowing alone
would have silently dropped Float32 cuDSS support. `UMFPACKELTYPES` is defined
locally rather than reusing `SparseArrays.UMFPACK.UMFVTypes`, which is a
non-public internal.
Float32/ComplexF32 sparse now resolve to the `KLUFactorization` slot, which
`algchoice_to_alg` maps to `PureKLUFactorization()` - pure Julia, and the only
thing in the tree that supports these eltypes. It is a hard dependency, so no
extra `using` is needed.
Two separate breakages, both bisected:
0ce03c2 2025-05-22
widened the cachevals to `T <: BLASELTYPES` while adding ComplexF64.
Broke Float32 sparse for Sparspak users; everyone else still hit the
"using Sparspak required" error in `defaultalg` first, so it stayed hidden.
52ebf25 (#1037) 2026-06-13
removed that early error, exposing the breakage to everyone.
Measured before/after, all 10 eltype/index combinations:
before: Float32 and ComplexF32 (Int64 and Int32) all `INIT THREW`
after: all 10 solve, residual 0, eltype preserved (no Float64 promotion)
Explicitly-requested `LUFactorization`/`UMFPACKFactorization` on Float32
sparse remain unsupported, as before this change - they now fail the way
SuiteSparse KLU already does for an unsupported eltype rather than with a
`MethodError`. Making them work would mean silent Float32->Float64 promotion,
which is a behavior addition, not a bug fix.
`Test.detect_ambiguities` on the extension: 12 before, 12 after.
GROUP=Core passes on the fixed tree and on unmodified main.
Claude-Session: https://claude.ai/code/session_017rr42T1vFRRT8D7DMAmJzf
Co-authored-by: ChrisRackauckas-Claude <accounts@chrisrackauckas.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>1 parent 2fcfb43 commit fd8271c
2 files changed
Lines changed: 43 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
128 | 128 | | |
129 | 129 | | |
130 | 130 | | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
131 | 136 | | |
132 | 137 | | |
133 | 138 | | |
| |||
169 | 174 | | |
170 | 175 | | |
171 | 176 | | |
172 | | - | |
| 177 | + | |
173 | 178 | | |
174 | 179 | | |
175 | 180 | | |
| |||
185 | 190 | | |
186 | 191 | | |
187 | 192 | | |
188 | | - | |
| 193 | + | |
189 | 194 | | |
190 | 195 | | |
191 | 196 | | |
| |||
198 | 203 | | |
199 | 204 | | |
200 | 205 | | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
201 | 221 | | |
202 | 222 | | |
203 | 223 | | |
| |||
231 | 251 | | |
232 | 252 | | |
233 | 253 | | |
234 | | - | |
| 254 | + | |
235 | 255 | | |
236 | 256 | | |
237 | 257 | | |
| |||
244 | 264 | | |
245 | 265 | | |
246 | 266 | | |
247 | | - | |
| 267 | + | |
248 | 268 | | |
249 | 269 | | |
250 | 270 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
115 | 115 | | |
116 | 116 | | |
117 | 117 | | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
118 | 137 | | |
119 | 138 | | |
120 | 139 | | |
| |||
0 commit comments