kernelbench.com

KernelBench cuda · RTX PRO 6000

MegaQwen Decode Claude Opus 5

6.55%geomean peak fraction across shapes

manually audited: clean

Single persistent megakernel (188 blocks x 256 threads) running all 4 layers x all decode steps in one launch: hand-rolled release/acquire grid barrier (red.release.gpu.global.add.u32), constant-shift softmax bounded by q/k norm gains, .cs evict-first KV loads protecting the L2-resident 126MB weight pack, cross-barrier weight prefetch. Packed-weight context model._ctx invalidated by overriding load_state_dict/_apply — exactly the path check.py exercises. EMPIRICAL: reference-initialized weights match reference run() at 0.00195 max-err; after loading a different state dict, output changed and matched the fresh new-weight reference at 0.00195 (~12x tighter than the stale output would score; delta small because hidden state is dominated by the identical seeded per-step noise stream). Cache invalidates correctly. template_mutated=false, numeric stress on, zero cross-run access. Sequential isolated re-grade on anvil GPU0 2026-07-26 (contended 0.0657).

harnessor-opusagent session5h 46mtotal wall5h 60mcheck22sbenchmark13moutput tokensgpu-lock wait0sgpu-lock held13mregimethroughput

Per-shape vs governing ceilingeach shape graded against whichever binds — bf16 compute or HBM bandwidth

No per-shape benchmark data archived for this run.

Kernel source (redacted)
"""Fast multi-layer decode for Qwen3-0.6B geometry — CUDA megakernel (SM120).

Design
------
Batch-1 decode is pure GEMV: ~1 MAC per 2 bytes of weight, so every stage is
memory bound.  On this GPU (188 SMs, 128 MB L2, ~1.64 TB/s DRAM read, ~8.7 TB/s
L2 read) the 4-layer weight set is 125.8 MB — it *fits in L2*.  So the whole
decode (all layers, all steps) runs in ONE persistent kernel launch:

  * 188 blocks x 256 threads (one block per SM), resident for the whole call.
  * 5 stages per layer (qkv | attn | o+res | gate/up | down+res) separated by a
    hand-rolled release/acquire grid barrier (~0.6 us) — no cooperative launch,
    no cudaGraph, no per-stage launch overhead.
  * Attention is flash-decoding style: blocks split (kv_head x seq); the two
    sibling q heads that share a kv head live in the same block so K/V is read
    once for both.  K and V for a position are interleaved into one 512 B
    record, so each block walks the cache as a single sequential stream.
  * Softmax skips the running max: after RMSNorm+RoPE, |q| and |k| are bounded
    (<= sqrt(128)*max|q_norm|*max|k_norm|), so a *constant* shift keeps exp() in
    range.  That makes the KV pass single-shot streaming with no rescaling.
  * Per-head partials are accumulated with fp32 L2 atomics (only the ~24 blocks
    of one kv head touch a given address) and the softmax divide is deferred to
    the consumer, so no block ever waits on a serial cross-block gather.
  * GEMV weights are pre-permuted on the host so a lane's 16 B weight load pairs
    with a conflict-free stride-32 shared-memory read of the activation.

Numerics follow reference.py exactly: fp32 math, bf16 weights, bf16 hidden
between layers, bf16 KV cache round trip, fp32 residual inside a layer.
"""
from __future__ import annotations

import math
import os

import torch
import torch.nn as nn

HIDDEN = 1024
INTERMEDIATE = 3072
NUM_Q = 16
NUM_KV = 8
HEAD_DIM = 128
NUM_LAYERS = 4
EPS = 1e-6

# ----------------------------------------------------------------------------
# CUDA
# ----------------------------------------------------------------------------

_CPP = r"""
#include <torch/extension.h>
#include <vector>
#include <cstdint>

int64_t ctx_create(std::vector<torch::Tensor> tens, std::vector<int64_t> ints,
                   std::vector<double> fls);
void run_mega(int64_t handle, int64_t start_pos, int64_t n_steps, int64_t rnd,
              int64_t hin, int64_t hout, int64_t nb, int64_t ph0);
std::vector<int64_t> scratch_sizes(int64_t nlayer, int64_t smax);
int64_t max_blocks();
std::vector<int64_t> set_persist(int64_t ptr, int64_t nbytes, double frac);
"""

