spark_model/layers/qwen3_ssm/
init.rs

1// SPDX-License-Identifier: AGPL-3.0-only
2
3//! Qwen3SsmLayer constructors + setters.
4
5use super::*;
6
7impl Qwen3SsmLayer {
8    pub fn new(
9        input_norm: DenseWeight,
10        ssm: SsmWeights,
11        post_attn_norm: DenseWeight,
12        ffn: FfnComponent,
13        qkvz_nvfp4: Option<QuantizedWeight>,
14        config: &avarok_core::config::ModelConfig,
15        gpu: &dyn GpuBackend,
16    ) -> Result<Self> {
17        let nv = config.linear_num_value_heads;
18        let vd = config.linear_value_head_dim;
19        let nk = config.linear_num_key_heads;
20        let kd = config.linear_key_head_dim;
21        let d_conv = config.linear_conv_kernel_dim;
22
23        // conv_dim = Q_flat + K_flat + V_flat = 2*key_dim + value_dim = 8192
24        let conv_dim = nk * kd * 2 + nv * vd;
25
26        // Resolved BEFORE the struct literal because two fields need it: the
27        // tensor-core spine's handle IS the bit that decides which spine the
28        // prefill launches, so the scalar spine's route line has to read it,
29        // and a field initializer cannot read a sibling field.
30        let gdn_tc_spine = gdn_prefill_tc_kernel(gpu);
31        let woa = super::woa::woa_kernels(gpu);
32
33        Ok(Self {
34            // mHC is attached later by the loader, and only for models that
35            // carry a hc_mult-wide residual highway. The handles are gated on
36            // the same condition `ArchProbes` uses, so a plain GDN model
37            // never issues the lookup.
38            hc: None,
39            ple: None,
40            hc_pre_k: hc_kernel(config, gpu, "hc_pre"),
41            hc_post_k: hc_kernel(config, gpu, "hc_post"),
42            hc_expand_k: hc_kernel(config, gpu, "hc_expand"),
43            input_norm,
44            ssm,
45            post_attn_norm,
46            ffn,
47            lora_out_proj: None,
48            qkvz_nvfp4,
49            qkvz_nvfp4_t: None,
50            out_proj_nvfp4_t: None,
51            out_proj_dense: None,
52            qkvz_fp8w: None,
53            out_proj_fp8w: None,
54            qkvz_fp8w_rowwise: None,
55            out_proj_fp8w_rowwise: None,
56            qkvz_rowwise_bf16: std::sync::atomic::AtomicU64::new(0),
57            out_proj_rowwise_bf16: std::sync::atomic::AtomicU64::new(0),
58            qkvz_q2: None,
59            q2_0_gemv_k: super::super::try_kernel(gpu, "q2_0_gemv_vec", "q2_0_gemv_vec"),
60            dequant_q2_0_gn_k: super::super::try_kernel(
61                gpu,
62                "dequant_gguf_bf16",
63                "dequant_q2_0_gn_to_bf16",
64            ),
65            // The keep-packed MMQ family ships only in targets that serve
66            // GGUF Q2 checkpoints; probing here would fail the boot audit on
67            // every other GDN target. `set_packed_q2_qkvz` resolves them —
68            // the only path that installs weights their dispatch sites check.
69            q2_0_mmq_nc_k: KernelHandle(0),
70            q2_0_mmq_wc_k: KernelHandle(0),
71            q4k_quant_act_k: KernelHandle(0),
72            sequential_qkvz: false,
73            // Resolved ONCE here from the driver, then carried on the layer:
74            // the projection dispatch asks "does this grid still fill the
75            // machine?" and that question has no portable answer.
76            sm_count: gpu.sm_count()?,
77            rms_norm_residual_k: gpu.kernel("norm", "rms_norm_residual")?,
78            // `output_gate_type: "sigmoid"` (qwen4_exp) swaps the gated-norm
79            // handles for the sigmoid twins ONCE, here, so no forward call
80            // site branches on it. Every other model keeps the SiLU originals.
81            gated_rms_norm_k: if config.gdn_norm_sigmoid {
82                gpu.kernel("gated_norm_sigmoid", "gated_rms_norm_sigmoid")?
83            } else {
84                gpu.kernel("norm", "gated_rms_norm")?
85            },
86            gated_rms_norm_f32_k: if config.gdn_norm_sigmoid {
87                super::super::try_kernel(
88                    gpu,
89                    "gated_norm_sigmoid",
90                    "gated_rms_norm_f32_input_sigmoid",
91                )
92            } else {
93                super::super::try_kernel(gpu, "norm", "gated_rms_norm_f32_input")
94            },
95            // Only the SiLU (non-sigmoid) family has a strided twin today; a
96            // `gdn_norm_sigmoid` model gets KernelHandle(0) and keeps the
97            // per-sequence loop, which is correct, just launch-heavy.
98            gated_rms_norm_f32_strided_k: if config.gdn_norm_sigmoid {
99                KernelHandle(0)
100            } else {
101                super::super::try_kernel(gpu, "norm", "gated_rms_norm_f32_input_strided")
102            },
103            dense_gemv_k: gpu.kernel("gemv", "dense_gemv_bf16")?,
104            dense_gemv_batch2_k: gpu.kernel("dense_gemv_bf16_batch2", "dense_gemv_bf16_batch2")?,
105            w4a16_gemv_k: gpu.kernel("w4a16_gemv", "w4a16_gemv")?,
106            w4a16_gemv_sw_k: super::super::try_kernel(gpu, "w4a16_gemv", "w4a16_gemv_sw"),
107            w8a16_gemv_k: gpu.kernel("w8a16_gemv", "w8a16_gemv")?,
108            w4a16_gemv_qkvz_k: gpu.kernel("w4a16_gemv", "w4a16_gemv_qkvz")?,
109            deinterleave_k: gpu.kernel("ssm_preprocess", "deinterleave_qkvz")?,
110            conv1d_k: gpu.kernel("causal_conv1d", "causal_conv1d_update")?,
111            conv1d_l2norm_k: gpu.kernel("causal_conv1d", "causal_conv1d_update_l2norm")?,
112            // FP32 conv1d output prevents BF16 truncation in the recurrent
113            // path from compounding past ~8k tokens. The Metal backend
114            // (kernels/metal/common/causal_conv1d_update_l2norm.metal) only
115            // ships the BF16 variant; on those targets we fall back to the
116            // BF16 kernel via the `.0 != 0` gate at the use site
117            // (ssm_forward.rs). Warn instead of error: missing-on-Metal is
118            // expected, and a startup `error!` would page on benign cases.
119            // Strided twin of `conv1d_l2norm_f32_k` for the batched multi-seq
120            // decode path. Optional: absent on older kernel sets, where the
121            // multi-seq conv stays a per-sequence loop.
122            conv1d_l2norm_f32_strided_k: super::super::try_kernel(
123                gpu,
124                "causal_conv1d",
125                "causal_conv1d_update_l2norm_f32_strided",
126            ),
127            conv1d_l2norm_f32_k: {
128                let h = super::super::try_kernel(
129                    gpu,
130                    "causal_conv1d",
131                    "causal_conv1d_update_l2norm_f32",
132                );
133                if h.0 == 0 {
134                    tracing::warn!(
135                        "FP32 conv1d kernel not loaded; SSM uses BF16 conv \
136                         output. Expect long-context coherence drift past ~8k \
137                         tokens on this backend."
138                    );
139                }
140                h
141            },
142            gdn_k: gpu.kernel("gated_delta_rule", "gated_delta_rule_decode")?,
143            gdn_f32_k: super::super::try_kernel(
144                gpu,
145                "gated_delta_rule",
146                "gated_delta_rule_decode_f32",
147            ),
148            gdn_f32_norm_k: super::super::try_kernel(
149                gpu,
150                "gated_delta_rule",
151                "gated_delta_rule_decode_f32_norm",
152            ),
153            gdn_f32_conv_norm_k: super::super::try_kernel(
154                gpu,
155                "gated_delta_rule",
156                "gated_delta_rule_decode_f32_conv_norm",
157            ),
158            gdn_f32_strided_k: super::super::try_kernel(
159                gpu,
160                "gated_delta_rule",
161                "gated_delta_rule_decode_f32_strided",
162            ),
163            gdn_f32_strided_norm_k: super::super::try_kernel(
164                gpu,
165                "gated_delta_rule",
166                "gated_delta_rule_decode_f32_strided_norm",
167            ),
168            gdn_f32_strided_norm_half_k: super::super::try_kernel(
169                gpu,
170                "gated_delta_rule",
171                "gated_delta_rule_decode_f32_strided_norm_half",
172            ),
173            gdn_f32_strided_norm_smem_k: super::super::try_kernel(
174                gpu,
175                "gated_delta_rule",
176                "gated_delta_rule_decode_f32_strided_norm_smem",
177            ),
178            gdn_f16_strided_norm_half_k: super::super::try_kernel(
179                gpu,
180                "gated_delta_rule",
181                "gated_delta_rule_decode_f16_strided_norm_half",
182            ),
183            gdn_f16_norm_k: super::super::try_kernel(
184                gpu,
185                "gated_delta_rule",
186                "gated_delta_rule_decode_f16_norm",
187            ),
188            ssm_h_f16_to_f32_k: super::super::try_kernel(
189                gpu,
190                "ssm_h_dtype",
191                "ssm_h_state_f16_to_f32",
192            ),
193            ssm_h_f32_to_f16_k: super::super::try_kernel(
194                gpu,
195                "ssm_h_dtype",
196                "ssm_h_state_f32_to_f16",
197            ),
198            ba_gates_k: gpu.kernel("ssm_preprocess", "dense_gemv_ba_gates")?,
199            residual_add_k: gpu.kernel("residual_add", "bf16_residual_add")?,
200            l2_norm_k: gpu.kernel("norm", "l2_norm_bf16")?,
201            residual_add_rms_norm_k: gpu.kernel("norm", "residual_add_rms_norm")?,
202            residual_add_rms_norm_gatef32_k: crate::layers::try_kernel(
203                gpu,
204                "norm",
205                "residual_add_rms_norm_gatef32",
206            ),
207            gated_rms_norm_prefill_k: if config.gdn_norm_sigmoid {
208                gpu.kernel("gated_norm_sigmoid", "gated_rms_norm_prefill_sigmoid")?
209            } else {
210                gpu.kernel("norm", "gated_rms_norm_prefill")?
211            },
212            w4a16_gemm_k: gpu.kernel("w4a16", "w4a16_gemm")?,
213            w4a16_gemm_t_k: crate::layers::tgemm_kernel(gpu),
214            w4a16_gemm_t_k64_k: crate::layers::k64_kernel(gpu)?,
215            w4a16_gemm_t_k64_n64_k: crate::layers::k64_n64_kernel(gpu),
216            w4a16_gemm_t_m128_k: gpu.kernel("w4a16", "w4a16_gemm_t_m128")?,
217            // 8-warp pipelined M128 (try_kernel: 0 when absent → falls back to m128/n128).
218            w4a16_gemm_t_m128_v2_k: super::super::w4a16_v2_kernel(gpu),
219            w4a16_gemv_batch2_k: gpu.kernel("w4a16_gemv", "w4a16_gemv_batch2")?,
220            dense_gemm_k: gpu.kernel("gemm", "dense_gemm_bf16")?,
221            // try_kernel: 0-handle if absent (gated at dispatch); the pipelined
222            // BF16 GEMM lives in the same `gemm` module as dense_gemm_bf16.
223            dense_gemm_pipelined_k: super::super::try_kernel(
224                gpu,
225                "gemm",
226                "dense_gemm_bf16_pipelined",
227            ),
228            gdn_prefill_k: gpu.kernel("gated_delta_rule", "gated_delta_rule_prefill")?,
229            gdn_prefill_split_k: gpu
230                .kernel("gated_delta_rule", "gated_delta_rule_prefill_split")?,
231            gdn_prefill_split4_k: gpu
232                .kernel("gated_delta_rule", "gated_delta_rule_prefill_split4")?,
233            gdn_prefill_persistent_k: super::super::try_kernel(
234                gpu,
235                "gated_delta_rule_persistent",
236                "gated_delta_rule_prefill_persistent",
237            ),
238            gdn_prefill_persistent_wy4_k: super::super::try_kernel(
239                gpu,
240                "gated_delta_rule_persistent",
241                "gated_delta_rule_prefill_persistent_wy4",
242            ),
243            gdn_prefill_regresident_k: super::super::try_kernel(
244                gpu,
245                "gated_delta_rule_regresident",
246                "gated_delta_rule_prefill_regresident",
247            ),
248            gdn_prefill_fla_recompute_wu_k: super::super::try_kernel(
249                gpu,
250                "gated_delta_rule_fla",
251                "gated_delta_rule_recompute_wu",
252            ),
253            gdn_prefill_fla_recompute_wu_hopper_k: init_kernels::prefill_wu_hopper_k(gpu),
254            gdn_prefill_fla_chunk_fwd_o_hopper_k: init_kernels::prefill_fwd_o_hopper_k(gpu),
255            gdn_prefill_fla_chunk_delta_h_k: super::super::try_kernel(
256                gpu,
257                "gated_delta_rule_fla",
258                "gated_delta_rule_chunk_delta_h_ksplit",
259            ),
260            gdn_prefill_fla_chunk_delta_h_tc_vblock_k: super::super::try_kernel(
261                gpu,
262                "gated_delta_rule_fla",
263                "gated_delta_rule_chunk_delta_h_tc_vblock",
264            ),
265            gdn_prefill_fla_chunk_delta_h_tcfuse_k: gdn_tc_spine,
266            // ONE handle for the scalar fused GDN state spine, and the route
267            // line naming whichever spine the prefill will launch — see
268            // `init_kernels::fused_spine_kernel` for both.
269            gdn_prefill_fla_chunk_delta_h_fused_k: fused_spine_kernel(gpu, gdn_tc_spine),
270            gdn_prefill_fla_chunk_delta_h_tma_k: super::super::try_kernel(
271                gpu,
272                "gated_delta_rule_fla",
273                "gated_delta_rule_chunk_delta_h_tma",
274            ),
275            gdn_prefill_fla_chunk_fwd_o_k: super::super::try_kernel(
276                gpu,
277                "gated_delta_rule_fla",
278                "gated_delta_rule_chunk_fwd_o",
279            ),
280            gdn_prefill_wy32_k: super::super::try_kernel(
281                gpu,
282                "gated_delta_rule_wy64_prefill",
283                "gated_delta_rule_prefill_wy64",
284            ),
285            // ── Q12 Phase 2b: batched GDN kernel handles ──
286            gdn_prefill_wy32_batched_k: super::super::try_kernel(
287                gpu,
288                "gated_delta_rule_wy64_prefill",
289                "gated_delta_rule_prefill_wy64_batched",
290            ),
291            gdn_prefill_persistent_batched_k: super::super::try_kernel(
292                gpu,
293                "gated_delta_rule_persistent",
294                "gated_delta_rule_prefill_persistent_batched",
295            ),
296            gdn_prefill_persistent_wy4_batched_k: super::super::try_kernel(
297                gpu,
298                "gated_delta_rule_persistent",
299                "gated_delta_rule_prefill_persistent_wy4_batched",
300            ),
301            gdn_prefill_split4_batched_k: super::super::try_kernel(
302                gpu,
303                "gated_delta_rule",
304                "gated_delta_rule_prefill_split4_batched",
305            ),
306            compute_gdn_gates_k: gpu.kernel("ssm_preprocess", "compute_gdn_gates")?,
307            ba_gates_prefill_k: gpu.kernel("ssm_preprocess", "dense_gemm_ba_gates_prefill")?,
308            ba_gates_prefill_hopper_k: init_kernels::ba_gates_hopper_k(gpu),
309            conv1d_prefill_k: gpu.kernel("causal_conv1d", "causal_conv1d_update_prefill")?,
310            conv1d_prefill_tp_k: super::super::try_kernel(
311                gpu,
312                "causal_conv1d",
313                "causal_conv1d_update_prefill_tp",
314            ),
315            gdn_chunk2_k: gpu.kernel("gated_delta_rule", "gated_delta_rule_chunk2")?,
316            conv1d_chunk2_k: gpu.kernel("causal_conv1d", "causal_conv1d_update_chunk2")?,
317            gdn_chunk3_k: gpu.kernel("gated_delta_rule", "gated_delta_rule_chunk3")?,
318            w4a16_gemv_batch3_k: gpu.kernel("w4a16_gemv", "w4a16_gemv_batch3")?,
319            gdn_wy2_k: gpu.kernel("gated_delta_rule_wy", "gated_delta_rule_wy2")?,
320            // Register-resident wy2 twin (own gb10-common module so non-gb10
321            // targets simply resolve 0 and keep the base wy2 — try_kernel
322            // misses are a silent handle 0, so `wy2_kernel` logs the
323            // resolution outcome once at first K=2 dispatch).
324            gdn_wy2_resident_k: super::super::try_kernel(
325                gpu,
326                "gated_delta_rule_wy2_resident",
327                "gated_delta_rule_wy2_resident",
328            ),
329            gdn_wy3_k: gpu.kernel("gated_delta_rule_wy3", "gated_delta_rule_wy3")?,
330            // Register-resident wy3 twin (same pattern as wy2's above:
331            // try_kernel so non-gb10 targets resolve 0 and keep base wy3;
332            // `wy3_kernel` logs the resolution outcome at first K=3 dispatch).
333            gdn_wy3_resident_k: super::super::try_kernel(
334                gpu,
335                "gated_delta_rule_wy3_resident",
336                "gated_delta_rule_wy3_resident",
337            ),
338            gdn_wy4_k: gpu.kernel("gated_delta_rule_wy4", "gated_delta_rule_wy4")?,
339            gdn_wy4_woa_k: woa.woa_k,
340            gdn_wy4_fold_k: woa.fold_k,
341            gdn_wy4_clear_k: woa.clear_k,
342            // Bound by the model on the first write-on-accept request.
343            woa_flag: std::sync::atomic::AtomicU64::new(0),
344            woa_stash: std::sync::atomic::AtomicU64::new(0),
345            woa_seqs: std::sync::atomic::AtomicUsize::new(0),
346            woa_dims: [nk, nv, kd, vd],
347            // ── AVAROK_SSM_H_FP16 stage 2: FP16 h-state twins of the MTP
348            // verify WY kernels. try_kernel for the same reason as the
349            // resident twins above — a miss is a silent handle 0, and the
350            // selectors gate on `.0 != 0` before ever picking one. Without
351            // these the flag and `--speculative` are mutually exclusive,
352            // because every WY kernel above writes the state as FP32 and an
353            // FP32 kernel over an FP16 pool produces fluent garbage, not an
354            // error. Preflight refuses the combination unless the K values the
355            // configured draft count can reach all have a twin here.
356            gdn_wy2_f16_k: super::super::try_kernel(
357                gpu,
358                "gated_delta_rule_wy_f16",
359                "gated_delta_rule_wy2_f16",
360            ),
361            gdn_wy2_resident_f16_k: super::super::try_kernel(
362                gpu,
363                "gated_delta_rule_wy2_resident_f16",
364                "gated_delta_rule_wy2_resident_f16",
365            ),
366            gdn_wy3_f16_k: super::super::try_kernel(
367                gpu,
368                "gated_delta_rule_wy3_f16",
369                "gated_delta_rule_wy3_f16",
370            ),
371            gdn_wy3_resident_f16_k: super::super::try_kernel(
372                gpu,
373                "gated_delta_rule_wy3_resident_f16",
374                "gated_delta_rule_wy3_resident_f16",
375            ),
376            gdn_wy4_f16_k: super::super::try_kernel(
377                gpu,
378                "gated_delta_rule_wy4_f16",
379                "gated_delta_rule_wy4_f16",
380            ),
381            // STAGE 1 fused K=2 verify epilogue. Only present in the gb10
382            // common PTX module set; NULL on targets lacking the .cu, in which
383            // case the num_tokens==2 arm keeps the per-token path even when
384            // AVAROK_GDN_FUSED_VERIFY is set.
385            gdn_verify_fused_conv_k2_k: super::super::try_kernel(
386                gpu,
387                "gdn_verify_fused_k2",
388                "gdn_verify_fused_conv_k2",
389            ),
390            gdn_verify_fused_norm_k2_k: super::super::try_kernel(
391                gpu,
392                "gdn_verify_fused_k2",
393                "gdn_verify_fused_norm_k2",
394            ),
395            // Generic-K fused verify conv (K=17 DFlash arm). gb10 common
396            // module; NULL on targets lacking the .cu, in which case the
397            // K=17 arm keeps its per-token conv loop.
398            gdn_verify_fused_conv_kn_k: super::super::try_kernel(
399                gpu,
400                "gdn_verify_fused_conv_kn",
401                "gdn_verify_fused_conv_kn",
402            ),
403            // Batched twin (gridDim.y = n_seq) for batched speculative decoding.
404            gdn_verify_fused_conv_kn_batched_k: super::super::try_kernel(
405                gpu,
406                "gdn_verify_fused_conv_kn",
407                "gdn_verify_fused_conv_kn_batched",
408            ),
409            // Exact-verify `_snap` twins (#435): model-shadow staged
410            // (qwen3.6-27b/nvfp4), 0 elsewhere — the exact arm then uses the
411            // parent kernel + copy_d2d snapshots (same bits, more launches).
412            // Every other GDN target declares these three lookups in its
413            // MODEL.toml [expected_absent] (#438) — the boot gate fails closed.
414            gdn_f32_norm_snap_k: super::super::try_kernel(
415                gpu,
416                "gated_delta_rule_snap",
417                "gated_delta_rule_decode_f32_norm_snap",
418            ),
419            gdn_f32_strided_norm_snap_k: super::super::try_kernel(
420                gpu,
421                "gated_delta_rule_snap",
422                "gated_delta_rule_decode_f32_strided_norm_snap",
423            ),
424            gdn_verify_fused_conv_kn_f32_k: super::super::try_kernel(
425                gpu,
426                "gdn_verify_fused_conv_kn_f32",
427                "gdn_verify_fused_conv_kn_f32",
428            ),
429            // wy17 ships only in qwen3.6-35b-a3b's and qwen3.6-27b's PTX sets;
430            // NULL elsewhere (declared [expected_absent] in those MODEL.tomls).
431            // decode_batched(K=17) checks for non-NULL before dispatching the fused path.
432            gdn_wy17_k: super::super::try_kernel(
433                gpu,
434                "gated_delta_rule_wy17",
435                "gated_delta_rule_wy17",
436            ),
437            gdn_wyn_k: init_kernels::wyn_kernels(gpu),
438            gdn_wyn_f16_k: init_kernels::wyn_f16_kernels(gpu),
439            // provenance-id: 526f6e616c6420522e205374657369616b
440            gdn_wyn_table_k: init_kernels::wyn_table_kernels(gpu),
441            gdn_wyn_f16_table_k: init_kernels::wyn_f16_table_kernels(gpu),
442            h_state_bytes: nv * vd * kd * 4, // FP32 [nv, kd, vd] transposed for coalescing
443            conv_state_bytes: conv_dim * d_conv * 4, // FP32 [conv_dim, d_conv]
444            qkvz_fp8: None,
445            out_proj_fp8: None,
446            fp8_gemm_k: gpu.kernel("w4a16", "fp8_gemm_t")?,
447            fp8_gemm_t_m128_k: gpu.kernel("w4a16", "fp8_gemm_t_m128")?,
448            w8a16_gemm_k: super::super::try_kernel(gpu, "w8a16_gemm", "w8a16_gemm"),
449            w8a16_gemm_pipelined_k: super::super::try_kernel(
450                gpu,
451                "w8a16_gemm_pipelined",
452                "w8a16_gemm_pipelined",
453            ),
454            w8a16_gemv_batch4_k: super::super::try_kernel(
455                gpu,
456                "w8a16_gemv_batch4",
457                "w8a16_gemv_batch4",
458            ),
459            w8a16_gemv_batch16_k: super::super::try_kernel(
460                gpu,
461                "w8a16_gemv_batch4",
462                "w8a16_gemv_batch16",
463            ),
464            // NVFP4 batched decode GEMV (all entries live in the w4a16_gemv module).
465            w4a16_batchm: crate::layers::w4a16_gemv_tiers::W4a16BatchmTiers::resolve(gpu),
466            w4a16_gemv_batch16_k: super::super::try_kernel(gpu, "w4a16_gemv", "w4a16_gemv_batch16"),
467            w8a16_gemm_t_k: super::super::try_kernel(gpu, "w8a16_gemm_t", "w8a16_gemm_t"),
468            per_token_group_quant_fp8_k: ops::Fp8ActQuant::resolve(gpu),
469            fp8_gemm_t_blockscaled_k: super::super::try_kernel(
470                gpu,
471                "fp8_gemm_t_blockscaled",
472                "fp8_gemm_t_blockscaled",
473            ),
474            fp8_act_scale_kmajor_k: super::super::try_kernel(
475                gpu,
476                "fp8_scale_transpose",
477                "fp8_act_scale_to_kmajor",
478            ),
479        })
480    }
481
482    // `new_sequential` moved to `init_sequential.rs` (≤500 LoC split).
483}
484
485#[path = "init_kernels.rs"]
486mod init_kernels;
487use init_kernels::{fused_spine_kernel, gdn_prefill_tc_kernel, hc_kernel};
488
489#[path = "init_sequential.rs"]
490mod init_sequential;