You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Matching-based 2×2 pairs (algo5) cost ~2.1× nnz(L) on MadNLP K2 systems #96
Found while working on: T21 (#21, branch task/T21-matching-scaling)
What: With matching_alg = "algo5" the "S"/"H" analysis pairs every 2×2 candidate of the scaled matrix that lies on a cycle of the symmetric matching (matching_pairs, src/matching/mc64.jl). On the K2 dumps of bench/pivot_pairs.jl this is nearly every candidate (case118: 1539 pairs; case1354: 16646), so nnz(L) is 2.09–2.19× the unpaired ordering, against 1.25–1.31× for the default structurally-zero pairs without matching (#66). Accuracy is excellent (case118: 0 perturbed pivots, max|L| ≤ 9.7, relres 5.6e-14 before refinement; case1354: 5–6 perturbed, relres ≤ 3.9e-6, 1e-15 after 5 IR steps; cuDSS algo5: 0/14 perturbed, 5.4e-13/7.7e-3), but the factor and the update stack are ~1.7× larger than needed for the default pairs. On the converged case14 iterate the matching pairs cost 2.06× (default pairs 1.91×) with 0 perturbed pivots instead of 9.
Why it is out of scope: T21 asked for the matching-based pairs; reducing their fill is a tuning question for the owner (T25 performance pass, or a refinement of the pair selection).
Suggested fix or plan change: Apply the structurally-zero test of zero_pivot_pairs! to the matching's cycle pairs (pair a matched 2-cycle only when its candidate's pivot is structurally zero or the scaled diagonal is below a much smaller tolerance), and measure fill vs perturbed pivots on the K2 dumps with bench/pivot_pairs.jl.
Triage of #96 by measurement. Host only, KA CPU backend, Julia 1.13.1. The nine K2 dumps were regenerated with bench/dump_madnlp_kkt.jl (MadNLP, ExaModels and ExaModelsPower in a scratch env): case14 iterations 1, 10 and 15 (15 is the converged iterate), and case118 and case1354 at iterations 1, 10 and 20.
Conclusion: no rule meets the bar. The fill is the price of the accuracy. No code change.
The bar on case1354: nperturbed within a few of T21's 5–6, relres after 5 IR steps ≤ 1e-10, and nnz(L) ≤ 1.5× the unpaired ordering.
rule (algo5)
case118 k2_1/10/20: ratio, perturbed, relres+5
case1354 k2_1: ratio, perturbed, relres+5
case1354 k2_10
case1354 k2_20
case14 k2_15 (converged)
T21 (cycle pairs with a candidate)
2.09–2.19, 0, ≤ 9.8e-16
2.18, 5, 7.4e-16
2.17, 5, 1.3e-15
2.15, 6, 1.2e-15
2.06, 0
a: structurally zero pivots, paired with their matching mate
b and c select nothing new. The K2 dual rows have an exactly zero diagonal. Every matched cycle therefore contains a candidate at any τ > 0, and the value rule keeps every cycle. With τ = 0 it keeps none, which is pivot_pairs = "none".
a reaches the "default" fill (1.24–1.34×) and keeps the T21 accuracy on case14, case118 and case1354 k2_1 (relres before refinement ≤ 1.8e-10 instead of 5.6e-14).
The broken pivots are structurally nonzero but cancel numerically. No structural rule can see them; only a value-aware choice can, which here means pairing every cycle (T21), or the a-posteriori pivoting of T27.
On the converged case14 iterate, a pairs 167 of the 169 cycles, since almost every pivot is structurally zero there. The fill stays 2.06×.
Variants tested along the way, also without success:
a with zero_pivot_pairs!'s greedy partner as a fallback when the mate is taken: never triggered, identical to a.
The structurally-zero rule with the greedy partners instead of the mates, on the scaled matrix: 13–125 perturbed pivots, relres+5 up to 1.1 on case1354.
The fill numbers of PLAN §2.3 step 2 do not change.
Next step: TASKS.md T25 gets the note "re-measure after the level merging whether the extra fronts matter; otherwise accepted" (docs-only PR, Refs #96). Owner: please label this issue triaged.
Full tables follow. Columns: nnz(L) ratio to "none"; zero and perturbed pivots; 2×2 pivots; max abs L and factor error ‖A[p,p] − LDLᵀ‖_F/‖A‖_F, both of the scaled matrix under matching; relres = ‖b − Ax‖/‖b‖ with b = A·1, before refinement and after 2 and 5 IR steps; inertia; dev=ref = device and CPU reference agree on inertia and nperturbed (the reference count is in parentheses when they disagree). The "a'"/"a''" rows are the two variants above.
Activity
PLAN.md: refresh to the implemented design after T21 [skip ci]
PLAN.md: refresh to the implemented design after T21 [skip ci] (#99)
michel2323 commentedon Oct 7, 2026
Triage of #96 by measurement. Host only, KA CPU backend, Julia 1.13.1. The nine K2 dumps were regenerated with
bench/dump_madnlp_kkt.jl(MadNLP, ExaModels and ExaModelsPower in a scratch env): case14 iterations 1, 10 and 15 (15 is the converged iterate), and case118 and case1354 at iterations 1, 10 and 20.Conclusion: no rule meets the bar. The fill is the price of the accuracy. No code change.
The bar on case1354: nperturbed within a few of T21's 5–6, relres after 5 IR steps ≤ 1e-10, and nnz(L) ≤ 1.5× the unpaired ordering.
What the table shows:
pivot_pairs = "none".The fill numbers of PLAN §2.3 step 2 do not change.
Next step: TASKS.md T25 gets the note "re-measure after the level merging whether the extra fronts matter; otherwise accepted" (docs-only PR, Refs #96). Owner: please label this issue
triaged.Full tables follow. Columns: nnz(L) ratio to "none"; zero and perturbed pivots; 2×2 pivots; max abs L and factor error ‖A[p,p] − LDLᵀ‖_F/‖A‖_F, both of the scaled matrix under matching; relres = ‖b − Ax‖/‖b‖ with b = A·1, before refinement and after 2 and 5 IR steps; inertia; dev=ref = device and CPU reference agree on inertia and nperturbed (the reference count is in parentheses when they disagree). The "a'"/"a''" rows are the two variants above.
Measured tables (nine K2 dumps)
kkt_pglib_opf_case118_ieee_k2_1.mtx (n = 3150)
kkt_pglib_opf_case118_ieee_k2_10.mtx (n = 3150)
kkt_pglib_opf_case118_ieee_k2_20.mtx (n = 3150)
kkt_pglib_opf_case1354_pegase_k2_1.mtx (n = 33811)
kkt_pglib_opf_case1354_pegase_k2_10.mtx (n = 33811)
kkt_pglib_opf_case1354_pegase_k2_20.mtx (n = 33811)
kkt_pglib_opf_case14_ieee_k2_1.mtx (n = 344)
kkt_pglib_opf_case14_ieee_k2_10.mtx (n = 344)
kkt_pglib_opf_case14_ieee_k2_15.mtx (n = 344)
Generated by Claude Code
Docs: accept the fill of matching-based pairs (#96) (#104)
michel2323 commentedon Oct 9, 2026
Triaged: accepted as documented in #104. The re-measurement after level merging is an item of T26 (segmented fused factorization) in
TASKS.md.Generated by Claude Code
Docs: split T25 into T22/T24-T26 after PR #107, renumber the post-v1 …
Docs: split T25 into T22/T24–T26 after PR #107, renumber the post-v1 …