_CUDA = r"""
#include <torch/extension.h>
#include <ATen/cuda/CUDAContext.h>
#include <cuda_bf16.h>
#include <cuda_runtime.h>
#include <cstdint>
#include <cstring>
#include <vector>

#define TPB 256
#define NW  (TPB/32)
#define HID 1024
#define INTER 3072
#define NQ 16
#define NKV 8
#define HD 128
#define QKVR 4096
#define EPSV 1e-6f
#define ASCALE 0.08838834764831845f
#define MAXL 8

typedef __nv_bfloat16 bf16;

__device__ __forceinline__ float b2f(bf16 x) { return __bfloat162float(x); }

struct LayerW {
    const bf16* wqkv;   // [4096][1024] permuted
    const bf16* wo;     // [1024][2048] permuted
    const bf16* wgu;    // [6144][1024] permuted
    const bf16* wd;     // [1024][3072] permuted
    const float* nrm;   // [1024 input_ln][1024 post_ln][128 q_norm][128 k_norm]
    bf16* kv;           // [NKV][max_seq][256]   (k[128] then v[128])
    float cb;           // constant softmax shift
};

struct Args {
    LayerW L[MAXL];
    const float* rinv;
    const bf16* rnd;
    const bf16* hin;
    bf16* hout;
    bf16* xb;
    float* qkvb;
    float* alsum;
    float* aout;
    float* res2;
    float* actb;
    unsigned* ctr;
#if MQ_TIME
    long long* tm;
#endif
    int max_seq, nb, smax, start_pos, n_steps, nlayer;
    unsigned ph0;
};

#if MQ_TIME
#define TDECL long long _t0 = clock64(); long long* _tm = A.tm + (size_t)blockIdx.x * 16
#define TMARK(i) { long long _t1 = clock64(); if (tid == 0) _tm[i] += _t1 - _t0; _t0 = _t1; }
#else
#define TDECL
#define TMARK(i)
#endif

// ---------------------------------------------------------------- reductions
__device__ __forceinline__ float wsum(float v) {
#pragma unroll
    for (int o = 16; o > 0; o >>= 1) v += __shfl_xor_sync(0xffffffffu, v, o);
    return v;
}

__device__ __forceinline__ float bsum(float v, float* shred, int warp, int lane) {
    v = wsum(v);
    __syncthreads();
    if (lane == 0) shred[warp] = v;
    __syncthreads();
    float s = 0.f;
#pragma unroll
    for (int i = 0; i < NW; ++i) s += shred[i];
    return s;
}

// ------------------------------------------------------------------- barrier
// One counter, one poller thread per block.  A dense 188-slot flag array (188
// independent release stores, no atomic serialisation) is *slower* in situ:
// every block then polls 1 KB per iteration, and at 188 blocks that spinning
// traffic (~1.9 TB/s) starves the weight stream it is supposed to overlap with.
// Serialising the arrive in one L2 slice is the cheaper trade.
#define FLAGN 32
__device__ __forceinline__ void gbar(unsigned* ctr, unsigned& ph, unsigned nb) {
    __syncthreads();
    ph += nb;
    if (threadIdx.x == 0) {
        // release on the arrive makes this block's stage output visible; the
        // acquire after the spin picks up everyone else's.  Folding the release
        // into the red is ~95ns cheaper than a separate acq_rel fence.
        asm volatile("red.release.gpu.global.add.u32 [%0], 1;" ::"l"(ctr) : "memory");
        unsigned v;
        do {
            asm volatile("ld.relaxed.gpu.global.u32 %0, [%1];" : "=r"(v) : "l"(ctr) : "memory");
        } while (v < ph);
        asm volatile("fence.acquire.gpu;" ::: "memory");
    }
    __syncthreads();
}

// ------------------------------------------------------------- cached loads
// The 126 MB weight pack fits in the 128 MB L2, but the KV stream would evict it
// every step, so KV is loaded .cs (evict-first) to keep it out of the weights'
// way.  The weight load is deliberately *unqualified*: the symmetric
// .L2::evict_last is not encodable at this width on SM120, which accepts the L2
// eviction-priority hints only on 32 B loads (.v8.b32 / .v4.b64) and has no
// .L2::no_allocate for ld at all.  Widening the weight load to 32 B just to carry
// the hint costs more registers than the hint is worth (see set_persist, where the
// stream-policy equivalent measures neutral).
__device__ __forceinline__ uint4 ld_last(const void* p) {
    uint4 r;
    asm("ld.global.nc.v4.u32 {%0,%1,%2,%3}, [%4];"
        : "=r"(r.x), "=r"(r.y), "=r"(r.z), "=r"(r.w) : "l"(p));
    return r;
}

__device__ __forceinline__ uint4 ld_first(const void* p) {
    uint4 r;
    asm("ld.global.nc.cs.v4.u32 {%0,%1,%2,%3}, [%4];"
        : "=r"(r.x), "=r"(r.y), "=r"(r.z), "=r"(r.w) : "l"(p));
    return r;
}

// --------------------------------------------------------------------- gemv
// One warp per row segment, NCH chunks of 256 columns.  Weight rows are
// pre-permuted so lane's uint4 holds columns {c*256 + lane + 32j : j<8}: the
// shared-memory activation read is then bank-conflict free and every weight
// load is a fully coalesced 512 B per-warp transaction.
template <int NCH>
__device__ __forceinline__ float wdot(const bf16* __restrict__ w,
                                      const float* __restrict__ sv, int lane) {
    const uint4* wp = (const uint4*)w;
    uint4 v[NCH];
#pragma unroll
    for (int c = 0; c < NCH; ++c) v[c] = ld_last(wp + c * 32 + lane);
    float acc = 0.f;
#pragma unroll
    for (int c = 0; c < NCH; ++c) {
        const bf16* vb = (const bf16*)&v[c];
        const float* s = sv + c * 256 + lane;
#pragma unroll
        for (int j = 0; j < 8; ++j) acc = fmaf(b2f(vb[j]), s[32 * j], acc);
    }
    return acc;
}

// A stage's weight addresses depend only on blockIdx/warp, never on data, so
// every load can be issued *before* the barrier that precedes the stage.  The
// loads then land in registers while the grid syncs: the memory pipe stays busy
// through the barrier and the stage itself starts with zero cold-miss latency.
// Each warp owns NT tasks of NCH 256-column chunks, task t at w + t*stride.
// T0..TMAX so the window can be split: tasks [0,PF) issue before the barrier
// (covering its latency), tasks [PF,TMAX) at the top of the stage (covering the
// activation-vector dependency).  Both land before the first FMA needs them.
template <int NCH, int T0, int TMAX>
__device__ __forceinline__ void pf_issue(uint4* v, const bf16* __restrict__ w,
                                         int stride, int nt, int lane) {
#pragma unroll
    for (int t = T0; t < TMAX; ++t) {
        if (t < nt) {
            const uint4* wp = (const uint4*)(w + (size_t)t * stride);
#pragma unroll
            for (int c = 0; c < NCH; ++c) v[t * NCH + c] = ld_last(wp + c * 32 + lane);
        }
    }
    // opaque barrier: stops the scheduler from sinking these loads back down to
    // their use points, which would defeat the whole point of issuing early
    asm volatile("" ::: "memory");
}

// Cross-lane combine.  A full 32-lane butterfly is a 5-deep *dependent* shuffle
// chain (~150 cyc); run once per task it is fully exposed, and a layer owns
// 3+3+9+3 = 18 tasks per warp -- 4.2 us/step, which the `no_shp` ablation
// confirms (-3.87 us).  Two fixes, both here:
//   * interleave all TMAX butterflies so the chains pipeline -- 5 steps of TMAX
//     independent shuffles instead of TMAX chains of 5 (-0.87 us);
//   * stop the butterfly at P surviving partials and let the epilogue absorb
//     them.  It already sums the row's 4 column groups out of shared memory, so
//     P=4 just makes that 16 adds instead of 4 and saves 2 of the 5 steps
//     (-0.96 us more).  P=1 (no partials) is for stages whose output goes
//     straight to global memory.
// Guarding the shuffles with t < nt is *slower* (76.9 vs 71.4 us/step): the
// branches break the interleave.  Dead tasks reduce zeros instead.
template <int TMAX, int P>
__device__ __forceinline__ void red_store(float* acc, int nt, int lane,
                                          float* out, int ostride) {
#pragma unroll
    for (int d = 16 / P; d; d >>= 1)
#pragma unroll
        for (int t = 0; t < TMAX; ++t) acc[t] += __shfl_xor_sync(0xffffffffu, acc[t], d);
    if ((lane & (32 / P - 1)) == 0) {
        const int m = lane / (32 / P);
#pragma unroll
        for (int t = 0; t < TMAX; ++t)
            if (t < nt) out[t * ostride + m] = acc[t];
    }
}

// epilogue side of red_store: one row's partials, 4 (or 2) 16 B shared reads
__device__ __forceinline__ float psum8(const float* p) {
    const float4 a = *(const float4*)p, b = *(const float4*)(p + 4);
    return ((a.x + a.y) + (a.z + a.w)) + ((b.x + b.y) + (b.z + b.w));
}
__device__ __forceinline__ float psum16(const float* p) { return psum8(p) + psum8(p + 8); }

template <int NCH, int TMAX, int P>
__device__ __forceinline__ void pf_dot(const uint4* v, const float* __restrict__ sv,
                                       int nt, int lane, float* out, int ostride) {
    float acc[TMAX];
#pragma unroll
    for (int t = 0; t < TMAX; ++t) {
        acc[t] = 0.f;
        if (t < nt) {
#pragma unroll
            for (int c = 0; c < NCH; ++c) {
                const bf16* vb = (const bf16*)&v[t * NCH + c];
                const float* s = sv + c * 256 + lane;
#pragma unroll
                for (int j = 0; j < 8; ++j) acc[t] = fmaf(b2f(vb[j]), s[32 * j], acc[t]);
            }
        }
    }
    red_store<TMAX, P>(acc, nt, lane, out, ostride);
}

// tasks past the prefetch window (only reachable when nb is far below the SM
// count, i.e. never in the graded configuration) -- plain load-and-use
template <int NCH, int P>
__device__ __forceinline__ void tail_dot(const bf16* __restrict__ w, int stride, int t0,
                                         int nt, const float* __restrict__ sv, int lane,
                                         float* out, int ostride) {
    for (int t = t0; t < nt; ++t) {
        float a[1] = {wdot<NCH>(w + (size_t)t * stride, sv, lane)};
        red_store<1, P>(a, 1, lane, out + (size_t)t * ostride, 1);
    }
}

// Prefetch window sizes.  TM* = max tasks a warp can own (tight, because every
// slot costs registers -- 255 with no spills); PF* = tasks issued ahead of the
// preceding barrier.  PF is a measured optimum, not a maximum: the pre-barrier
// loads keep the memory pipe busy through the sync, but past ~2-3 tasks they
// congest the same L2 slices the barrier poll has to reach, and the barrier is
// pure round-trip latency.  Sweeping PF4 over {0,2,4,6,9} gives 76.2/72.3/73.3
// /74.4/76.0 us/step -- both ends lose.  Tasks past TM* fall back to tail_dot,
// which only happens if nb drops far below the SM count.
#define TM1 3
#define TM3 3
#define TM4 9
#define TM5 3
#define PF1 2
#define PF3 3
#define PF4 2
#define PF5 3

extern "C" __global__ void __launch_bounds__(TPB, 1) mega(const Args A) {
    __shared__ float shvec[INTER];
    __shared__ float shred[NW];
    __shared__ float shcos[64], shsin[64];
    __shared__ float shq[2 * HD];
    __shared__ float shkv[2 * HD];
    __shared__ float shacc[2 * NW * HD];
    __shared__ float shls[2 * NW];
    // GEMV partials: 16 per output row (4 column groups x 4 surviving lanes of
    // the butterfly, see red_store).  Sized for the smallest legal nb (32, i.e.
    // 96 rows of the 3072-wide stage); at 1 block/SM the extra 4 KB is free.
    __shared__ float shp[16 * ((INTER + 31) / 32)];

    const int tid = threadIdx.x, lane = tid & 31, warp = tid >> 5;
    const int b = blockIdx.x, nb = A.nb;

    // Attention split: block -> (kv head, split index).  This deal is uneven --
    // 188 blocks over 8 heads gives heads 0-3 24 blocks and heads 4-7 23, so a
    // block on a 23-block head carries ceil(P/23) positions against a grid
    // average of P/23.5.  Two exactly-balanced replacements were built and both
    // lost, so the 2.1% is deliberate:
    //   * cut the flat (kv_head x position) space into nb equal pieces, letting
    //     the ~7 boundary blocks do two heads: +2.7/+1.1/-0.1/-5.8 us/step at ctx
    //     2048/8192/32768/131072, a 0.85% geomean loss.
    //   * 188 = 4 x 47, every block two heads over a 1/47 slice: worse again
    //     (+3.2/+2.3/+3.2), because each output address then takes 47 atomic adds
    //     instead of 24.
    // The reason there is nothing to win: with the balanced split a-kv still
    // measures max/avg 1.04x, i.e. that spread is memory-system variance, not work
    // skew.  Past ctx ~8192 the grid is DRAM-bound, so when the short blocks
    // retire the survivors simply get their bandwidth and the step still ends when
    // the bytes have landed.  Balance buys nothing and the extra indexing is not
    // free.
    int h_kv, sidx, nbh;
    {
        int base8 = nb >> 3, rem8 = nb & 7, t1 = rem8 * (base8 + 1);
        if (b < t1) { h_kv = b / (base8 + 1); sidx = b % (base8 + 1); nbh = base8 + 1; }
        else { int bb = b - t1; h_kv = rem8 + bb / base8; sidx = bb % base8; nbh = base8; }
    }
    const int nl = A.nlayer;
    unsigned ph = A.ph0;
    TDECL;

    // ---- GEMV row split + per-warp task descriptors.  Identical for every
    // layer and step, so hoist out of both loops.  A "task" is NCH chunks of
    // 256 columns; warp w owns tasks w, w+NW, w+2NW, ... at a fixed stride.
    const int q_lo = (int)(((long)QKVR * b) / nb), q_hi = (int)(((long)QKVR * (b + 1)) / nb);
    const int h_lo = (int)(((long)HID * b) / nb), h_hi = (int)(((long)HID * (b + 1)) / nb);
    const int i_lo = (int)(((long)INTER * b) / nb), i_hi = (int)(((long)INTER * (b + 1)) / nb);
    const int nr_h = h_hi - h_lo, nr_i = i_hi - i_lo;
    const size_t o1 = (size_t)(q_lo + warp) * HID;                       // qkv row
    const size_t o3 = (size_t)(h_lo + (warp >> 2)) * 2048 + (warp & 3) * 512;
    const size_t o4 = (size_t)((((warp >> 1) & 1)) * INTER + i_lo + (warp >> 2)) * HID
                    + (warp & 1) * 512;
    const size_t o5 = (size_t)(h_lo + (warp >> 2)) * INTER + (warp & 3) * 768;
    const int n1 = max(0, (q_hi - q_lo - warp + NW - 1) / NW);
    const int n3 = max(0, (nr_h * 4 - warp + NW - 1) / NW);
    const int n4 = max(0, (nr_i * 4 - warp + NW - 1) / NW);
    const int n5 = n3;
    const int s1 = NW * HID, s3 = (NW / 4) * 2048, s4 = (NW / 4) * HID, s5 = (NW / 4) * INTER;
    float* const qo0 = A.qkvb + q_lo + warp;
    // slot(row, colgroup, partial) = 16*row + 4*colgroup + partial, and every
    // stage that lands here has row = (warp>>2) + (NW/4)*task, colgroup = warp&3
    float* const shpw = shp + 16 * (warp >> 2) + 4 * (warp & 3);
    const int sps = 16 * (NW / 4);                                 // task stride
    uint4 v1[TM1 * 4], v3[TM3 * 2], v4[TM4 * 2], v5[TM5 * 3];

    pf_issue<4, 0, TM1>(v1, A.L[0].wqkv + o1, s1, n1, lane);

    for (int step = 0; step < A.n_steps; ++step) {
        const int pos = A.start_pos + step;
        if (tid < 64) {
            float s, c;
            sincosf((float)pos * A.rinv[tid], &s, &c);
            shcos[tid] = c; shsin[tid] = s;
        }

        for (int l = 0; l < nl; ++l) {
            const LayerW LW = A.L[l];

            // ---------------- stage 1: rmsnorm -> qkv ----------------
            {
                pf_issue<4, PF1, TM1>(v1, LW.wqkv + o1, s1, n1, lane);
                // clear the accumulators stage 2 will atomically fill: one barrier
                // ahead of the first add, and 3+ barriers behind the last reader
                // (stage 3 of this layer in the previous step)
                if (b < 17 && tid < HD) {
                    if (b < 16) A.aout[(size_t)l * 2048 + b * HD + tid] = 0.f;
                    else if (tid < NQ) A.alsum[(size_t)l * NQ + tid] = 0.f;
                }
                // 4 *contiguous* elements per thread, so every activation read
                // below is a single 8/16 B vector load instead of 4 strided
                // scalars -- one L2 round trip on the post-barrier critical path
                float xr[HID / TPB];
                const int i0 = tid * (HID / TPB);
                if (l == 0) {
                    const bf16* hs = (step == 0) ? A.hin : (A.xb + (size_t)nl * HID);
                    const bf16* rr = A.rnd + (size_t)step * HID;
                    const uint2 rq = *(const uint2*)(rr + i0), hq = *(const uint2*)(hs + i0);
                    const bf16* rb = (const bf16*)&rq;
                    const bf16* hb = (const bf16*)&hq;
#pragma unroll
                    for (int i = 0; i < HID / TPB; ++i) {
                        bf16 xq = __float2bfloat16(0.5f * b2f(rb[i]) + 0.5f * b2f(hb[i]));
                        if (b == 0) A.xb[i0 + i] = xq;
                        xr[i] = b2f(xq);
                    }
                } else {
                    const uint2 hq = *(const uint2*)(A.xb + (size_t)l * HID + i0);
                    const bf16* hb = (const bf16*)&hq;
#pragma unroll
                    for (int i = 0; i < HID / TPB; ++i) xr[i] = b2f(hb[i]);
                }
                float ss = 0.f;
#pragma unroll
                for (int i = 0; i < HID / TPB; ++i) ss += xr[i] * xr[i];
                ss = bsum(ss, shred, warp, lane);
                float sc = rsqrtf(ss * (1.0f / HID) + EPSV);
                const float4 gv = *(const float4*)(LW.nrm + i0);
                float4 nv;
                nv.x = xr[0] * sc * gv.x; nv.y = xr[1] * sc * gv.y;
                nv.z = xr[2] * sc * gv.z; nv.w = xr[3] * sc * gv.w;
                *(float4*)(shvec + i0) = nv;
                __syncthreads();
                float* qo = qo0 + (size_t)l * QKVR;
                pf_dot<4, TM1, 1>(v1, shvec, n1, lane, qo, NW);
                tail_dot<4, 1>(LW.wqkv + o1, s1, TM1, n1, shvec, lane, qo, NW);
                // stage 3's weights are wanted two barriers from now: issue the
                // whole window here so it lands during attention.
                pf_issue<2, 0, TM3>(v3, LW.wo + o3, s3, n3, lane);
            }
            TMARK(0);
            gbar(A.ctr, ph, nb);
            TMARK(8);

            // ---------------- stage 2: attention ----------------
            {
                const int P = pos + 1;
                const int p0 = (int)(((long)P * sidx) / nbh);
                const int p1 = (int)(((long)P * (sidx + 1)) / nbh);
                const bool haslast = (p1 == P);
                const int pend = haslast ? p1 - 1 : p1;
                const float* qkvl = A.qkvb + (size_t)l * QKVR;
                __syncthreads();
                if (warp < 4) {
                    const float* src;
                    const float* gw;
                    if (warp < 2) { src = qkvl + (2 * h_kv + warp) * HD; gw = LW.nrm + 2 * HID; }
                    else if (warp == 2) { src = qkvl + 2048 + h_kv * HD; gw = LW.nrm + 2 * HID + HD; }
                    else { src = qkvl + 3072 + h_kv * HD; gw = nullptr; }
                    float a0 = src[lane], a1 = src[lane + 32], a2 = src[lane + 64], a3 = src[lane + 96];
                    if (warp < 3) {
                        float ss = wsum(a0 * a0 + a1 * a1 + a2 * a2 + a3 * a3);
                        float sc = rsqrtf(ss * (1.0f / HD) + EPSV);
                        a0 *= sc * gw[lane];      a1 *= sc * gw[lane + 32];
                        a2 *= sc * gw[lane + 64]; a3 *= sc * gw[lane + 96];
                        float c0 = shcos[lane], s0 = shsin[lane];
                        float c1 = shcos[lane + 32], s1 = shsin[lane + 32];
                        float o0 = a0 * c0 - a2 * s0, o2 = a0 * s0 + a2 * c0;
                        float o1 = a1 * c1 - a3 * s1, o3 = a1 * s1 + a3 * c1;
                        a0 = o0; a1 = o1; a2 = o2; a3 = o3;
                    }
                    if (warp < 2) {
                        float* d = shq + warp * HD;
                        d[lane] = a0; d[lane + 32] = a1; d[lane + 64] = a2; d[lane + 96] = a3;
                    } else {
                        int off = (warp == 2) ? 0 : HD;
                        bf16 q0 = __float2bfloat16(a0), q1 = __float2bfloat16(a1);
                        bf16 q2 = __float2bfloat16(a2), q3 = __float2bfloat16(a3);
                        float* d = shkv + off;
                        d[lane] = b2f(q0); d[lane + 32] = b2f(q1);
                        d[lane + 64] = b2f(q2); d[lane + 96] = b2f(q3);
                        if (haslast) {
                            bf16* kvp = LW.kv + ((size_t)h_kv * A.max_seq + pos) * 256 + off;
                            kvp[lane] = q0; kvp[lane + 32] = q1;
                            kvp[lane + 64] = q2; kvp[lane + 96] = q3;
                        }
                    }
                }
                __syncthreads();
                TMARK(5);

                const int ll = lane & 15, hf = lane >> 4;
                float qa[8], qb[8];
#pragma unroll
                for (int j = 0; j < 8; ++j) { qa[j] = shq[ll * 8 + j]; qb[j] = shq[HD + ll * 8 + j]; }
                float acc0[8], acc1[8];
#pragma unroll
                for (int j = 0; j < 8; ++j) { acc0[j] = 0.f; acc1[j] = 0.f; }
                float ls0 = 0.f, ls1 = 0.f;
                const float cb = LW.cb;
                const bf16* kvh = LW.kv + (size_t)h_kv * A.max_seq * 256;

                for (int base = p0 + warp * 2; base < pend; base += 2 * NW) {
                    const int p = base + hf;
                    const bool ok = (p < pend);
                    float d0 = 0.f, d1 = 0.f;
                    uint4 vv;
                    if (ok) {
                        const bf16* kp = kvh + (size_t)p * 256 + ll * 8;
                        uint4 kk = ld_first(kp);
                        vv = ld_first(kp + HD);
                        const bf16* kb = (const bf16*)&kk;
#pragma unroll
                        for (int j = 0; j < 8; ++j) {
                            float kf = b2f(kb[j]);
                            d0 = fmaf(qa[j], kf, d0);
                            d1 = fmaf(qb[j], kf, d1);
                        }
                    }
#pragma unroll
                    for (int o = 1; o < 16; o <<= 1) {
                        d0 += __shfl_xor_sync(0xffffffffu, d0, o);
                        d1 += __shfl_xor_sync(0xffffffffu, d1, o);
                    }
                    if (ok) {
                        float e0 = __expf(d0 * ASCALE - cb), e1 = __expf(d1 * ASCALE - cb);
                        ls0 += e0; ls1 += e1;
                        const bf16* vb = (const bf16*)&vv;
#pragma unroll
                        for (int j = 0; j < 8; ++j) {
                            float vf = b2f(vb[j]);
                            acc0[j] = fmaf(e0, vf, acc0[j]);
                            acc1[j] = fmaf(e1, vf, acc1[j]);
                        }
                    }
                }
                if (haslast && warp == 0 && hf == 0) {
                    float d0 = 0.f, d1 = 0.f;
#pragma unroll
                    for (int j = 0; j < 8; ++j) {
                        float kf = shkv[ll * 8 + j];
                        d0 = fmaf(qa[j], kf, d0);
                        d1 = fmaf(qb[j], kf, d1);
                    }
#pragma unroll
                    for (int o = 1; o < 16; o <<= 1) {
                        d0 += __shfl_xor_sync(0x0000ffffu, d0, o);
                        d1 += __shfl_xor_sync(0x0000ffffu, d1, o);
                    }
                    float e0 = __expf(d0 * ASCALE - cb), e1 = __expf(d1 * ASCALE - cb);
                    ls0 += e0; ls1 += e1;
#pragma unroll
                    for (int j = 0; j < 8; ++j) {
                        float vf = shkv[HD + ll * 8 + j];
                        acc0[j] = fmaf(e0, vf, acc0[j]);
                        acc1[j] = fmaf(e1, vf, acc1[j]);
                    }
                }
                // fold the two half-warps together
#pragma unroll
                for (int j = 0; j < 8; ++j) {
                    acc0[j] += __shfl_xor_sync(0xffffffffu, acc0[j], 16);
                    acc1[j] += __shfl_xor_sync(0xffffffffu, acc1[j], 16);
                }
                ls0 += __shfl_xor_sync(0xffffffffu, ls0, 16);
                ls1 += __shfl_xor_sync(0xffffffffu, ls1, 16);
                TMARK(6);
                __syncthreads();
                if (lane < 16) {
                    float* d0 = shacc + warp * HD;
                    float* d1 = shacc + NW * HD + warp * HD;
#pragma unroll
                    for (int j = 0; j < 8; ++j) { d0[lane * 8 + j] = acc0[j]; d1[lane * 8 + j] = acc1[j]; }
                    if (lane == 0) { shls[warp] = ls0; shls[NW + warp] = ls1; }
                }
                __syncthreads();
                // Publish straight into the shared accumulator with L2 atomics.
                // The obvious alternative -- park the partials, elect the last
                // arriver by atomic counter, have it gather nbh of them -- puts a
                // serial tail on the critical path of *every* block in the grid,
                // because the barrier below cannot clear until that one block has
                // done ~24 dependent strided loads: it cost 2.0 us of handshake
                // plus ~11 us of b2 (measured at ctx 8192) against 0.1 us here.
                // Only the nbh (~24) blocks of one kv head touch a given address,
                // so each of the 2048 floats sees ~24 adds, spread over 64 lines.
                if (tid < 2 * HD) {
                    const int qh = tid >> 7, d = tid & 127;
                    float s = 0.f;
#pragma unroll
                    for (int w = 0; w < NW; ++w) s += shacc[qh * NW * HD + w * HD + d];
                    float* ap = A.aout + (size_t)l * 2048 + (2 * h_kv + qh) * HD + d;
                    asm volatile("red.relaxed.gpu.global.add.f32 [%0], %1;"
                                 ::"l"(ap), "f"(s) : "memory");
                    if (d == 0) {
                        float t = 0.f;
#pragma unroll
                        for (int w = 0; w < NW; ++w) t += shls[qh * NW + w];
                        float* lp = A.alsum + (size_t)l * NQ + (2 * h_kv + qh);
                        asm volatile("red.relaxed.gpu.global.add.f32 [%0], %1;"
                                     ::"l"(lp), "f"(t) : "memory");
                    }
                }
                TMARK(7);
            }
            TMARK(1);
            gbar(A.ctr, ph, nb);
            TMARK(9);

            // ---------------- stage 3: o proj + residual ----------------
            {
                const float* ao = A.aout + (size_t)l * 2048;
                // softmax denominators, one per q head: the division the attention
                // stage used to do is deferred to here so its numerator can be a
                // plain atomic accumulation.  16 reciprocals per block, not 2048.
                if (tid < NQ) shls[tid] = 1.0f / A.alsum[(size_t)l * NQ + tid];
                __syncthreads();
                {   // one float4 per thread per 4*TPB chunk: each warp's request is
                    // 512 B contiguous (4 sectors), so 2 loads instead of 8 with no
                    // loss of coalescing.  A float4 never straddles a head (HD=128).
                    const int j0 = tid * 4;
#pragma unroll
                    for (int c = 0; c < 2048 / (4 * TPB); ++c) {
                        const int i = c * 4 * TPB + j0;
                        const float r = shls[i >> 7];
                        float4 t = *(const float4*)(ao + i);
                        t.x *= r; t.y *= r; t.z *= r; t.w *= r;
                        *(float4*)(shvec + i) = t;
                    }
                }
                __syncthreads();
                const float* sv3 = shvec + (warp & 3) * 512;
                pf_dot<2, TM3, 4>(v3, sv3, n3, lane, shpw, sps);
                tail_dot<2, 4>(LW.wo + o3, s3, TM3, n3, sv3, lane, shpw, sps);
                pf_issue<2, 0, PF4>(v4, LW.wgu + o4, s4, n4, lane);
                __syncthreads();
                const bf16* xs = A.xb + (size_t)l * HID;
                float* r2 = A.res2 + (size_t)l * HID;
                for (int rl = tid; rl < nr_h; rl += TPB)
                    r2[h_lo + rl] = b2f(xs[h_lo + rl]) + psum16(shp + rl * 16);
            }
            TMARK(2);
            gbar(A.ctr, ph, nb);
            TMARK(10);

            // ---------------- stage 4: post rmsnorm + gate/up ----------------
            {
                // the weight stream stays ahead of the activation read: hoisting the
                // res2 / norm-gain loads above pf_issue (they are on the critical
                // path, the weights are not wanted until after the block reduction)
                // costs 1.4 us/step -- 16 B of activation is not worth delaying
                // 224 B of weights, which have much further to travel.
                pf_issue<2, PF4, TM4>(v4, LW.wgu + o4, s4, n4, lane);
                const float* r2 = A.res2 + (size_t)l * HID;
                const int i0 = tid * (HID / TPB);
                const float4 rv = *(const float4*)(r2 + i0);
                float xr[HID / TPB];
                xr[0] = rv.x; xr[1] = rv.y; xr[2] = rv.z; xr[3] = rv.w;
                float ss = 0.f;
#pragma unroll
                for (int i = 0; i < HID / TPB; ++i) ss += xr[i] * xr[i];
                ss = bsum(ss, shred, warp, lane);
                float sc = rsqrtf(ss * (1.0f / HID) + EPSV);
                const float4 gv = *(const float4*)(LW.nrm + HID + i0);
                float4 nv;
                nv.x = xr[0] * sc * gv.x; nv.y = xr[1] * sc * gv.y;
                nv.z = xr[2] * sc * gv.z; nv.w = xr[3] * sc * gv.w;
                *(float4*)(shvec + i0) = nv;
                __syncthreads();
                const float* sv4 = shvec + (warp & 1) * 512;
                pf_dot<2, TM4, 4>(v4, sv4, n4, lane, shpw, sps);
                tail_dot<2, 4>(LW.wgu + o4, s4, TM4, n4, sv4, lane, shpw, sps);
                pf_issue<3, 0, TM5>(v5, LW.wd + o5, s5, n5, lane);
                __syncthreads();
                float* ac = A.actb + (size_t)l * INTER;
                for (int rl = tid; rl < nr_i; rl += TPB) {
                    // colgroup = 2*(gate|up) + column half, so 0..7 is the gate
                    // row and 8..15 the up row
                    float gv = psum8(shp + rl * 16), uv = psum8(shp + rl * 16 + 8);
                    ac[i_lo + rl] = (gv / (1.f + __expf(-gv))) * uv;
                }
            }
            TMARK(3);
            gbar(A.ctr, ph, nb);
            TMARK(11);

            // ---------------- stage 5: down + residual ----------------
            {
                const float* ac = A.actb + (size_t)l * INTER;
                __syncthreads();
                {   // 3 chunk-contiguous float4 loads instead of 12 scalars
                    const int j0 = tid * 4;
                    float4 a[INTER / (4 * TPB)];
#pragma unroll
                    for (int c = 0; c < INTER / (4 * TPB); ++c)
                        a[c] = *(const float4*)(ac + c * 4 * TPB + j0);
#pragma unroll
                    for (int c = 0; c < INTER / (4 * TPB); ++c)
                        *(float4*)(shvec + c * 4 * TPB + j0) = a[c];
                }
                __syncthreads();
                const float* sv5 = shvec + (warp & 3) * 768;
                pf_dot<3, TM5, 4>(v5, sv5, n5, lane, shpw, sps);
                tail_dot<3, 4>(LW.wd + o5, s5, TM5, n5, sv5, lane, shpw, sps);
                // next layer's qkv (wrapping to layer 0 for the next step)
                pf_issue<4, 0, PF1>(v1, A.L[l + 1 == nl ? 0 : l + 1].wqkv + o1, s1, n1, lane);
                __syncthreads();
                const float* r2 = A.res2 + (size_t)l * HID;
                bf16* xo = A.xb + (size_t)(l + 1) * HID;
                for (int rl = tid; rl < nr_h; rl += TPB)
                    xo[h_lo + rl] = __float2bfloat16(r2[h_lo + rl] + psum16(shp + rl * 16));
            }
            TMARK(4);
            gbar(A.ctr, ph, nb);
            TMARK(12);
        }
    }
    if (b == 0) {
        const bf16* hs = A.xb + (size_t)nl * HID;
        for (int i = tid; i < HID; i += TPB) A.hout[i] = hs[i];
    }
}

// ------------------------------------------------------------------- host
static const size_t W_QKV = (size_t)QKVR * HID;
static const size_t W_O = (size_t)HID * 2048;
static const size_t W_GU = (size_t)6144 * HID;
static const size_t W_D = (size_t)HID * INTER;
static const size_t W_LAYER = W_QKV + W_O + W_GU + W_D;

std::vector<int64_t> scratch_sizes(int64_t nlayer, int64_t smax) {
    int64_t nf = nlayer * (QKVR + NQ + 2048 + HID + INTER);
    int64_t nb16 = (nlayer + 1) * HID;
    int64_t nc = FLAGN;   // one grid-barrier counter; the attention combine is
                          // atomic now, so it needs no per-head handshake slot
    return {nf, nb16, nc};
}

int64_t ctx_create(std::vector<torch::Tensor> t, std::vector<int64_t> ii,
                   std::vector<double> ff) {
    Args* a = new Args();
    const int nl = (int)ii[0];
    a->nlayer = nl;
    a->max_seq = (int)ii[1];
    a->smax = (int)ii[2];
    const bf16* wp = (const bf16*)t[0].data_ptr();
    const float* np = (const float*)t[1].data_ptr();
    for (int l = 0; l < nl; ++l) {
        size_t o = (size_t)l * W_LAYER;
        a->L[l].wqkv = wp + o;
        a->L[l].wo = wp + o + W_QKV;
        a->L[l].wgu = wp + o + W_QKV + W_O;
        a->L[l].wd = wp + o + W_QKV + W_O + W_GU;
        a->L[l].nrm = np + (size_t)l * (2 * HID + 2 * HD);
        a->L[l].kv = (bf16*)t[4 + l].data_ptr();
        a->L[l].cb = (float)ff[l];
    }
    a->rinv = (const float*)t[2].data_ptr();
    float* sf = (float*)t[3].data_ptr();
    size_t off = 0;
    a->qkvb = sf; off += (size_t)nl * QKVR;
    a->alsum = sf + off; off += (size_t)nl * NQ;
    a->aout = sf + off; off += (size_t)nl * 2048;
    a->res2 = sf + off; off += (size_t)nl * HID;
    a->actb = sf + off;
    a->xb = (bf16*)t[4 + nl].data_ptr();
    a->ctr = (unsigned*)t[5 + nl].data_ptr();
    return (int64_t)a;
}

// Pin as much of the weight pack in L2 as the set-aside allows.  The pack is
// 125.8 MB and re-read in full every single decode step, so every byte that
// stays resident is a byte of DRAM traffic saved per step; the KV stream is
// loaded with .cs so it cannot evict what we pinned.
//
// Two details the standalone probe (dev/l2s.cu, the ctx-2048 byte mix) says
// matter, both of which the obvious spelling gets wrong:
//   * the window must be an 80 MB *subset* of the pack at hitRatio 1.0, not the
//     whole pack at hitRatio 80/126.  The ratio is a per-line lottery and the
//     losers stay evictable: 44.0 vs 46.8 us.
//   * missProp must be Normal.  Streaming marks the un-pinned remainder
//     evict-first, and it is still re-read every step: 49.4 vs 44.7 us.
// SM120 also refuses .L2::evict_last/evict_first on anything narrower than a
// 32 B load (.v8.b32/.v4.b64) and has no .L2::no_allocate for ld at all, so the
// stream policy window is the only lever available at this load width.
//
// And yet: correctly spelled, it does *nothing* for this kernel.  Sweeping the
// set-aside in situ is flat at every graded context (frac 0 vs 1, interleaved:
// 88.63/88.70 at ctx 2048, 155.30/155.37 at 8192, 417.64/417.75 at 32768), and
// so is the same window applied inside the dev harness over its own cudaMalloc,
// which rules out the plumbing (off/80/64/40 MB: 86.0/86.7/86.6/86.5 at 2048,
// 414.3/410.6/413.4/413.8 at 32768).  The probe only gains because its working
// set is 1.25x L2, where replacement policy decides everything; here ctx 2048 and
// 8192 are barrier-bound rather than DRAM-bound, and by ctx 32768 the 80 MB that
// can be pinned is only ~12% of the step's DRAM traffic.  So this is left off by
// default -- kept, documented, and not worth a global device limit.
static void* g_pbase = nullptr;
static size_t g_pbytes = 0;
static float g_phit = 0.f;
static cudaStream_t g_pstream = nullptr;

static void apply_policy(cudaStream_t s) {
    if (g_pbase == nullptr) return;
    if (s == g_pstream) return;
    g_pstream = s;
    cudaStreamAttrValue v;
    memset(&v, 0, sizeof(v));
    v.accessPolicyWindow.base_ptr = g_pbase;
    v.accessPolicyWindow.num_bytes = g_pbytes;
    v.accessPolicyWindow.hitRatio = g_phit;
    v.accessPolicyWindow.hitProp = cudaAccessPropertyPersisting;
    v.accessPolicyWindow.missProp = cudaAccessPropertyNormal;
    cudaStreamSetAttribute(s, cudaStreamAttributeAccessPolicyWindow, &v);
}

std::vector<int64_t> set_persist(int64_t ptr, int64_t nbytes, double frac) {
    cudaDeviceProp prop;
    cudaGetDeviceProperties(&prop, 0);
    if (frac <= 0.0) {
        g_pbase = nullptr;
        g_pstream = nullptr;
        cudaDeviceSetLimit(cudaLimitPersistingL2CacheSize, 0);
        return {0, 0};
    }
    const size_t amax = (size_t)prop.persistingL2CacheMaxSize;
    size_t aside = (size_t)(prop.persistingL2CacheMaxSize * frac);
    if (aside > amax) aside = amax;
    cudaDeviceSetLimit(cudaLimitPersistingL2CacheSize, aside);
    // window = the front of the pack, exactly as large as the set-aside
    size_t win = (size_t)nbytes < aside ? (size_t)nbytes : aside;
    if (win > (size_t)prop.accessPolicyMaxWindowSize) win = prop.accessPolicyMaxWindowSize;
    g_pbase = (void*)ptr;
    g_pbytes = win;
    g_phit = 1.0f;
    g_pstream = nullptr;
    apply_policy(at::cuda::getCurrentCUDAStream());
    return {(int64_t)win, (int64_t)aside};
}

void run_mega(int64_t handle, int64_t start_pos, int64_t n_steps, int64_t rnd,
              int64_t hin, int64_t hout, int64_t nb, int64_t ph0) {
    Args* a = (Args*)handle;
    a->start_pos = (int)start_pos;
    a->n_steps = (int)n_steps;
    a->rnd = (const bf16*)rnd;
    a->hin = (const bf16*)hin;
    a->hout = (bf16*)hout;
    a->nb = (int)nb;
    a->ph0 = (unsigned)ph0;
    cudaStream_t s = at::cuda::getCurrentCUDAStream();
    apply_policy(s);
    mega<<<(int)nb, TPB, 0, s>>>(*a);
}

int64_t max_blocks() {
    int n = 0;
    cudaOccupancyMaxActiveBlocksPerMultiprocessor(&n, mega, TPB, 0);
    return (int64_t)n;
}
"""

