spark_model/layers/ops/ssm_gdn_tc_route.rs
1// SPDX-License-Identifier: AGPL-3.0-only
2
3//! The tensor-core GDN prefill spine's ENTRY NAME and its route line.
4//!
5//! # Why the name is a constant
6//!
7//! H100 round 12 (`h100-round12-report.md`, stage 2c and 4b): the serve logged
8//!
9//! ```text
10//! GDN state spine: gated_delta_rule_chunk_delta_h_tcfuse (ATLAS_GDN_PREFILL_TC; …)
11//! ```
12//!
13//! while the nsys trace of the same cell showed launches of
14//! `gated_delta_rule_chunk_delta_h_tcfuse_x2` and **none** of the 1-limb entry.
15//! The log named the FAMILY; the binary ran the `_x2` member. That is not a
16//! cosmetic difference on this kernel — the 1-limb `…_tcfuse` entry misses the
17//! spine's own accuracy contract (`h` rel_rms 2.0e-3 to 2.7e-3 against a 1e-3
18//! budget, at every T the microtest runs) and the `_x2` arm is the one that
19//! passes it (3.0e-6 to 3.9e-6). A reader diffing the serve log against the
20//! microtest's arm names reads the shipped arm as the ungated one.
21//!
22//! So the name exists ONCE, here. `qwen3_ssm::init_kernels` binds the handle
23//! with it and [`gdn_tc_spine_route_line`] prints it; neither spells a string
24//! of its own, which is the only arrangement in which the two cannot drift
25//! apart again.
26
27/// The spine entry the `[defaults] gdn_prefill_tc` lever ships.
28///
29/// `_x2` = two bf16 limbs of `S_c` in Phase A. Both entries are ABI-, grid-,
30/// block- and smem-identical, so the choice is invisible downstream and only
31/// the accuracy contract separates them (see the module docs).
32pub const GDN_TC_SPINE_ENTRY: &str = "gated_delta_rule_chunk_delta_h_tcfuse_x2";
33
34/// The module the entry lives in — `kernels/gb10/common/
35/// gated_delta_rule_chunk_tc.cu`, shared, not relocated to `kernels/hopper`.
36pub const GDN_TC_SPINE_MODULE: &str = "gated_delta_rule_chunk_tc";
37
38/// The SCALAR spine entries `qwen3_ssm::init` can bind — `ATLAS_GDN_PIPE=1`,
39/// `ATLAS_GDN_VTILE=1`, and the default. Named here beside the tensor-core
40/// entry for the same reason that one is: the init route line and the handle
41/// are built from the same string or they drift apart.
42pub const GDN_SCALAR_SPINE_PIPE: &str = "gated_delta_rule_chunk_delta_h_pipe";
43/// SPLIT=4 / 512 threads. Reachable, never default — see `init_kernels`.
44pub const GDN_SCALAR_SPINE_VTILE: &str = "gated_delta_rule_chunk_delta_h_vtile";
45/// SPLIT=2 / 256 threads: the default scalar spine.
46pub const GDN_SCALAR_SPINE_VFUSED: &str = "gated_delta_rule_chunk_delta_h_vfused";
47
48/// `GDN state spine: …` — the line `qwen3_ssm::init` prints ONCE PER LAYER as
49/// it binds the handles, before any prefill has run.
50///
51/// # Why it is not simply the scalar entry's name
52///
53/// H100 round 14 (`h100-round14-report.md`, anomaly 2). A serve with the
54/// tensor-core spine live logged both of these:
55///
56/// ```text
57/// 48 qwen3_ssm::init: GDN state spine: gated_delta_rule_chunk_delta_h_vfused
58/// 14400 GDN state spine: gated_delta_rule_chunk_delta_h_tcfuse_x2 (…)
59/// ```
60///
61/// 48 init lines naming the scalar parent, one per layer, ahead of 14 400
62/// dispatch lines naming the kernel that actually ran. `f9ae638` fixed the
63/// dispatch line; the init line was not touched, and it is the FIRST GDN line
64/// a reader meets in a log they opened to answer "did the lever engage?" — so
65/// it read as "the TC spine is not engaged" on a serve where it was.
66///
67/// The line now reads the handle the probe resolved, which is the same bit the
68/// dispatch reads: with the `[defaults] gdn_prefill_tc` handle bound, the spine
69/// that will launch is [`GDN_TC_SPINE_ENTRY`] and the line says so. The scalar
70/// entry stays bound underneath — the dispatch's shape guards fall back to it,
71/// and the dispatch logs whichever one it launched — but it is no longer what
72/// this line NAMES, which was the whole defect.
73pub fn gdn_init_spine_line(tc_spine_bound: bool, scalar_entry: &str) -> String {
74 if tc_spine_bound {
75 format!(
76 "GDN state spine: {GDN_TC_SPINE_ENTRY} ([defaults] gdn_prefill_tc; the \
77 scalar spine stays bound as the fallback the prefill's shape guards \
78 drop to, and the prefill logs the entry it launches)"
79 )
80 } else {
81 format!("GDN state spine: {scalar_entry}")
82 }
83}
84
85/// `GDN state spine: …` — the line the prefill prints when the tensor-core
86/// spine is live, built from [`GDN_TC_SPINE_ENTRY`] so it can only ever name
87/// the kernel the probe bound.
88///
89/// Pure and returning a `String` rather than logging: a route line nothing can
90/// grade is how a log comes to describe a kernel the binary does not run,
91/// which is the defect this file exists to close.
92pub fn gdn_tc_spine_route_line(num_v_heads: u32, batch_size: u32, smem_bytes: u32) -> String {
93 format!(
94 "GDN state spine: {GDN_TC_SPINE_ENTRY} (ATLAS_GDN_PREFILL_TC; bf16 mma.sync \
95 operands, f32 accumulator = the recurrent state, h stays f32) \
96 grid=[{num_v_heads},{batch_size}] block=256 smem={smem_bytes}B"
97 )
98}
99
100#[cfg(test)]
101mod tests {
102 use super::{
103 GDN_SCALAR_SPINE_PIPE, GDN_SCALAR_SPINE_VFUSED, GDN_SCALAR_SPINE_VTILE, GDN_TC_SPINE_ENTRY,
104 gdn_init_spine_line, gdn_tc_spine_route_line,
105 };
106
107 /// THE ROUND-12 NIT, pinned: the line names the `_x2` entry, not the
108 /// family. `…_tcfuse ` with a trailing space is what the old line printed
109 /// and is what a reader would mistake for the ungated 1-limb arm.
110 #[test]
111 fn the_route_line_names_the_entry_that_is_launched() {
112 let line = gdn_tc_spine_route_line(48, 1, 88_324);
113 assert!(line.contains(GDN_TC_SPINE_ENTRY), "{line}");
114 assert!(
115 !line.contains("gated_delta_rule_chunk_delta_h_tcfuse "),
116 "the line must not name the FAMILY where the binary launches the \
117 `_x2` member — round 12 stage 4b:\n{line}"
118 );
119 }
120
121 /// …and it still carries the launch geometry an operator reads it for.
122 #[test]
123 fn the_route_line_carries_the_geometry() {
124 let line = gdn_tc_spine_route_line(48, 2, 88_324);
125 for field in [
126 "grid=[48,2]",
127 "block=256",
128 "smem=88324B",
129 "ATLAS_GDN_PREFILL_TC",
130 ] {
131 assert!(line.contains(field), "missing `{field}` in:\n{line}");
132 }
133 }
134
135 /// THE ROUND-14 NIT, pinned. With the tensor-core handle bound, the INIT
136 /// line names the entry the dispatch will launch — not the scalar parent
137 /// that merely stays bound behind it (round 14, anomaly 2: 48 of these
138 /// lines said `…_vfused` while all 14 400 dispatches went to `…_x2`).
139 #[test]
140 fn the_init_line_names_the_tc_entry_when_its_handle_is_bound() {
141 let line = gdn_init_spine_line(true, GDN_SCALAR_SPINE_VFUSED);
142 assert!(line.contains(GDN_TC_SPINE_ENTRY), "{line}");
143 assert!(
144 !line.contains(GDN_SCALAR_SPINE_VFUSED),
145 "the init line must not NAME the scalar spine where the probe bound \
146 the tensor-core one:\n{line}"
147 );
148 }
149
150 /// …and the init line and the dispatch line name the SAME entry, which is
151 /// the property that makes 48 lines and 14 400 lines one answer.
152 #[test]
153 fn the_two_route_lines_agree_on_the_entry() {
154 let init = gdn_init_spine_line(true, GDN_SCALAR_SPINE_VFUSED);
155 let dispatch = gdn_tc_spine_route_line(48, 1, 88_324);
156 for line in [&init, &dispatch] {
157 assert!(line.contains(GDN_TC_SPINE_ENTRY), "{line}");
158 }
159 }
160
161 /// With the probe OFF — every target but `kernels/hopper` today — the line
162 /// is the scalar entry it has always been, in all three arms, and spells no
163 /// string of its own.
164 #[test]
165 fn the_init_line_names_the_scalar_entry_when_the_probe_is_off() {
166 for entry in [
167 GDN_SCALAR_SPINE_PIPE,
168 GDN_SCALAR_SPINE_VTILE,
169 GDN_SCALAR_SPINE_VFUSED,
170 ] {
171 assert_eq!(
172 gdn_init_spine_line(false, entry),
173 format!("GDN state spine: {entry}"),
174 );
175 }
176 }
177}