Skip to main content

logicaffeine_compile/codegen_cuda/
qwen_emit.rs

1//! The **whole-forward orchestrator** — composing a multi-stage LOGOS tensor-op program into ONE CUDA
2//! program that chains genuine PARALLEL kernels through shared device buffers.
3//!
4//! The per-op emitters ([`super::matrix`], [`super::fused_row`]) each emit a *self-contained* `.cu` (its own
5//! `main` that fills one input and prints a checksum). A transformer forward is a SEQUENCE of ops
6//! (`rmsnorm → matmul → softmax → …`), so this module does what a single-op emitter cannot: it walks the
7//! program's ordered tensor-op stages (each desugars to one `Stmt::Splice`, recognized independently via the
8//! backend-agnostic [`crate::tensor_recognize`] recognizers), then emits — for each stage — a
9//! uniquely-named `__global__` kernel plus a single host driver that allocates one device buffer per tensor
10//! variable, fills the inputs deterministically, launches each stage's kernel in dataflow order (chaining by
11//! variable name), and prints the final tensor. The kernels ARE composable — same bodies the standalone
12//! emitters use, only re-parameterized (unique name, dims as args) so many coexist in one translation unit.
13//!
14//! This is the seam the "beat llama.cpp" path needs: the forward is authored in LOGOS tensor ops, and the
15//! compiler emits one runnable device program of chained parallel kernels — not the single-thread whole-
16//! program lowering.
17
18use std::collections::HashMap;
19
20use logicaffeine_language::ast::stmt::{Expr, Literal, Stmt};
21
22use crate::intern::{Interner, Symbol};
23use crate::model::quant::GgmlType;
24use crate::tensor_graph::front::TensorOpSpec;
25use crate::tensor_graph::fuse::{leaves, optimize};
26use crate::tensor_graph::graph::{Fused, Op, Storage, Sym, TensorGraph};
27use crate::tensor_graph::symbols::ClassId;
28use crate::tensor_recognize::qwen;
29use crate::tensor_recognize::{ElementwiseOp, ElementwiseSpec, FusedRowSpec, RowReduceKind};
30
31use super::forward_shim::{kernel_refusal, ForwardShim};
32
33/// A concrete element initializer value — integer or float.
34#[derive(Debug, Clone, Copy)]
35pub enum InitVal {
36    I(i64),
37    F(f64),
38}
39
40/// A **Q8_0 weight** loaded resident as int8 quants + f32 block scales (the real Qwen weights: 8 GB int8 fits
41/// a 12 GB card where 32 GB of f32 would not). Dequant `W[o][t] = quants[o*in+t] * scales[o*nb + t/32]` — the
42/// matmul against it becomes a dequant-in-kernel GEMV, matching `codegen_cuda::qwen`'s certified matvec.
43#[derive(Debug, Clone)]
44pub struct Q8Ref {
45    pub quants: String,
46    pub scales: String,
47    pub in_dim: usize,
48    pub out_dim: usize,
49}
50
51/// A **Mixture-of-Experts FFN block**'s weights, all int8-resident (Q8_0): the router `[E, d]`, and the E
52/// experts' gate/up `[E·dff, d]` and down `[E·d, dff]` STACKED so expert `e`'s rows begin at `e·dff` (gate/up)
53/// or `e·d` (down). This is the Qwen3-30B-A3B block; the SAME struct describes any `(d, dff, E, K)` — the
54/// emitter indexes the experts by a base-pointer offset, so 8 experts and 128 experts share one code path.
55#[derive(Debug, Clone)]
56pub struct MoeWeights {
57    pub router: Q8Ref,
58    pub gate: Q8Ref,
59    pub up: Q8Ref,
60    pub down: Q8Ref,
61    pub d: usize,
62    pub dff: usize,
63    pub ne: usize,
64    pub k: usize,
65}
66
67/// Emit a self-contained CUDA program for ONE Mixture-of-Experts FFN block over real int8 weights: router GEMV
68/// → top-K route (softmax, keep K, renormalize) → each expert's SwiGLU with an EXPERT-INDEXED weight base →
69/// weighted combine. The weights stream from files (int8 quants + f32 block scales), never a 4×-larger f32
70/// buffer, so the 30B block (~30 GB int8) fits a 48 GB card. Dequant-in-kernel GEMV (f32 activation × int8
71/// weight, f64 accumulate) matches the LOGOS `moe` op on the VM exactly; the whole block is captured as one
72/// CUDA graph. `x` is the block input (`d` floats, inlined). The experts are UNROLLED in the host launch list
73/// (not the kernels), so E scales without changing a kernel — the same emitter serves 8B-scale and 30B-scale.
74pub fn emit_moe_forward(x: &[f64], w: &MoeWeights) -> String {
75    let (d, dff, ne, k) = (w.d, w.dff, w.ne, w.k);
76    let (dnb, fnb) = (d / 32, dff / 32); // per-32-block counts for the two contraction dims
77    assert!(
78        ne <= 256,
79        "moe emitter caps E at 256 (top-K scratch is a 256-float stack array)"
80    );
81
82    // ── kernels ──────────────────────────────────────────────────────────────────────────────────────
83    // Dequant-in-kernel Q8 GEMV: y[o] = Σ_bl (Σ_j wq[o·K+bl·32+j]·a[bl·32+j]) · ws[o·nb+bl]. One output/thread,
84    // f64 accumulate — the certified matvec, expert-selected by the base pointers the host passes.
85    let kernels = format!(
86        "__global__ void moe_gemv(const float* a, const signed char* wq, const float* ws, float* y, int N, int K){{\n\
87         \x20 int o=blockIdx.x*blockDim.x+threadIdx.x; if(o>=N) return; int nb=K/32;\n\
88         \x20 const signed char* wr=wq+(long)o*K; const float* wsr=ws+(long)o*nb; double acc=0.0;\n\
89         \x20 for(int bl=0;bl<nb;++bl){{ double dot=0.0; for(int j=0;j<32;++j) dot+=(double)wr[bl*32+j]*(double)a[bl*32+j]; acc+=dot*(double)wsr[bl]; }}\n\
90         \x20 y[o]=(float)acc;\n}}\n\
91         __global__ void moe_silu_had(const float* g, const float* u, float* he, int n){{\n\
92         \x20 int i=blockIdx.x*blockDim.x+threadIdx.x; if(i>=n) return; float gv=g[i]; he[i]=(gv/(1.0f+expf(-gv)))*u[i];\n}}\n\
93         __global__ void moe_zero(float* y, int n){{ int i=blockIdx.x*blockDim.x+threadIdx.x; if(i<n) y[i]=0.0f; }}\n\
94         __global__ void moe_combine(float* H, const float* oute, const float* wv, int e, int d){{\n\
95         \x20 int o=blockIdx.x*blockDim.x+threadIdx.x; if(o<d) H[o]+=wv[e]*oute[o];\n}}\n\
96         // top-K router: softmax over the E logits, keep the K largest (masked argmax), renormalize. w[e]=0 for\n\
97         // the non-selected — the data-dependent routing decision, computed on-device.\n\
98         __global__ void moe_topk(const float* logits, float* w, int E, int K){{\n\
99         \x20 if(threadIdx.x!=0) return; float p[256]; float pm[256];\n\
100         \x20 float m=logits[0]; for(int e=1;e<E;++e) if(logits[e]>m) m=logits[e];\n\
101         \x20 float s=0.0f; for(int e=0;e<E;++e) s+=expf(logits[e]-m);\n\
102         \x20 for(int e=0;e<E;++e){{ p[e]=expf(logits[e]-m)/s; pm[e]=p[e]; w[e]=0.0f; }}\n\
103         \x20 float wsum=0.0f;\n\
104         \x20 for(int r=0;r<K;++r){{ float bv=-1e30f; int bi=0; for(int e=0;e<E;++e) if(pm[e]>bv){{ bv=pm[e]; bi=e; }} wsum+=p[bi]; w[bi]=p[bi]; pm[bi]=-1e30f; }}\n\
105         \x20 for(int e=0;e<E;++e) w[e]/=wsum;\n}}\n"
106    );
107
108    // ── host: load int8 weights, run the block on a stream, capture as one CUDA graph, print H ──────────
109    let load_q8 = |var: &str, q: &Q8Ref| -> String {
110        let nb = q.in_dim / 32;
111        let (qn, sn) = (q.in_dim * q.out_dim, q.out_dim * nb);
112        format!(
113            "  signed char* {var}_q; if(cudaMallocManaged(&{var}_q,(size_t){qn})){{ fprintf(stderr,\"malloc\\n\"); return 1; }}\n\
114             \x20 float* {var}_s; if(cudaMallocManaged(&{var}_s,(size_t){sn}*sizeof(float))){{ fprintf(stderr,\"malloc\\n\"); return 1; }}\n\
115             \x20 {{ FILE* f=fopen(\"{qp}\",\"rb\"); if(!f||fread({var}_q,1,(size_t){qn},f)!=(size_t){qn}){{ fprintf(stderr,\"q {var}\\n\"); return 1; }} fclose(f); }}\n\
116             \x20 {{ FILE* f=fopen(\"{sp}\",\"rb\"); if(!f||fread({var}_s,sizeof(float),(size_t){sn},f)!=(size_t){sn}){{ fprintf(stderr,\"s {var}\\n\"); return 1; }} fclose(f); }}\n",
117            qp = q.quants, sp = q.scales
118        )
119    };
120    let mut allocs = String::new();
121    allocs.push_str(&load_q8("Wr", &w.router));
122    allocs.push_str(&load_q8("Wg", &w.gate));
123    allocs.push_str(&load_q8("Wu", &w.up));
124    allocs.push_str(&load_q8("Wd", &w.down));
125    // activation + scratch buffers
126    for (nm, n) in [
127        ("x", d),
128        ("logits", ne),
129        ("w", ne),
130        ("gate_e", dff),
131        ("up_e", dff),
132        ("he", dff),
133        ("oute", d),
134        ("H", d),
135    ] {
136        allocs.push_str(&format!("  float* {nm}; if(cudaMallocManaged(&{nm},(size_t){n}*sizeof(float))){{ fprintf(stderr,\"malloc\\n\"); return 1; }}\n"));
137    }
138    let mut fills = String::new();
139    for (i, v) in x.iter().enumerate() {
140        fills.push_str(&format!("  x[{i}]={:?}f;\n", v));
141    }
142
143    // The block: router → topk → per-expert SwiGLU (expert-indexed weight bases) → weighted combine.
144    let etopk = ne.min(1024);
145    let mut body = String::new();
146    body.push_str(&format!(
147        "  moe_gemv<<<({ne}+255)/256,256,0,_st>>>(x,Wr_q,Wr_s,logits,{ne},{d});\n"
148    ));
149    body.push_str(&format!(
150        "  moe_topk<<<1,{etopk},0,_st>>>(logits,w,{ne},{k});\n"
151    ));
152    body.push_str(&format!(
153        "  moe_zero<<<({d}+255)/256,256,0,_st>>>(H,{d});\n"
154    ));
155    for e in 0..ne {
156        let (goff, gsoff) = (e * dff * d, e * dff * dnb);
157        let (doff, dsoff) = (e * d * dff, e * d * fnb);
158        body.push_str(&format!(
159            "  moe_gemv<<<({dff}+255)/256,256,0,_st>>>(x,Wg_q+{goff},Wg_s+{gsoff},gate_e,{dff},{d});\n\
160             \x20 moe_gemv<<<({dff}+255)/256,256,0,_st>>>(x,Wu_q+{goff},Wu_s+{gsoff},up_e,{dff},{d});\n\
161             \x20 moe_silu_had<<<({dff}+255)/256,256,0,_st>>>(gate_e,up_e,he,{dff});\n\
162             \x20 moe_gemv<<<({d}+255)/256,256,0,_st>>>(he,Wd_q+{doff},Wd_s+{dsoff},oute,{d},{dff});\n\
163             \x20 moe_combine<<<({d}+255)/256,256,0,_st>>>(H,oute,w,{e},{d});\n"
164        ));
165    }
166
167    format!(
168        "// Auto-generated by LOGOS codegen_cuda::qwen_emit — a Mixture-of-Experts FFN block (E={ne}, top-{k},\n\
169         // d={d}, dff={dff}) over real int8 weights, captured as one CUDA graph. The SAME emitter serves any E.\n\
170         #include <cstdio>\n#include <cstdlib>\n#include <cuda_runtime.h>\n#include <cmath>\n\n\
171         {kernels}\nint main(void){{\n{allocs}{fills}\n\
172         \x20 cudaStream_t _st; if(cudaStreamCreate(&_st)!=cudaSuccess){{ fprintf(stderr,\"stream\\n\"); return 1; }}\n\
173         {body}  if(cudaStreamSynchronize(_st)!=cudaSuccess){{ fprintf(stderr,\"sync\\n\"); return 1; }}\n\
174         \x20 cudaGraph_t _g; cudaGraphExec_t _ge;\n\
175         \x20 if(cudaStreamBeginCapture(_st, cudaStreamCaptureModeGlobal)!=cudaSuccess){{ fprintf(stderr,\"capture\\n\"); return 1; }}\n\
176         {body}  if(cudaStreamEndCapture(_st,&_g)!=cudaSuccess){{ fprintf(stderr,\"endcap\\n\"); return 1; }}\n\
177         \x20 if(cudaGraphInstantiate(&_ge,_g,0)!=cudaSuccess){{ fprintf(stderr,\"inst\\n\"); return 1; }}\n\
178         \x20 cudaGraphLaunch(_ge,_st); cudaStreamSynchronize(_st);\n\
179         \x20 cudaEvent_t _e0,_e1; cudaEventCreate(&_e0); cudaEventCreate(&_e1);\n\
180         \x20 cudaEventRecord(_e0,_st); for(int _it=0;_it<20;++_it){{ cudaGraphLaunch(_ge,_st); }}\n\
181         \x20 cudaEventRecord(_e1,_st); cudaStreamSynchronize(_st); float _ms=0.0f; cudaEventElapsedTime(&_ms,_e0,_e1);\n\
182         \x20 fprintf(stderr,\"MOE_MS %f\\n\", _ms/20.0f);\n\
183         \x20 for(int o=0;o<{d};++o) printf(\"%.6f\\n\",(double)H[o]);\n  return 0;\n}}\n"
184    )
185}
186
187pub use crate::tensor_recognize::qwen::{recognize_moe, MoeSpec};
188
189/// Collect the concrete initializers a program writes — `Set item N of V to <literal>` with literal `N` and an
190/// integer/float value (1-based `N`, recorded 0-based) — so the orchestrator's INPUT buffers hold the
191/// program's own values and its GPU output equals the VM's, not merely a deterministic fill. Recurses through
192/// desugar `Splice`s.
193pub fn collect_inits(
194    stmts: &[Stmt],
195    interner: &Interner,
196) -> HashMap<String, Vec<(usize, InitVal)>> {
197    fn lit_int(e: &Expr) -> Option<i64> {
198        match e {
199            Expr::Literal(Literal::Number(n)) => Some(*n),
200            _ => None,
201        }
202    }
203    fn lit_val(e: &Expr) -> Option<InitVal> {
204        match e {
205            Expr::Literal(Literal::Number(n)) => Some(InitVal::I(*n)),
206            Expr::Literal(Literal::Float(f)) => Some(InitVal::F(*f)),
207            _ => None,
208        }
209    }
210    fn walk(stmts: &[Stmt], interner: &Interner, out: &mut HashMap<String, Vec<(usize, InitVal)>>) {
211        for s in stmts {
212            match s {
213                Stmt::SetIndex {
214                    collection,
215                    index,
216                    value,
217                } => {
218                    let (coll, idx, val): (&Expr, &Expr, &Expr) = (*collection, *index, *value);
219                    if let (Expr::Identifier(c), Some(k), Some(v)) =
220                        (coll, lit_int(idx), lit_val(val))
221                    {
222                        if k >= 1 {
223                            out.entry(interner.resolve(*c).to_string())
224                                .or_default()
225                                .push((k as usize - 1, v));
226                        }
227                    }
228                }
229                Stmt::Splice { body } => walk(body, interner, out),
230                Stmt::While { body, .. } | Stmt::Repeat { body, .. } => walk(body, interner, out),
231                Stmt::If {
232                    then_block,
233                    else_block,
234                    ..
235                } => {
236                    walk(then_block, interner, out);
237                    if let Some(eb) = else_block {
238                        walk(eb, interner, out);
239                    }
240                }
241                _ => {}
242            }
243        }
244    }
245    let mut out = HashMap::new();
246    walk(stmts, interner, &mut out);
247    out
248}
249
250/// Why a program is not a lowerable multi-stage tensor-op forward.
251#[derive(Debug, Clone, PartialEq, Eq)]
252pub enum ForwardError {
253    /// No tensor-op stage was recognized in the program.
254    NoStages,
255    /// A `moe` stage produced this output var but the MoE weight manifest has no entry for it.
256    MissingMoeWeights(String),
257    /// Statements the forward cannot lower faithfully, in program order. A program is lowered whole or not at all.
258    Refused(Vec<StageRefusal>),
259}
260
261impl std::fmt::Display for ForwardError {
262    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
263        match self {
264            ForwardError::NoStages => write!(f, "no tensor-op stage recognized in the program"),
265            ForwardError::MissingMoeWeights(v) => {
266                write!(f, "moe stage `{v}` has no entry in the MoE weight manifest")
267            }
268            ForwardError::Refused(rs) => {
269                write!(f, "the CUDA forward refuses {} statement(s): ", rs.len())?;
270                for (k, r) in rs.iter().enumerate() {
271                    if k > 0 {
272                        write!(f, "; ")?;
273                    }
274                    write!(f, "{r}")?;
275                }
276                Ok(())
277            }
278        }
279    }
280}
281
282/// Why the forward refuses one statement — the statement by its top-level index, and what it is.
283#[derive(Debug, Clone, PartialEq, Eq)]
284pub enum StageRefusal {
285    /// A compound statement no tensor recognizer lifts (a hand-written loop, a branch, an unknown block), named by
286    /// its binder or loop variable.
287    Unrecognized { stmt: usize, what: String },
288    /// A write to a declared tensor that no stage computes and no starting fill can hold.
289    UnliftedWrite {
290        stmt: usize,
291        tensor: String,
292        why: &'static str,
293    },
294    /// An op the tensor front end lifts whose meaning this lane's kernels do not compute — no kernel for the
295    /// op, or a form of it (a field of its spec) the kernel does not implement.
296    NoKernel {
297        stmt: usize,
298        kind: &'static str,
299        out: String,
300        why: &'static str,
301    },
302}
303
304impl std::fmt::Display for StageRefusal {
305    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
306        match self {
307            StageRefusal::Unrecognized { stmt, what } => {
308                write!(f, "statement {stmt} ({what}) is no tensor op the front end lifts")
309            }
310            StageRefusal::UnliftedWrite { stmt, tensor, why } => {
311                write!(f, "statement {stmt} writes `{tensor}`: {why}")
312            }
313            StageRefusal::NoKernel {
314                stmt,
315                kind,
316                out,
317                why,
318            } => write!(
319                f,
320                "statement {stmt} binds `{out}` with {kind}, which the CUDA forward cannot lower: {why}"
321            ),
322        }
323    }
324}
325
326/// The SPARSE INT8-ACTIVATION DP4A MoE kernels (the llama.cpp-beating path): quantize the activation to int8
327/// once (`moe_qact`), route to the top-K experts by INDEX (`moe_topk_idx` — softmax → keep K → renormalize,
328/// emitting the chosen expert indices, not a dense mask), then run ONLY the selected experts through the two
329/// deeply-fused kernels (`moe_gate_up_silu`, `moe_down_combine` — one warp per output row, each lane streams a
330/// 128-byte-coalesced int of 4 packed int8 of BOTH operands, `__dp4a`-accumulates, warp-reduces; the expert
331/// index is read on-device so the weight base is data-dependent yet the launch is static ⇒ CUDA-graph-
332/// capturable). This reads ~K/E of the weights per token (the "A3B = 3B active" sparsity) at full coalesced
333/// int8 bandwidth — the two wins over the dense dequant path. The router + top-K pair is precision-independent;
334/// [`moe_dp4a_kernels`] appends the single-pass (default, llama-matched) or two-pass (logit-exact) trio.
335const MOE_ROUTER_TOPK_KERNELS: &str = "\
336// FAST router GEMV (warp per output row, `char4`-coalesced int8 × f32 activation, f32 accumulate) — replaces the
337// dense f64 thread-per-output `moe_gemv` that ran the WHOLE 128-expert routing on ONE block/SM (the batch-1\n\
338// bottleneck: 2000× slower than bandwidth). f32 vs f64 does not change which top-K experts route ⇒ token-exact.\n\
339__global__ void moe_router_fast(const float* a, const signed char* wq, const float* ws, float* y, int N, int K){\n\
340\x20 int o=(blockIdx.x*blockDim.x+threadIdx.x)>>5; if(o>=N) return; int lane=threadIdx.x&31; int nb=K/32, nq=K/128;\n\
341\x20 const signed char* wr=wq+(long)o*K; const float* wsr=ws+(long)o*nb; const char4* w4=(const char4*)wr;\n\
342\x20 float acc=0.0f;\n\
343\x20 for(int b=0;b<nq;++b){ char4 w=w4[b*32+lane]; int blk=b*4+lane/8; const float* at=a+b*128+lane*4;\n\
344\x20   acc += wsr[blk]*((float)w.x*at[0]+(float)w.y*at[1]+(float)w.z*at[2]+(float)w.w*at[3]); }\n\
345\x20 for(int t=nq*128+lane;t<K;t+=32){ int blk=t/32; acc += wsr[blk]*(float)wr[t]*a[t]; }\n\
346\x20 for(int s=16;s>0;s>>=1) acc+=__shfl_down_sync(0xffffffffu,acc,s);\n\
347\x20 if(lane==0) y[o]=acc;\n}\n\
348// Top-K router select. The 128-expert softmax (max + exp + sum) is done BLOCK-PARALLEL into shared `sp` (each\n\
349// global logit read + expf once, not serialized in one thread — the old single-thread form was 30us/call, the\n\
350// #2 batch-1 hog); only the tiny top-K argmax scan stays on thread 0, now over fast shared memory. E<=1024.\n\
351__global__ void moe_topk_idx(const float* logits, int* idx, float* w, int E, int K){\n\
352\x20 __shared__ float sp[1024]; __shared__ float red[32];\n\
353\x20 int t=threadIdx.x, nt=blockDim.x, wp=t>>5, ln=t&31, nw=(nt+31)>>5;\n\
354\x20 float lm=-1e30f; for(int e=t;e<E;e+=nt) lm=fmaxf(lm,logits[e]);\n\
355\x20 for(int s=16;s>0;s>>=1) lm=fmaxf(lm,__shfl_down_sync(0xffffffffu,lm,s));\n\
356\x20 if(ln==0) red[wp]=lm; __syncthreads();\n\
357\x20 if(t==0){ float m=red[0]; for(int i=1;i<nw;++i) m=fmaxf(m,red[i]); red[0]=m; } __syncthreads();\n\
358\x20 float mx=red[0];\n\
359\x20 float ls=0.0f; for(int e=t;e<E;e+=nt){ float p=expf(logits[e]-mx); sp[e]=p; ls+=p; }\n\
360\x20 for(int s=16;s>0;s>>=1) ls+=__shfl_down_sync(0xffffffffu,ls,s);\n\
361\x20 if(ln==0) red[wp]=ls; __syncthreads();\n\
362\x20 if(t==0){ float s=0.0f; for(int i=0;i<nw;++i) s+=red[i]; red[0]=s; } __syncthreads();\n\
363\x20 float sum=red[0];\n\
364\x20 if(t==0){ float wsum=0.0f;\n\
365\x20   for(int r=0;r<K;++r){ float bv=-1e30f; int bi=0; for(int e=0;e<E;++e) if(sp[e]>bv){ bv=sp[e]; bi=e; } idx[r]=bi; float pv=sp[bi]/sum; w[r]=pv; wsum+=pv; sp[bi]=-1e30f; }\n\
366\x20   for(int r=0;r<K;++r) w[r]/=wsum; }\n}\n";
367
368/// The TWO-PASS (logit-exact) fused trio — see [`Q8MatKind::TwoPassInt8`].
369const MOE_TWO_PASS_KERNELS: &str = "\
370// DEEPEST FUSION + TWO-PASS INT8-ACTIVATION dp4a (batch-1 latency-optimal AND ~14-bit exact). Two hard barriers
371// (router, h-complete); everything between fuses. gate+up+SwiGLU collapse into ONE kernel, down+combine into
372// another; only h and H touch HBM. The shared activation is quantized ONCE per MoE stage into a hi byte + a lo
373// residual byte (moe_qact); both fused kernels run TWO int8×int8 `__dp4a` per block (hi and lo) — the SHORT
374// dependency chain that wins the latency-bound regime, but with ~14-bit activation so a near-tie token does NOT
375// flip (single int8 flips it — like llama.cpp). Weights read once ⇒ memory cost unchanged. sl=sh/128. Scalar
376// tails cover Kd%128. N=dff/d, Kd=d/dff.\n\
377__global__ void moe_qact(const float* a, signed char* aqh, signed char* aql, float* as_, int K){\n\
378\x20 int nb=K/32; int blk=blockIdx.x*(blockDim.x/32)+threadIdx.x/32; if(blk>=nb) return;\n\
379\x20 int lane=threadIdx.x&31; float v=a[blk*32+lane], av=fabsf(v);\n\
380\x20 for(int s=16;s>0;s>>=1) av=fmaxf(av,__shfl_down_sync(0xffffffffu,av,s));\n\
381\x20 av=__shfl_sync(0xffffffffu,av,0); float amax=av>1e-30f?av:1e-30f; float sh=amax/127.0f;\n\
382\x20 if(lane==0) as_[blk]=sh;\n\
383\x20 int qh=(int)rintf(v/sh); if(qh>127)qh=127; if(qh<-128)qh=-128; aqh[blk*32+lane]=(signed char)qh;\n\
384\x20 float r=v-qh*sh; float sl=sh*0.0078125f; int ql=(int)rintf(r/sl); if(ql>127)ql=127; if(ql<-128)ql=-128; aql[blk*32+lane]=(signed char)ql;\n}\n\
385__global__ void moe_gate_up_silu(const signed char* xqh, const signed char* xql, const float* xs, const signed char* wg_q, const float* wg_s, const signed char* wu_q, const float* wu_s, const int* idx, float* h, int K, int N, int Kd){\n\
386\x20 long row=(blockIdx.x*(long)blockDim.x+threadIdx.x)>>5; if(row>=(long)K*N) return; int lane=threadIdx.x&31;\n\
387\x20 int kk=row/N, j=row%N; int e=idx[kk]; int nb=Kd/32, nq=Kd/128;\n\
388\x20 const signed char* gwr=wg_q+((long)e*N+j)*Kd; const int* gw4=(const int*)gwr; const float* gsr=wg_s+((long)e*N+j)*nb;\n\
389\x20 const signed char* uwr=wu_q+((long)e*N+j)*Kd; const int* uw4=(const int*)uwr; const float* usr=wu_s+((long)e*N+j)*nb;\n\
390\x20 const signed char* xhb=xqh; const int* xh4=(const int*)xqh; const signed char* xlb=xql; const int* xl4=(const int*)xql;\n\
391\x20 float ga=0.0f, ua=0.0f;\n\
392\x20 for(int b=0;b<nq;++b){ int blk=b*4+lane/8; int aih=xh4[b*32+lane]; int ail=xl4[b*32+lane]; float sh=xs[blk]; float sl=sh*0.0078125f; int gwi=gw4[b*32+lane]; int uwi=uw4[b*32+lane];\n\
393\x20   ga+=gsr[blk]*(sh*(float)__dp4a(gwi,aih,0)+sl*(float)__dp4a(gwi,ail,0));\n\
394\x20   ua+=usr[blk]*(sh*(float)__dp4a(uwi,aih,0)+sl*(float)__dp4a(uwi,ail,0)); }\n\
395\x20 for(int t=nq*128+lane;t<Kd;t+=32){ int blk=t/32; float sh=xs[blk]; float sl=sh*0.0078125f; int gwj=(int)gwr[t]; int uwj=(int)uwr[t]; int xh=(int)xhb[t]; int xl=(int)xlb[t]; ga+=gsr[blk]*(sh*(float)(gwj*xh)+sl*(float)(gwj*xl)); ua+=usr[blk]*(sh*(float)(uwj*xh)+sl*(float)(uwj*xl)); }\n\
396\x20 for(int s=16;s>0;s>>=1){ ga+=__shfl_down_sync(0xffffffffu,ga,s); ua+=__shfl_down_sync(0xffffffffu,ua,s); }\n\
397\x20 if(lane==0) h[row]=(ga/(1.0f+expf(-ga)))*ua;\n}\n\
398__global__ void moe_down_combine(const signed char* hqh, const signed char* hql, const float* hs, const signed char* wd_q, const float* wd_s, const int* idx, const float* wc, float* H, int K, int N, int Kd){\n\
399\x20 int o=blockIdx.x; int warp=threadIdx.x>>5, lane=threadIdx.x&31;\n\
400\x20 int e=idx[warp]; int nb=Kd/32, nq=Kd/128;\n\
401\x20 const signed char* hhb=hqh+(long)warp*Kd; const int* hh4=(const int*)hhb; const signed char* hlb=hql+(long)warp*Kd; const int* hl4=(const int*)hlb; const float* hsr=hs+(long)warp*nb;\n\
402\x20 const signed char* wr=wd_q+((long)e*N+o)*Kd; const int* w4=(const int*)wr; const float* wsr=wd_s+((long)e*N+o)*nb;\n\
403\x20 float acc=0.0f;\n\
404\x20 for(int b=0;b<nq;++b){ int blk=b*4+lane/8; int wi=w4[b*32+lane]; float sh=hsr[blk]; float sl=sh*0.0078125f; acc+=wsr[blk]*(sh*(float)__dp4a(wi,hh4[b*32+lane],0)+sl*(float)__dp4a(wi,hl4[b*32+lane],0)); }\n\
405\x20 for(int t=nq*128+lane;t<Kd;t+=32){ int blk=t/32; float sh=hsr[blk]; float sl=sh*0.0078125f; int wj=(int)wr[t]; acc+=wsr[blk]*(sh*(float)(wj*(int)hhb[t])+sl*(float)(wj*(int)hlb[t])); }\n\
406\x20 for(int s=16;s>0;s>>=1) acc+=__shfl_down_sync(0xffffffffu,acc,s);\n\
407\x20 __shared__ float part[64];\n\
408\x20 if(lane==0) part[warp]=wc[warp]*acc;\n\
409\x20 __syncthreads();\n\
410\x20 if(threadIdx.x==0){ float sum=0.0f; for(int kk=0;kk<K;++kk) sum+=part[kk]; H[o]=sum; }\n}\n";
411
412/// The SINGLE-PASS (default, llama-matched precision) fused trio — see [`Q8MatKind::Int8Act`]. Identical
413/// fusion shape to the two-pass trio with the lo-residual pass deleted: ONE int8 quantization per activation
414/// (`moe_qact`) and ONE `__dp4a` per operand per 32-block — the shortest dependency chain, the fastest path
415/// (the A100 head-to-head beat over llama.cpp at matched precision).
416const MOE_SINGLE_PASS_KERNELS: &str = "\
417// DEEPEST FUSION + SINGLE-PASS INT8-ACTIVATION dp4a (batch-1 latency-optimal, llama.cpp-matched precision).
418// Two hard barriers (router, h-complete); everything between fuses. gate+up+SwiGLU collapse into ONE kernel,\n\
419// down+combine into another; only h and H touch HBM. The shared activation is quantized ONCE per MoE stage\n\
420// (moe_qact); both fused kernels run ONE int8×int8 `__dp4a` per block — the SHORT dependency chain that wins\n\
421// the latency-bound regime, at llama.cpp's activation precision (a near-tie logit can flip exactly as its\n\
422// does; the TwoPassInt8 mode holds it). Weights read once ⇒ memory cost unchanged. Scalar tails cover Kd%128.\n\
423__global__ void moe_qact(const float* a, signed char* aq, float* as_, int K){\n\
424\x20 int nb=K/32; int blk=blockIdx.x*(blockDim.x/32)+threadIdx.x/32; if(blk>=nb) return;\n\
425\x20 int lane=threadIdx.x&31; float v=a[blk*32+lane], av=fabsf(v);\n\
426\x20 for(int s=16;s>0;s>>=1) av=fmaxf(av,__shfl_down_sync(0xffffffffu,av,s));\n\
427\x20 av=__shfl_sync(0xffffffffu,av,0); float amax=av>1e-30f?av:1e-30f; float sc=amax/127.0f;\n\
428\x20 if(lane==0) as_[blk]=sc;\n\
429\x20 int q=(int)rintf(v/sc); if(q>127)q=127; if(q<-128)q=-128; aq[blk*32+lane]=(signed char)q;\n}\n\
430__global__ void moe_gate_up_silu(const signed char* xq, const float* xs, const signed char* wg_q, const float* wg_s, const signed char* wu_q, const float* wu_s, const int* idx, float* h, int K, int N, int Kd){\n\
431\x20 long row=(blockIdx.x*(long)blockDim.x+threadIdx.x)>>5; if(row>=(long)K*N) return; int lane=threadIdx.x&31;\n\
432\x20 int kk=row/N, j=row%N; int e=idx[kk]; int nb=Kd/32, nq=Kd/128;\n\
433\x20 const signed char* gwr=wg_q+((long)e*N+j)*Kd; const int* gw4=(const int*)gwr; const float* gsr=wg_s+((long)e*N+j)*nb;\n\
434\x20 const signed char* uwr=wu_q+((long)e*N+j)*Kd; const int* uw4=(const int*)uwr; const float* usr=wu_s+((long)e*N+j)*nb;\n\
435\x20 const signed char* xb=xq; const int* x4=(const int*)xq;\n\
436\x20 float ga=0.0f, ua=0.0f; int nq16=Kd/512;\n\
437\x20 const int4* gw16=(const int4*)gwr; const int4* uw16=(const int4*)uwr; const int4* x16=(const int4*)xq;\n\
438\x20 for(int b=0;b<nq16;++b){ int blk=b*16+lane/2; float sc=xs[blk]; int4 av=x16[b*32+lane]; int4 gv=gw16[b*32+lane]; int4 uv=uw16[b*32+lane];\n\
439\x20   int gd=__dp4a(gv.x,av.x,0); gd=__dp4a(gv.y,av.y,gd); gd=__dp4a(gv.z,av.z,gd); gd=__dp4a(gv.w,av.w,gd);\n\
440\x20   int ud=__dp4a(uv.x,av.x,0); ud=__dp4a(uv.y,av.y,ud); ud=__dp4a(uv.z,av.z,ud); ud=__dp4a(uv.w,av.w,ud);\n\
441\x20   ga+=gsr[blk]*sc*(float)gd; ua+=usr[blk]*sc*(float)ud; }\n\
442\x20 for(int b4=nq16*4;b4<nq;++b4){ int blk=b4*4+lane/8; int ai=x4[b4*32+lane]; float sc=xs[blk]; int gwi=gw4[b4*32+lane]; int uwi=uw4[b4*32+lane]; ga+=gsr[blk]*sc*(float)__dp4a(gwi,ai,0); ua+=usr[blk]*sc*(float)__dp4a(uwi,ai,0); }\n\
443\x20 for(int t=nq*128+lane;t<Kd;t+=32){ int blk=t/32; float sc=xs[blk]; int gwj=(int)gwr[t]; int uwj=(int)uwr[t]; int xv=(int)xb[t]; ga+=gsr[blk]*sc*(float)(gwj*xv); ua+=usr[blk]*sc*(float)(uwj*xv); }\n\
444\x20 for(int s=16;s>0;s>>=1){ ga+=__shfl_down_sync(0xffffffffu,ga,s); ua+=__shfl_down_sync(0xffffffffu,ua,s); }\n\
445\x20 if(lane==0) h[row]=(ga/(1.0f+expf(-ga)))*ua;\n}\n\
446__global__ void moe_down_combine(const signed char* hq, const float* hs, const signed char* wd_q, const float* wd_s, const int* idx, const float* wc, float* H, int K, int N, int Kd){\n\
447\x20 int o=blockIdx.x; int warp=threadIdx.x>>5, lane=threadIdx.x&31;\n\
448\x20 int e=idx[warp]; int nb=Kd/32, nq=Kd/128;\n\
449\x20 const signed char* hb=hq+(long)warp*Kd; const int* h4=(const int*)hb; const float* hsr=hs+(long)warp*nb;\n\
450\x20 const signed char* wr=wd_q+((long)e*N+o)*Kd; const int* w4=(const int*)wr; const float* wsr=wd_s+((long)e*N+o)*nb;\n\
451\x20 float acc=0.0f; int nq16=Kd/512;\n\
452\x20 const int4* w16=(const int4*)wr; const int4* h16=(const int4*)hb;\n\
453\x20 for(int b=0;b<nq16;++b){ int blk=b*16+lane/2; int4 wv=w16[b*32+lane]; int4 hv=h16[b*32+lane];\n\
454\x20   int d=__dp4a(wv.x,hv.x,0); d=__dp4a(wv.y,hv.y,d); d=__dp4a(wv.z,hv.z,d); d=__dp4a(wv.w,hv.w,d);\n\
455\x20   acc+=wsr[blk]*hsr[blk]*(float)d; }\n\
456\x20 for(int b4=nq16*4;b4<nq;++b4){ int blk=b4*4+lane/8; int wi=w4[b4*32+lane]; acc+=wsr[blk]*hsr[blk]*(float)__dp4a(wi,h4[b4*32+lane],0); }\n\
457\x20 for(int t=nq*128+lane;t<Kd;t+=32){ int blk=t/32; int wj=(int)wr[t]; acc+=wsr[blk]*hsr[blk]*(float)(wj*(int)hb[t]); }\n\
458\x20 for(int s=16;s>0;s>>=1) acc+=__shfl_down_sync(0xffffffffu,acc,s);\n\
459\x20 __shared__ float part[64];\n\
460\x20 if(lane==0) part[warp]=wc[warp]*acc;\n\
461\x20 __syncthreads();\n\
462\x20 if(threadIdx.x==0){ float sum=0.0f; for(int kk=0;kk<K;++kk) sum+=part[kk]; H[o]=sum; }\n}\n";
463
464/// The sparse fused MoE kernel set for a coalesced int8 path: the precision-independent router + top-K pair,
465/// then the single-pass (default) or two-pass (logit-exact) quantize/gate-up-SwiGLU/down-combine trio.
466/// Public so a checked-in copy of the kernel set can be pinned byte-equal to what the compiler emits today.
467pub fn moe_dp4a_kernels(two_pass: bool) -> String {
468    let mut s = String::from(MOE_ROUTER_TOPK_KERNELS);
469    s.push_str(if two_pass {
470        MOE_TWO_PASS_KERNELS
471    } else {
472        MOE_SINGLE_PASS_KERNELS
473    });
474    s
475}
476
477/// The shared kernels a MoE stage launches (emitted once when any `Stage::Moe` is present): a dequant-in-kernel
478/// Q8 GEMV (f64 accumulate — the certified matvec, expert-selected by the base pointers the host passes), the
479/// SwiGLU element op, a zero, a top-K router (softmax → keep K → renormalize, on-device), and a weighted
480/// combine. Identical to `emit_moe_forward`'s block, re-parameterized for the chained-buffer host.
481const MOE_KERNELS: &str = "\
482__global__ void moe_gemv(const float* a, const signed char* wq, const float* ws, float* y, int N, int K){\n\
483\x20 int o=blockIdx.x*blockDim.x+threadIdx.x; if(o>=N) return; int nb=K/32;\n\
484\x20 const signed char* wr=wq+(long)o*K; const float* wsr=ws+(long)o*nb; double acc=0.0;\n\
485\x20 for(int bl=0;bl<nb;++bl){ double dot=0.0; for(int j=0;j<32;++j) dot+=(double)wr[bl*32+j]*(double)a[bl*32+j]; acc+=dot*(double)wsr[bl]; }\n\
486\x20 y[o]=(float)acc;\n}\n\
487__global__ void moe_silu_had(const float* g, const float* u, float* he, int n){\n\
488\x20 int i=blockIdx.x*blockDim.x+threadIdx.x; if(i>=n) return; float gv=g[i]; he[i]=(gv/(1.0f+expf(-gv)))*u[i];\n}\n\
489__global__ void moe_zero(float* y, int n){ int i=blockIdx.x*blockDim.x+threadIdx.x; if(i<n) y[i]=0.0f; }\n\
490__global__ void moe_combine(float* H, const float* oute, const float* wv, int e, int d){\n\
491\x20 int o=blockIdx.x*blockDim.x+threadIdx.x; if(o<d) H[o]+=wv[e]*oute[o];\n}\n\
492__global__ void moe_topk(const float* logits, float* w, int E, int K){\n\
493\x20 if(threadIdx.x!=0) return; float p[256]; float pm[256];\n\
494\x20 float m=logits[0]; for(int e=1;e<E;++e) if(logits[e]>m) m=logits[e];\n\
495\x20 float s=0.0f; for(int e=0;e<E;++e) s+=expf(logits[e]-m);\n\
496\x20 for(int e=0;e<E;++e){ p[e]=expf(logits[e]-m)/s; pm[e]=p[e]; w[e]=0.0f; }\n\
497\x20 float wsum=0.0f;\n\
498\x20 for(int r=0;r<K;++r){ float bv=-1e30f; int bi=0; for(int e=0;e<E;++e) if(pm[e]>bv){ bv=pm[e]; bi=e; } wsum+=p[bi]; w[bi]=p[bi]; pm[bi]=-1e30f; }\n\
499\x20 for(int e=0;e<E;++e) w[e]/=wsum;\n}\n";
500
501/// The single-query GQA `attention` block as this lane's tuple: `(q, kc, vc, out, h, kv, hd, l)` — the shared
502/// [`qwen::AttentionSpec`] without its position bound (this lane attends to every cached row).
503#[allow(clippy::type_complexity)]
504pub fn recognize_attention(
505    stmts: &[Stmt],
506) -> Option<(Symbol, Symbol, Symbol, Symbol, usize, usize, usize, usize)> {
507    qwen::recognize_attention(stmts).map(|a| (a.q, a.kc, a.vc, a.out, a.h, a.kv, a.hd, a.l))
508}
509
510/// The forward of a program as the shared table fuses it under the forward's shim ([`ForwardShim`]): every statement
511/// the front end lifts ([`crate::spatial::passes::recognize_stages::walk`]), or the program refused whole, each refusal
512/// naming its statement. The front end decides what a statement IS (an op, a declaration, a fill, a write no op
513/// computes); [`kernel_refusal`] decides whether this lane's kernels compute it. `q8` and `moe` name the weights it
514/// reads in Q8_0.
515pub fn forward_graph(
516    stmts: &[Stmt],
517    interner: &Interner,
518    q8: &HashMap<String, Q8Ref>,
519    moe: &HashMap<String, MoeWeights>,
520    kind: Q8MatKind,
521) -> Result<TensorGraph, ForwardError> {
522    forward_graph_holding(stmts, interner, q8, moe, kind, &[])
523}
524
525/// [`forward_graph`] with the optimizer's steps `held` held back: the program run apart where they would fuse.
526pub fn forward_graph_holding(
527    stmts: &[Stmt],
528    interner: &Interner,
529    q8: &HashMap<String, Q8Ref>,
530    moe: &HashMap<String, MoeWeights>,
531    kind: Q8MatKind,
532    held: &[&str],
533) -> Result<TensorGraph, ForwardError> {
534    let front = crate::spatial::passes::recognize_stages::walk(stmts, interner);
535    let mut refusals: Vec<StageRefusal> = front
536        .unrecognized
537        .iter()
538        .map(|(stmt, what)| StageRefusal::Unrecognized {
539            stmt: *stmt,
540            what: what.clone(),
541        })
542        .chain(
543            front
544                .unlifted_writes
545                .iter()
546                .map(|(stmt, tensor, why)| StageRefusal::UnliftedWrite {
547                    stmt: *stmt,
548                    tensor: tensor.clone(),
549                    why,
550                }),
551        )
552        .collect();
553    for st in &front.stages {
554        if let Some(why) = kernel_refusal(&st.op) {
555            refusals.push(StageRefusal::NoKernel {
556                stmt: st.stmt_index,
557                kind: st.op.kind(),
558                out: st.out.clone(),
559                why,
560            });
561        }
562    }
563    if !refusals.is_empty() {
564        refusals.sort_by_key(StageRefusal::stmt);
565        return Err(ForwardError::Refused(refusals));
566    }
567    if front.stages.is_empty() {
568        return Err(ForwardError::NoStages);
569    }
570    let mut stored: std::collections::BTreeSet<&str> = q8.keys().map(String::as_str).collect();
571    for st in &front.stages {
572        if matches!(st.op, TensorOpSpec::Moe(_)) && moe.contains_key(&st.out) {
573            stored.extend(st.ins[1..5].iter().map(String::as_str));
574        }
575    }
576    let storage = |t: &str| {
577        if stored.contains(t) {
578            Storage::Rows { format: GgmlType::Q8_0, transposed: true }
579        } else {
580            Storage::Values
581        }
582    };
583    let lifted = TensorGraph::lift_stages(&front, None, None, &storage);
584    Ok(optimize(&lifted, &ForwardShim { kind }, held).graph)
585}
586
587impl StageRefusal {
588    /// The top-level statement the refusal names.
589    pub fn stmt(&self) -> usize {
590        match self {
591            StageRefusal::Unrecognized { stmt, .. }
592            | StageRefusal::UnliftedWrite { stmt, .. }
593            | StageRefusal::NoKernel { stmt, .. } => *stmt,
594        }
595    }
596}
597
598/// One step of a fused elementwise chain applied to the register-carried value `t`: a binary op against an
599/// external operand (`t = t ⊕ ext[idx]`), or a unary SiLU (`t = silu(t)`, no operand).
600#[derive(Debug, Clone)]
601pub enum ChainStep {
602    Binary(ElementwiseOp, Symbol),
603    Silu,
604}
605
606/// The op a quantize folded into it computes, and whether it quantizes its result in its epilogue.
607fn folded(op: &Op) -> (&Op, bool) {
608    match &op.sym {
609        Sym::Fused(f) if matches!(f.class, ClassId::NormQuant | ClassId::AddNormQuant | ClassId::AttnOutputQuant) => (&f.parts[0], true),
610        _ => (op, false),
611    }
612}
613
614/// The kernels the forward writes for its graph, in order, each with the stage number its kernels are named by, and the
615/// count of stages: every op but a quantize, which the product reading it launches. A sum and the norm it adds into keep
616/// the two numbers their two statements have.
617fn kernels_of(graph: &TensorGraph) -> (Vec<(usize, &Op)>, usize) {
618    let mut at = 0;
619    let mut out = Vec::new();
620    for op in &graph.ops {
621        if matches!(op.sym, Sym::Quantize(_)) {
622            continue;
623        }
624        out.push((at, op));
625        at += match &folded(op).0.sym {
626            Sym::Fused(Fused { class: ClassId::AddNorm, .. }) => 2,
627            _ => 1,
628        };
629    }
630    (out, at)
631}
632
633/// An elementwise op's spec, and the RMS norm it adds into when the op is a sum and its norm.
634fn sum_and_norm(op: &Op) -> (&ElementwiseSpec, Option<&FusedRowSpec>) {
635    match (&op.sym, op.prim()) {
636        (Sym::Fused(f), _) => match (f.parts[0].prim(), f.parts[1].prim()) {
637            (Some(TensorOpSpec::Elementwise(e)), Some(TensorOpSpec::FusedRow(r))) => (e, Some(r)),
638            _ => unreachable!("a sum and the norm it adds into"),
639        },
640        (_, Some(TensorOpSpec::Elementwise(e))) => (e, None),
641        _ => unreachable!("an elementwise op"),
642    }
643}
644
645/// A fused run of elementwise ops as the forward's one kernel takes it: the first op's operands and op, each later
646/// member as a step carrying the running value through it, the run's result and its length.
647fn chain(members: &[Op]) -> (Symbol, Symbol, ElementwiseOp, Vec<ChainStep>, Symbol, usize) {
648    let Some(TensorOpSpec::Elementwise(e0)) = members[0].prim() else { unreachable!("a run starts with an elementwise op") };
649    let mut carry = e0.c;
650    let mut tail = Vec::new();
651    for m in &members[1..] {
652        match m.prim() {
653            Some(TensorOpSpec::Elementwise(e)) => {
654                tail.push(ChainStep::Binary(e.op, if e.a == carry { e.b } else { e.a }));
655                carry = e.c;
656            }
657            Some(TensorOpSpec::Silu(u)) => {
658                tail.push(ChainStep::Silu);
659                carry = u.out;
660            }
661            _ => unreachable!("a run carries elementwise ops and SiLUs"),
662        }
663    }
664    (e0.a, e0.b, e0.op, tail, carry, e0.n)
665}
666
667/// Under the single-pass int8 numerics, each activation an int8 product of a Q8_0 weight reads, with the product's
668/// `(M, K)`.
669fn q8_fed(ops: &[Op], q8: &HashMap<String, Q8Ref>, kind: Q8MatKind, interner: &Interner) -> HashMap<String, (usize, usize)> {
670    let mut fed = HashMap::new();
671    if kind == Q8MatKind::Int8Act {
672        for op in ops {
673            if let Some(TensorOpSpec::Matmul(m)) = op.prim() {
674                if q8.contains_key(interner.resolve(m.b)) {
675                    fed.insert(interner.resolve(m.a).to_string(), (m.m, m.k));
676                }
677            }
678        }
679    }
680    fed
681}
682
683/// The variables a kernel touches, each with its element count, in the order the forward sizes their buffers: a sum and
684/// its norm as their two statements, a run by its operands and result (its intermediates live in registers).
685fn kernel_vars(op: &Op, interner: &Interner) -> Vec<(String, usize)> {
686    let name = |s: Symbol| interner.resolve(s).to_string();
687    let host = folded(op).0;
688    match &host.sym {
689        Sym::Fused(f) if f.class == ClassId::ElementwiseChains => {
690            let (a, b, _, tail, out, n) = chain(&leaves(host.clone()));
691            let mut v = vec![(name(a), n), (name(b), n), (name(out), n)];
692            v.extend(tail.iter().filter_map(|step| match step {
693                ChainStep::Binary(_, ext) => Some((name(*ext), n)),
694                ChainStep::Silu => None,
695            }));
696            v
697        }
698        Sym::Fused(f) if f.class == ClassId::ElementwiseRegions => {
699            let n = region_body(host, "float").1;
700            host.ins.iter().cloned().chain(region_outputs(host)).map(|v| (v, n)).collect()
701        }
702        Sym::Fused(f) => f.parts.iter().flat_map(|p| kernel_vars(p, interner)).collect(),
703        _ => match host.prim().expect("a lifted op") {
704            TensorOpSpec::Matmul(m) => vec![(name(m.a), m.m * m.k), (name(m.b), m.k * m.n), (name(m.c), m.m * m.n)],
705            TensorOpSpec::Elementwise(e) => vec![(name(e.a), e.n), (name(e.b), e.n), (name(e.c), e.n)],
706            TensorOpSpec::FusedRow(r) => {
707                let mut v = vec![(name(r.x), r.rows * r.cols), (name(r.y), r.rows * r.cols)];
708                if let Some(w) = r.weight {
709                    v.push((name(w), r.cols));
710                }
711                // Residual (a same-shape fused-add operand) and bias (per-column) are genuine INPUTS, sized as buffers.
712                if let Some(res) = r.residual {
713                    v.push((name(res), r.rows * r.cols));
714                }
715                if let Some(bias) = r.bias {
716                    v.push((name(bias), r.cols));
717                }
718                v
719            }
720            TensorOpSpec::Transpose(t) => vec![(name(t.x), t.rows * t.cols), (name(t.out), t.rows * t.cols)],
721            TensorOpSpec::Silu(u) => vec![(name(u.x), u.n), (name(u.out), u.n)],
722            TensorOpSpec::Rope(r) => {
723                let d = r.h * 2 * r.half;
724                vec![(name(r.q), d), (name(r.rc), r.half), (name(r.rs), r.half), (name(r.out), d)]
725            }
726            // The grouped weights load from the MoE manifest (not chained buffers); only x (input) and out size here.
727            TensorOpSpec::Moe(m) => vec![(name(m.x), m.d), (name(m.out), m.d)],
728            TensorOpSpec::Attention(a) => vec![
729                (name(a.q), a.h * a.hd),
730                (name(a.kc), a.l * a.kv * a.hd),
731                (name(a.vc), a.l * a.kv * a.hd),
732                (name(a.out), a.h * a.hd),
733            ],
734            other => unreachable!("the forward's shim admits no {}", other.kind()),
735        },
736    }
737}
738
739/// The variables a kernel produces: a sum and its norm both, every other kernel its result.
740fn kernel_outputs(op: &Op) -> Vec<String> {
741    match &folded(op).0.sym {
742        Sym::Fused(f) if f.class == ClassId::AddNorm => f.parts.iter().map(|p| p.out.clone()).collect(),
743        Sym::Fused(f) if f.class == ClassId::ElementwiseRegions => region_outputs(op),
744        _ => vec![op.out.clone()],
745    }
746}
747
748/// What a region writes: its result, then every member's a later op reads.
749fn region_outputs(op: &Op) -> Vec<String> {
750    std::iter::once(op.out.clone()).chain(op.keeps.iter().cloned()).collect()
751}
752
753/// The values a region computes element by element: each member's, as its own kernel computes it, over the region's
754/// operands read at the element's place and the earlier members' values in registers `t{k}`; then the count of
755/// elements. A real product is rounded as its own kernel rounds it (`__fmul_rn`), which the compiler never contracts
756/// with a sum after it into one fused multiply-add.
757fn region_body(op: &Op, ty: &str) -> (Vec<String>, usize) {
758    let members = leaves(op.clone());
759    let value = |t: &str, upto: usize| match members[..upto].iter().position(|m| m.out == t) {
760        Some(k) => format!("t{k}"),
761        None => format!("i{}[idx]", op.ins.iter().position(|x| x == t).expect("a region reads its operands")),
762    };
763    let mut n = 0;
764    let lines = members
765        .iter()
766        .enumerate()
767        .map(|(k, m)| match m.prim() {
768            Some(TensorOpSpec::Elementwise(e)) => {
769                n = e.n;
770                let (x, y) = (value(&m.ins[0], k), value(&m.ins[1], k));
771                match e.op {
772                    ElementwiseOp::Mul if ty == "float" => format!("{ty} t{k} = __fmul_rn({x}, {y});"),
773                    op => format!("{ty} t{k} = {x} {} {y};", op.c_op()),
774                }
775            }
776            Some(TensorOpSpec::Silu(u)) => {
777                n = u.n;
778                format!("{ty} t{k}; {{ float v=(float){}; t{k} = v/(1.0f+expf(-v)); }}", value(&m.ins[0], k))
779            }
780            _ => unreachable!("a region the forward links holds elementwise ops and SiLUs"),
781        })
782        .collect();
783    (lines, n)
784}
785
786/// How a Q8_0 matmul lowers to CUDA. At batch-1 decode a matmul is bound on the int8 WEIGHT bytes, not the
787/// math — so these three modes trade accuracy/latency, NOT weight bandwidth.
788#[derive(Clone, Copy, PartialEq, Eq, Debug)]
789pub enum Q8MatKind {
790    /// f64 dequant, thread-per-output — the numeric reference (exact, but uncoalesced and slow).
791    Dequant,
792    /// SINGLE-PASS int8-activation MMQ (`__dp4a`, int32 accumulate), coalesced — THE DEFAULT fast path:
793    /// llama.cpp-matched activation precision (identical greedy token) with the shortest per-iteration
794    /// dependency chain, which wins the latency-bound batch-1 regime (the A100 head-to-head beat). A
795    /// near-tie logit can flip exactly as llama.cpp's does.
796    Int8Act,
797    /// TWO-PASS int8 activation (hi byte + lo residual byte ⇒ ~14-bit) — the logit-exact mode: the same
798    /// short `__dp4a` dependency chain, ~2× the activation math (two dp4a per block), logits within ~1e-3
799    /// of the f64 reference so a near-tie token does NOT flip. The correctness mode llama.cpp lacks.
800    TwoPassInt8,
801}
802
803/// Emit the composed CUDA program for a forward's graph ([`forward_graph`]): one uniquely-named kernel per stage plus a
804/// host driver that allocates a buffer per variable, fills the inputs `v[p] = (p % 7) - 3` (float chains scale by
805/// 0.5), launches each stage in order, and prints every element of the final stage's output. Deterministic,
806/// self-contained, `nvcc`-compilable; its output is checked against a clean-room reference of the same graph.
807pub fn emit_forward(
808    graph: &TensorGraph,
809    inits: &HashMap<String, Vec<(usize, InitVal)>>,
810    weights: &HashMap<String, (String, usize)>,
811    q8: &HashMap<String, Q8Ref>,
812    moe: &HashMap<String, MoeWeights>,
813    kind: Q8MatKind,
814    interner: &Interner,
815) -> Result<String, ForwardError> {
816    let (kernel_ops, stage_count) = kernels_of(graph);
817    if kernel_ops.is_empty() {
818        return Err(ForwardError::NoStages);
819    }
820    let lifted: Vec<Op> = graph.ops.iter().flat_map(|op| leaves(op.clone())).collect();
821    // A chain is float-typed if any stage is a (float) reduction or any input carries a float initializer;
822    // every kernel is then emitted over `float` (a matmul/elementwise inherits its operands' element type,
823    // and LOGOS tensor DSL programs are consistently typed, so this per-chain decision is exact). This lets a
824    // real transformer sub-block — `rmsnorm → matmul → residual`, all float — compose. A MoE stage is float too.
825    let has_float_init = inits
826        .values()
827        .flatten()
828        .any(|(_, v)| matches!(v, InitVal::F(_)));
829    let any_moe = lifted.iter().any(|o| matches!(o.prim(), Some(TensorOpSpec::Moe(_))));
830    let floaty = lifted.iter().any(|o| {
831        matches!(o.prim(), Some(TensorOpSpec::FusedRow(_) | TensorOpSpec::Moe(_) | TensorOpSpec::Attention(_) | TensorOpSpec::Silu(_)))
832    }) || has_float_init;
833    let ty = if floaty { "float" } else { "long long" };
834
835    // Collect every variable + its size, and which vars are produced (outputs) vs supplied (inputs).
836    let mut sizes: Vec<(String, usize)> = Vec::new();
837    let mut outputs: Vec<String> = Vec::new();
838    let mut seen = std::collections::HashSet::new();
839    for (_, op) in &kernel_ops {
840        for (v, sz) in kernel_vars(op, interner) {
841            if seen.insert(v.clone()) {
842                sizes.push((v, sz));
843            }
844        }
845        outputs.extend(kernel_outputs(op));
846    }
847    let is_output = |v: &str| outputs.iter().any(|o| o == v);
848
849    // ── kernels: one per stage, uniquely named k{i}_{kind} ──────────────────────────────────────────
850    let mut kernels = String::new();
851    // The MoE stages share one set of kernels (many layers reuse them); emit once. Both coalesced paths add
852    // the sparse fused set (router+topk, gate+up+SwiGLU, down+combine) in their precision; the dense
853    // router/silu/zero come from the base set.
854    if any_moe {
855        kernels.push_str(MOE_KERNELS);
856        if kind != Q8MatKind::Dequant {
857            kernels.push_str(&moe_dp4a_kernels(kind == Q8MatKind::TwoPassInt8));
858        }
859    }
860    let mut launches = String::new();
861    // Int8Act only: each distinct activation feeding an int8-activation DP4A matmul needs a scratch pair (int8
862    // quants + f32 block-scales) that `k{i}_qact` writes and `k{i}_q8dp4a` reads; collected here, allocated below.
863    let mut dp4a_scratch: Vec<(String, usize, usize)> = Vec::new();
864    // PRODUCER-FUSED activation quantization (Int8Act): an activation feeding a q8 matmul is quantized to int8
865    // INLINE by its producer kernel (rmsnorm/attention epilogue), so the consuming matmul skips its own `qact`
866    // launch — llama.cpp's inline-quant edge. `q8_fed[act] = (M, K)`; `producer_quantized` records the ones a
867    // producer already wrote (the matmul then just reads `buf_{act}_q8act`/`_q8scl`).
868    let q8_fed = q8_fed(&lifted, q8, kind, interner);
869    let mut producer_quantized: std::collections::HashSet<String> =
870        std::collections::HashSet::new();
871    for &(i, op) in &kernel_ops {
872        let (host, quantized) = folded(op);
873        match &host.sym {
874            Sym::Prim(TensorOpSpec::Matmul(m)) => {
875                let (a, b, c) = (
876                    interner.resolve(m.a),
877                    interner.resolve(m.b),
878                    interner.resolve(m.c),
879                );
880                if q8.contains_key(b) {
881                    match kind {
882                        Q8MatKind::TwoPassInt8 => {
883                            // INT8-ACTIVATION dp4a (llama.cpp's MMQ) for the attention/LM-head Q8 matmul: `k{i}_qact`
884                            // quantizes the f32 activation to int8 per 32-block (careful per-block amax/127, matching
885                            // llama's q8_1), then `k{i}_q8dp4a` streams int8 weight × int8 activation via `__dp4a` (int32
886                            // accumulate) — a SHORT per-iteration dependency chain (one instruction vs the f32 chain of
887                            // 4 int→float casts + half→float + FMA), which is the win in the batch-1 LATENCY-bound regime
888                            // (both ILP and split-K hurt ⇒ we're latency-, not throughput-bound). Same math llama uses ⇒
889                            // TWO-PASS int8 (hi byte + lo residual byte ⇒ ~14-bit activation) so `__dp4a` keeps its short
890                            // dependency chain AND enough precision to hold the true token on a near-tie (single int8-act
891                            // flips it — like llama.cpp). Weights read ONCE (memory-bound cost unchanged); the extra dp4a is
892                            // near-free. `sl = sh/128` — the residual lives in ±sh/2, so /128 fills the int8 range.
893                            let nb_ct = m.k / 32;
894                            kernels.push_str(&format!(
895                        "__global__ void k{i}_qact(const float* a, signed char* aqh, signed char* aql, float* as_, int M, int K){{\n\
896                         \x20 int nb=K/32; int blk=blockIdx.x*(blockDim.x/32)+threadIdx.x/32; if(blk>=M*nb) return;\n\
897                         \x20 int lane=threadIdx.x&31; float v=a[blk*32+lane], av=fabsf(v);\n\
898                         \x20 for(int s=16;s>0;s>>=1) av=fmaxf(av,__shfl_down_sync(0xffffffffu,av,s));\n\
899                         \x20 av=__shfl_sync(0xffffffffu,av,0); float amax=av>1e-30f?av:1e-30f; float sh=amax/127.0f;\n\
900                         \x20 if(lane==0) as_[blk]=sh;\n\
901                         \x20 int qh=(int)rintf(v/sh); if(qh>127)qh=127; if(qh<-128)qh=-128; aqh[blk*32+lane]=(signed char)qh;\n\
902                         \x20 float r=v-qh*sh; float sl=sh*0.0078125f; int ql=(int)rintf(r/sl); if(ql>127)ql=127; if(ql<-128)ql=-128; aql[blk*32+lane]=(signed char)ql;\n}}\n\
903                         __global__ void k{i}_q8dp4a(const signed char* aqh, const signed char* aql, const float* as_, const signed char* wq, const __half* ws, float* y, int M, int N, int K){{\n\
904                         \x20 int o=(blockIdx.x*blockDim.x+threadIdx.x)>>5; if(o>=N) return; int lane=threadIdx.x&31; int nb=K/32;\n\
905                         \x20 const signed char* wrow=wq+(long)o*K; const int* w4=(const int*)wrow; const __half* wsr=ws+(long)o*nb;\n\
906                         \x20 for(int r=0;r<M;++r){{\n\
907                         \x20   const signed char* arh=aqh+(long)r*K; const int* ah4=(const int*)arh; const signed char* arl=aql+(long)r*K; const int* al4=(const int*)arl; const float* asr=as_+(long)r*nb;\n\
908                         \x20   float acc=0.0f; int nq=K/128;\n\
909                         \x20   for(int b4=0;b4<nq;++b4){{ int wi=w4[b4*32+lane]; int blk=b4*4+lane/8; float ws_=__half2float(wsr[blk]); float sh=asr[blk];\n\
910                         \x20     acc += ws_*(sh*(float)__dp4a(wi,ah4[b4*32+lane],0) + sh*0.0078125f*(float)__dp4a(wi,al4[b4*32+lane],0)); }}\n\
911                         \x20   for(int j=nq*128+lane;j<K;j+=32){{ int blk=j/32; float ws_=__half2float(wsr[blk]); float sh=asr[blk]; int wj=(int)wrow[j];\n\
912                         \x20     acc += ws_*(sh*(float)(wj*(int)arh[j]) + sh*0.0078125f*(float)(wj*(int)arl[j])); }}\n\
913                         \x20   for(int s=16;s>0;s>>=1) acc+=__shfl_down_sync(0xffffffffu,acc,s);\n\
914                         \x20   if(lane==0) y[(long)r*N+o]=acc;\n\
915                         \x20 }}\n}}\n"
916                    ));
917                            if !dp4a_scratch.iter().any(|(v, _, _)| v == a) {
918                                dp4a_scratch.push((a.to_string(), m.m, m.k));
919                            }
920                            launches.push_str(&format!(
921                        "  {{ k{i}_qact<<<({M}*{NB}+7)/8,256>>>(buf_{a},buf_{a}_q8act,buf_{a}_q8actlo,buf_{a}_q8scl,{M},{K});\n\
922                         \x20   k{i}_q8dp4a<<<({N}+7)/8,256>>>(buf_{a}_q8act,buf_{a}_q8actlo,buf_{a}_q8scl,buf_{b}_q,buf_{b}_s,buf_{c},{M},{N},{K}); }}\n",
923                        M = m.m, N = m.n, K = m.k, NB = nb_ct
924                    ));
925                        }
926                        Q8MatKind::Int8Act => {
927                            // INT8-ACTIVATION MMQ, COALESCED — mirrors `cuda/qwen_forward.cu`'s `q8_gemv_dp4a`. Two kernels:
928                            // (1) `k{i}_qact` quantizes each 32-block of the f32 activation to int8 + an f32 block-scale (one
929                            // warp per block, `__shfl` max-reduce); (2) `k{i}_q8dp4a` assigns ONE WARP per output row — each
930                            // lane streams a 128-byte-coalesced `int` (4 packed int8) of BOTH int8 operands, `__dp4a`-
931                            // accumulates (4 MACs/instr, int32), recombining per 32-block by weight-scale × activation-scale,
932                            // a scalar tail covering K%128, then a warp-shuffle reduction. THE DEFAULT batch-1 path: the
933                            // single dp4a per block is the shortest dependency chain — the fastest in the latency-bound
934                            // regime, at llama.cpp-matched activation precision; `TwoPassInt8` is the logit-exact opt-in.
935                            let nb_ct = m.k / 32;
936                            kernels.push_str(&format!(
937                        "__global__ void k{i}_qact(const float* a, signed char* aq, float* as_, int M, int K){{\n\
938                         \x20 int nb=K/32; int blk=blockIdx.x*(blockDim.x/32)+threadIdx.x/32; if(blk>=M*nb) return;\n\
939                         \x20 int lane=threadIdx.x&31; float v=a[blk*32+lane], av=fabsf(v);\n\
940                         \x20 for(int s=16;s>0;s>>=1) av=fmaxf(av,__shfl_down_sync(0xffffffffu,av,s));\n\
941                         \x20 av=__shfl_sync(0xffffffffu,av,0); float amax=av>1e-30f?av:1e-30f; float scale=amax/127.0f;\n\
942                         \x20 if(lane==0) as_[blk]=scale;\n\
943                         \x20 int q=(int)rintf(v/scale); if(q>127)q=127; if(q<-128)q=-128; aq[blk*32+lane]=(signed char)q;\n}}\n\
944                         __global__ void k{i}_q8dp4a(const signed char* aq, const float* as_, const signed char* wq, const __half* ws, float* y, int M, int N, int K){{\n\
945                         \x20 int o=(blockIdx.x*blockDim.x+threadIdx.x)>>5; if(o>=N) return; int lane=threadIdx.x&31; int nb=K/32;\n\
946                         \x20 const signed char* wrow=wq+(long)o*K; const int* w4=(const int*)wrow; const __half* wsr=ws+(long)o*nb;\n\
947                         \x20 for(int r=0;r<M;++r){{\n\
948                         \x20   const signed char* arow=aq+(long)r*K; const int* a4=(const int*)arow; const float* asr=as_+(long)r*nb;\n\
949                         \x20   float acc=0.0f; int nq16=K/512; int nq=K/128;\n\
950                         \x20   const int4* w16=(const int4*)wrow; const int4* a16=(const int4*)arow;\n\
951                         \x20   for(int b=0;b<nq16;++b){{ int4 wv=w16[b*32+lane]; int4 av=a16[b*32+lane]; int blk=b*16+lane/2; float sw=__half2float(wsr[blk])*asr[blk];\n\
952                         \x20     int d=__dp4a(wv.x,av.x,0); d=__dp4a(wv.y,av.y,d); d=__dp4a(wv.z,av.z,d); d=__dp4a(wv.w,av.w,d); acc += (float)d * sw; }}\n\
953                         \x20   for(int b4=nq16*4;b4<nq;++b4){{ int wi=w4[b4*32+lane], ai=a4[b4*32+lane]; int blk=b4*4+lane/8; acc += (float)__dp4a(wi,ai,0) * (__half2float(wsr[blk])*asr[blk]); }}\n\
954                         \x20   for(int j=nq*128+lane;j<K;j+=32){{ int blk=j/32; acc += (float)((int)arow[j]*(int)wrow[j]) * (__half2float(wsr[blk])*asr[blk]); }}\n\
955                         \x20   for(int s=16;s>0;s>>=1) acc+=__shfl_down_sync(0xffffffffu,acc,s);\n\
956                         \x20   if(lane==0) y[(long)r*N+o]=acc;\n\
957                         \x20 }}\n}}\n"
958                    ));
959                            // DEDUP the activation quantization: an activation feeding several projections (Q/K/V all read
960                            // the SAME `xn`) is quantized to int8 ONCE, not per-matmul — the `q8act`/`q8scl` buffers are
961                            // shared (allocated once via `dp4a_scratch`). Emit `k{i}_qact` only on the first matmul that
962                            // uses `a`; later matmuls read the already-quantized buffer. (Kills the redundant Q/K/V qacts.)
963                            let first_qact = !dp4a_scratch.iter().any(|(v, _, _)| v == a);
964                            if first_qact {
965                                dp4a_scratch.push((a.to_string(), m.m, m.k));
966                            }
967                            // Skip the qact launch entirely if the PRODUCER already quantized this activation inline
968                            // (fused into its rmsnorm/attention epilogue), or if a prior matmul on the same activation
969                            // already quantized it (Q/K/V dedup). `buf_{a}_q8act`/`_q8scl` are filled either way.
970                            let qact_launch = if first_qact && !producer_quantized.contains(a) {
971                                format!("k{i}_qact<<<({M}*{NB}+7)/8,256>>>(buf_{a},buf_{a}_q8act,buf_{a}_q8scl,{M},{K}); ", M = m.m, K = m.k, NB = nb_ct)
972                            } else {
973                                String::new()
974                            };
975                            launches.push_str(&format!(
976                        "  {{ {qact_launch}k{i}_q8dp4a<<<({N}+7)/8,256>>>(buf_{a}_q8act,buf_{a}_q8scl,buf_{b}_q,buf_{b}_s,buf_{c},{M},{N},{K}); }}\n",
977                        M = m.m, N = m.n, K = m.k
978                    ));
979                        }
980                        Q8MatKind::Dequant => {
981                            // INT8-quantized projection `y = W·x`: W is the GGUF `[out, in]` Q8_0 weight (quants + f32
982                            // block scales), the activation f32. Dequant-in-kernel GEMV — one output per thread,
983                            // accumulate over 32-wide blocks scaled by the block scale (matches `qwen.rs` matvec).
984                            kernels.push_str(&format!(
985                        "__global__ void k{i}_q8gemv(const float* a, const signed char* wq, const float* ws, float* y, int M, int N, int K){{\n\
986                         \x20 int idx = blockIdx.x*blockDim.x + threadIdx.x; if(idx >= M*N) return;\n\
987                         \x20 int r = idx / N, n = idx % N; int nb = K/32; double acc = 0.0;\n\
988                         \x20 for(int bl=0;bl<nb;++bl){{ double dot=0.0; for(int j=0;j<32;++j) dot += (double)wq[n*K + bl*32 + j] * (double)a[r*K + bl*32 + j]; acc += dot * (double)ws[n*nb + bl]; }}\n\
989                         \x20 y[idx] = (float)acc;\n}}\n"
990                    ));
991                            launches.push_str(&format!(
992                        "  {{ int total={M}*{N}; k{i}_q8gemv<<<(total+255)/256,256>>>(buf_{a},buf_{b}_q,buf_{b}_s,buf_{c},{M},{N},{K}); }}\n",
993                        M = m.m, N = m.n, K = m.k
994                    ));
995                        }
996                    }
997                } else {
998                    kernels.push_str(&format!(
999                        "__global__ void k{i}_matmul(const {ty}* a, const {ty}* b, {ty}* c, int M, int N, int K){{\n\
1000                         \x20 int idx = blockIdx.x*blockDim.x + threadIdx.x; if(idx >= M*N) return;\n\
1001                         \x20 int r = idx / N, col = idx % N; {ty} s = 0;\n\
1002                         \x20 for(int k=0;k<K;++k) s += a[r*K+k]*b[k*N+col];\n\
1003                         \x20 c[idx] = s;\n}}\n"
1004                    ));
1005                    launches.push_str(&format!(
1006                        "  {{ int total={M}*{N}; k{i}_matmul<<<(total+255)/256,256>>>(buf_{a},buf_{b},buf_{c},{M},{N},{K}); }}\n",
1007                        M = m.m, N = m.n, K = m.k
1008                    ));
1009                }
1010            }
1011            Sym::Prim(TensorOpSpec::Elementwise(_)) | Sym::Fused(Fused { class: ClassId::AddNorm, .. }) => {
1012                let (e, normed) = sum_and_norm(host);
1013                let (a, b, c) = (
1014                    interner.resolve(e.a),
1015                    interner.resolve(e.b),
1016                    interner.resolve(e.c),
1017                );
1018                let op = e.op.c_op();
1019                // FUSE `c = a + b` directly into an immediately-following RMSNorm of `c` (the transformer's
1020                // residual-then-norm): emit ONE kernel that adds, writes `c` (still needed by the next residual),
1021                // and normalizes. The standalone add kernel + its residual read-back disappear. Only Add fuses
1022                // (norm needs the summed row), and only when the whole row lines up (e.n == rows*cols).
1023                if let Some(r) = normed {
1024                    let (cols, rows, y) = (r.cols, r.rows, interner.resolve(r.y));
1025                    let eps = format!("{:e}", r.eps.get());
1026                    let wparam = if r.weight.is_some() {
1027                        ", const float* w"
1028                    } else {
1029                        ""
1030                    };
1031                    let ymul = if r.weight.is_some() { "*w[i]" } else { "" };
1032                    // Fused activation quant (as in the plain norm): if this add+norm's output feeds a q8 matmul,
1033                    // quantize `yr` inline so the consuming matmul skips its own qact.
1034                    let qact_out = quantized;
1035                    let qparam = if qact_out {
1036                        ", signed char* yq, float* ys"
1037                    } else {
1038                        ""
1039                    };
1040                    let qepilogue = if qact_out {
1041                        format!(
1042                            "\x20 __syncthreads(); {{ int qlane=threadIdx.x&31, qwp=threadIdx.x>>5, qnw=blockDim.x>>5; int qnb={cols}/32;\n\
1043                             \x20   for(int blk=qwp;blk<qnb;blk+=qnw){{ float v=yr[blk*32+qlane], av=fabsf(v);\n\
1044                             \x20     for(int s=16;s>0;s>>=1) av=fmaxf(av,__shfl_down_sync(0xffffffffu,av,s)); av=__shfl_sync(0xffffffffu,av,0);\n\
1045                             \x20     float amax=av>1e-30f?av:1e-30f, scale=amax/127.0f; if(qlane==0) ys[blk]=scale;\n\
1046                             \x20     int qq=(int)rintf(v/scale); if(qq>127)qq=127; if(qq<-128)qq=-128; yq[blk*32+qlane]=(signed char)qq; }} }}\n",
1047                            cols = cols
1048                        )
1049                    } else {
1050                        String::new()
1051                    };
1052                    kernels.push_str(&format!(
1053                        "__global__ void k{i}_add_row(const float* a, const float* b{wparam}, float* c, float* y{qparam}){{\n\
1054                         \x20 int row=blockIdx.x; const float* ar=a+(long)row*{cols}; const float* br=b+(long)row*{cols};\n\
1055                         \x20 float* cr=c+(long)row*{cols}; float* yr=y+(long)row*{cols}; __shared__ double sh[256];\n\
1056                         \x20 double sc=0; for(int i=threadIdx.x;i<{cols};i+=blockDim.x){{ float v=ar[i]+br[i]; cr[i]=v; sc+=(double)v*v; }}\n\
1057                         \x20 sh[threadIdx.x]=sc; __syncthreads();\n\
1058                         \x20 for(int k=blockDim.x/2;k>0;k>>=1){{ if(threadIdx.x<k) sh[threadIdx.x]+=sh[threadIdx.x+k]; __syncthreads(); }}\n\
1059                         \x20 double scale=1.0/sqrt(sh[0]/(double){cols}+{eps});\n\
1060                         \x20 for(int i=threadIdx.x;i<{cols};i+=blockDim.x) yr[i]=(float)((double)cr[i]*scale){ymul};\n{qepilogue}}}\n"
1061                    ));
1062                    let warg = if let Some(w) = r.weight {
1063                        format!(",buf_{}", interner.resolve(w))
1064                    } else {
1065                        String::new()
1066                    };
1067                    let qarg = if qact_out {
1068                        format!(",buf_{y}_q8act,buf_{y}_q8scl")
1069                    } else {
1070                        String::new()
1071                    };
1072                    launches.push_str(&format!(
1073                        "  k{i}_add_row<<<{rows},256>>>(buf_{a},buf_{b}{warg},buf_{c},buf_{y}{qarg});\n"
1074                    ));
1075                    if qact_out {
1076                        if !dp4a_scratch.iter().any(|(v, _, _)| v == y) {
1077                            let (mm, kk) = q8_fed[y];
1078                            dp4a_scratch.push((y.to_string(), mm, kk));
1079                        }
1080                        producer_quantized.insert(y.to_string());
1081                    }
1082                } else {
1083                    kernels.push_str(&format!(
1084                        "__global__ void k{i}_elem(const {ty}* a, const {ty}* b, {ty}* c, int N){{\n\
1085                         \x20 int idx = blockIdx.x*blockDim.x + threadIdx.x; if(idx < N) c[idx] = a[idx] {op} b[idx];\n}}\n"
1086                    ));
1087                    launches.push_str(&format!(
1088                        "  k{i}_elem<<<({N}+255)/256,256>>>(buf_{a},buf_{b},buf_{c},{N});\n",
1089                        N = e.n
1090                    ));
1091                }
1092            }
1093            Sym::Fused(Fused { class: ClassId::ElementwiseChains, .. }) => {
1094                let (a, b, first_op, tail, out, n) = chain(&leaves(host.clone()));
1095                let (a, b, first_op, tail, out, n) = (&a, &b, &first_op, &tail, &out, &n);
1096                // The whole run in ONE kernel: seed `t = a ⊕₀ b`, carry `t = t ⊕ ext` per tail op (registers,
1097                // no global round-trip), store `o = t` once. Params i0,i1 are the seed operands; i{k+2} the
1098                // k-th tail external. This is where the (N−1) intermediate loads/stores + launches vanish.
1099                let (a, b, out) = (
1100                    interner.resolve(*a),
1101                    interner.resolve(*b),
1102                    interner.resolve(*out),
1103                );
1104                // A real product the next step adds to is rounded as its own kernel rounds it (`__fmul_rn`), which the
1105                // compiler never contracts with the sum into one fused multiply-add: the run computes what its ops
1106                // compute apart, bit for bit.
1107                let summed = |k: usize| ty == "float" && matches!(tail.get(k), Some(ChainStep::Binary(ElementwiseOp::Add, _)));
1108                let apply = |op: ElementwiseOp, x: &str, y: &str, k: usize| match op {
1109                    ElementwiseOp::Mul if summed(k) => format!("__fmul_rn({x}, {y})"),
1110                    op => format!("{x} {} {y}", op.c_op()),
1111                };
1112                let mut params = format!("const {ty}* i0, const {ty}* i1");
1113                let mut args = format!("buf_{a},buf_{b}");
1114                let mut body = format!("{ty} t = {};", apply(*first_op, "i0[idx]", "i1[idx]", 0));
1115                let mut pk = 2; // next input-param index; only BINARY steps consume an operand param
1116                for (k, step) in tail.iter().enumerate() {
1117                    match step {
1118                        ChainStep::Binary(op, ext) => {
1119                            params.push_str(&format!(", const {ty}* i{pk}"));
1120                            args.push_str(&format!(",buf_{}", interner.resolve(*ext)));
1121                            body.push_str(&format!(" t = {};", apply(*op, "t", &format!("i{pk}[idx]"), k + 1)));
1122                            pk += 1;
1123                        }
1124                        ChainStep::Silu => body.push_str(" t = t/(1.0f+expf(-t));"),
1125                    }
1126                }
1127                kernels.push_str(&format!(
1128                    "__global__ void k{i}_fused({params}, {ty}* o, int N){{\n\
1129                     \x20 int idx = blockIdx.x*blockDim.x + threadIdx.x; if(idx < N){{ {body} o[idx] = t; }}\n}}\n"
1130                ));
1131                launches.push_str(&format!(
1132                    "  k{i}_fused<<<({N}+255)/256,256>>>({args},buf_{out},{N});\n",
1133                    N = n
1134                ));
1135            }
1136            Sym::Fused(Fused { class: ClassId::ElementwiseRegions, .. }) => {
1137                // The whole region in ONE kernel: each member in registers, the region's operands read once at the
1138                // element's place, its result and every member a later op reads written out.
1139                let (lines, n) = region_body(host, ty);
1140                let members = leaves(host.clone());
1141                let outputs = region_outputs(host);
1142                let mut params: Vec<String> = (0..host.ins.len()).map(|p| format!("const {ty}* i{p}")).collect();
1143                params.extend((0..outputs.len()).map(|q| format!("{ty}* o{q}")));
1144                let stores: String = outputs
1145                    .iter()
1146                    .enumerate()
1147                    .map(|(q, o)| format!(" o{q}[idx] = t{};", members.iter().position(|m| m.out == *o).expect("a region writes its members")))
1148                    .collect();
1149                kernels.push_str(&format!(
1150                    "__global__ void k{i}_region({}, int N){{\n\
1151                     \x20 int idx = blockIdx.x*blockDim.x + threadIdx.x; if(idx < N){{ {}{stores} }}\n}}\n",
1152                    params.join(", "),
1153                    lines.join(" ")
1154                ));
1155                let args: Vec<String> = host.ins.iter().chain(&outputs).map(|v| format!("buf_{v}")).collect();
1156                launches.push_str(&format!("  k{i}_region<<<({n}+255)/256,256>>>({},{n});\n", args.join(",")));
1157            }
1158            Sym::Prim(TensorOpSpec::FusedRow(r)) => {
1159                let (x, y) = (interner.resolve(r.x), interner.resolve(r.y));
1160                let cols = r.cols;
1161                let eps = format!("{:e}", r.eps.get());
1162                // The reduced value: `X[i]`, or `X[i] + R[i]` when the norm carries a fused residual (summed in
1163                // double, as the reference adds two reals).
1164                let xv = |i: &str| match r.residual {
1165                    Some(_) => format!("((double)xr[{i}]+(double)rr[{i}])"),
1166                    None => format!("(double)xr[{i}]"),
1167                };
1168                let body = match (r.reduce, r.weight.is_some()) {
1169                    (RowReduceKind::RmsNorm, false) => format!(
1170                        "  double sc=0; for(int i=threadIdx.x;i<{cols};i+=blockDim.x) sc+={v}*{v};\n\
1171                         \x20 sh[threadIdx.x]=sc; __syncthreads();\n\
1172                         \x20 for(int k=blockDim.x/2;k>0;k>>=1){{ if(threadIdx.x<k) sh[threadIdx.x]+=sh[threadIdx.x+k]; __syncthreads(); }}\n\
1173                         \x20 double scale=1.0/sqrt(sh[0]/(double){cols}+{eps});\n\
1174                         \x20 for(int i=threadIdx.x;i<{cols};i+=blockDim.x) yr[i]=(float)({v}*scale);\n",
1175                        v = xv("i")
1176                    ),
1177                    (RowReduceKind::RmsNorm, true) => format!(
1178                        "  double sc=0; for(int i=threadIdx.x;i<{cols};i+=blockDim.x) sc+={v}*{v};\n\
1179                         \x20 sh[threadIdx.x]=sc; __syncthreads();\n\
1180                         \x20 for(int k=blockDim.x/2;k>0;k>>=1){{ if(threadIdx.x<k) sh[threadIdx.x]+=sh[threadIdx.x+k]; __syncthreads(); }}\n\
1181                         \x20 double scale=1.0/sqrt(sh[0]/(double){cols}+{eps});\n\
1182                         \x20 for(int i=threadIdx.x;i<{cols};i+=blockDim.x) yr[i]=(float)({v}*scale)*w[i];\n",
1183                        v = xv("i")
1184                    ),
1185                    (RowReduceKind::Softmax, _) => format!(
1186                        "  double m=-1e30; for(int i=threadIdx.x;i<{cols};i+=blockDim.x) m=fmax(m,(double)xr[i]);\n\
1187                         \x20 sh[threadIdx.x]=m; __syncthreads();\n\
1188                         \x20 for(int k=blockDim.x/2;k>0;k>>=1){{ if(threadIdx.x<k) sh[threadIdx.x]=fmax(sh[threadIdx.x],sh[threadIdx.x+k]); __syncthreads(); }}\n\
1189                         \x20 double mx=sh[0]; __syncthreads();\n\
1190                         \x20 double s=0; for(int i=threadIdx.x;i<{cols};i+=blockDim.x) s+=exp((double)xr[i]-mx);\n\
1191                         \x20 sh[threadIdx.x]=s; __syncthreads();\n\
1192                         \x20 for(int k=blockDim.x/2;k>0;k>>=1){{ if(threadIdx.x<k) sh[threadIdx.x]+=sh[threadIdx.x+k]; __syncthreads(); }}\n\
1193                         \x20 double sm=sh[0]; for(int i=threadIdx.x;i<{cols};i+=blockDim.x) yr[i]=(float)(exp((double)xr[i]-mx)/sm);\n"
1194                    ),
1195                    // Two reductions over the row, each in double: the mean, then the population variance about it;
1196                    // then `(X - mean) / sqrt(var + eps) * W + B` in the reference's order.
1197                    (RowReduceKind::LayerNorm, _) => {
1198                        let wmul = if r.weight.is_some() { "*(double)w[i]" } else { "" };
1199                        let badd = if r.bias.is_some() { "+(double)bias[i]" } else { "" };
1200                        format!(
1201                            "  double sm=0; for(int i=threadIdx.x;i<{cols};i+=blockDim.x) sm+=(double)xr[i];\n\
1202                             \x20 sh[threadIdx.x]=sm; __syncthreads();\n\
1203                             \x20 for(int k=blockDim.x/2;k>0;k>>=1){{ if(threadIdx.x<k) sh[threadIdx.x]+=sh[threadIdx.x+k]; __syncthreads(); }}\n\
1204                             \x20 double mean=sh[0]/(double){cols}; __syncthreads();\n\
1205                             \x20 double vs=0; for(int i=threadIdx.x;i<{cols};i+=blockDim.x){{ double d=(double)xr[i]-mean; vs+=d*d; }}\n\
1206                             \x20 sh[threadIdx.x]=vs; __syncthreads();\n\
1207                             \x20 for(int k=blockDim.x/2;k>0;k>>=1){{ if(threadIdx.x<k) sh[threadIdx.x]+=sh[threadIdx.x+k]; __syncthreads(); }}\n\
1208                             \x20 double denom=sqrt(sh[0]/(double){cols}+{eps});\n\
1209                             \x20 for(int i=threadIdx.x;i<{cols};i+=blockDim.x) yr[i]=(float)(((double)xr[i]-mean)/denom{wmul}{badd});\n"
1210                        )
1211                    }
1212                };
1213                let wparam = format!(
1214                    "{}{}{}",
1215                    if r.weight.is_some() { ", const float* w" } else { "" },
1216                    if r.residual.is_some() { ", const float* res" } else { "" },
1217                    if r.bias.is_some() { ", const float* bias" } else { "" },
1218                );
1219                let rrow = if r.residual.is_some() {
1220                    format!(" const float* rr = res + (long)row*{cols};")
1221                } else {
1222                    String::new()
1223                };
1224                // FUSED activation quantization: if this norm's output feeds an int8-act q8 matmul, quantize `yr`
1225                // to int8 + per-32-block scales in the SAME kernel (warp per 32-block, `__shfl` max) — the
1226                // consuming matmul then skips its own `qact` launch (llama's inline-quant edge).
1227                let qact_out = quantized;
1228                let qparam = if qact_out {
1229                    ", signed char* yq, float* ys"
1230                } else {
1231                    ""
1232                };
1233                let qepilogue = if qact_out {
1234                    format!(
1235                        "\x20 __syncthreads(); {{ int qlane=threadIdx.x&31, qwp=threadIdx.x>>5, qnw=blockDim.x>>5; int qnb={cols}/32;\n\
1236                         \x20   for(int blk=qwp;blk<qnb;blk+=qnw){{ float v=yr[blk*32+qlane], av=fabsf(v);\n\
1237                         \x20     for(int s=16;s>0;s>>=1) av=fmaxf(av,__shfl_down_sync(0xffffffffu,av,s)); av=__shfl_sync(0xffffffffu,av,0);\n\
1238                         \x20     float amax=av>1e-30f?av:1e-30f, scale=amax/127.0f; if(qlane==0) ys[blk]=scale;\n\
1239                         \x20     int qq=(int)rintf(v/scale); if(qq>127)qq=127; if(qq<-128)qq=-128; yq[blk*32+qlane]=(signed char)qq; }} }}\n",
1240                        cols = cols
1241                    )
1242                } else {
1243                    String::new()
1244                };
1245                kernels.push_str(&format!(
1246                    "__global__ void k{i}_row(const float* x{wparam}, float* y{qparam}){{\n\
1247                     \x20 int row = blockIdx.x; const float* xr = x + (long)row*{cols}; float* yr = y + (long)row*{cols};{rrow}\n\
1248                     \x20 __shared__ double sh[256];\n{body}{qepilogue}}}\n"
1249                ));
1250                let warg: String = [r.weight, r.residual, r.bias]
1251                    .into_iter()
1252                    .flatten()
1253                    .map(|t| format!(",buf_{}", interner.resolve(t)))
1254                    .collect();
1255                let qarg = if qact_out {
1256                    format!(",buf_{y}_q8act,buf_{y}_q8scl")
1257                } else {
1258                    String::new()
1259                };
1260                launches.push_str(&format!(
1261                    "  k{i}_row<<<{rows},256>>>(buf_{x}{warg},buf_{y}{qarg});\n",
1262                    rows = r.rows
1263                ));
1264                if qact_out {
1265                    if !dp4a_scratch.iter().any(|(v, _, _)| v == y) {
1266                        let (mm, kk) = q8_fed[y];
1267                        dp4a_scratch.push((y.to_string(), mm, kk));
1268                    }
1269                    producer_quantized.insert(y.to_string());
1270                }
1271            }
1272            Sym::Prim(TensorOpSpec::Transpose(t)) => {
1273                let (x, out, rows, cols) = (&t.x, &t.out, &t.rows, &t.cols);
1274                let (xn, on) = (interner.resolve(*x), interner.resolve(*out));
1275                kernels.push_str(&format!(
1276                    "__global__ void k{i}_transpose(const {ty}* x, {ty}* y, int R, int C){{\n\
1277                     \x20 int idx = blockIdx.x*blockDim.x + threadIdx.x; if(idx >= R*C) return;\n\
1278                     \x20 int r = idx / C, c = idx % C; y[c*R + r] = x[r*C + c];\n}}\n"
1279                ));
1280                launches.push_str(&format!(
1281                    "  {{ int total={R}*{C}; k{i}_transpose<<<(total+255)/256,256>>>(buf_{xn},buf_{on},{R},{C}); }}\n",
1282                    R = rows, C = cols
1283                ));
1284            }
1285            Sym::Prim(TensorOpSpec::Silu(s)) => {
1286                let (x, out, n) = (&s.x, &s.out, &s.n);
1287                let (xn, on) = (interner.resolve(*x), interner.resolve(*out));
1288                kernels.push_str(&format!(
1289                    "__global__ void k{i}_silu(const {ty}* x, {ty}* y, int N){{\n\
1290                     \x20 int idx = blockIdx.x*blockDim.x + threadIdx.x; if(idx < N){{ float v=(float)x[idx]; y[idx] = v/(1.0f+expf(-v)); }}\n}}\n"
1291                ));
1292                launches.push_str(&format!(
1293                    "  k{i}_silu<<<({N}+255)/256,256>>>(buf_{xn},buf_{on},{N});\n",
1294                    N = n
1295                ));
1296            }
1297            Sym::Prim(TensorOpSpec::Rope(r)) => {
1298                let (q, rc, rs, out, h, half) = (&r.q, &r.rc, &r.rs, &r.out, &r.h, &r.half);
1299                let (qn, rcn, rsn, on) = (
1300                    interner.resolve(*q),
1301                    interner.resolve(*rc),
1302                    interner.resolve(*rs),
1303                    interner.resolve(*out),
1304                );
1305                kernels.push_str(&format!(
1306                    "__global__ void k{i}_rope(const float* q, const float* rc, const float* rs, float* y, int H, int HALF){{\n\
1307                     \x20 int hd = 2*HALF; int idx = blockIdx.x*blockDim.x + threadIdx.x; if(idx >= H*HALF) return;\n\
1308                     \x20 int hh = idx/HALF, i = idx%HALF; float a=q[hh*hd+i], b=q[hh*hd+i+HALF], c=rc[i], s=rs[i];\n\
1309                     \x20 y[hh*hd+i] = a*c - b*s; y[hh*hd+i+HALF] = a*s + b*c;\n}}\n"
1310                ));
1311                launches.push_str(&format!(
1312                    "  {{ int total={H}*{HALF}; k{i}_rope<<<(total+255)/256,256>>>(buf_{qn},buf_{rcn},buf_{rsn},buf_{on},{H},{HALF}); }}\n",
1313                    H = h, HALF = half
1314                ));
1315            }
1316            Sym::Prim(TensorOpSpec::Moe(m)) => {
1317                // MoE FFN: router GEMV → top-K route → each expert's SwiGLU (expert-indexed grouped weight bases
1318                // buf_{out}_W{r,g,u,d}) → weighted combine, through shared scratch (moe_logits/w/gate_e/up_e/he/
1319                // oute) reused across MoE stages (they run sequentially on the stream). Weights load from the MoE
1320                // manifest keyed by the output var (allocated below). Stream added by the graph rewrite.
1321                let (x, out) = (interner.resolve(m.x), interner.resolve(m.out));
1322                let (d, dff, ne, k) = (m.d, m.dff, m.ne, m.k);
1323                let (dnb, fnb) = (d / 32, dff / 32);
1324                let etopk = ne.min(1024);
1325                if kind != Q8MatKind::Dequant {
1326                    // SPARSE, DEEPLY FUSED, coalesced int8: route to the top-K expert INDICES, then just THREE
1327                    // kernels — quantize-activation, gate+up+SwiGLU fused (Wg/Wu rows read interleaved for 2×
1328                    // MLP, only h written), and down+combine fused (K warps/output dim, only H written). The
1329                    // two barriers (router, h-complete) are the only kernel boundaries; every intermediate
1330                    // (g, u, per-expert o) stays off HBM. Reads ~K/E of the weights per token (A3B sparsity)
1331                    // at full coalesced int8 bandwidth. Int8Act quantizes once per activation (the DEFAULT,
1332                    // llama-matched precision); TwoPassInt8 adds the lo-residual pass (~14-bit, logit-exact).
1333                    if kind == Q8MatKind::TwoPassInt8 {
1334                        launches.push_str(&format!(
1335                            "  moe_router_fast<<<({ne}+7)/8,256>>>(buf_{x},buf_{out}_Wr_q,buf_{out}_Wr_s,moe_logits,{ne},{d});\n\
1336                             \x20 moe_topk_idx<<<1,{etopk}>>>(moe_logits,moe_idx,moe_w,{ne},{k});\n\
1337                             \x20 moe_qact<<<(({d}/32)+7)/8,256>>>(buf_{x},moe_xqh,moe_xql,moe_xs,{d});\n\
1338                             \x20 moe_gate_up_silu<<<({k}*{dff}+7)/8,256>>>(moe_xqh,moe_xql,moe_xs,buf_{out}_Wg_q,buf_{out}_Wg_s,buf_{out}_Wu_q,buf_{out}_Wu_s,moe_idx,moe_he_all,{k},{dff},{d});\n\
1339                             \x20 moe_qact<<<((({k}*{dff})/32)+7)/8,256>>>(moe_he_all,moe_hqh,moe_hql,moe_hs,{k}*{dff});\n\
1340                             \x20 moe_down_combine<<<{d},{k}*32>>>(moe_hqh,moe_hql,moe_hs,buf_{out}_Wd_q,buf_{out}_Wd_s,moe_idx,moe_w,buf_{out},{k},{d},{dff});\n"
1341                        ));
1342                    } else {
1343                        launches.push_str(&format!(
1344                            "  moe_router_fast<<<({ne}+7)/8,256>>>(buf_{x},buf_{out}_Wr_q,buf_{out}_Wr_s,moe_logits,{ne},{d});\n\
1345                             \x20 moe_topk_idx<<<1,{etopk}>>>(moe_logits,moe_idx,moe_w,{ne},{k});\n\
1346                             \x20 moe_qact<<<(({d}/32)+7)/8,256>>>(buf_{x},moe_xqh,moe_xs,{d});\n\
1347                             \x20 moe_gate_up_silu<<<({k}*{dff}+7)/8,256>>>(moe_xqh,moe_xs,buf_{out}_Wg_q,buf_{out}_Wg_s,buf_{out}_Wu_q,buf_{out}_Wu_s,moe_idx,moe_he_all,{k},{dff},{d});\n\
1348                             \x20 moe_qact<<<((({k}*{dff})/32)+7)/8,256>>>(moe_he_all,moe_hqh,moe_hs,{k}*{dff});\n\
1349                             \x20 moe_down_combine<<<{d},{k}*32>>>(moe_hqh,moe_hs,buf_{out}_Wd_q,buf_{out}_Wd_s,moe_idx,moe_w,buf_{out},{k},{d},{dff});\n"
1350                        ));
1351                    }
1352                } else {
1353                    // A host `for` loop over experts (runtime expert index → runtime weight-base offset) keeps
1354                    // the emitted source tiny at 48 layers × 128 experts; the CUDA-graph capture still records
1355                    // every per-expert launch, so the replayed graph is identical to the unrolled form. This is
1356                    // the DENSE dequant path (computes all E experts, weighted by the top-K-masked router).
1357                    launches.push_str(&format!(
1358                        "  moe_gemv<<<({ne}+255)/256,256>>>(buf_{x},buf_{out}_Wr_q,buf_{out}_Wr_s,moe_logits,{ne},{d});\n\
1359                         \x20 moe_topk<<<1,{etopk}>>>(moe_logits,moe_w,{ne},{k});\n\
1360                         \x20 moe_zero<<<({d}+255)/256,256>>>(buf_{out},{d});\n\
1361                         \x20 for(int _e=0;_e<{ne};++_e){{\n\
1362                         \x20   moe_gemv<<<({dff}+255)/256,256>>>(buf_{x},buf_{out}_Wg_q+(long)_e*{gstride},buf_{out}_Wg_s+(long)_e*{gsstride},moe_gate_e,{dff},{d});\n\
1363                         \x20   moe_gemv<<<({dff}+255)/256,256>>>(buf_{x},buf_{out}_Wu_q+(long)_e*{gstride},buf_{out}_Wu_s+(long)_e*{gsstride},moe_up_e,{dff},{d});\n\
1364                         \x20   moe_silu_had<<<({dff}+255)/256,256>>>(moe_gate_e,moe_up_e,moe_he,{dff});\n\
1365                         \x20   moe_gemv<<<({d}+255)/256,256>>>(moe_he,buf_{out}_Wd_q+(long)_e*{dstride},buf_{out}_Wd_s+(long)_e*{dsstride},moe_oute,{d},{dff});\n\
1366                         \x20   moe_combine<<<({d}+255)/256,256>>>(buf_{out},moe_oute,moe_w,_e,{d});\n\
1367                         \x20 }}\n",
1368                        gstride = dff * d, gsstride = dff * dnb, dstride = d * dff, dsstride = d * fnb, etopk = etopk
1369                    ));
1370                }
1371            }
1372            Sym::Prim(TensorOpSpec::Attention(a)) => {
1373                assert!(a.softcap.is_none(), "the forward's shim admits no soft-capped attention");
1374                let (q, kc, vc, out, h, kv, hd, l) = (&a.q, &a.kc, &a.vc, &a.out, &a.h, &a.kv, &a.hd, &a.l);
1375                // Single-query multi-head GQA attention over the L-length KV cache — ONE parallel kernel, a BLOCK
1376                // per query head. Each block: dot the query head against every cached key of its GQA kv-head →
1377                // `sc[0..L]`, block-softmax (shuffle+shared reduce, exp in place), then the weighted sum of the
1378                // cached values → `ctx[head]`. `scale = 1/√hd`. This is the batch-1 decode attention llama does.
1379                let (qn, kcn, vcn, on) = (
1380                    interner.resolve(*q),
1381                    interner.resolve(*kc),
1382                    interner.resolve(*vc),
1383                    interner.resolve(*out),
1384                );
1385                let scale = 1.0f64 / (*hd as f64).sqrt();
1386                // Fused activation quant: ctx feeds Wo (a q8 matmul). Each block owns head*HD..+HD contiguous ctx
1387                // elements — head*HD is a multiple of 32 (HD % 32 == 0), so every 32-lane quant block lies wholly
1388                // inside this head's region. Quantize inline so the Wo matmul skips its own qact.
1389                let qact_out = quantized;
1390                let qparam = if qact_out {
1391                    ", signed char* yq, float* ys"
1392                } else {
1393                    ""
1394                };
1395                let qepilogue = if qact_out {
1396                    "\x20 __syncthreads(); {{ int qlane=threadIdx.x&31, qwp=threadIdx.x>>5, qnw=blockDim.x>>5; int qnb=HD/32; int base=head*HD;\n\
1397                     \x20   for(int lb=qwp;lb<qnb;lb+=qnw){{ float v=ctx[base+lb*32+qlane], av=fabsf(v);\n\
1398                     \x20     for(int s=16;s>0;s>>=1) av=fmaxf(av,__shfl_down_sync(0xffffffffu,av,s)); av=__shfl_sync(0xffffffffu,av,0);\n\
1399                     \x20     float amax=av>1e-30f?av:1e-30f, scl=amax/127.0f; int gb=base/32+lb; if(qlane==0) ys[gb]=scl;\n\
1400                     \x20     int qq=(int)rintf(v/scl); if(qq>127)qq=127; if(qq<-128)qq=-128; yq[gb*32+qlane]=(signed char)qq; }} }}\n"
1401                } else {
1402                    ""
1403                };
1404                kernels.push_str(&format!(
1405                    "__global__ void k{i}_attn(const float* q, const float* kc, const float* vc, float* ctx, int L, int H, int KV, int HD, float scale{qparam}){{\n\
1406                     \x20 int head=blockIdx.x; if(head>=H) return; int kvh=head/(H/KV); const float* qh=q+head*HD;\n\
1407                     \x20 __shared__ float sc[{L}]; __shared__ float red[32];\n\
1408                     \x20 int lane=threadIdx.x&31, wp=threadIdx.x>>5, nw=(blockDim.x+31)>>5;\n\
1409                     \x20 for(int j=wp;j<L;j+=nw){{ const float* kj=kc+(long)j*KV*HD+kvh*HD; float s=0.0f; for(int e=lane;e<HD;e+=32) s+=qh[e]*kj[e]; for(int r=16;r>0;r>>=1) s+=__shfl_down_sync(0xffffffffu,s,r); if(lane==0) sc[j]=s*scale; }}\n\
1410                     \x20 __syncthreads();\n\
1411                     \x20 float m=-1e30f; for(int j=threadIdx.x;j<L;j+=blockDim.x) m=fmaxf(m,sc[j]);\n\
1412                     \x20 for(int s=16;s>0;s>>=1) m=fmaxf(m,__shfl_down_sync(0xffffffffu,m,s)); if(lane==0) red[wp]=m; __syncthreads();\n\
1413                     \x20 if(threadIdx.x==0){{ float mm=red[0]; for(int i=1;i<nw;++i) mm=fmaxf(mm,red[i]); red[0]=mm; }} __syncthreads(); float mx=red[0];\n\
1414                     \x20 float ss=0.0f; for(int j=threadIdx.x;j<L;j+=blockDim.x){{ float e=expf(sc[j]-mx); sc[j]=e; ss+=e; }}\n\
1415                     \x20 for(int s=16;s>0;s>>=1) ss+=__shfl_down_sync(0xffffffffu,ss,s); if(lane==0) red[wp]=ss; __syncthreads();\n\
1416                     \x20 if(threadIdx.x==0){{ float su=0.0f; for(int i=0;i<nw;++i) su+=red[i]; red[0]=su; }} __syncthreads(); float den=red[0];\n\
1417                     \x20 for(int e=threadIdx.x;e<HD;e+=blockDim.x){{ float acc=0.0f; for(int j=0;j<L;++j) acc+=sc[j]*vc[(long)j*KV*HD+kvh*HD+e]; ctx[head*HD+e]=acc/den; }}\n{qepilogue}}}\n",
1418                    L = l
1419                ));
1420                // 2-arg launch (grid=one block per query head, block=256) so the graph rewrite `>>>`→`,0,_st>>>`
1421                // yields the valid `<<<H,256,0,_st>>>` stream form; the `sc[L]` scores live in STATIC shared memory.
1422                let qarg = if qact_out {
1423                    format!(",buf_{on}_q8act,buf_{on}_q8scl")
1424                } else {
1425                    String::new()
1426                };
1427                launches.push_str(&format!(
1428                    "  k{i}_attn<<<{H},256>>>(buf_{qn},buf_{kcn},buf_{vcn},buf_{on},{L},{H},{KV},{HD},{scale}f{qarg});\n",
1429                    H = h, KV = kv, HD = hd, L = l, scale = scale
1430                ));
1431                if qact_out {
1432                    if !dp4a_scratch.iter().any(|(v, _, _)| v == on) {
1433                        let (mm, kk) = q8_fed[on];
1434                        dp4a_scratch.push((on.to_string(), mm, kk));
1435                    }
1436                    producer_quantized.insert(on.to_string());
1437                }
1438            }
1439            _ => unreachable!("the forward's shim links no `{}` whole", host.kind()),
1440        }
1441    }
1442
1443    // ── host: one managed buffer per variable; fill inputs; chain launches; print the final output ───
1444    let final_out = outputs.last().cloned().unwrap();
1445    let final_size = sizes
1446        .iter()
1447        .find(|(v, _)| v == &final_out)
1448        .map(|(_, s)| *s)
1449        .unwrap_or(0);
1450    let mut allocs = String::new();
1451    let mut fills = String::new();
1452    for (v, sz) in &sizes {
1453        // A Q8_0 weight stays INT8-resident: allocate int8 quants + f32 block scales and load them from files
1454        // (never a 4×-larger f32 buffer). The matmul against it dequantizes in-kernel.
1455        if let Some(q) = q8.get(v) {
1456            let nb = q.in_dim / 32;
1457            let (qn, sn) = (q.in_dim * q.out_dim, q.out_dim * nb);
1458            allocs.push_str(&format!(
1459                "  signed char* buf_{v}_q; if(cudaMallocManaged(&buf_{v}_q,(size_t){qn})){{ fprintf(stderr,\"malloc q\\n\"); return 1; }}\n"
1460            ));
1461            fills.push_str(&format!(
1462                "  {{ FILE* f=fopen(\"{qp}\",\"rb\"); if(!f||fread(buf_{v}_q,1,(size_t){qn},f)!=(size_t){qn}){{ fprintf(stderr,\"q8 quants {v}\\n\"); return 1; }} fclose(f); }}\n",
1463                qp = q.quants
1464            ));
1465            if kind != Q8MatKind::Dequant {
1466                // Both coalesced paths (Int8Act, TwoPassInt8) store block scales as __half — the checkpoint's
1467                // NATIVE Q8_0 scale precision — halving scale bandwidth vs f32 (the f32 file is host-converted).
1468                allocs.push_str(&format!(
1469                    "  __half* buf_{v}_s; if(cudaMallocManaged(&buf_{v}_s,(size_t){sn}*sizeof(__half))){{ fprintf(stderr,\"malloc s\\n\"); return 1; }}\n"
1470                ));
1471                fills.push_str(&format!(
1472                    "  {{ float* _t=(float*)malloc((size_t){sn}*sizeof(float)); FILE* f=fopen(\"{sp}\",\"rb\"); if(!f||fread(_t,sizeof(float),(size_t){sn},f)!=(size_t){sn}){{ fprintf(stderr,\"q8 scales {v}\\n\"); return 1; }} fclose(f); for(size_t _i=0;_i<(size_t){sn};++_i) buf_{v}_s[_i]=__float2half(_t[_i]); free(_t); }}\n",
1473                    sp = q.scales
1474                ));
1475            } else {
1476                allocs.push_str(&format!(
1477                    "  float* buf_{v}_s; if(cudaMallocManaged(&buf_{v}_s,(size_t){sn}*sizeof(float))){{ fprintf(stderr,\"malloc s\\n\"); return 1; }}\n"
1478                ));
1479                fills.push_str(&format!(
1480                    "  {{ FILE* f=fopen(\"{sp}\",\"rb\"); if(!f||fread(buf_{v}_s,sizeof(float),(size_t){sn},f)!=(size_t){sn}){{ fprintf(stderr,\"q8 scales {v}\\n\"); return 1; }} fclose(f); }}\n",
1481                    sp = q.scales
1482                ));
1483            }
1484            continue;
1485        }
1486        allocs.push_str(&format!(
1487            "  {ty}* buf_{v}; if(cudaMallocManaged(&buf_{v}, (size_t){sz}*sizeof({ty}))){{ fprintf(stderr,\"malloc\\n\"); return 1; }}\n"
1488        ));
1489        if is_output(v) {
1490            continue;
1491        }
1492        // A WEIGHT handle: the tensor is too big to inline — its `count` float values are loaded from an
1493        // external file at runtime (the real Qwen weights, extracted from the GGUF checkpoint). This is the
1494        // mechanism the real-8B forward needs; the file is populated by the host loader / test.
1495        if let Some((path, count)) = weights.get(v) {
1496            fills.push_str(&format!(
1497                "  {{ FILE* wf=fopen(\"{path}\",\"rb\"); if(!wf){{ fprintf(stderr,\"weight open {v}\\n\"); return 1; }}\n\
1498                 \x20   size_t rd=fread(buf_{v},sizeof(float),(size_t){count},wf); fclose(wf);\n\
1499                 \x20   if(rd!=(size_t){count}){{ fprintf(stderr,\"weight size {v}\\n\"); return 1; }} }}\n"
1500            ));
1501            continue;
1502        }
1503        // Inputs with the program's own `Set item` values → the orchestrator computes the SAME thing the VM
1504        // does (not merely a deterministic fill). Unset elements default to 0 (the tensor's init).
1505        if let Some(vals) = inits.get(v) {
1506            let zero = if floaty { "0.0f" } else { "0" };
1507            fills.push_str(&format!(
1508                "  for(size_t p=0;p<(size_t){sz};++p) buf_{v}[p]={zero};\n"
1509            ));
1510            for (idx, val) in vals {
1511                if *idx >= *sz {
1512                    continue;
1513                }
1514                let lit = match (floaty, val) {
1515                    (true, InitVal::F(f)) => format!("(float){:?}", f),
1516                    (true, InitVal::I(n)) => format!("(float){n}"),
1517                    (false, InitVal::I(n)) => format!("{n}"),
1518                    (false, InitVal::F(f)) => format!("(long long){}", *f as i64),
1519                };
1520                fills.push_str(&format!("  buf_{v}[{idx}]={lit};\n"));
1521            }
1522            continue;
1523        }
1524        // Fallback: deterministic fill (no literal initializers recognized).
1525        let fill = if floaty {
1526            "buf_{v}[p] = (float)((int)(p%7)-3) * 0.5f;"
1527        } else {
1528            "buf_{v}[p] = (long long)((int)(p%7)-3);"
1529        };
1530        fills.push_str(&format!(
1531            "  for(size_t p=0;p<(size_t){sz};++p) {}\n",
1532            fill.replace("{v}", v)
1533        ));
1534    }
1535    // Int8-activation DP4A scratch: per activation feeding a DP4A matmul, the quantized int8 view + its f32
1536    // per-32-block scales; the `k{i}_qact` kernel fills them each launch (M×K int8, M×(K/32) f32). The
1537    // two-pass path adds the lo-residual byte view (the ~14-bit exactness).
1538    for (a, m_rows, k_dim) in &dp4a_scratch {
1539        let (qn, sn) = (m_rows * k_dim, m_rows * (k_dim / 32));
1540        allocs.push_str(&format!(
1541            "  signed char* buf_{a}_q8act; if(cudaMallocManaged(&buf_{a}_q8act,(size_t){qn})){{ fprintf(stderr,\"malloc qact\\n\"); return 1; }}\n"
1542        ));
1543        if kind == Q8MatKind::TwoPassInt8 {
1544            allocs.push_str(&format!(
1545                "  signed char* buf_{a}_q8actlo; if(cudaMallocManaged(&buf_{a}_q8actlo,(size_t){qn})){{ fprintf(stderr,\"malloc qactlo\\n\"); return 1; }}\n"
1546            ));
1547        }
1548        allocs.push_str(&format!(
1549            "  float* buf_{a}_q8scl; if(cudaMallocManaged(&buf_{a}_q8scl,(size_t){sn}*sizeof(float))){{ fprintf(stderr,\"malloc qscl\\n\"); return 1; }}\n"
1550        ));
1551    }
1552    // MoE grouped weights (per stage, keyed by output var) + shared scratch (one set reused across stages).
1553    let mut moe_scratch: Option<(usize, usize, usize)> = None; // (max_d, max_dff, max_E)
1554    for (_, op) in &kernel_ops {
1555        if let Some(TensorOpSpec::Moe(m)) = folded(op).0.prim() {
1556            let out = interner.resolve(m.out);
1557            let w = moe
1558                .get(out)
1559                .ok_or_else(|| ForwardError::MissingMoeWeights(out.to_string()))?;
1560            for (tag, q) in [
1561                ("Wr", &w.router),
1562                ("Wg", &w.gate),
1563                ("Wu", &w.up),
1564                ("Wd", &w.down),
1565            ] {
1566                let nb = q.in_dim / 32;
1567                let (qn, sn) = (q.in_dim * q.out_dim, q.out_dim * nb);
1568                allocs.push_str(&format!(
1569                    "  signed char* buf_{out}_{tag}_q; if(cudaMallocManaged(&buf_{out}_{tag}_q,(size_t){qn})){{ fprintf(stderr,\"malloc moe q\\n\"); return 1; }}\n\
1570                     \x20 float* buf_{out}_{tag}_s; if(cudaMallocManaged(&buf_{out}_{tag}_s,(size_t){sn}*sizeof(float))){{ fprintf(stderr,\"malloc moe s\\n\"); return 1; }}\n"
1571                ));
1572                fills.push_str(&format!(
1573                    "  {{ FILE* f=fopen(\"{qp}\",\"rb\"); if(!f||fread(buf_{out}_{tag}_q,1,(size_t){qn},f)!=(size_t){qn}){{ fprintf(stderr,\"moe q {out}_{tag}\\n\"); return 1; }} fclose(f); }}\n\
1574                     \x20 {{ FILE* f=fopen(\"{sp}\",\"rb\"); if(!f||fread(buf_{out}_{tag}_s,sizeof(float),(size_t){sn},f)!=(size_t){sn}){{ fprintf(stderr,\"moe s {out}_{tag}\\n\"); return 1; }} fclose(f); }}\n",
1575                    qp = q.quants, sp = q.scales
1576                ));
1577            }
1578            let (md, mdff, me) = moe_scratch.unwrap_or((0, 0, 0));
1579            moe_scratch = Some((md.max(m.d), mdff.max(m.dff), me.max(m.ne)));
1580        }
1581    }
1582    if let Some((md, mdff, me)) = moe_scratch {
1583        for (nm, n) in [
1584            ("moe_logits", me),
1585            ("moe_w", me),
1586            ("moe_gate_e", mdff),
1587            ("moe_up_e", mdff),
1588            ("moe_he", mdff),
1589            ("moe_oute", md),
1590        ] {
1591            allocs.push_str(&format!(
1592                "  float* {nm}; if(cudaMallocManaged(&{nm},(size_t){n}*sizeof(float))){{ fprintf(stderr,\"malloc moe scratch\\n\"); return 1; }}\n"
1593            ));
1594        }
1595        if kind != Q8MatKind::Dequant {
1596            // Deeply-fused path scratch: just the top-K expert-index array + the K-expert-wide SwiGLU
1597            // intermediate `h` (`K·dff`, sized to the max over stages). The gate/up/per-expert-output buffers of
1598            // the old 6-kernel path are gone — those intermediates never leave registers now.
1599            allocs.push_str(&format!("  int* moe_idx; if(cudaMallocManaged(&moe_idx,(size_t){me}*sizeof(int))){{ fprintf(stderr,\"malloc idx\\n\"); return 1; }}\n"));
1600            allocs.push_str(&format!("  float* moe_he_all; if(cudaMallocManaged(&moe_he_all,(size_t){n}*sizeof(float))){{ fprintf(stderr,\"malloc moe fused\\n\"); return 1; }}\n", n = me * mdff));
1601            // int8 scratch: the shared block input `x` (Kd=d) and the SwiGLU intermediate `h` (K·dff), each
1602            // quantized once per stage into an int8 view + a per-32-block f32 scale; the two-pass path adds
1603            // the lo residual byte view.
1604            allocs.push_str(&format!("  signed char* moe_xqh; if(cudaMallocManaged(&moe_xqh,(size_t){md})){{ fprintf(stderr,\"malloc xqh\\n\"); return 1; }}\n", md = md));
1605            allocs.push_str(&format!("  float* moe_xs; if(cudaMallocManaged(&moe_xs,(size_t)(({md}/32)+1)*sizeof(float))){{ fprintf(stderr,\"malloc xs\\n\"); return 1; }}\n", md = md));
1606            allocs.push_str(&format!("  signed char* moe_hqh; if(cudaMallocManaged(&moe_hqh,(size_t){n})){{ fprintf(stderr,\"malloc hqh\\n\"); return 1; }}\n", n = me * mdff));
1607            allocs.push_str(&format!("  float* moe_hs; if(cudaMallocManaged(&moe_hs,(size_t)(({n}/32)+1)*sizeof(float))){{ fprintf(stderr,\"malloc hs\\n\"); return 1; }}\n", n = me * mdff));
1608            if kind == Q8MatKind::TwoPassInt8 {
1609                allocs.push_str(&format!("  signed char* moe_xql; if(cudaMallocManaged(&moe_xql,(size_t){md})){{ fprintf(stderr,\"malloc xql\\n\"); return 1; }}\n", md = md));
1610                allocs.push_str(&format!("  signed char* moe_hql; if(cudaMallocManaged(&moe_hql,(size_t){n})){{ fprintf(stderr,\"malloc hql\\n\"); return 1; }}\n", n = me * mdff));
1611            }
1612        }
1613    }
1614    let printf = if floaty {
1615        "printf(\"%.6f\\n\", (double)buf_{v}[p]);"
1616    } else {
1617        "printf(\"%lld\\n\", (long long)buf_{v}[p]);"
1618    };
1619    let print_final = format!(
1620        "  for(size_t p=0;p<(size_t){final_size};++p) {}\n",
1621        printf.replace("{v}", &final_out)
1622    );
1623
1624    // Every launch runs on a dedicated stream so the whole forward can be captured as ONE CUDA graph
1625    // (all launches are 2-arg `<<<grid,block>>>` with static shared memory ⇒ the blanket rewrite yields the
1626    // 4-arg `<<<grid,block,0,_st>>>` stream form). Graph replay collapses the hundreds of per-token kernel
1627    // launches into a single dispatch — the last step past llama.cpp's tok/s (mirrors cuda/qwen_forward.cu).
1628    let launches_st = launches.replace(">>>", ",0,_st>>>");
1629    // ── Flamegraph pins ─────────────────────────────────────────────────────────────────────────────────
1630    // GPU hardware counters are perms-gated on cloud pods (`ncu` → ERR_NVGPUCTRPERM), so we time on the HOST:
1631    // an optional pass (runtime-gated on `LOGOS_CUDA_PINS`) re-runs the forward once with a CUDA-event bracket
1632    // around EVERY kernel launch, accumulating GPU time into per-phase buckets. Emits folded `PIN <phase> <ms>`
1633    // lines to stderr → `scripts/accel/cuda-pins-flamegraph.sh` renders a flamegraph SVG. Zero cost when unset.
1634    let bucket = |k: &str| -> usize {
1635        if k.contains("moe_router") || k.contains("moe_topk") {
1636            3
1637        } else if k.contains("moe_qact") {
1638            4
1639        } else if k.contains("moe_gate_up")
1640            || k.contains("moe_down")
1641            || k.contains("moe_silu")
1642            || k.contains("moe_combine")
1643            || k.contains("moe_zero")
1644            || k.contains("moe_gemv")
1645        {
1646            5
1647        } else if k.contains("_attn") {
1648            1
1649        } else if k.contains("_q8dp4a") {
1650            2
1651        } else if k.contains("_add_row") || k.contains("_row") {
1652            0
1653        } else if k.contains("_qact") {
1654            6
1655        } else {
1656            7
1657        }
1658    };
1659    let mut pinned = String::new();
1660    for line in launches.lines() {
1661        let t = line.trim_start();
1662        if let Some(pos) = t.find("<<<") {
1663            let kname = t[..pos]
1664                .rsplit(|c: char| c == ' ' || c == '{' || c == '}' || c == ';')
1665                .find(|s| !s.is_empty())
1666                .unwrap_or("");
1667            let b = bucket(kname);
1668            let ln = line.replace(">>>", ",0,_st>>>");
1669            pinned.push_str(&format!(
1670                "  cudaEventRecord(_pa,_st); {} cudaEventRecord(_pb,_st); cudaEventSynchronize(_pb); {{ float _dt=0; cudaEventElapsedTime(&_dt,_pa,_pb); _pin[{b}]+=_dt; _cnt[{b}]++; }}\n",
1671                ln.trim_start()
1672            ));
1673        } else if !t.is_empty() {
1674            pinned.push_str(&line.replace(">>>", ",0,_st>>>"));
1675            pinned.push('\n');
1676        }
1677    }
1678    let pins_pass = format!(
1679        "\x20 if(getenv(\"LOGOS_CUDA_PINS\")){{\n\
1680         \x20   const char* _bn[8]={{\"norm+quant\",\"attention\",\"attn_proj+lmhead\",\"moe_router+topk\",\"moe_qact\",\"moe_ffn\",\"qact\",\"other\"}};\n\
1681         \x20   double _pin[8]={{0}}; long _cnt[8]={{0}}; cudaEvent_t _pa,_pb; cudaEventCreate(&_pa); cudaEventCreate(&_pb);\n\
1682         {pinned}\
1683         \x20   double _tot=0; for(int _b=0;_b<8;++_b) _tot+=_pin[_b];\n\
1684         \x20   for(int _b=0;_b<8;++_b) fprintf(stderr,\"PIN %-18s %8.4f ms  x%-5ld %5.1f%%\\n\",_bn[_b],_pin[_b],_cnt[_b], _tot>0?100.0*_pin[_b]/_tot:0.0);\n\
1685         \x20   fprintf(stderr,\"PIN %-18s %8.4f ms  (%.1f tok/s single-pass, event-serialized)\\n\",\"TOTAL\",_tot, _tot>0?1000.0/_tot:0.0);\n\
1686         \x20 }}\n"
1687    );
1688    let prov = super::provenance::header(super::provenance::Provenance::Compiled);
1689    Ok(format!(
1690        "{prov}// A multi-stage tensor-op forward composed as chained PARALLEL kernels through shared device buffers\n\
1691         // ({n} stages), captured as one CUDA graph for replay.\n\
1692         #include <cstdio>\n#include <cstdlib>\n#include <cuda_runtime.h>\n#include <cuda_fp16.h>\n#include <cmath>\n\n\
1693         {kernels}\nint main(void){{\n{allocs}{fills}\n\
1694         \x20 cudaStream_t _st; if(cudaStreamCreate(&_st)!=cudaSuccess){{ fprintf(stderr,\"stream\\n\"); return 1; }}\n\
1695         \x20 // Warm-up launch: runs the forward once, migrating the managed weight pages resident on the GPU.\n\
1696         {launches_st}\
1697         \x20 if(cudaStreamSynchronize(_st)!=cudaSuccess){{ fprintf(stderr,\"sync\\n\"); return 1; }}\n\
1698         {pins_pass}\
1699         \x20 // Capture the entire forward into a single CUDA graph, then instantiate + replay it.\n\
1700         \x20 cudaGraph_t _g; cudaGraphExec_t _ge;\n\
1701         \x20 if(cudaStreamBeginCapture(_st, cudaStreamCaptureModeGlobal)!=cudaSuccess){{ fprintf(stderr,\"capture\\n\"); return 1; }}\n\
1702         {launches_st}\
1703         \x20 if(cudaStreamEndCapture(_st, &_g)!=cudaSuccess){{ fprintf(stderr,\"endcap\\n\"); return 1; }}\n\
1704         \x20 if(cudaGraphInstantiate(&_ge, _g, 0)!=cudaSuccess){{ fprintf(stderr,\"instantiate\\n\"); return 1; }}\n\
1705         \x20 cudaGraphLaunch(_ge, _st); cudaStreamSynchronize(_st);\n\
1706         \x20 cudaEvent_t _e0,_e1; cudaEventCreate(&_e0); cudaEventCreate(&_e1);\n\
1707         \x20 cudaEventRecord(_e0,_st); for(int _it=0;_it<20;++_it){{ cudaGraphLaunch(_ge,_st); }}\n\
1708         \x20 cudaEventRecord(_e1,_st); cudaStreamSynchronize(_st); float _ms=0.0f; cudaEventElapsedTime(&_ms,_e0,_e1);\n\
1709         \x20 fprintf(stderr,\"FORWARD_MS %f\\n\", _ms/20.0f);\n\
1710         {print_final}  return 0;\n}}\n",
1711        n = stage_count
1712    ))
1713}
1714
1715/// The Qwen3-30B-A3B architecture (n_layer is overridable to keep local emit/compile fast; the per-layer shape
1716/// is identical to the real model).
1717pub struct Qwen30bCfg {
1718    pub d: usize,      // hidden (n_embd) = 2048
1719    pub dff: usize,    // moe expert intermediate = 768
1720    pub ne: usize,     // experts = 128
1721    pub k: usize,      // active experts = 8
1722    pub layers: usize, // blocks (48 real)
1723    pub h: usize,      // query heads = 32
1724    pub kv: usize,     // KV heads (GQA) = 4
1725    pub hd: usize,     // head dim = 128
1726    pub vocab: usize,  // 151936
1727    /// RoPE base frequency (`<arch>.rope.freq_base` in the GGUF). **Read it from the checkpoint** — it was a
1728    /// hardcoded `1e6` in the emitted CUDA until Qwen3.8-27B arrived with `1e7`, which would have silently
1729    /// mis-rotated every query and key while still producing plausible-looking tokens.
1730    pub rope_theta: f64,
1731    /// RMSNorm epsilon (`<arch>.attention.layer_norm_rms_epsilon`). Also formerly hardcoded.
1732    pub rms_eps: f64,
1733    /// Split-K factor for the flash-attention lane. Per-chip tuning knob, not a model property: measured best
1734    /// at 4 on the A100 and 8 as the portable default.
1735    pub attn_split: usize,
1736}
1737
1738impl Qwen30bCfg {
1739    pub fn real() -> Self {
1740        Qwen30bCfg {
1741            d: 2048,
1742            dff: 768,
1743            ne: 128,
1744            k: 8,
1745            layers: 48,
1746            h: 32,
1747            kv: 4,
1748            hd: 128,
1749            vocab: 151936,
1750            rope_theta: 1.0e6,
1751            rms_eps: 1e-6,
1752            attn_split: 8,
1753        }
1754    }
1755}
1756
1757/// A placeholder or real Q8 file pair under `dir`.
1758fn q8ref(dir: &str, tag: &str, inn: usize, out: usize) -> Q8Ref {
1759    Q8Ref {
1760        quants: format!("{dir}/{tag}.q"),
1761        scales: format!("{dir}/{tag}.s"),
1762        in_dim: inn,
1763        out_dim: out,
1764    }
1765}
1766
1767/// Generate the full Qwen3-30B-A3B forward as a LOGOS `.lg` string, plus the manifests the emitter needs:
1768/// `weights` (f32 embedding + RMSNorm weights), `q8` (attention V/O + LM head, int8), `moe` (per-layer FFN,
1769/// keyed by the block's FFN output var). `dir` is where the weight files are (real `/workspace/...` on the pod,
1770/// a placeholder for compile-only use). This is THE canonical authored-in-LOGOS 30B program: the pod run, the
1771/// local emit lock, and every printed copy of the program come from it.
1772/// The device-state kernels for autoregressive generation — a mirror of the proven 8B `cuda/qwen_forward.cu`
1773/// decode loop, with f32 block scales (the extractor writes f32 `.s` files; scales are a negligible bandwidth
1774/// fraction). Position + token live in device memory (`d_pos`/`d_tok`) so ONE captured graph replays every token.
1775/// The GEMVs are the SAME uint4-coalesced DP4A kernels that beat llama on the single-token forward.
1776/// ★ M5: the compiler EMITS the certified Marlin-class Q8_0 GEMM (it is not a hand-written `.cu`). Given the
1777/// auto-tuned subtile count `nt` (the fastest golden config the auto-tuner picked for this shape/GPU — M2), this
1778/// lowers the recognized `matmul` of a Q8_0 weight into a register-dequant tensor-core kernel:
1779/// `mma.sync.m16n8k32.s8` (int8 tensor core), the mma-k==32 aligned to the Q8_0 scale block (SAT-certified, M3),
1780/// per-block dequant scale applied in REGISTERS in the same float grouping as our dp4a GEMV (golden-bounded to
1781/// 4.2e-7, M4). This is the fusion pass in action: GEMM + per-block-dequant + scale fused into ONE kernel, and
1782/// the compiler right-sizes `nt` per shape rather than a hand-tuned constant. Beats dp4a's 7.5x wall on batch.
1783pub fn emit_marlin_q8_gemm(nt: usize) -> String {
1784    format!(
1785        r#"// AUTO-TUNED (nt={nt}) + SAT-CERTIFIED (fragment bijection, k==Q8_0-block==32, no int32 overflow) + GOLDEN
1786// (<=4.2e-7 vs dp4a: int32 exact, only f32 reassociation). Register-dequant tensor-core Q8_0 GEMM, emitted by our
1787// compiler from the recognized `A matmul Wq8` op -- the world's-smartest-compiler Marlin lowering.
1788__global__ void gk_marlin_q8(const signed char* Xq,const float* Xs,const signed char* Wq,const float* Ws,float* Y,int B,int N,int K){{
1789  const int NT={nt}; int KB=K/32;
1790  int warp=(blockIdx.x*blockDim.x+threadIdx.x)>>5; int lane=threadIdx.x&31;
1791  int ntiles=N/(8*NT); int mtile=warp/ntiles, ntile=warp%ntiles; int m0=mtile*16, n0=ntile*8*NT;
1792  int gid=lane>>2, tid=lane&3;
1793  float d[NT][4]; for(int j=0;j<NT;j++){{d[j][0]=d[j][1]=d[j][2]=d[j][3]=0;}}
1794  for(int kb=0;kb<KB;kb++){{ int k0=kb*32;
1795    int a0=*(const int*)(Xq+(long)(m0+gid)*K+k0+tid*4);
1796    int a1=*(const int*)(Xq+(long)(m0+gid+8)*K+k0+tid*4);
1797    int a2=*(const int*)(Xq+(long)(m0+gid)*K+k0+16+tid*4);
1798    int a3=*(const int*)(Xq+(long)(m0+gid+8)*K+k0+16+tid*4);
1799    float xs0=Xs[(long)(m0+gid)*KB+kb], xs1=Xs[(long)(m0+gid+8)*KB+kb];
1800    #pragma unroll
1801    for(int j=0;j<NT;j++){{ int nn=n0+j*8;
1802      int b0=*(const int*)(Wq+(long)(nn+gid)*K+k0+tid*4);
1803      int b1=*(const int*)(Wq+(long)(nn+gid)*K+k0+16+tid*4);
1804      int c0=0,c1=0,c2=0,c3=0;
1805      asm volatile("mma.sync.aligned.m16n8k32.row.col.s32.s8.s8.s32 {{%0,%1,%2,%3}}, {{%4,%5,%6,%7}}, {{%8,%9}}, {{%0,%1,%2,%3}};"
1806        : "+r"(c0),"+r"(c1),"+r"(c2),"+r"(c3) : "r"(a0),"r"(a1),"r"(a2),"r"(a3), "r"(b0),"r"(b1));
1807      float ws0=Ws[(long)(nn+tid*2)*KB+kb], ws1=Ws[(long)(nn+tid*2+1)*KB+kb];
1808      d[j][0]+=(float)c0*(ws0*xs0); d[j][1]+=(float)c1*(ws1*xs0);
1809      d[j][2]+=(float)c2*(ws0*xs1); d[j][3]+=(float)c3*(ws1*xs1);
1810    }}
1811  }}
1812  for(int j=0;j<NT;j++){{ int nn=n0+j*8; int r0=m0+gid,r1=m0+gid+8,cc0=nn+tid*2,cc1=nn+tid*2+1;
1813    if(r0<B){{ if(cc0<N)Y[(long)r0*N+cc0]=d[j][0]; if(cc1<N)Y[(long)r0*N+cc1]=d[j][1]; }}
1814    if(r1<B){{ if(cc0<N)Y[(long)r1*N+cc0]=d[j][2]; if(cc1<N)Y[(long)r1*N+cc1]=d[j][3]; }} }}
1815}}
1816"#
1817    )
1818}
1819
1820pub const GEN_DEVICE_KERNELS: &str = r#"
1821__global__ void gk_embed(float* x, const signed char* wq, const float* ws, const int* d_tok, int E){
1822  int t=blockIdx.x*blockDim.x+threadIdx.x; if(t>=E) return;
1823  long tok=*d_tok; x[t]=(float)wq[tok*E+t]*ws[tok*(E/32)+t/32];
1824}
1825__global__ void gk_rmsnorm(float* out, const float* x, const float* w, int n, float eps){
1826  __shared__ float sh[256]; float s=0; for(int i=threadIdx.x;i<n;i+=blockDim.x) s+=x[i]*x[i];
1827  sh[threadIdx.x]=s; __syncthreads();
1828  for(int k=blockDim.x/2;k>0;k>>=1){ if(threadIdx.x<k) sh[threadIdx.x]+=sh[threadIdx.x+k]; __syncthreads(); }
1829  float sc=rsqrtf(sh[0]/n+eps); for(int i=threadIdx.x;i<n;i+=blockDim.x) out[i]=x[i]*sc*w[i];
1830}
1831// FUSED residual-add + RMSNorm: `x += y` (the residual, kept for the next block) AND `out = rmsnorm(x)*w`, in
1832// ONE kernel launch and ONE pass over x. The reduction is the SAME 256-thread tree as gk_rmsnorm over the SAME
1833// summed values (v = x[i]+y[i]), so the float sum is bit-identical ⇒ token-exact. Removes a kernel node and the
1834// residual write/re-read per layer — the win in the latency-bound batch-1 H100 decode.
1835__global__ void gk_add_rmsnorm(float* x, const float* y, float* out, const float* w, int n, float eps){
1836  __shared__ float sh[256]; float s=0; for(int i=threadIdx.x;i<n;i+=blockDim.x){ float v=x[i]+y[i]; x[i]=v; s+=v*v; }
1837  sh[threadIdx.x]=s; __syncthreads();
1838  for(int k=blockDim.x/2;k>0;k>>=1){ if(threadIdx.x<k) sh[threadIdx.x]+=sh[threadIdx.x+k]; __syncthreads(); }
1839  float sc=rsqrtf(sh[0]/n+eps); for(int i=threadIdx.x;i<n;i+=blockDim.x) out[i]=x[i]*sc*w[i];
1840}
1841// FUSED residual-add + RMSNorm + INT8 QUANT: like gk_add_rmsnorm, but ALSO emits `out` quantized to int8 per
1842// 32-block (oq + per-block scale os_) in the SAME kernel — folding the standalone `moe_qact(x2n)` away. `out`
1843// (float) still feeds the router; `oq`/`os_` (int8) feed the experts. The quant replicates moe_qact's per-32
1844// amax/127 scheme EXACTLY (one warp per 32-block, shfl amax) ⇒ the experts see bit-identical int8 (token-exact).
1845__global__ void gk_add_rmsnorm_q8(float* x, const float* y, float* out, const float* w, signed char* oq, float* os_, int n, float eps){
1846  __shared__ float sh[256]; float s=0; for(int i=threadIdx.x;i<n;i+=blockDim.x){ float v=x[i]+y[i]; x[i]=v; s+=v*v; }
1847  sh[threadIdx.x]=s; __syncthreads();
1848  for(int k=blockDim.x/2;k>0;k>>=1){ if(threadIdx.x<k) sh[threadIdx.x]+=sh[threadIdx.x+k]; __syncthreads(); }
1849  float scale=rsqrtf(sh[0]/n+eps); for(int i=threadIdx.x;i<n;i+=blockDim.x) out[i]=x[i]*scale*w[i];
1850  __syncthreads();
1851  int warp=threadIdx.x>>5, lane=threadIdx.x&31, nb=n/32;
1852  for(int b=warp;b<nb;b+=(blockDim.x>>5)){ float v=out[b*32+lane], av=fabsf(v);
1853    for(int t=16;t>0;t>>=1) av=fmaxf(av,__shfl_down_sync(0xffffffffu,av,t));
1854    av=__shfl_sync(0xffffffffu,av,0); float amax=av>1e-30f?av:1e-30f; float qs=amax/127.0f;
1855    if(lane==0) os_[b]=qs; int q=(int)rintf(v/qs); if(q>127)q=127; if(q<-128)q=-128; oq[b*32+lane]=(signed char)q; }
1856}
1857__global__ void gk_rmsnorm_q8(const float* x, signed char* xq, float* xs, const float* w, int n, float eps){
1858  __shared__ float red[256]; float s=0; for(int i=threadIdx.x;i<n;i+=blockDim.x) s+=x[i]*x[i];
1859  red[threadIdx.x]=s; __syncthreads();
1860  for(int k=128;k>0;k>>=1){ if(threadIdx.x<k) red[threadIdx.x]+=red[threadIdx.x+k]; __syncthreads(); }
1861  float rms=rsqrtf(red[0]/n+eps); int warp=threadIdx.x>>5, lane=threadIdx.x&31, nb=n/32;
1862  for(int b=warp;b<nb;b+=8){ float y=x[b*32+lane]*rms*w[b*32+lane], a=fabsf(y);
1863    for(int sh=16;sh>0;sh>>=1) a=fmaxf(a,__shfl_down_sync(0xffffffffu,a,sh));
1864    a=__shfl_sync(0xffffffffu,a,0); float sc=a>0?a/127.0f:1.0f;
1865    if(lane==0) xs[b]=sc; xq[b*32+lane]=(signed char)__float2int_rn(y/sc); }
1866}
1867// FUSED residual-add + RMSNorm + int8 quant for the ATTENTION norm: `x += y` (residual kept) AND quantize
1868// rmsnorm(x)*w to int8 (xq/xs) — folds the post-MoE `gk_add` into the NEXT layer's attn norm+quant. Identical
1869// 128-thread reduction + per-32 quant as gk_rmsnorm_q8 over v=x[i]+y[i] ⇒ bit-identical ⇒ token-exact.
1870__global__ void gk_add_rmsnorm_q8a(float* x, const float* y, signed char* xq, float* xs, const float* w, int n, float eps){
1871  __shared__ float red[256]; float s=0; for(int i=threadIdx.x;i<n;i+=blockDim.x){ float v=x[i]+y[i]; x[i]=v; s+=v*v; }
1872  red[threadIdx.x]=s; __syncthreads();
1873  for(int k=128;k>0;k>>=1){ if(threadIdx.x<k) red[threadIdx.x]+=red[threadIdx.x+k]; __syncthreads(); }
1874  float rms=rsqrtf(red[0]/n+eps); int warp=threadIdx.x>>5, lane=threadIdx.x&31, nb=n/32;
1875  for(int b=warp;b<nb;b+=8){ float y2=x[b*32+lane]*rms*w[b*32+lane], a=fabsf(y2);
1876    for(int sh=16;sh>0;sh>>=1) a=fmaxf(a,__shfl_down_sync(0xffffffffu,a,sh));
1877    a=__shfl_sync(0xffffffffu,a,0); float sc=a>0?a/127.0f:1.0f;
1878    if(lane==0) xs[b]=sc; xq[b*32+lane]=(signed char)__float2int_rn(y2/sc); }
1879}
1880__global__ void gk_quant_act(const float* x, signed char* xq, float* xs, int K){
1881  int blk=blockIdx.x*(blockDim.x/32)+threadIdx.x/32; if((long)blk*32>=K) return; int lane=threadIdx.x&31;
1882  float v=x[blk*32+lane], a=fabsf(v);
1883  for(int s=16;s>0;s>>=1) a=fmaxf(a,__shfl_down_sync(0xffffffffu,a,s)); a=__shfl_sync(0xffffffffu,a,0);
1884  float sc=a>0?a/127.0f:1.0f; if(lane==0) xs[blk]=sc; xq[blk*32+lane]=(signed char)__float2int_rn(v/sc);
1885}
1886__global__ void gk_gemv(float* y, const signed char* wq, const float* ws, const signed char* xq, const float* xs, int K, int N){
1887  int o=(blockIdx.x*blockDim.x+threadIdx.x)>>5; if(o>=N) return; int lane=threadIdx.x&31;
1888  const int4* w16=(const int4*)(wq+(long)o*K); const int4* x16=(const int4*)xq; const float* wsr=ws+(long)o*(K/32);
1889  float acc=0.f; int nq=K/512;
1890  for(int b=0;b<nq;b++){ int4 w=w16[b*32+lane], xx=x16[b*32+lane]; int blk=b*16+lane/2;
1891    int d=__dp4a(w.x,xx.x,0)+__dp4a(w.y,xx.y,0)+__dp4a(w.z,xx.z,0)+__dp4a(w.w,xx.w,0);
1892    acc += (float)d * (wsr[blk]*xs[blk]); }
1893  int done=nq*512; for(int j=done+lane;j<K;j+=32){ int blk=j/32; acc += (float)((int)xq[j]*(int)wq[(long)o*K+j])*(wsr[blk]*xs[blk]); }
1894  for(int s=16;s>0;s>>=1) acc+=__shfl_down_sync(0xffffffffu,acc,s); if(lane==0) y[o]=acc;
1895}
1896__global__ void gk_gemv_kv(float* cache, const int* d_pos, int KD, const signed char* wq, const float* ws, const signed char* xq, const float* xs, int K, int N){
1897  int o=(blockIdx.x*blockDim.x+threadIdx.x)>>5; if(o>=N) return; int lane=threadIdx.x&31;
1898  const int4* w16=(const int4*)(wq+(long)o*K); const int4* x16=(const int4*)xq; const float* wsr=ws+(long)o*(K/32);
1899  float acc=0.f; int nq=K/512;
1900  for(int b=0;b<nq;b++){ int4 w=w16[b*32+lane], xx=x16[b*32+lane]; int blk=b*16+lane/2;
1901    int d=__dp4a(w.x,xx.x,0)+__dp4a(w.y,xx.y,0)+__dp4a(w.z,xx.z,0)+__dp4a(w.w,xx.w,0);
1902    acc += (float)d * (wsr[blk]*xs[blk]); }
1903  int done=nq*512; for(int j=done+lane;j<K;j+=32){ int blk=j/32; acc += (float)((int)xq[j]*(int)wq[(long)o*K+j])*(wsr[blk]*xs[blk]); }
1904  for(int s=16;s>0;s>>=1) acc+=__shfl_down_sync(0xffffffffu,acc,s); if(lane==0) cache[(long)(*d_pos)*KD+o]=acc;
1905}
1906// FUSED Q/K/V projection: one launch over QD+2·KD output warps, each picking its weight matrix by output range
1907// (Q→qbuf, K→cache[pos], V→cache[pos]) and reading the SHARED int8 activation once. Replaces three separate
1908// launch-bound gemvs with one — measured the single largest decode-throughput win (A100: +7 tok/s), because
1909// batch-1 decode is dominated by per-kernel launch/latency, not weight bandwidth.
1910__global__ void gk_gemv_qkv(float* qbuf,float* kc,float* vc,const int* d_pos,int KD,
1911    const signed char* wqq,const float* wqs,const signed char* wkq,const float* wks,const signed char* wvq,const float* wvs,
1912    const signed char* xq,const float* xs,int K,int QD){
1913  int og=(blockIdx.x*blockDim.x+threadIdx.x)>>5; int lane=threadIdx.x&31; int Ntot=QD+2*KD; if(og>=Ntot) return;
1914  const signed char* wq; const float* ws; int o; float* dst; long dsti;
1915  if(og<QD){ wq=wqq; ws=wqs; o=og; dst=qbuf; dsti=o; }
1916  else if(og<QD+KD){ wq=wkq; ws=wks; o=og-QD; dst=kc; dsti=(long)(*d_pos)*KD+o; }
1917  else { wq=wvq; ws=wvs; o=og-QD-KD; dst=vc; dsti=(long)(*d_pos)*KD+o; }
1918  const int4* w16=(const int4*)(wq+(long)o*K); const int4* x16=(const int4*)xq; const float* wsr=ws+(long)o*(K/32);
1919  float acc=0.f; int nq=K/512;
1920  for(int b=0;b<nq;b++){ int4 w=w16[b*32+lane], xx=x16[b*32+lane]; int blk=b*16+lane/2;
1921    int d=__dp4a(w.x,xx.x,0)+__dp4a(w.y,xx.y,0)+__dp4a(w.z,xx.z,0)+__dp4a(w.w,xx.w,0);
1922    acc += (float)d * (wsr[blk]*xs[blk]); }
1923  int done=nq*512; for(int j=done+lane;j<K;j+=32){ int blk=j/32; acc += (float)((int)xq[j]*(int)wq[(long)o*K+j])*(wsr[blk]*xs[blk]); }
1924  for(int s=16;s>0;s>>=1) acc+=__shfl_down_sync(0xffffffffu,acc,s); if(lane==0) dst[dsti]=acc;
1925}
1926__global__ void gk_qk_norm_rope(float* base, const int* d_pos, int stride, const float* nw, int n_heads, int hd, float rbase, float eps){
1927  int head=blockIdx.x; if(head>=n_heads) return; float* h=base+(long)(*d_pos)*stride+head*hd;
1928  __shared__ float sh[128]; float s=0; for(int i=threadIdx.x;i<hd;i+=blockDim.x) s+=h[i]*h[i]; sh[threadIdx.x]=s; __syncthreads();
1929  for(int k=blockDim.x/2;k>0;k>>=1){ if(threadIdx.x<k) sh[threadIdx.x]+=sh[threadIdx.x+k]; __syncthreads(); }
1930  float sc=rsqrtf(sh[0]/hd+eps); __syncthreads();
1931  for(int i=threadIdx.x;i<hd;i+=blockDim.x) h[i]=h[i]*sc*nw[i]; __syncthreads();
1932  int half=hd/2; int pos=*d_pos;
1933  for(int i=threadIdx.x;i<half;i+=blockDim.x){ float f=powf(rbase,-2.0f*i/hd); float a=pos*f,c=cosf(a),si=sinf(a);
1934    float x0=h[i],x1=h[i+half]; h[i]=x0*c-x1*si; h[i+half]=x0*si+x1*c; }
1935}
1936// FUSED Q+K per-head RMSNorm+RoPE: one launch over NH+NKV head-blocks, picking Q params (block<NH) or K params
1937// (block≥NH). Replaces two underfilled launches (NH and NKV blocks) with one — the Q and K norm-rope are the
1938// same body over different (base,stride,weight), so a branch on blockIdx fuses them (A100: +4 tok/s).
1939__global__ void gk_qk_norm_rope2(float* qbase, float* kbase, const int* d_pos, int kstride, const float* qnw, const float* knw, int nh, int nkv, int hd, float rbase, float eps){
1940  int b=blockIdx.x; float* base; const float* nw; int stride; int head;
1941  if(b<nh){ base=qbase; nw=qnw; stride=0; head=b; } else { base=kbase; nw=knw; stride=kstride; head=b-nh; }
1942  float* h=base+(long)(*d_pos)*stride+head*hd;
1943  __shared__ float sh[128]; float s=0; for(int i=threadIdx.x;i<hd;i+=blockDim.x) s+=h[i]*h[i]; sh[threadIdx.x]=s; __syncthreads();
1944  for(int k=blockDim.x/2;k>0;k>>=1){ if(threadIdx.x<k) sh[threadIdx.x]+=sh[threadIdx.x+k]; __syncthreads(); }
1945  float sc=rsqrtf(sh[0]/hd+eps); __syncthreads();
1946  for(int i=threadIdx.x;i<hd;i+=blockDim.x) h[i]=h[i]*sc*nw[i]; __syncthreads();
1947  int half=hd/2; int pos=*d_pos;
1948  for(int i=threadIdx.x;i<half;i+=blockDim.x){ float f=powf(rbase,-2.0f*i/hd); float a=pos*f,c=cosf(a),si=sinf(a);
1949    float x0=h[i],x1=h[i+half]; h[i]=x0*c-x1*si; h[i+half]=x0*si+x1*c; }
1950}
1951// Flash-attention-style single-query decode: one block per query head, a WARP per cached key (parallel qh·kj
1952// dot, warp-reduced), a parallel block-softmax (shuffle max/sum + shared cross-warp reduce), then a parallel
1953// weighted sum over V. Q is normed+roped by the preceding gk_qk_norm_rope; fusing it in here perturbs the float
1954// order enough to flip a precise near-tie AND doesn't cut graph time (the work just moves) — so kept separate.
1955__global__ void gk_attn(float* out, const float* q, const float* kc, const float* vc, const int* d_pos, int n_head, int n_kv, int hd, float scale){
1956  int head=blockIdx.x; if(head>=n_head) return; int kvh=head/(n_head/n_kv); int L=*d_pos+1; int KD=n_kv*hd;
1957  const float* qh=q+(long)head*hd; extern __shared__ float sc[]; __shared__ float red[32];
1958  int lane=threadIdx.x&31, wp=threadIdx.x>>5, nw=(blockDim.x+31)>>5;
1959  for(int j=wp;j<L;j+=nw){ const float* kj=kc+(long)j*KD+kvh*hd; float s=0.f; for(int e=lane;e<hd;e+=32) s+=qh[e]*kj[e];
1960    for(int r=16;r>0;r>>=1) s+=__shfl_down_sync(0xffffffffu,s,r); if(lane==0) sc[j]=s*scale; }
1961  __syncthreads();
1962  float m=-1e30f; for(int j=threadIdx.x;j<L;j+=blockDim.x) m=fmaxf(m,sc[j]);
1963  for(int r=16;r>0;r>>=1) m=fmaxf(m,__shfl_down_sync(0xffffffffu,m,r)); if(lane==0) red[wp]=m; __syncthreads();
1964  if(threadIdx.x==0){ float mm=red[0]; for(int i=1;i<nw;i++) mm=fmaxf(mm,red[i]); red[0]=mm; } __syncthreads(); float mx=red[0];
1965  float ss=0.f; for(int j=threadIdx.x;j<L;j+=blockDim.x){ float e=expf(sc[j]-mx); sc[j]=e; ss+=e; }
1966  for(int r=16;r>0;r>>=1) ss+=__shfl_down_sync(0xffffffffu,ss,r); if(lane==0) red[wp]=ss; __syncthreads();
1967  if(threadIdx.x==0){ float su=0.f; for(int i=0;i<nw;i++) su+=red[i]; red[0]=su; } __syncthreads(); float den=red[0];
1968  for(int e=threadIdx.x;e<hd;e+=blockDim.x){ float a=0.f; for(int j=0;j<L;j++) a+=sc[j]*vc[(long)j*KD+kvh*hd+e]; out[(long)head*hd+e]=a/den; }
1969}
1970// ONLINE-SOFTMAX flash-attention decode (llama's fattn-vec shape): one block per query head, warps stream
1971// DISJOINT slabs of the KV cache, each keeping a RUNNING (max, sum) + weighted-V accumulator in REGISTERS —
1972// a single pass, warp-shuffle score reduce (no per-key __syncthreads, no shared score array), then ONE
1973// cross-warp flash-combine. Q lives in registers. Replaces the multi-pass score→sync→max→sync→exp→sync→V form.
1974__global__ void gk_attn_online(float* out, const float* q, const float* kc, const float* vc, const int* d_pos, int n_head, int n_kv, int hd, float scale){
1975  int head=blockIdx.x; if(head>=n_head) return; int kvh=head/(n_head/n_kv); int L=*d_pos+1; int KD=n_kv*hd;
1976  const float* qh=q+(long)head*hd;
1977  int lane=threadIdx.x&31, wp=threadIdx.x>>5, nw=blockDim.x>>5; int dpl=hd>>5;
1978  float qreg[8], acc[8]; for(int i=0;i<dpl;i++){ qreg[i]=qh[lane+(i<<5)]; acc[i]=0.f; }
1979  float m=-1e30f, dsum=0.f;
1980  for(int j=wp;j<L;j+=nw){
1981    const float* kj=kc+(long)j*KD+kvh*hd; float part=0.f;
1982    for(int i=0;i<dpl;i++) part+=qreg[i]*kj[lane+(i<<5)];
1983    for(int r=16;r>0;r>>=1) part+=__shfl_xor_sync(0xffffffffu,part,r);
1984    float sj=part*scale; float mn=fmaxf(m,sj), c=__expf(m-mn), p=__expf(sj-mn); m=mn; dsum=dsum*c+p;
1985    const float* vj=vc+(long)j*KD+kvh*hd;
1986    for(int i=0;i<dpl;i++) acc[i]=acc[i]*c + p*vj[lane+(i<<5)];
1987  }
1988  __shared__ float sm[8], sd[8], sa[8][128];
1989  if(lane==0){ sm[wp]=m; sd[wp]=dsum; }
1990  for(int i=0;i<dpl;i++) sa[wp][lane+(i<<5)]=acc[i];
1991  __syncthreads();
1992  float M=-1e30f; for(int w=0;w<nw;w++) M=fmaxf(M,sm[w]);
1993  float D=0.f; for(int w=0;w<nw;w++) D+=sd[w]*__expf(sm[w]-M);
1994  for(int d=threadIdx.x; d<hd; d+=blockDim.x){ float a=0.f; for(int w=0;w<nw;w++) a+=sa[w][d]*__expf(sm[w]-M); out[(long)head*hd+d]=a/D; }
1995}
1996// SPLIT-K flash-attention (llama's fattn-vec `parallel_blocks`): P blocks PER query head each stream a disjoint
1997// slab of the KV cache with a register online-softmax → a partial (local max, denom, un-normalized weighted-V)
1998// in scratch; grid = n_head*P for FULL SM occupancy at decode (32 heads × 4 = 128 blocks vs 32). `gk_attn_comb`
1999// then flash-merges the P partials per head. This is the measured +14 tok/s edge llama gets from `-fa`.
2000__global__ void gk_attn_part(const float* q, const float* kc, const float* vc, const int* d_pos, int n_head, int n_kv, int hd, float scale, int P, float* acc_part, float* m_part, float* d_part){
2001  int b=blockIdx.x; int head=b/P, p=b%P; if(head>=n_head) return;
2002  int kvh=head/(n_head/n_kv); int L=*d_pos+1; int KD=n_kv*hd; const float* qh=q+(long)head*hd;
2003  int lane=threadIdx.x&31, wp=threadIdx.x>>5, nw=blockDim.x>>5; int dpl=hd>>5;
2004  float qreg[8], acc[8]; for(int i=0;i<dpl;i++){ qreg[i]=qh[lane+(i<<5)]; acc[i]=0.f; }
2005  float m=-1e30f, dsum=0.f;
2006  for(int idx=wp; ; idx+=nw){ int j=p+idx*P; if(j>=L) break;
2007    const float* kj=kc+(long)j*KD+kvh*hd; float pt=0.f;
2008    for(int i=0;i<dpl;i++) pt+=qreg[i]*kj[lane+(i<<5)];
2009    for(int r=16;r>0;r>>=1) pt+=__shfl_xor_sync(0xffffffffu,pt,r);
2010    float sj=pt*scale; float mn=fmaxf(m,sj), c=__expf(m-mn), pp=__expf(sj-mn); m=mn; dsum=dsum*c+pp;
2011    const float* vj=vc+(long)j*KD+kvh*hd; for(int i=0;i<dpl;i++) acc[i]=acc[i]*c + pp*vj[lane+(i<<5)];
2012  }
2013  __shared__ float sm[8], sd[8], sa[8][128];
2014  if(lane==0){ sm[wp]=m; sd[wp]=dsum; }
2015  for(int i=0;i<dpl;i++) sa[wp][lane+(i<<5)]=acc[i];
2016  __syncthreads();
2017  float M=-1e30f; for(int w=0;w<nw;w++) M=fmaxf(M,sm[w]);
2018  float D=0.f; for(int w=0;w<nw;w++) D+=sd[w]*__expf(sm[w]-M);
2019  if(threadIdx.x==0){ m_part[b]=M; d_part[b]=D; }
2020  for(int d=threadIdx.x; d<hd; d+=blockDim.x){ float a=0.f; for(int w=0;w<nw;w++) a+=sa[w][d]*__expf(sm[w]-M); acc_part[(long)b*hd+d]=a; }
2021}
2022__global__ void gk_attn_comb(float* out, int n_head, int hd, int P, const float* acc_part, const float* m_part, const float* d_part){
2023  int head=blockIdx.x; if(head>=n_head) return; __shared__ float GM, GD;
2024  if(threadIdx.x==0){ float M=-1e30f; for(int p=0;p<P;p++) M=fmaxf(M,m_part[head*P+p]); GM=M;
2025    float D=0.f; for(int p=0;p<P;p++) D+=d_part[head*P+p]*__expf(m_part[head*P+p]-M); GD=D; }
2026  __syncthreads(); float M=GM, D=GD;
2027  for(int d=threadIdx.x; d<hd; d+=blockDim.x){ float a=0.f;
2028    for(int p=0;p<P;p++) a += acc_part[(long)(head*P+p)*hd+d]*__expf(m_part[head*P+p]-M);
2029    out[(long)head*hd+d]=a/D; }
2030}
2031// FUSED split-K combine + activation-quant: the combine already lands each head's hd attention outputs in one
2032// block, so it quantizes them into int8 32-blocks in its epilogue (per-32-block warp max-abs) instead of a
2033// separate gk_quant_act launch feeding the O-projection. One fewer kernel on the decode critical path (+~1).
2034__global__ void gk_attn_comb_q(signed char* aq, float* as_, int n_head, int hd, int P, const float* acc_part, const float* m_part, const float* d_part){
2035  int head=blockIdx.x; if(head>=n_head) return; __shared__ float GM,GD; __shared__ float so[128];
2036  if(threadIdx.x==0){ float M=-1e30f; for(int p=0;p<P;p++) M=fmaxf(M,m_part[head*P+p]); GM=M;
2037    float D=0.f; for(int p=0;p<P;p++) D+=d_part[head*P+p]*__expf(m_part[head*P+p]-M); GD=D; }
2038  __syncthreads(); float M=GM,D=GD;
2039  for(int d=threadIdx.x; d<hd; d+=blockDim.x){ float a=0.f; for(int p=0;p<P;p++) a+=acc_part[(long)(head*P+p)*hd+d]*__expf(m_part[head*P+p]-M); so[d]=a/D; }
2040  __syncthreads();
2041  int nb=hd/32, warp=threadIdx.x>>5, lane=threadIdx.x&31, nw=blockDim.x>>5;
2042  for(int blk=warp; blk<nb; blk+=nw){ int gi=head*nb+blk; float v=so[blk*32+lane], av=fabsf(v);
2043    for(int s2=16;s2>0;s2>>=1) av=fmaxf(av,__shfl_down_sync(0xffffffffu,av,s2));
2044    av=__shfl_sync(0xffffffffu,av,0); float amax=av>1e-30f?av:1e-30f; float qsc=amax/127.0f;
2045    if(lane==0) as_[gi]=qsc; int q=(int)rintf(v/qsc); if(q>127)q=127; if(q<-128)q=-128; aq[gi*32+lane]=(signed char)q; }
2046}
2047__global__ void gk_add(float* x, const float* y, int n){ int i=blockIdx.x*blockDim.x+threadIdx.x; if(i<n) x[i]+=y[i]; }
2048__global__ void gk_argmax_adv(const float* logits, int vocab, int* d_tok, int* d_pos){
2049  __shared__ float bv[256]; __shared__ int bi[256]; float bestv=-1e30f; int besti=0;
2050  for(int i=threadIdx.x;i<vocab;i+=blockDim.x){ float v=logits[i]; if(v>bestv){bestv=v;besti=i;} }
2051  bv[threadIdx.x]=bestv; bi[threadIdx.x]=besti; __syncthreads();
2052  for(int k=blockDim.x/2;k>0;k>>=1){ if(threadIdx.x<k && bv[threadIdx.x+k]>bv[threadIdx.x]){ bv[threadIdx.x]=bv[threadIdx.x+k]; bi[threadIdx.x]=bi[threadIdx.x+k]; } __syncthreads(); }
2053  if(threadIdx.x==0){ *d_tok=bi[0]; *d_pos=*d_pos+1; }
2054}
2055// ── PRECISE (dequant) lane — llama's batch-1 recipe: f32 activation × int8 weight (no activation quantization),
2056// so the logits have clear margins (no int8-act near-ties) and the attention can be FUSED without flipping a
2057// token. Memory-bound on the same int8 weights ⇒ ~same bandwidth as the dp4a lane, but robustly llama-exact. ──
2058__global__ void gk_gemv_deq(float* y, const signed char* wq, const float* ws, const float* x, int K, int N){
2059  int o=(blockIdx.x*blockDim.x+threadIdx.x)>>5; if(o>=N) return; int lane=threadIdx.x&31;
2060  const int4* w16=(const int4*)(wq+(long)o*K); const float* wsr=ws+(long)o*(K/32); float acc=0.f; int nq=K/512;
2061  for(int b=0;b<nq;b++){ int4 wv=w16[b*32+lane]; int blk=b*16+lane/2; float sc=wsr[blk];
2062    const signed char* wb=(const signed char*)&wv; const float* xt=x+b*512+lane*16;
2063    float ba=0.f; for(int i=0;i<16;i++) ba += (float)wb[i]*xt[i]; acc += sc*ba; }
2064  for(int t=nq*512+lane;t<K;t+=32){ int blk=t/32; acc += wsr[blk]*(float)wq[(long)o*K+t]*x[t]; }
2065  for(int s=16;s>0;s>>=1) acc+=__shfl_down_sync(0xffffffffu,acc,s); if(lane==0) y[o]=acc;
2066}
2067__global__ void gk_gemv_kv_deq(float* cache, const int* d_pos, int KD, const signed char* wq, const float* ws, const float* x, int K, int N){
2068  int o=(blockIdx.x*blockDim.x+threadIdx.x)>>5; if(o>=N) return; int lane=threadIdx.x&31;
2069  const int4* w16=(const int4*)(wq+(long)o*K); const float* wsr=ws+(long)o*(K/32); float acc=0.f; int nq=K/512;
2070  for(int b=0;b<nq;b++){ int4 wv=w16[b*32+lane]; int blk=b*16+lane/2; float sc=wsr[blk];
2071    const signed char* wb=(const signed char*)&wv; const float* xt=x+b*512+lane*16;
2072    float ba=0.f; for(int i=0;i<16;i++) ba += (float)wb[i]*xt[i]; acc += sc*ba; }
2073  for(int t=nq*512+lane;t<K;t+=32){ int blk=t/32; acc += wsr[blk]*(float)wq[(long)o*K+t]*x[t]; }
2074  for(int s=16;s>0;s>>=1) acc+=__shfl_down_sync(0xffffffffu,acc,s); if(lane==0) cache[(long)(*d_pos)*KD+o]=acc;
2075}
2076// FUSED flash-attention: Q per-head QK-RMSNorm + RoPE + scores + block-softmax + weighted-V, all in one kernel.
2077__global__ void gk_fused_attn(float* out, const float* q, const float* kc, const float* vc, const int* d_pos, int n_head, int n_kv, int hd, float scale, const float* qnw, float rbase, float eps){
2078  int head=blockIdx.x; if(head>=n_head) return; int kvh=head/(n_head/n_kv); int pos=*d_pos; int L=pos+1; int KD=n_kv*hd;
2079  extern __shared__ float sc[]; __shared__ float red[32]; __shared__ float qh[256];
2080  int lane=threadIdx.x&31, wp=threadIdx.x>>5, nw=(blockDim.x+31)>>5;
2081  const float* qsrc=q+(long)head*hd;
2082  float qsum=0.f; for(int i=threadIdx.x;i<hd;i+=blockDim.x) qsum+=qsrc[i]*qsrc[i];
2083  for(int r=16;r>0;r>>=1) qsum+=__shfl_down_sync(0xffffffffu,qsum,r); if(lane==0) red[wp]=qsum; __syncthreads();
2084  if(threadIdx.x==0){ float s=0.f; for(int i=0;i<nw;i++) s+=red[i]; red[0]=s; } __syncthreads();
2085  float qrms=rsqrtf(red[0]/hd+eps);
2086  for(int i=threadIdx.x;i<hd;i+=blockDim.x) qh[i]=qsrc[i]*qrms*qnw[i]; __syncthreads();
2087  int half=hd/2;
2088  for(int i=threadIdx.x;i<half;i+=blockDim.x){ float f=powf(rbase,-2.0f*i/hd); float a=pos*f,c=cosf(a),si=sinf(a); float x0=qh[i],x1=qh[i+half]; qh[i]=x0*c-x1*si; qh[i+half]=x0*si+x1*c; }
2089  __syncthreads();
2090  for(int j=wp;j<L;j+=nw){ const float* kj=kc+(long)j*KD+kvh*hd; float s=0.f; for(int e=lane;e<hd;e+=32) s+=qh[e]*kj[e];
2091    for(int r=16;r>0;r>>=1) s+=__shfl_down_sync(0xffffffffu,s,r); if(lane==0) sc[j]=s*scale; }
2092  __syncthreads();
2093  float m=-1e30f; for(int j=threadIdx.x;j<L;j+=blockDim.x) m=fmaxf(m,sc[j]);
2094  for(int r=16;r>0;r>>=1) m=fmaxf(m,__shfl_down_sync(0xffffffffu,m,r)); if(lane==0) red[wp]=m; __syncthreads();
2095  if(threadIdx.x==0){ float mm=red[0]; for(int i=1;i<nw;i++) mm=fmaxf(mm,red[i]); red[0]=mm; } __syncthreads(); float mx=red[0];
2096  float ss=0.f; for(int j=threadIdx.x;j<L;j+=blockDim.x){ float e=expf(sc[j]-mx); sc[j]=e; ss+=e; }
2097  for(int r=16;r>0;r>>=1) ss+=__shfl_down_sync(0xffffffffu,ss,r); if(lane==0) red[wp]=ss; __syncthreads();
2098  if(threadIdx.x==0){ float su=0.f; for(int i=0;i<nw;i++) su+=red[i]; red[0]=su; } __syncthreads(); float den=red[0];
2099  for(int e=threadIdx.x;e<hd;e+=blockDim.x){ float a=0.f; for(int j=0;j<L;j++) a+=sc[j]*vc[(long)j*KD+kvh*hd+e]; out[(long)head*hd+e]=a/den; }
2100}
2101// Dequant MoE (f32 activation): gate/up SwiGLU + down-combine over the top-K experts, no activation quant.
2102__global__ void gk_moe_gate_up_deq(const float* x, const signed char* wg_q, const float* wg_s, const signed char* wu_q, const float* wu_s, const int* idx, float* h, int K, int N, int Kd){
2103  long row=(blockIdx.x*(long)blockDim.x+threadIdx.x)>>5; if(row>=(long)K*N) return; int lane=threadIdx.x&31;
2104  int kk=row/N, j=row%N; int e=idx[kk]; int nb=Kd/32, nq=Kd/512;
2105  const signed char* gwr=wg_q+((long)e*N+j)*Kd; const float* gsr=wg_s+((long)e*N+j)*nb;
2106  const signed char* uwr=wu_q+((long)e*N+j)*Kd; const float* usr=wu_s+((long)e*N+j)*nb;
2107  const int4* gw16=(const int4*)gwr; const int4* uw16=(const int4*)uwr; float ga=0.f, ua=0.f;
2108  for(int b=0;b<nq;b++){ int blk=b*16+lane/2; int4 gv=gw16[b*32+lane], uv=uw16[b*32+lane];
2109    const signed char* gb=(const signed char*)&gv; const signed char* ub=(const signed char*)&uv; const float* xt=x+b*512+lane*16;
2110    float gsc=gsr[blk], usc=usr[blk]; float gba=0.f, uba=0.f;
2111    for(int i=0;i<16;i++){ float xi=xt[i]; gba+=(float)gb[i]*xi; uba+=(float)ub[i]*xi; } ga+=gsc*gba; ua+=usc*uba; }
2112  for(int t=nq*512+lane;t<Kd;t+=32){ int blk=t/32; float xi=x[t]; ga+=gsr[blk]*(float)gwr[t]*xi; ua+=usr[blk]*(float)uwr[t]*xi; }
2113  for(int s=16;s>0;s>>=1){ ga+=__shfl_down_sync(0xffffffffu,ga,s); ua+=__shfl_down_sync(0xffffffffu,ua,s); }
2114  if(lane==0) h[row]=(ga/(1.0f+expf(-ga)))*ua;
2115}
2116__global__ void gk_moe_down_deq(const float* hbuf, const signed char* wd_q, const float* wd_s, const int* idx, const float* wc, float* H, int K, int N, int Kd){
2117  int o=blockIdx.x; int warp=threadIdx.x>>5, lane=threadIdx.x&31; int e=idx[warp]; int nb=Kd/32, nq=Kd/512;
2118  const float* hb=hbuf+(long)warp*Kd; const signed char* wr=wd_q+((long)e*N+o)*Kd; const float* wsr=wd_s+((long)e*N+o)*nb;
2119  const int4* w16=(const int4*)wr; float acc=0.f;
2120  for(int b=0;b<nq;b++){ int blk=b*16+lane/2; int4 wv=w16[b*32+lane]; const signed char* wb=(const signed char*)&wv; const float* ht=hb+b*512+lane*16;
2121    float sc=wsr[blk]; float ba=0.f; for(int i=0;i<16;i++) ba += (float)wb[i]*ht[i]; acc += sc*ba; }
2122  for(int t=nq*512+lane;t<Kd;t+=32){ int blk=t/32; acc += wsr[blk]*(float)wr[t]*hb[t]; }
2123  for(int s=16;s>0;s>>=1) acc+=__shfl_down_sync(0xffffffffu,acc,s);
2124  __shared__ float part[64]; if(lane==0) part[warp]=wc[warp]*acc; __syncthreads();
2125  if(threadIdx.x==0){ float sum=0.f; for(int kk=0;kk<K;kk++) sum+=part[kk]; H[o]=sum; }
2126}
2127"#;
2128
2129/// Emit a self-contained CUDA program that AUTOREGRESSIVELY GENERATES from the real Qwen3-30B-A3B weights: the
2130/// per-token math is the recognized LOGOS forward (RMSNorm → Q/K/V → per-head QK-norm + RoPE → causal attention
2131/// over a KV cache → O-proj → residual → RMSNorm → 8-of-128 MoE → residual → LM head), wrapped in the compiler's
2132/// generation runtime — a prompt prefill, then a T=1 decode step captured as ONE CUDA graph and replayed per
2133/// token (device-side position + token). This is the "llama.cpp, but authored in LOGOS" whole demo: it prints
2134/// the generated token stream and the fair tg-style tok/s (a growing KV cache, exactly like llama-bench tg128).
2135pub fn emit_qwen30b_generate(
2136    cfg: &Qwen30bCfg,
2137    wdir: &str,
2138    prompt: &[usize],
2139    n_gen: usize,
2140    precise: bool,
2141    flash: bool,
2142) -> String {
2143    let (e, qd, kd, ff) = (cfg.d, cfg.h * cfg.hd, cfg.kv * cfg.hd, cfg.dff);
2144    let (ne, ktop, vocab, layers) = (cfg.ne, cfg.k, cfg.vocab, cfg.layers);
2145    let (nh, nkv, hd) = (cfg.h, cfg.kv, cfg.hd);
2146    let (rope_theta, rms_eps, attn_split) = (cfg.rope_theta, cfg.rms_eps, cfg.attn_split);
2147    let maxseq = prompt.len() + n_gen + 110;
2148    let scale = 1.0f64 / (hd as f64).sqrt();
2149    let prompt_c = prompt
2150        .iter()
2151        .map(|t| t.to_string())
2152        .collect::<Vec<_>>()
2153        .join(",");
2154    let moe_kernels = moe_dp4a_kernels(false);
2155    // FAST-lane attention: default `gk_attn` (byte-exact-vs-llama token stream, the lock) or `flash` = SPLIT-K
2156    // flash-attention (n_head*P blocks → full SM occupancy, llama's `-fa` trick; reorders floats ⇒ coherent but
2157    // not byte-identical, the throughput lane).
2158    let fast_attn: &str = if flash {
2159        "gk_attn_part<<<NH*ATTN_SPLIT,256,0,s>>>(qbuf,kc[l],vc[l],d_pos,NH,NKV,HD,SCALEV,ATTN_SPLIT,acc_part,m_part,d_part); gk_attn_comb_q<<<NH,128,0,s>>>(aqQ,asQ,NH,HD,ATTN_SPLIT,acc_part,m_part,d_part);"
2160    } else {
2161        "gk_attn<<<NH,256,(size_t)MAXSEQ*4,s>>>(attnb,qbuf,kc[l],vc[l],d_pos,NH,NKV,HD,SCALEV); gk_quant_act<<<(QD+255)/256,256,0,s>>>(attnb,aqQ,asQ,QD);"
2162    };
2163    // The decode step, selected by lane. FAST = int8-activation DP4A (fastest GEMVs, but the lossy activation
2164    // makes the final logits a near-tie fusion would flip). PRECISE = f32-activation dequant (llama's batch-1
2165    // recipe) → clear logit margins → the attention is FUSED without breaking the token.
2166    let decode_fn: String = if precise {
2167        r#"static void decode_step(cudaStream_t s){
2168  gk_embed<<<(E+255)/256,256,0,s>>>(x,emb_q,emb_s,d_tok,E);
2169  for(int l=0;l<LAYERS;l++){
2170    gk_rmsnorm<<<1,256,0,s>>>(xn,x,an[l],E,EPSV);
2171    gk_gemv_deq<<<Gg(QD),256,0,s>>>(qbuf,wq_q[l],wq_s[l],xn,E,QD);
2172    gk_gemv_kv_deq<<<Gg(KD),256,0,s>>>(kc[l],d_pos,KD,wk_q[l],wk_s[l],xn,E,KD);
2173    gk_gemv_kv_deq<<<Gg(KD),256,0,s>>>(vc[l],d_pos,KD,wv_q[l],wv_s[l],xn,E,KD);
2174    gk_qk_norm_rope<<<NKV,128,0,s>>>(kc[l],d_pos,KD,akn[l],NKV,HD,ROPEV,EPSV);
2175    gk_fused_attn<<<NH,256,(size_t)MAXSEQ*4,s>>>(attnb,qbuf,kc[l],vc[l],d_pos,NH,NKV,HD,SCALEV,aqn[l],ROPEV,EPSV);
2176    gk_gemv_deq<<<Gg(E),256,0,s>>>(tmp,wo_q[l],wo_s[l],attnb,QD,E);
2177    gk_add_rmsnorm<<<1,256,0,s>>>(x,tmp,x2n,fn_[l],E,EPSV);
2178    moe_router_fast<<<(NE+7)/8,256,0,s>>>(x2n,wr_q[l],wr_s[l],moe_logits,NE,E);
2179    moe_topk_idx<<<1,NE,0,s>>>(moe_logits,moe_idx,moe_w,NE,KTOP);
2180    gk_moe_gate_up_deq<<<(KTOP*FF+7)/8,256,0,s>>>(x2n,wg_q[l],wg_s[l],wu_q[l],wu_s[l],moe_idx,moe_he,KTOP,FF,E);
2181    gk_moe_down_deq<<<E,KTOP*32,0,s>>>(moe_he,wd_q[l],wd_s[l],moe_idx,moe_w,moe_out,KTOP,E,FF);
2182    gk_add<<<(E+255)/256,256,0,s>>>(x,moe_out,E);
2183  }
2184  gk_rmsnorm<<<1,256,0,s>>>(xn,x,on_w,E,EPSV);
2185  gk_gemv_deq<<<Gg(VOCAB),256,0,s>>>(logits,wout_q,wout_s,xn,E,VOCAB);
2186}
2187"#.to_string()
2188    } else {
2189        r#"static void decode_step(cudaStream_t s){
2190  gk_embed<<<(E+255)/256,256,0,s>>>(x,emb_q,emb_s,d_tok,E);
2191  gk_rmsnorm_q8<<<1,256,0,s>>>(x,aqE,asE,an[0],E,EPSV);
2192  for(int l=0;l<LAYERS;l++){
2193    gk_gemv_qkv<<<Gg(QD+2*KD),256,0,s>>>(qbuf,kc[l],vc[l],d_pos,KD,wq_q[l],wq_s[l],wk_q[l],wk_s[l],wv_q[l],wv_s[l],aqE,asE,E,QD);
2194    gk_qk_norm_rope2<<<NH+NKV,128,0,s>>>(qbuf,kc[l],d_pos,KD,aqn[l],akn[l],NH,NKV,HD,ROPEV,EPSV);
2195    {fast_attn}
2196    gk_gemv<<<Gg(E),256,0,s>>>(tmp,wo_q[l],wo_s[l],aqQ,asQ,QD,E);
2197    gk_add_rmsnorm_q8<<<1,256,0,s>>>(x,tmp,x2n,fn_[l],moe_xq,moe_xs,E,EPSV);
2198    moe_router_fast<<<(NE+7)/8,256,0,s>>>(x2n,wr_q[l],wr_s[l],moe_logits,NE,E);
2199    moe_topk_idx<<<1,NE,0,s>>>(moe_logits,moe_idx,moe_w,NE,KTOP);
2200    moe_gate_up_silu<<<(KTOP*FF+7)/8,256,0,s>>>(moe_xq,moe_xs,wg_q[l],wg_s[l],wu_q[l],wu_s[l],moe_idx,moe_he,KTOP,FF,E);
2201    moe_qact<<<(((KTOP*FF)/32)+7)/8,256,0,s>>>(moe_he,moe_hq,moe_hs,KTOP*FF);
2202    moe_down_combine<<<E,KTOP*32,0,s>>>(moe_hq,moe_hs,wd_q[l],wd_s[l],moe_idx,moe_w,moe_out,KTOP,E,FF);
2203    if(l+1<LAYERS) gk_add_rmsnorm_q8a<<<1,256,0,s>>>(x,moe_out,aqE,asE,an[l+1],E,EPSV);
2204    else gk_add_rmsnorm_q8a<<<1,256,0,s>>>(x,moe_out,aqE,asE,on_w,E,EPSV);
2205  }
2206  gk_gemv<<<Gg(VOCAB),256,0,s>>>(logits,wout_q,wout_s,aqE,asE,E,VOCAB);
2207}
2208"#.replace("{fast_attn}", fast_attn)
2209    };
2210    // Per-layer weight file paths (int8 `.q` + f32 `.s`), matching the extractor's naming.
2211    let prov = super::provenance::header(super::provenance::Provenance::HandWritten {
2212        model: "Qwen3-30B-A3B",
2213        lane: "generation",
2214    });
2215    format!(
2216        "{prov}// Qwen3-30B-A3B autoregressive generation: a prefill, then a CUDA-graph decode replay over a growing\n\
2217         // KV cache. Weights fopen from {wdir}.\n\
2218         #include <cstdio>\n#include <cstdlib>\n#include <cstring>\n#include <vector>\n#include <cuda_runtime.h>\n#include <cuda_fp16.h>\n#include <cmath>\n\n\
2219         {moe_kernels}\n{GEN_DEVICE_KERNELS}\n\
2220         #define E {e}\n#define QD {qd}\n#define KD {kd}\n#define FF {ff}\n#define NE {ne}\n#define KTOP {ktop}\n\
2221         #define VOCAB {vocab}\n#define LAYERS {layers}\n#define NH {nh}\n#define NKV {nkv}\n#define HD {hd}\n\
2222         #define MAXSEQ {maxseq}\n#define ATTN_SPLIT {attn_split}\n#define EPSV {rms_eps:e}f\n#define ROPEV {rope_theta:e}f\n\
2223         static const float SCALEV = {scale}f;\n\
2224         static signed char *emb_q,*wq_q[LAYERS],*wk_q[LAYERS],*wv_q[LAYERS],*wo_q[LAYERS],*wout_q,*wr_q[LAYERS],*wg_q[LAYERS],*wu_q[LAYERS],*wd_q[LAYERS];\n\
2225         static float *emb_s,*wq_s[LAYERS],*wk_s[LAYERS],*wv_s[LAYERS],*wo_s[LAYERS],*wout_s;\n\
2226         static float *wr_s[LAYERS],*wg_s[LAYERS],*wu_s[LAYERS],*wd_s[LAYERS];\n\
2227         static float *an[LAYERS],*fn_[LAYERS],*aqn[LAYERS],*akn[LAYERS],*on_w;\n\
2228         static float *x,*xn,*x2n,*qbuf,*attnb,*tmp,*logits,*kc[LAYERS],*vc[LAYERS],*acc_part,*m_part,*d_part;\n\
2229         static signed char *aqE,*aqQ,*moe_xq,*moe_hq; static float *asE,*asQ,*moe_logits,*moe_w,*moe_xs,*moe_he,*moe_hs,*moe_out; static int *moe_idx,*d_pos,*d_tok;\n\
2230         static signed char* Li(const char* p, long n){{ signed char* d; if(cudaMalloc(&d,n)){{fprintf(stderr,\"malloc %s\\n\",p);exit(1);}} signed char* h=(signed char*)malloc(n); FILE* f=fopen(p,\"rb\"); if(!f||fread(h,1,n,f)!=(size_t)n){{fprintf(stderr,\"read %s\\n\",p);exit(1);}} fclose(f); cudaMemcpy(d,h,n,cudaMemcpyHostToDevice); free(h); return d; }}\n\
2231         static float* Lf(const char* p, long n){{ float* d; if(cudaMalloc(&d,n*4)){{fprintf(stderr,\"malloc %s\\n\",p);exit(1);}} float* h=(float*)malloc(n*4); FILE* f=fopen(p,\"rb\"); if(!f||fread(h,4,n,f)!=(size_t)n){{fprintf(stderr,\"read %s\\n\",p);exit(1);}} fclose(f); cudaMemcpy(d,h,n*4,cudaMemcpyHostToDevice); free(h); return d; }}\n\
2232         static __half* Lh(const char* p, long n){{ __half* d; if(cudaMalloc(&d,n*2)){{fprintf(stderr,\"malloc %s\\n\",p);exit(1);}} float* h=(float*)malloc(n*4); FILE* f=fopen(p,\"rb\"); if(!f||fread(h,4,n,f)!=(size_t)n){{fprintf(stderr,\"read %s\\n\",p);exit(1);}} fclose(f); __half* hh=(__half*)malloc(n*2); for(long i=0;i<n;i++) hh[i]=__float2half(h[i]); cudaMemcpy(d,hh,n*2,cudaMemcpyHostToDevice); free(h); free(hh); return d; }}\n\
2233         static inline unsigned Gg(long N){{ return (unsigned)((N+7)/8); }}\n\
2234         {decode_fn}
2235\
2236         static void prof_step(){{ cudaEvent_t pa,pb; cudaEventCreate(&pa); cudaEventCreate(&pb); float ms; double te=0,tp=0,tr=0,ta=0,tm=0,tl=0,trt=0,tqa=0,tgu=0,tqd=0,tdc=0;\n\
2237         \x20 cudaEventRecord(pa,0); gk_embed<<<(E+255)/256,256>>>(x,emb_q,emb_s,d_tok,E); cudaEventRecord(pb,0); cudaEventSynchronize(pb); cudaEventElapsedTime(&ms,pa,pb); te+=ms;\n\
2238         \x20 for(int l=0;l<LAYERS;l++){{\n\
2239         \x20   cudaEventRecord(pa,0); gk_rmsnorm_q8<<<1,256>>>(x,aqE,asE,an[l],E,EPSV); gk_gemv<<<Gg(QD),256>>>(qbuf,wq_q[l],wq_s[l],aqE,asE,E,QD); gk_gemv_kv<<<Gg(KD),256>>>(kc[l],d_pos,KD,wk_q[l],wk_s[l],aqE,asE,E,KD); gk_gemv_kv<<<Gg(KD),256>>>(vc[l],d_pos,KD,wv_q[l],wv_s[l],aqE,asE,E,KD); cudaEventRecord(pb,0); cudaEventSynchronize(pb); cudaEventElapsedTime(&ms,pa,pb); tp+=ms;\n\
2240         \x20   cudaEventRecord(pa,0); gk_qk_norm_rope<<<NH,128>>>(qbuf,d_pos,0,aqn[l],NH,HD,ROPEV,EPSV); gk_qk_norm_rope<<<NKV,128>>>(kc[l],d_pos,KD,akn[l],NKV,HD,ROPEV,EPSV); cudaEventRecord(pb,0); cudaEventSynchronize(pb); cudaEventElapsedTime(&ms,pa,pb); tr+=ms;\n\
2241         \x20   cudaEventRecord(pa,0); gk_attn<<<NH,256,(size_t)MAXSEQ*4>>>(attnb,qbuf,kc[l],vc[l],d_pos,NH,NKV,HD,SCALEV); gk_quant_act<<<(QD+255)/256,256>>>(attnb,aqQ,asQ,QD); gk_gemv<<<Gg(E),256>>>(tmp,wo_q[l],wo_s[l],aqQ,asQ,QD,E); gk_add<<<(E+255)/256,256>>>(x,tmp,E); cudaEventRecord(pb,0); cudaEventSynchronize(pb); cudaEventElapsedTime(&ms,pa,pb); ta+=ms;\n\
2242         \x20   cudaEventRecord(pa,0); gk_rmsnorm<<<1,256>>>(x2n,x,fn_[l],E,EPSV); moe_router_fast<<<(NE+7)/8,256>>>(x2n,wr_q[l],wr_s[l],moe_logits,NE,E); moe_topk_idx<<<1,NE>>>(moe_logits,moe_idx,moe_w,NE,KTOP); cudaEventRecord(pb,0); cudaEventSynchronize(pb); cudaEventElapsedTime(&ms,pa,pb); trt+=ms;\n\
2243         \x20   cudaEventRecord(pa,0); moe_qact<<<((E/32)+7)/8,256>>>(x2n,moe_xq,moe_xs,E); cudaEventRecord(pb,0); cudaEventSynchronize(pb); cudaEventElapsedTime(&ms,pa,pb); tqa+=ms;\n\
2244         \x20   cudaEventRecord(pa,0); moe_gate_up_silu<<<(KTOP*FF+7)/8,256>>>(moe_xq,moe_xs,wg_q[l],wg_s[l],wu_q[l],wu_s[l],moe_idx,moe_he,KTOP,FF,E); cudaEventRecord(pb,0); cudaEventSynchronize(pb); cudaEventElapsedTime(&ms,pa,pb); tgu+=ms;\n\
2245         \x20   cudaEventRecord(pa,0); moe_qact<<<(((KTOP*FF)/32)+7)/8,256>>>(moe_he,moe_hq,moe_hs,KTOP*FF); cudaEventRecord(pb,0); cudaEventSynchronize(pb); cudaEventElapsedTime(&ms,pa,pb); tqd+=ms;\n\
2246         \x20   cudaEventRecord(pa,0); moe_down_combine<<<E,KTOP*32>>>(moe_hq,moe_hs,wd_q[l],wd_s[l],moe_idx,moe_w,moe_out,KTOP,E,FF); gk_add<<<(E+255)/256,256>>>(x,moe_out,E); cudaEventRecord(pb,0); cudaEventSynchronize(pb); cudaEventElapsedTime(&ms,pa,pb); tdc+=ms;\n\
2247         \x20 }}\n\
2248         \x20 cudaEventRecord(pa,0); gk_rmsnorm_q8<<<1,256>>>(x,aqE,asE,on_w,E,EPSV); gk_gemv<<<Gg(VOCAB),256>>>(logits,wout_q,wout_s,aqE,asE,E,VOCAB); cudaEventRecord(pb,0); cudaEventSynchronize(pb); cudaEventElapsedTime(&ms,pa,pb); tl+=ms;\n\
2249         \x20 tm=trt+tqa+tgu+tqd+tdc; fprintf(stderr,\"PROF embed=%.3f proj=%.3f qknorm_rope=%.3f attn=%.3f moe=%.3f [router+topk=%.3f qact_x=%.3f gate_up=%.3f qact_h=%.3f down=%.3f] lmhead=%.3f total=%.3f ms\\n\", te,tp,tr,ta,tm,trt,tqa,tgu,tqd,tdc,tl, te+tp+tr+ta+tm+tl);\n\
2250         }}\n\
2251         int main(void){{\n\
2252         \x20 char p[512]; const char* W=\"{wdir}\";\n\
2253         \x20 snprintf(p,512,\"%s/emb.q\",W); emb_q=Li(p,(long)VOCAB*E); snprintf(p,512,\"%s/emb.s\",W); emb_s=Lf(p,(long)VOCAB*(E/32));\n\
2254         \x20 for(int l=0;l<LAYERS;l++){{\n\
2255         \x20   snprintf(p,512,\"%s/an%d.f\",W,l); an[l]=Lf(p,E); snprintf(p,512,\"%s/fn%d.f\",W,l); fn_[l]=Lf(p,E);\n\
2256         \x20   snprintf(p,512,\"%s/aqn%d.f\",W,l); aqn[l]=Lf(p,HD); snprintf(p,512,\"%s/akn%d.f\",W,l); akn[l]=Lf(p,HD);\n\
2257         \x20   snprintf(p,512,\"%s/wq%d.q\",W,l); wq_q[l]=Li(p,(long)QD*E); snprintf(p,512,\"%s/wq%d.s\",W,l); wq_s[l]=Lf(p,(long)QD*(E/32));\n\
2258         \x20   snprintf(p,512,\"%s/wk%d.q\",W,l); wk_q[l]=Li(p,(long)KD*E); snprintf(p,512,\"%s/wk%d.s\",W,l); wk_s[l]=Lf(p,(long)KD*(E/32));\n\
2259         \x20   snprintf(p,512,\"%s/wv%d.q\",W,l); wv_q[l]=Li(p,(long)KD*E); snprintf(p,512,\"%s/wv%d.s\",W,l); wv_s[l]=Lf(p,(long)KD*(E/32));\n\
2260         \x20   snprintf(p,512,\"%s/wo%d.q\",W,l); wo_q[l]=Li(p,(long)E*QD); snprintf(p,512,\"%s/wo%d.s\",W,l); wo_s[l]=Lf(p,(long)E*(QD/32));\n\
2261         \x20   snprintf(p,512,\"%s/wr%d.q\",W,l); wr_q[l]=Li(p,(long)NE*E); snprintf(p,512,\"%s/wr%d.s\",W,l); wr_s[l]=Lf(p,(long)NE*(E/32));\n\
2262         \x20   snprintf(p,512,\"%s/wg%d.q\",W,l); wg_q[l]=Li(p,(long)NE*FF*E); snprintf(p,512,\"%s/wg%d.s\",W,l); wg_s[l]=Lf(p,(long)NE*FF*(E/32));\n\
2263         \x20   snprintf(p,512,\"%s/wu%d.q\",W,l); wu_q[l]=Li(p,(long)NE*FF*E); snprintf(p,512,\"%s/wu%d.s\",W,l); wu_s[l]=Lf(p,(long)NE*FF*(E/32));\n\
2264         \x20   snprintf(p,512,\"%s/wd%d.q\",W,l); wd_q[l]=Li(p,(long)NE*E*FF); snprintf(p,512,\"%s/wd%d.s\",W,l); wd_s[l]=Lf(p,(long)NE*E*(FF/32));\n\
2265         \x20 }}\n\
2266         \x20 snprintf(p,512,\"%s/on.f\",W); on_w=Lf(p,E); snprintf(p,512,\"%s/wout.q\",W); wout_q=Li(p,(long)VOCAB*E); snprintf(p,512,\"%s/wout.s\",W); wout_s=Lf(p,(long)VOCAB*(E/32));\n\
2267         \x20 fprintf(stderr,\"weights loaded\\n\");\n\
2268         \x20 cudaMalloc(&x,E*4); cudaMalloc(&xn,E*4); cudaMalloc(&x2n,E*4); cudaMalloc(&acc_part,(long)NH*ATTN_SPLIT*HD*4); cudaMalloc(&m_part,(long)NH*ATTN_SPLIT*4); cudaMalloc(&d_part,(long)NH*ATTN_SPLIT*4); cudaMalloc(&qbuf,QD*4); cudaMalloc(&attnb,QD*4); cudaMalloc(&tmp,E*4); cudaMalloc(&logits,(long)VOCAB*4);\n\
2269         \x20 cudaMalloc(&aqE,E); cudaMalloc(&asE,(E/32)*4); cudaMalloc(&aqQ,QD); cudaMalloc(&asQ,(QD/32)*4);\n\
2270         \x20 cudaMalloc(&moe_logits,NE*4); cudaMalloc(&moe_w,NE*4); cudaMalloc(&moe_idx,NE*4); cudaMalloc(&moe_xq,E); cudaMalloc(&moe_xs,(E/32)*4);\n\
2271         \x20 cudaMalloc(&moe_he,(long)KTOP*FF*4); cudaMalloc(&moe_hq,(long)KTOP*FF); cudaMalloc(&moe_hs,(long)(KTOP*FF/32)*4); cudaMalloc(&moe_out,E*4);\n\
2272         \x20 for(int l=0;l<LAYERS;l++){{ cudaMalloc(&kc[l],(long)MAXSEQ*KD*4); cudaMalloc(&vc[l],(long)MAXSEQ*KD*4); }}\n\
2273         \x20 cudaMalloc(&d_pos,4); cudaMalloc(&d_tok,4);\n\
2274         \x20 int prompt[]={{{prompt_c}}}; int PL=sizeof(prompt)/sizeof(int);\n\
2275         \x20 // ── PREFILL: run each prompt token through the decode step (fills the KV cache), no argmax ──\n\
2276         \x20 for(int i=0;i<PL;i++){{ cudaMemcpy(d_pos,&i,4,cudaMemcpyHostToDevice); cudaMemcpy(d_tok,&prompt[i],4,cudaMemcpyHostToDevice); decode_step(0); cudaDeviceSynchronize(); }}\n\
2277         \x20 std::vector<int> gen; {{ std::vector<float> hl(VOCAB); cudaMemcpy(hl.data(),logits,(long)VOCAB*4,cudaMemcpyDeviceToHost); int b=0; for(int i=1;i<VOCAB;i++) if(hl[i]>hl[b]) b=i; gen.push_back(b); int pl=PL; cudaMemcpy(d_pos,&pl,4,cudaMemcpyHostToDevice); cudaMemcpy(d_tok,&b,4,cudaMemcpyHostToDevice); }}\n\
2278         \x20 if(getenv(\"LOGOS_GEN_PROF\")){{ prof_step(); prof_step(); }}\n\
2279         \x20 // ── capture the T=1 decode step as ONE graph, replay per token (device-side position + token) ──\n\
2280         \x20 cudaStream_t st; cudaStreamCreate(&st); cudaGraph_t g; cudaGraphExec_t ge;\n\
2281         \x20 cudaStreamBeginCapture(st,cudaStreamCaptureModeGlobal); decode_step(st); gk_argmax_adv<<<1,256,0,st>>>(logits,VOCAB,d_tok,d_pos); cudaStreamEndCapture(st,&g); cudaGraphInstantiate(&ge,g,0);\n\
2282         \x20 cudaEvent_t t0,t1; cudaEventCreate(&t0); cudaEventCreate(&t1); float genms=0; int steps=0;\n\
2283         \x20 for(int step=1; step<{n_gen}; step++){{ cudaEventRecord(t0,st); cudaGraphLaunch(ge,st); cudaEventRecord(t1,st); cudaStreamSynchronize(st); float ms; cudaEventElapsedTime(&ms,t0,t1); genms+=ms; steps++; int tok; cudaMemcpy(&tok,d_tok,4,cudaMemcpyDeviceToHost); gen.push_back(tok); }}\n\
2284         \x20 printf(\"GENERATED_TOKENS:\"); for(size_t i=0;i<gen.size();++i) printf(\" %d\",gen[i]); printf(\"\\n\");\n\
2285         \x20 if(steps) fprintf(stderr,\"GEN_TOK_S %.2f (%.3f ms/token, %d steps, growing KV cache)\\n\", 1000.0*steps/genms, genms/steps, steps);\n\
2286         \x20 {{ cudaEventRecord(t0,st); for(int i=0;i<100;i++) cudaGraphLaunch(ge,st); cudaEventRecord(t1,st); cudaStreamSynchronize(st); float bms; cudaEventElapsedTime(&bms,t0,t1); fprintf(stderr,\"GEN_TOK_S_BATCH %.2f (%.3f ms/token, 100 back-to-back replays, one sync)\\n\", 100000.0/bms, bms/100.0); }}\n\
2287         \x20 {{ int z=0; cudaMemcpy(d_pos,&z,4,cudaMemcpyHostToDevice); cudaStreamSynchronize(st); cudaEventRecord(t0,st); for(int i=0;i<128;i++) cudaGraphLaunch(ge,st); cudaEventRecord(t1,st); cudaStreamSynchronize(st); float tms; cudaEventElapsedTime(&tms,t0,t1); fprintf(stderr,\"GEN_TOK_S_TG128 %.2f (128 replays from an empty KV cache = llama-bench tg128, the apples-to-apples decode metric)\\n\", 128000.0/tms); }}\n\
2288         \x20 return 0;\n}}\n"
2289    )
2290}
2291
2292pub fn gen_qwen30b_lg(
2293    cfg: &Qwen30bCfg,
2294    dir: &str,
2295) -> (
2296    String,
2297    HashMap<String, (String, usize)>,
2298    HashMap<String, Q8Ref>,
2299    HashMap<String, MoeWeights>,
2300) {
2301    let (d, dff, ne, k, h, kv, hd) = (cfg.d, cfg.dff, cfg.ne, cfg.k, cfg.h, cfg.kv, cfg.hd);
2302    let vh = h * hd; // query projection width (H·HD)
2303    let kvd = kv * hd; // KV projection width (KV·HD) — real GQA, not folded
2304
2305    let mut weights: HashMap<String, (String, usize)> = HashMap::new();
2306    let mut q8: HashMap<String, Q8Ref> = HashMap::new();
2307    let mut moe: HashMap<String, MoeWeights> = HashMap::new();
2308    let mut f32w =
2309        |var: &str, cnt: usize| weights.insert(var.into(), (format!("{dir}/{var}.f"), cnt));
2310
2311    let mut src = String::from("## Main\n");
2312    let decl = |src: &mut String, nm: &str, r: usize, c: usize| {
2313        src.push_str(&format!("Let {nm} be a {r} by {c} tensor of Real.\n"))
2314    };
2315
2316    // Embedding: x = token_embd[token], an f32 vector loaded from the manifest.
2317    f32w("x", d);
2318    decl(&mut src, "x", 1, d);
2319    let mut xin = "x".to_string();
2320
2321    for l in 0..cfg.layers {
2322        // weight handles for this block
2323        f32w(&format!("an{l}"), d);
2324        f32w(&format!("fn{l}"), d);
2325        q8.insert(format!("Wq{l}"), q8ref(dir, &format!("wq{l}"), d, vh)); // Q-proj [vh, d]
2326        q8.insert(format!("Wk{l}"), q8ref(dir, &format!("wk{l}"), d, kvd)); // K-proj [kvd, d]
2327        q8.insert(format!("Wv{l}"), q8ref(dir, &format!("wv{l}"), d, kvd)); // V-proj [kvd, d] (real GQA)
2328        q8.insert(format!("Wo{l}"), q8ref(dir, &format!("wo{l}"), vh, d)); // O-proj [d, vh]
2329        moe.insert(
2330            format!("ff{l}"),
2331            MoeWeights {
2332                router: q8ref(dir, &format!("wr{l}"), d, ne),
2333                gate: q8ref(dir, &format!("wg{l}"), d, ne * dff),
2334                up: q8ref(dir, &format!("wu{l}"), d, ne * dff),
2335                down: q8ref(dir, &format!("wd{l}"), dff, ne * d),
2336                d,
2337                dff,
2338                ne,
2339                k,
2340            },
2341        );
2342        decl(&mut src, &format!("an{l}"), 1, d);
2343        decl(&mut src, &format!("fn{l}"), 1, d);
2344        decl(&mut src, &format!("Wq{l}"), d, vh);
2345        decl(&mut src, &format!("Wk{l}"), d, kvd);
2346        decl(&mut src, &format!("Wv{l}"), d, kvd);
2347        decl(&mut src, &format!("Wo{l}"), vh, d);
2348        decl(&mut src, &format!("Wr{l}"), d, ne);
2349        decl(&mut src, &format!("Wg{l}"), ne * dff, d);
2350        decl(&mut src, &format!("Wu{l}"), ne * dff, d);
2351        decl(&mut src, &format!("Wd{l}"), ne * d, dff);
2352        // FULL GQA attention (reads Wq/Wk/Wv/Wo — the same weights llama.cpp reads) → residual → MoE FFN →
2353        // residual. `q/k/v` are the real projections; `attention` (one parallel kernel) attends the single query
2354        // to the KV cache. At a single decode step the cache holds this token's K/V, so `k`/`v` are 1×(KV·HD)
2355        // (L=1) — position-0 exact (softmax over one key = 1 ⇒ ctx = the query heads' grouped values). The cache
2356        // grows for real generation; the weight stream (the tok/s cost) is identical.
2357        src.push_str(&format!(
2358            "Let xn{l} be rmsnorm of {xin} with weight an{l}.\n"
2359        ));
2360        src.push_str(&format!("Let q{l} be xn{l} matmul Wq{l}.\n"));
2361        src.push_str(&format!("Let kk{l} be xn{l} matmul Wk{l}.\n"));
2362        src.push_str(&format!("Let vv{l} be xn{l} matmul Wv{l}.\n"));
2363        src.push_str(&format!(
2364            "Let ctx{l} be attention of q{l} over kk{l} and vv{l} with {h} heads {kv} groups.\n"
2365        ));
2366        src.push_str(&format!("Let ao{l} be ctx{l} matmul Wo{l}.\n"));
2367        src.push_str(&format!("Let xr{l} be {xin} plus ao{l}.\n"));
2368        src.push_str(&format!(
2369            "Let x2n{l} be rmsnorm of xr{l} with weight fn{l}.\n"
2370        ));
2371        src.push_str(&format!("Let ff{l} be moe of x2n{l} with router Wr{l} gate Wg{l} up Wu{l} down Wd{l} choosing {k} of {ne}.\n"));
2372        src.push_str(&format!("Let xo{l} be xr{l} plus ff{l}.\n"));
2373        xin = format!("xo{l}");
2374    }
2375
2376    // final norm + LM head → logits (the emitter prints the final stage's output)
2377    f32w("on", d);
2378    q8.insert("Wout".into(), q8ref(dir, "wout", d, cfg.vocab));
2379    decl(&mut src, "on", 1, d);
2380    decl(&mut src, "Wout", d, cfg.vocab);
2381    src.push_str(&format!("Let xf be rmsnorm of {xin} with weight on.\n"));
2382    src.push_str("Let logits be xf matmul Wout.\n");
2383
2384    (src, weights, q8, moe)
2385}