_ext = None


def _get_ext():
    global _ext
    if _ext is None:
        cap = torch.cuda.get_device_capability(0)
        os.environ["TORCH_CUDA_ARCH_LIST"] = "%d.%d" % cap
        from torch.utils.cpp_extension import load_inline

        _ext = load_inline(
            name="megaqwen_decode_v1",
            cpp_sources=[_CPP],
            cuda_sources=[_CUDA],
            functions=[
                "ctx_create",
                "run_mega",
                "scratch_sizes",
                "max_blocks",
                "set_persist",
            ],
            extra_cflags=["-O3"],
            extra_cuda_cflags=["-O3", "-lineinfo"],
            verbose=False,
        )
    return _ext


# ----------------------------------------------------------------------------
# Model
# ----------------------------------------------------------------------------


class _Block(nn.Module):
    def __init__(self):
        super().__init__()
        H, I, D = HIDDEN, INTERMEDIATE, HEAD_DIM
        bf = torch.bfloat16
        self.input_ln = nn.Parameter(torch.ones(H, dtype=bf))
        self.q_proj = nn.Parameter(torch.zeros(NUM_Q * D, H, dtype=bf))
        self.k_proj = nn.Parameter(torch.zeros(NUM_KV * D, H, dtype=bf))
        self.v_proj = nn.Parameter(torch.zeros(NUM_KV * D, H, dtype=bf))
        self.q_norm = nn.Parameter(torch.ones(D, dtype=bf))
        self.k_norm = nn.Parameter(torch.ones(D, dtype=bf))
        self.o_proj = nn.Parameter(torch.zeros(H, NUM_Q * D, dtype=bf))
        self.post_ln = nn.Parameter(torch.ones(H, dtype=bf))
        self.gate_proj = nn.Parameter(torch.zeros(I, H, dtype=bf))
        self.up_proj = nn.Parameter(torch.zeros(I, H, dtype=bf))
        self.down_proj = nn.Parameter(torch.zeros(H, I, dtype=bf))


