feat(gpu): O2 — arm the register_budget contract, vacuous since 2026-04-06 - #3064
Merged
Conversation
…s since 2026-04-06
contracts/trueno/ptx-codegen-safety-v1.yaml equation `register_budget` declares
forall kernel K:
reg_count(K) <= max_regs_per_thread(sm)
shared_mem(K) <= max_shared_per_block(sm)
postcondition: cuOccupancyMaxActiveBlocksPerMultiprocessor > 0
and NOTHING enforced it. The generated macro `contract_register_budget!` is invoked
nowhere in the tree, and its postcondition names an unbound identifier that would
not compile if it ever were. Meanwhile aprender launches hand-emitted PTX with
hardcoded block sizes (128/256) and validates nothing about the kernel the JIT
actually produced. This is that missing enforcement.
Design — two deliberate splits:
1. POLICY IS UNGATED. `crate::launch_budget::validate_launch` is pure and lives at
the crate root, NOT under `driver`. The whole `driver` module is
`#[cfg(feature = "cuda")]` (lib.rs:138), so anything placed there runs only with
--features cuda and would never reach the required check. Measured: that is why
driver::ptx_patch's GH-480 tests are dark today, despite its module comment
claiming "NOT feature-gated so that its tests run without CUDA hardware".
The 13-case table therefore runs everywhere; aprender-gpu --lib goes 444 -> 457.
2. LIMITS ARE QUERIED, NOT TABULATED. A per-SM limit table goes stale every GPU
generation and this one did: the hand-written CU_TARGET_COMPUTE_* list stops at
90, and so did the contract's own `domain`. driver/budget_query.rs reads the
limits from cuDeviceGetAttribute, so sm_100/120/121 and whatever ships next
need no edit here.
New FFI (driver/sys/mod.rs, via the existing load_sym! pattern):
cuFuncGetAttribute, cuOccupancyMaxActiveBlocksPerMultiprocessor, plus the
CU_FUNC_ATTRIBUTE_* / CU_DEVICE_ATTRIBUTE_* constants they need.
Contract repaired in the same commit:
- `registry: true` dropped (operator ruling 2026-08-21)
- FALSIFY-PTX-003's prose test ("Parse ptxas output...") replaced with two
executable cargo commands; a prose test never runs
- `domain` extended past sm_90 to 100/120/121
- two pre-monorepo reference paths fixed (trueno/src/..., realizar/src/...)
- `enforced_by:` names the two files that now implement it
- pv validate: 0 errors, 0 warnings
MUTATION PROOF (measured, not asserted). Deleting the block-size comparison in
validate_launch turns 4 tests RED and restoring turns them GREEN:
launch_budget::tests::rejects_block_above_kernel_max
launch_budget::tests::kernel_max_is_reported_before_device_max
launch_budget::tests::violations_name_both_sides_of_the_comparison
driver::cuda_tests::launch_budget_hw::budget_goes_red_on_an_oversized_block
The hardware test earns its place only because it asserts the SPECIFIC violation.
Its first version asserted merely that an error occurred and SURVIVED the mutation
-- the oversized launch falls through to the device-wide check and still errors, so
the test witnessed nothing. That was found by running the mutation, not by review,
and the contract's red_witness records it.
Verified: fmt clean; clippy -D warnings clean on default AND --features cuda (the
raw-pointer entry points are `unsafe fn` with Safety docs rather than an #[allow]);
457/457 default tests; 19/19 with --features cuda on RTX 4090 sm_89.
Refs #3062
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J9cSQynVPYeUkQ2i7ccvrs
noahgift
enabled auto-merge
September 9, 2026 12:33
|
§13.11 rung 1 — quorum shadow verdict Shadow mode: this records a verdict and merges nothing. A refusal |
noahgift
added a commit
that referenced
this pull request
Sep 9, 2026
…es re-derived from a cwd OUTSIDE the checkout — a worktree nested under /home/noah/src/aprender inherits its .cargo/config.toml [patch.crates-io], and the bump's regenerated locks carried 11 [[patch.unused]] entries CI's clean cargo refuses under --locked (guard-cargo + bump --check RED on run 34407841821) Pmat-Ticket: PMAT-1096 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BjhtNUSensCYpQb3mCYLod
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.
O2 of the 0.67 CUDA Rust spec (#3062). Developed and validated on gx10 (GB10 Blackwell sm_121), the only host where the interesting arch lives.
The defect
contracts/trueno/ptx-codegen-safety-v1.yamlequationregister_budgetdeclares a register/shared-memory budget with postconditioncuOccupancyMaxActiveBlocksPerMultiprocessor > 0. Nothing enforced it:contract_register_budget!is invoked nowhere in the treecuOccupancyMaxActiveBlocksPerMultiprocessor, an unbound identifier that would not compile if the macro ever were invokedFALSIFY-PTX-003'stest:is prose — "Parse ptxas output for register count, assert <= 128" — and prose never runsregistry: true, the exemption class retired 2026-08-21Meanwhile
aprender-gpulaunches hand-emitted PTX with hardcoded block sizes (128/256) and validates nothing about the kernel the JIT actually produced.Two deliberate design splits
1. The policy is ungated.
crate::launch_budget::validate_launchis pure and lives at the crate root, not underdriver. The wholedrivermodule is#[cfg(feature = "cuda")](lib.rs:138), so anything placed there runs only with--features cudaand would never reach the required check.aprender-gpu --libgoes 444 → 457 tests, all in the CPU-only path #3063 un-darks.2. Limits are queried, not tabulated. A per-SM table goes stale every GPU generation and this one did — the hand-written
CU_TARGET_COMPUTE_*list stops at 90, and so did the contract's owndomain.driver/budget_query.rsreads limits fromcuDeviceGetAttribute, so sm_100/120/121 and whatever ships next need no edit here.Mechanism engaged, on Blackwell
Not "it compiled" — the actual values read back on GB10 sm_121 under ptxas 13.3:
19/19with--features cudaon sm_121, and13/13pure on the default build. Also 19/19 on RTX 4090 sm_89.Mutation proof — and the test that failed it
Deleting the block-size comparison in
validate_launchturns 4 tests RED, restoring turns them GREEN:The hardware test's first version SURVIVED the mutation. It asserted only that an error occurred — but with the kernel-max check deleted the oversized launch falls through to the device-wide check and still errors, so the test witnessed nothing. It now asserts the specific violation. That was found by running the mutation, not by reading the test, and the contract's
red_witnessrecords it.Contract repaired in the same commit
registry: truedroppedFALSIFY-PTX-003prose replaced with two executablecargo testcommandsdomainextended past sm_90 to 100/120/121trueno/src/…,realizar/src/…— neither exists since APR-MONO)enforced_by:names the two files that now implement itpv validate→ 0 errors, 0 warningsVerification
cargo fmtclean ·clippy -D warningsclean on both default and--features cuda— the raw-pointer entry points areunsafe fnwith# Safetydocs rather than an#[allow]· 457/457 default · 19/19 cuda on sm_89 and sm_121.Refs #3062
🤖 Generated with Claude Code
https://claude.ai/code/session_01J9cSQynVPYeUkQ2i7ccvrs