GOAL — full GPU execution of the AOM/moment screening engine (2026-06-08 →)¶
Objective (user-set): make the three screening layers run fully on GPU, with a measured before/after at each step.
Moments on GPU — base moments
XᵀX/XᵀYbuilt and kept device-resident, no per-candidate host round-trip.AOM on GPU — the per-candidate operator→moment transform and the Ridge GCV solve on the device, batched over candidates.
PLS tuning loop on GPU — the screen batched over chain × candidate × fold in one launch (folds already batched), fed device-resident moments.
Measured priority (5b-0, nsys on BERRY p=2101, 71.3 s) — see fused_moment_executor_design.md¶
Rank |
Host hotspot |
Share |
GPU target |
|---|---|---|---|
1 |
|
37% |
cuSOLVER SPD Cholesky/eigh |
2 |
synchronous |
~20% samples |
device residency / pinned mem |
3 |
CPU OpenBLAS matmuls |
~6% |
route to cuBLAS / device moments |
— |
|
2.6% |
minor — batch later |
The draft “fused IKPLS scorer” and “dense moment transform” were not the bottleneck (Codex-flagged, profile-confirmed). Reordered accordingly.
Blocks (ordered by measured value; each behind the green gate, ABI 1.22.0, fp64 host-equivalence)¶
B1 — Ridge GCV solve → GPU (cuSOLVER). ✅ DONE (2026-06-08). Device SPD Cholesky (
spd_solve) on the 3 dual ridge sites, host fallback, equivalence-tested. 3.83× total on BERRY/COLZA/LUCAS (BERRY 7.59×), RMSEP preserved, green gate green, ABI 1.22.0. See worklog 2026-06-08.B2 — Device-resident dual-Ridge (upload K once). ✅ DONE (2026-06-08). Per-fold
prepare_dual_ridgeuploads K once + reuse-buffers Cholesky +add_scaled_identityλ-shift. 1.07× incremental (cumulative 4.22×), RMSEP bit-identical, green gate green, ABI 1.22.0. Targeted the ridge-solve copies; broader moment copies → B3.B3 — Device moment/gram build. ⚙️ KEPT as a size-gated env opt-in (2026-06-08). The un-gated drop-in regressed (0.96×: the moment build is host-OpenBLAS-optimal and XᵀX is consumed on host, so GPU-only-build adds a D2H), so it is gated:
build_moments_device/build_gram_devicerun only whenn·p² ≥ N4M_CUDA_MOMENT_MIN_PRODUCT(default 15e9;0=always GPU, higher=always host). Correct, bit-equivalent, equivalence-tested; a wash on consumer GPUs but a potential win on strong-fp64 datacenter GPUs (A100/H100) — zero cost when off. Default = host build. See worklog. (The operator-transform route Fable’s trace expected is dead code, gated off p>1024 — not the target.)B4 — (not pursued) Full device-resident moment chain + device-pointer PLS scorer entry. The investigation (incl. LUCAS_SOC: moment build ~1% of a 2402s fit) showed the moment build is never the pipeline bottleneck at any scale, so B4 would not help either; the captured win is B1+B2 (4.22×). Pursue only if a future profile / different hardware justifies it.
Process (multi-agent, user-set)¶
Fable 5 (
claude --model claude-fable-5): block design/roadmap + code review.Codex (
codex exec): implementation under Fable’s design + Opus’s directives.Opus (orchestrator): directives, final diff review, build + green gate (
n4m_tests/n4m_internal_testsCUDA & dev-release, catalog/ABI checks), and the before/after benchmark on BERRY/COLZA/LUCAS (/tmp/bench_5b_baseline.csvis the “before”). Corrects when needed.
Green gate per block: CUDA n4m_c + n4m_tests + n4m_internal_tests; dev-release
n4m_c; catalog/scripts/validate.py --check-references --strict-abi,
reconcile_abi.py --check; git diff --check. ABI stays 1.22.0 (internal only).