fix(gpu): cap the GPU test targets, count the aux retries, split the downgrade counter - #924
Open
MauroToscano wants to merge 3 commits into
Open
fix(gpu): cap the GPU test targets, count the aux retries, split the downgrade counter#924MauroToscano wants to merge 3 commits into
MauroToscano wants to merge 3 commits into
Conversation
A panic on a device-only cliff assert can leave the prover hung instead of aborting: the panicking thread unwinds while its siblings stay parked in CUDA driver waits, so the process never exits. Observed repeatedly on rented 5090s under VRAM pressure. The merge-queue GPU job runs the Makefile targets through scripts/gpu_test.sh with no per-target limit, so one hang holds the box until the workflow timeout kills the whole job with no indication of which group stalled. Wrap the four cuda targets that run the prover in `timeout -k 30 2700`. 45 minutes is well above their normal runtime and well below the job timeout, and timeout's 124 exit fails the target, so gpu_test.sh names the stalled group and the merge is blocked. test-math-cuda is left alone: kernel parity never enters the prover.
The R1 resident-aux path retries the device LDE after a full device drain when the first attempt declines, and that retry usually succeeds — which is the problem: a successful retry left no trace anywhere except an eprintln, so how often the device actually declines under VRAM pressure was unmeasurable in production, where nobody is reading stderr. GPU_RESIDENT_AUX_RETRIES makes the decline rate observable and separates it from its consequence: retries with no downgrades means the drain absorbed the pressure, while the two rising together means the drain is no longer enough.
GPU_DEVICE_ONLY_DOWNGRADES counted two unrelated events: the R2 device-only downgrade in materialize_lde_trace_host, which is always a device-only gate miss, and the R1 resident-aux downgrade in materialize_aux_trace_host, which is entered whenever aux_resident() is set and so fires on tables the gate never marked device-only. A GPU run made that concrete: a preprocessed BITWISE table took the R1 downgrade despite never being device-only, and the combined counter reported it as a gate miss with nothing to distinguish it from one. Keep GPU_DEVICE_ONLY_DOWNGRADES on the R2 site alone and add GPU_RESIDENT_AUX_DOWNGRADES for the R1 site, so a nonzero value names its own fix: mirror the missing condition into the gate for the former, relieve VRAM pressure for the latter. The integration test now asserts both are zero with per-site messages, and the gate docs say which counter each round bumps.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three more follow-ups on the device-only downgrade recovery, continuing #921
(merged) on the same base. #921 hardened the recovery path by reading; these
come from watching it run.
Addendum (post-GPU-investigation)
The hang was observed live on rented 5090s: a panic on a device-only cliff
assert does not reliably abort the process — the panicking thread unwinds while
its siblings stay parked in CUDA driver waits, and the prover hangs forever —
so the merge-queue GPU targets now carry per-target
timeouts rather thanholding the rented box until the workflow-level timeout kills the job with no
indication of which group stalled. The resident-aux retry counter makes decline
frequency observable in production, where the drain-and-retry usually succeeds
and, until now, left no trace but an eprintln nobody reads. And the downgrade
counter is split by site, because the investigation showed the two sites firing
independently: a preprocessed BITWISE table took the R1 resident-aux downgrade
despite never having been device-only, which the combined counter reported as a
device-only gate miss with nothing to tell the two apart. Each counter now names
its own fix — mirror the missing condition into the gate for R2, relieve VRAM
pressure for R1.
1. Per-target wall clock on the GPU test targets
scripts/gpu_test.shruns five Makefile targets on the rented box with noper-target limit, so a hung prover burns the box until the workflow timeout and
the log never says which group stalled. The four targets that run the prover
(
test-cuda-integration,test-cuda-fallback,test-prover-cuda,test-prover-comprehensive-cuda) are now wrapped in a sharedGPU_TEST_TIMEOUT := timeout -k 30 2700. 45 minutes is well above their normalruntime and well below the job timeout;
timeout's 124 exit fails the target,so
gpu_test.shnames the group and blocks the merge as it would for any otherfailure.
test-math-cudais deliberately left alone — kernel parity neverenters the prover, so it has no exposure to this hang.
2.
GPU_RESIDENT_AUX_RETRIESThe R1 resident-aux path retries the device LDE after a full device drain, and
that retry usually succeeds — which is exactly why it was invisible. The counter
is bumped where the "declined … retrying after device drain" eprintln fires, so
it counts declines rather than outcomes, and it is included in
reset_all_gpu_call_counters(). Read against the downgrade counter it separatescause from consequence: retries with no downgrades means the drain absorbed the
pressure, both rising together means it no longer does.
3. Splitting
GPU_DEVICE_ONLY_DOWNGRADESThe counter was incremented from two sites with different meanings:
materialize_lde_trace_host(R2), which is always a device-only gate miss, andmaterialize_aux_trace_host(R1), which is entered wheneveraux_resident()isset — whatever the gate said — and so fires on tables that were never
device-only. Conflating them makes the number unusable for the thing it exists
to surface.
GPU_DEVICE_ONLY_DOWNGRADESnow counts the R2 site only, and thenew
GPU_RESIDENT_AUX_DOWNGRADEScounts R1; both doc comments state their soleincrement site, and the
device_only_gatedocs (rewritten by #920, whichdescribed the combined semantics) now say which counter each round bumps and
that the gate does not govern the R1 one.
gpu_device_only_residency_fires_and_verifiesasserted the old combined counterwas zero; it now asserts both are zero with per-site messages, the existing
gate-mirroring text staying on the device-only one.
Testing
make fmtclean,make lintgreen across all four passes including--features lambda-vm-prover/cudavia the empty-cubin stubs, andcargo check -p starkfor the non-cuda build.The touched code was not executed. No CUDA toolchain on this machine, and
the counters sit on the recovery path, which runs only when a device dispatch
declines under real VRAM pressure. The Makefile change is verified by
make -nexpansion; the rest is by reading plus the merge-queue GPU job. Notethat the timeout wrapper assumes GNU coreutils
timeout, which the Linux GPUbox has but stock macOS does not — these targets already require an NVIDIA GPU
and nvcc, so they were never runnable on a mac.