From 7a395c756f5d8d6b975442ac393f037d0c547d81 Mon Sep 17 00:00:00 2001 From: juliankang4 <200967947+juliankang4@users.noreply.github.com> Date: Thu, 22 Oct 2026 06:20:19 +0900 Subject: [PATCH 1/2] gate_nvtier: the all-RAM arm loads before the paged arm The paged arm's tier, which the room, advice, footprint and counters clauses read after both arms, kept its RAM arena (about 23.5 GB on the gate plan) mapped while the all-RAM arm loaded. That arm's host need (105.8 GB on the gate plan) does not count the arena, but the host's reading had already lost it, so a 128 GB host refused the load although the arm alone fits. The all-RAM arm now loads first, as the nvtier family gate already orders its arms. --- crates/gpu-gates/src/bin/gate_nvtier.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/crates/gpu-gates/src/bin/gate_nvtier.rs b/crates/gpu-gates/src/bin/gate_nvtier.rs index 2b810a315..8e99c69fa 100644 --- a/crates/gpu-gates/src/bin/gate_nvtier.rs +++ b/crates/gpu-gates/src/bin/gate_nvtier.rs @@ -1996,6 +1996,12 @@ fn run() -> Result<(), GateError> { // `grant` (clause 13)'s children run before the paged arm holds its // arena; their answer is read after the `bits` line. let grant = grant_run(&grant_terms); + // The all-RAM arm loads first: the paged arm's tier, which the clauses + // below read, holds its arena until the stepunion arms, and the host's + // reading at the all-RAM arm's load would lose those bytes. + let ram = arm( + path, &machine, None, residency, host, &ids, false, &probe, None, + )?; let mut paged = arm( path, &machine, @@ -2007,9 +2013,6 @@ fn run() -> Result<(), GateError> { &probe, band, )?; - let ram = arm( - path, &machine, None, residency, host, &ids, false, &probe, None, - )?; let tokens_eq = paged.tokens == ram.tokens; let digests_eq = paged.digests == ram.digests; From 13ba94237bf4223de435ef2ebaf181fd932c7319 Mon Sep 17 00:00:00 2001 From: juliankang4 <200967947+juliankang4@users.noreply.github.com> Date: Thu, 22 Oct 2026 07:42:42 +0900 Subject: [PATCH 2/2] gate_nvtier: the pack's resource row carries the all-RAM arm's host need The row declared 92,054,154,240 B, the qwen4exp plan's need, but the gate's all-RAM arm also holds the 14.6 GB residency churn pool and needs 105,818,045,440 B. --- tools/gate-batch-resources.tsv | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/gate-batch-resources.tsv b/tools/gate-batch-resources.tsv index 3d991bd12..050235b12 100644 --- a/tools/gate-batch-resources.tsv +++ b/tools/gate-batch-resources.tsv @@ -13,6 +13,9 @@ # glm5next --place gate: need=173,015,891,968 B (the glm5next serve log's cache line) # qwen4exp --place gate: need=92,054,154,240 B (the qwen38 serve log's cache line); the serve/residency seats add # the churn pool 35.6e9 B beside it; iqleg loads the file twice (both resident): 2 x. +# nvtier gate_nvtier: the all-RAM arm loads first and its load need is 105,818,045,440 B (host experts 62,397,542,400 B + +# tables 28,800,138,240 B + reserves 6,694,629,376 B + residency churn pool 14,620,364,800 B − OS reserve 6,694,629,376 B); +# the paged arm loads after it, 5.5e9 B need + 23.5e9 B arena, the smaller. [derived from the load check's refusal line] # qwen38-media: the qwen38-serve row's need, qwen4exp --place gate (the text load, the media load and the servers load one # after the other, never two at once; the media load's rotation tables are card bytes, none are host bytes); # the server arms may run the residency pool, whose 35.6e9 B the serve row carries [derived] @@ -36,7 +39,7 @@ gate-gpu-ds41-long m 237600000000 gate-gpu-ds41-twocard - 237600000000 gate-gpu-glm5next-serve - 173015891968 gate-gpu-glm5next-twocard - 173015891968 -gate-gpu-nvtier - 92054154240 +gate-gpu-nvtier - 105818045440 gate-gpu-qwen38-media - 127654154240 gate-gpu-qwen38-residency - 127700000000 gate-gpu-qwen38-serve - 127654154240