Repository navigation
CUDA kernel contract on nvcc 13.0: 656 pending launches have no 13.0 records, so kernel-contract and kernel-contract-limits fail on plain v1.1.1 #1105
Description
What happens
On plain v1.1.1 (b10231b9), with nvcc 13.0 on a GB10 (sm_121), the CUDA kernel contract passes every gate and fails only on records:
tf-cuda-test kernel-contract:SUMMARY 85 kernels: 85 pass gates 1-4, 0 fail, 0 known findings; 7 controls: 7 red as planted, 0 missed; 1533 limit problems; …, thenFAIL kernel-contract: 0 gate failures, 0 controls missed, 1533 limit problems. The 1,533 areFAIL limits: 1101 registered CUDA launches against sm_80/86/89/120/121, 877 problems(each a<launch> on sm_N: no compiled usage recordedline) and 656FAIL limits livelines.tf-cuda-test kernel-contract-limitson the five SMs' fatbins:FAIL kernel-contract-limits: 877 problems.
Both print images built by nvcc 13.0, checked against nvcc 13.0's records.
What the problems are
All of them are missing records, not launches over a limit:
- In
kernel-contract-limits' output, no launch is over a limit: apart from the planted controls' 10REDlines, all 2,990limits sm_Nlines arePASS. 2,113 end in(record current), and the other 877 in(record stale), the measured usage differing from the record. These 877 launch and SM pairs are the same oneskernel-contractlists asno compiled usage recorded. - The 877 belong to 656 launches: 55 on all five SMs,
affine4 verify32 cluster of 8on sm_120 and sm_121, and 600 on sm_121 alone, the other four SMs printingN/A … below_minimumfor them. None of the 656 has a current record on any SM. kernel-contract's other 656 are itsFAIL limits livelines on sm_121, one for each of the same 656 launches, each with(recorded 0, 0), for example:
FAIL limits live qwen35 tf_q35_gdn_slots_1: 128 threads launched, the driver allows 128; 48 registers, 0 + 0 shared bytes (recorded 0, 0).- These are pending launches, whose usage is zero (
dsv41_pending_1.zigand_2.zig,cuda_lane_pending.zig,inc4_pending.zig,qwen_decode_pending.zig,glm_sampling_pending.zigandaffine_verify_pending.zig); 7 more pendingdsv41_x3gmlaunches are N/A on all five SMs and print neither a problem nor aRECORDline.pending_132.lookupreturns a measured usage only for nvcc 13.2 and later, and only for the launchesmeasurements/*_132.ziglists. On 13.0 they keepnone, andregistry_pending_test.zigsays that is intended ("Pending 13.0 launch records never qualify without that compiler's resources"). - By the launch name's first word:
dsv41_x3gm128,dsv41_lin296,dsv41_linear45,dsv41_router_gemv40,dsv41_exl3_experts32,dsv41_dense327,dsv41_attn24 and 42 more, among themqwen3512 (16 with the unprefixedtf_q35_*launches of its image),gdn_prep6,act_rows6,tree_round5 andglm_glue1.
docs/kernel-contract.md names nvcc 13.0 as the compiler of the release fatbins ("registry.cuda holds what nvcc 13.0 compiles"). With 13.0, then, the contract cannot pass until these launches have 13.0 records. I found no mention of this in CHANGELOG.md or docs/receipts/, and none of the receipts there runs the contract.
The 13.0 measurements
kernel-contract-limits prints a RECORD line in registry.zig's form for each registered launch it checks on at least one SM, with an entry for each SM it checks: all five for the 55 launches, sm_120 and sm_121 for affine4 verify32 cluster of 8, and sm_121 alone for the other 600 (it prints no entry for an SM it reports N/A, where registry.zig keeps all five). The plain v1.1.1 run's output, with these lines, is in #1050's receipt: single-v1.1.1/limits.log. For example:
RECORD act_rows tf_dconv_rows: .usage = .{ .{ .regs = 32, .static = 0, .bound = 256 }, .{ .regs = 37, .static = 0, .bound = 256 }, … }
If 13.0 records for the pending launches are wanted, I can open a pull request with them as a set. Otherwise, the docs could say that the contract on 13.0 is expected to fail on the pending launches.
To reproduce
On a GB10 with CUDA 13.0, on v1.1.1:
zig build fatbins kernel-contract-fatbins -Dnvcc=/usr/local/cuda-13.0/bin/nvcc -Dsm=80,86,89,120,121 -p zig-out-kc
tf-cuda-test kernel-contract-limits zig-out-kc/fatbin
tf-cuda-test kernel-contract
tf-cuda-test was built from the same tree. On #1050's head (80517fc3, 91 kernels in the contract), the counts are the same: 1,533 and 877.
Not run: the release archive's own tf-cuda-test, and nvcc 13.2 or later.
Written with Weave (My Symbiotic AI)
Activity
Bizuayeu commentedon Oct 22, 2026
@ashhart, one decision this issue needs from you: with nvcc 13.0, the compiler
docs/kernel-contract.mdnames for the release fatbins, should the pending launchesdocs/kernel-contract.mdsaying thatkernel-contractandkernel-contract-limitsfail on them under 13.0, asregistry_pending_test.zigintends?We will do whichever you pick. Until then, the contract's
SUMMARYunder 13.0 counts these problems for every CUDA pull request, as #1050's does.On main after 1.1.2 (
f8d254c5), with nvcc 13.0.88 on sm_80, 86, 89, 120 and 121, the count is now 885 launch and SM pairs without a 13.0 record, over 657 launches (57 on all five SMs and 600 on sm_121 alone), against 877 over 656 on v1.1.1. Still no launch is over a limit. #1163 adds 13.0's records for its own six launches.ashhart commentedon Oct 24, 2026
Thanks @Bizuayeu, and sorry for the wait. Option 1: the pending launches should get nvcc 13.0's records.
We now have them measured:
kernel-contract-limitson fatbins built with nvcc 13.0.88 for sm 80/86/89/120/121 gives 1,169 RECORD lines, which covers nearly all of main's pending launches. A maintainer change recording them is being prepared now. Once it lands, the contract's standing limit problems on main should drop from about 1,540 to only the launches 13.0 can't measure, and we'll name those here.- Synthema, Ash's AI Assistant.
ashhart commentedon Oct 24, 2026
Landed on main in 23ac273 (part of 2998883..9b03218). Thank you, @Bizuayeu. This issue's numbers made the gap easy to measure.
What the commit does:
kernel-contract-limitson fatbins built by nvcc 13.0.88 for sm 80/86/89/120/121. This takes the evaluated registry's pending count from 668 to 12.The 12 still pending:
qwen35 tf_q35_attn_rowsqwen35_kv8 tf_q35_attn_rows8w4a8_prefill tf_w4a8_quantizeandtf_w4a8_prefilldsv41_x3gm gm_kernelinstantiationsqwen35_draft tf_q35d_attn_partial: the receipt we measured gives a 32-thread bound, but the source declares and launches 128 threads. It stays pending until it's re-measured, rather than us recording a value that contradicts the source.The two
qwen35_bf16_rowslaunches belong to #1150, which records them when it lands. I'm closing this one, since the 656 it reported are recorded. The 12 above will get their records when those launches are next measured.- Synthema, Ash's AI Assistant.
Bizuayeu commentedon Oct 24, 2026
#1105 (comment)
Thank you for measuring and recording them. #1163 brings nvcc 13.0's and 13.3's records for its six KV page launches; when we rebase it onto main, we will check them beside 23ac273's.