Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 40 additions & 2 deletions PERFORMANCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ Performance issues carry the GitHub label `performance` ([list](https://github.c

| issue | what | experiment | status |
| --- | --- | --- | --- |
| #81 (PR) | regime-A subtrees ran a whole KKT tree on one workgroup; flop limit `subtree_parallelism` | 0 | open PR |
| #81 (PR) | regime-A subtrees ran a whole KKT tree on one workgroup; flop limit `subtree_parallelism` | 0 | merged |
| #82 | KKT refactorization and solve are level-bound after #81: 54–59 launches per refactorization, 62–85 per solve | 5, 6 | open |
| #75 | device LDLᵀ: serial pivot search, one workgroup per regime-B/C front, no vendor `sytrf` | 1, 2 | open, triaged |
| #75 | device LDLᵀ: serial pivot search, one workgroup per regime-B/C front, no vendor `sytrf` | 1, 2 | open, triaged; step 1 (cooperative pivot search) in a PR from `perf/exp1-pivot-search` |
| #60 | regime-A follow-ups: CUDA timings (partly answered by experiment 0) and per-backend local-memory caps | 7 | open, triaged |
| #25 | T25 performance pass (task) | 5, 6, 7 | open |

Expand Down Expand Up @@ -109,6 +109,44 @@ A side effect: the default solve (`deterministic_mode = 0`) now uses its atomic

Revised order: experiments 1–2 (LDLᵀ kernels, #75) and 5–6 (launches and solve) now have the largest measured payoff; experiment 3 (matching and scaling) remains the accuracy blocker on K2 (relres unchanged by this fix).

## Experiments 1–2 results (2026-10-05, RTX 4080)

Issue #75 in three steps, one PR each, measured on the same machine with nothing else running. Refactorization: best of 5 warm runs of `bench/profile_phases.jl` (`*`: the `bench/compare.jl` median, for the matrices the profile skips); cuDSS from `bench/comparison/cudss.csv`; SDS Cholesky from the profile of `main`. The contract does not move: `piv` and `pivot_kind` equal `ref_ldlt!` on the test matrices on the CPU backend and CUDA, D and the panels within `panel_tol`.

### Step 1: cooperative pivot search

The pivot search of `front_ldlt_kernel!` and `subtree_ldlt_kernel!` ran on work item 1. Its column maxima are now workgroup reductions in up to three passes (λ and r with the column maximum; σ and the column-r maxima of Bunch–Kaufman; the fallback scan, one lane per candidate column), with the reference's tie-breaking (first maximum), so every decision is the serial one. Work item 1 takes the pivot from the values before the interchange, which keeps five barriers per step, and folds only the lanes that can hold data. The reference's fallback (`_best_1x1`) skips columns that cannot win and stops the threshold test at the first violation; the result is the same. The regime-A LDLᵀ kernel reserves 1024 B of local memory (`SUBTREE_LOCAL_RESERVE_LDLT`) for the reduction slots.

LDLᵀ refactorization, `main` → step 1:

| matrix | main ms | step 1 ms | step 1 / cuDSS | step 1 / SDS Cholesky |
| --- | --- | --- | --- | --- |
| lap2d_300 | 228 | 192 | 37.4× | 6.12× |
| lap3d_40 | 14,777* | 14,494* | 248× | 64.7× |
| HB/bcsstk17 | 206 | 167 | 49.5× | 6× |
| Boeing/bcsstk38 | 137 | 106 | 32.1× | 4.69× |
| GHS_psdef/apache2 | 92,576* | 97,296* | 199× | 94.5× |
| kkt_pglib_opf_case118_ieee_condensed_1 | 1.77 | 1.82 | 4.66× | 1.99× |
| kkt_pglib_opf_case118_ieee_condensed_10 | 1.72 | 1.79 | 5.13× | 2.04× |
| kkt_pglib_opf_case118_ieee_condensed_20 | 1.87 | 1.82 | 5.18× | 2.08× |
| kkt_pglib_opf_case118_ieee_k2_1 | 1.69 | 1.69 | 4.66× | |
| kkt_pglib_opf_case118_ieee_k2_10 | 1.62 | 1.68 | 4.74× | |
| kkt_pglib_opf_case118_ieee_k2_20 | 1.6 | 1.66 | 4.16× | |
| kkt_pglib_opf_case1354_pegase_condensed_1 | 10.9 | 7.2 | 10.5× | 2.46× |
| kkt_pglib_opf_case1354_pegase_condensed_10 | 10.9 | 7.3 | 11.4× | 2.5× |
| kkt_pglib_opf_case1354_pegase_condensed_20 | 11 | 7.32 | 10.4× | 2.51× |
| kkt_pglib_opf_case1354_pegase_k2_1 | 8.31 | 6.6 | 8.08× | |
| kkt_pglib_opf_case1354_pegase_k2_10 | 7.15 | 6.05 | 7.32× | |
| kkt_pglib_opf_case1354_pegase_k2_20 | 9.1 | 6.71 | 8.32× | |
| kkt_pglib_opf_case14_ieee_condensed_1 | 0.446 | 0.503 | 2.61× | 1.38× |
| kkt_pglib_opf_case14_ieee_condensed_10 | 0.443 | 0.52 | 2.26× | 1.53× |
| kkt_pglib_opf_case14_ieee_condensed_11 | 0.448 | 0.463 | 1.59× | 1.41× |
| kkt_pglib_opf_case14_ieee_k2_1 | 0.669 | 0.697 | 2.49× | |
| kkt_pglib_opf_case14_ieee_k2_10 | 0.722 | 0.708 | 2.98× | |
| kkt_pglib_opf_case14_ieee_k2_15 | 0.97 | 1.03 | 3.2× | |

On the K2 dumps the inertia and `nperturbed` are those of `main` on all nine. On the T15 matrix `kkt_matrix(3000, 1000, 1e-8)` (fallback scans on most steps of its two large root fronts) CUDA goes from 33.9 s to 8.3 s; the KA CPU backend stays at 7.0 s against 2.6 s for `ref_ldlt!` (it runs the work items of a workgroup one after another, so a parallel search saves nothing there). The medium matrices gain 16–34%; the smallest KKT dumps (case14, w ≤ 16) lose up to 17% to the reductions' barriers; the two matrices with very large regime-C fronts (apache2, lap3d_40) are within ±5%, still one workgroup per front.

## Recommendations: Prioritized Experiment Plan

| # | Experiment | Payoff | Effort | Key measurement | Success criterion |
Expand Down
Loading
Loading