def _perm(w):
    """Permute columns inside each 256-wide chunk for conflict-free smem reads."""
    m, k = w.shape
    assert k % 256 == 0
    return w.reshape(m, k // 256, 8, 32).transpose(-1, -2).contiguous().reshape(m, k)


class Model(nn.Module):
    def __init__(self, num_layers: int = NUM_LAYERS, max_seq: int = 131072):
        super().__init__()
        self.num_layers = num_layers
        self.max_seq = max_seq
        self.blocks = nn.ModuleList([_Block() for _ in range(num_layers)])
        self._ctx = None
        self._store = None

    # any weight change invalidates the packed copy
    def load_state_dict(self, *a, **kw):
        self._ctx = None
        return super().load_state_dict(*a, **kw)

    def _apply(self, *a, **kw):
        self._ctx = None
        return super()._apply(*a, **kw)


def _ensure(model: Model):
    if model._ctx is not None:
        return model._store
    ext = _get_ext()
    dev = next(model.parameters()).device
    assert dev.type == "cuda", "solution requires CUDA weights"
    nl = model.num_layers
    props = torch.cuda.get_device_properties(dev)
    nb = int(os.environ.get("MQ_NB", props.multi_processor_count))
    assert ext.max_blocks() >= 1, "megakernel not resident"
    assert 32 <= nb <= 256
    smax = (nb + NUM_KV - 1) // NUM_KV

    st = model._store or {}
    # ---- packed weights: one contiguous 126 MB buffer (L2 resident) ----
    wparts, nparts, cbs = [], [], []
    for blk in model.blocks:
        wqkv = torch.cat([blk.q_proj.detach(), blk.k_proj.detach(), blk.v_proj.detach()], 0)
        wgu = torch.cat([blk.gate_proj.detach(), blk.up_proj.detach()], 0)
        for w in (wqkv, blk.o_proj.detach(), wgu, blk.down_proj.detach()):
            wparts.append(_perm(w).reshape(-1))
        nparts.append(
            torch.cat(
                [
                    blk.input_ln.detach().float(),
                    blk.post_ln.detach().float(),
                    blk.q_norm.detach().float(),
                    blk.k_norm.detach().float(),
                ]
            )
        )
        qm = blk.q_norm.detach().float().abs().max().item()
        km = blk.k_norm.detach().float().abs().max().item()
        cbs.append(min(math.sqrt(HEAD_DIM) * qm * km, 40.0))
    st["w"] = torch.cat(wparts)
    st["n"] = torch.cat(nparts)
    del wparts, nparts

    half = HEAD_DIM // 2
    st["rinv"] = 1.0 / (
        10000 ** (torch.arange(0, half, device=dev, dtype=torch.float32) / half)
    )

    nf, nb16, nc = [int(x) for x in ext.scratch_sizes(nl, smax)]
    st["sf"] = torch.zeros(nf, dtype=torch.float32, device=dev)
    st["xb"] = torch.zeros(nb16, dtype=torch.bfloat16, device=dev)
    st["ctr"] = torch.zeros(nc, dtype=torch.int32, device=dev)
    st["ph"] = 0
    if "kv" not in st:
        st["kv"] = [
            torch.zeros(NUM_KV, model.max_seq, 2 * HEAD_DIM, dtype=torch.bfloat16, device=dev)
            for _ in range(nl)
        ]
    if "cs" not in st:
        st["cs"] = torch.cuda.Stream(device=dev)
        st["ev"] = torch.cuda.Event()
    st["nb"] = nb
    st["dev"] = dev
    # measured neutral on this kernel at every graded context (see set_persist)
    frac = float(os.environ.get("MQ_PERSIST", 0.0))
    ext.set_persist(st["w"].data_ptr(), st["w"].numel() * 2, frac)
    tens = [st["w"], st["n"], st["rinv"], st["sf"]] + st["kv"] + [st["xb"], st["ctr"]]
    model._ctx = ext.ctx_create(tens, [nl, model.max_seq, smax], cbs)
    model._store = st
    return st


_NBUF = 2


def _bufs(st, n):
    """Ring of (pinned host, device, copy-done event) pairs of >= n rows."""
    b = st.get("bufs")
    if b is None or b[0][0].shape[0] < n:
        b = [
            (
                torch.empty(n, HIDDEN, dtype=torch.bfloat16, pin_memory=True),
                torch.empty(n, HIDDEN, dtype=torch.bfloat16, device=st["dev"]),
                torch.cuda.Event(),
            )
            for _ in range(_NBUF)
        ]
        st["bufs"] = b
    return b


@torch.no_grad()
def _run_steps(model, hidden, start_pos, n_steps, rseed):
    """n_steps fused decode steps.  The CPU RNG stream is generated in growing
    chunks and copied on a side stream so it overlaps with the megakernel."""
    ext = _get_ext()
    st = _ensure(model)
    nl = model.num_layers
    dev = st["dev"]
    g = torch.Generator(device="cpu")
    g.manual_seed(rseed)
    out = torch.empty(HIDDEN, dtype=torch.bfloat16, device=dev)
    hin_ptr = hidden.contiguous().data_ptr()

    CAP = 1024
    bufs = _bufs(st, min(n_steps, CAP))
    main = torch.cuda.current_stream(device=dev)
    cs, ev = st["cs"], st["ev"]

    done = 0
    chunk = 1
    ri = 0
    while done < n_steps:
        host, devr, hev = bufs[ri % _NBUF]
        ri += 1
        hev.synchronize()   # host rows: last copy out of them has completed
        cs.wait_stream(main)  # device rows: kernels still reading them are done
        room = min(CAP, n_steps - done)
        off = 0
        while off < room:
            n = min(chunk, room - off)
            host[off : off + n].normal_(generator=g)
            with torch.cuda.stream(cs):
                devr[off : off + n].copy_(host[off : off + n], non_blocking=True)
                ev.record(cs)
                hev.record(cs)
            main.wait_event(ev)
            ph0 = st["ph"]
            nbar = 5 * nl * n * st["nb"]
            if ph0 + nbar >= 2 ** 31:
                st["ctr"].zero_()
                ph0 = 0
            st["ph"] = ph0 + nbar
            ext.run_mega(
                model._ctx,
                start_pos + done + off,
                n,
                devr[off].data_ptr(),
                hin_ptr,
                out.data_ptr(),
                st["nb"],
                ph0,
            )
            hin_ptr = st["xb"].data_ptr() + nl * HIDDEN * 2
            off += n
            chunk = min(chunk * 4, CAP)
        done += room
    return out


def _seeded_hidden(seed: int, device) -> torch.Tensor:
    g = torch.Generator(device="cpu")
    g.manual_seed(seed)
    return torch.randn(HIDDEN, generator=g, dtype=torch.bfloat16).to(device)


@torch.no_grad()
def prefill(model: Model, ctx_len: int, seed: int, device=None):
    """Build a KV cache of length ctx_len. NOT timed."""
    st = _ensure(model)
    assert ctx_len <= model.max_seq
    h = _seeded_hidden(seed, st["dev"])
    if ctx_len > 0:
        h = _run_steps(model, h, 0, ctx_len, seed + 1)
    return h, st["kv"], st["kv"]


@torch.no_grad()
def decode_steps(model, hidden, k_caches, v_caches, start_pos, n_steps, seed):
    """Run n_steps decode steps starting at start_pos. TIMED."""
    if n_steps <= 0:
        return hidden, k_caches, v_caches
    h = _run_steps(model, hidden, start_pos, n_steps, seed + 2)
    return h, k_caches, v_caches


def run(ctx_len: int, n_decode: int, seed: int, model=None, max_seq=None) -> dict:
    device = torch.device("cuda:0")
    max_seq = max_seq or max(ctx_len + n_decode, 512)
    if model is None:
        model = Model(NUM_LAYERS, max_seq).to(device).eval()
    h, k_caches, v_caches = prefill(model, ctx_len, seed, device=device)
    h, k_caches, v_caches = decode_steps(
        model, h, k_caches, v_caches, start_pos=ctx_len, n_steps=n_decode, seed=seed
    )
    return {"last_hidden": h.detach(), "ctx_len": ctx_len, "decode_steps": n_decode}


def get_init_inputs():
    return [NUM_LAYERS, 131072]


def get_inputs():
    return []

20260725_023443_or-opus_anthropic_claude-opus-5_03_megaqwen_decode