Skip to main content

memra_engine/
model.rs

1//! Dense transformer model: loads GGUF weights to GPU (Stage-1: dequant→f32), runs the
2//! shared full-attention + SwiGLU forward graph. Arch-agnostic via ModelConfig; this path is
3//! exactly the dense-transformer graph (qwen3) and the full-attention layers of hybrids.
4
5use crate::{
6    Engine, QT_BF16, QT_F32, QT_F8_E4M3, QT_IQ3_S, QT_IQ4_XS, QT_NVFP4, QT_NVFP4_RP, QT_Q2_K,
7    QT_Q3_K, QT_Q4_0, QT_Q4_K, QT_Q5_K, QT_Q6_K, QT_Q8_0,
8};
9use memra_gguf::config::ModelConfig;
10use memra_gguf::source::{DiskExtent, GgufSource, TensorSource};
11use memra_gguf::{dequant, GgmlType, GgufFile};
12use cudarc::driver::CudaSlice;
13use std::collections::HashMap;
14
15/// RESIDENCY CENSUS (lane/fp8-decode-v1, 2026-08-05) — per-qtype tally of the 2D matmul weights
16/// that actually went resident, keyed by `QT_*`. The FP8-ST decode arm's whole claim is about
17/// WHICH container the checkpoint's projections end up in, and the two candidate containers
18/// differ in bytes (e4m3 1.0 B/w vs the Q8_0 re-encode 1.0625 B/w). Before this instrument the
19/// only evidence available was end-to-end tok/s, which cannot distinguish "the arm ran and was
20/// flat" from "the arm never engaged" — the exact ambiguity in this lane's first loadprobe pair.
21/// Slot = qtype index; `.0` = tensor count, `.1` = resident bytes.
22static RESIDENCY_CENSUS: [(std::sync::atomic::AtomicUsize, std::sync::atomic::AtomicU64); 16] = {
23    #[allow(clippy::declare_interior_mutable_const)]
24    const Z: (std::sync::atomic::AtomicUsize, std::sync::atomic::AtomicU64) =
25        (std::sync::atomic::AtomicUsize::new(0), std::sync::atomic::AtomicU64::new(0));
26    [Z; 16]
27};
28
29fn residency_census_note(qtype: i32, bytes: usize) {
30    use std::sync::atomic::Ordering::Relaxed;
31    if let Some(slot) = RESIDENCY_CENSUS.get(qtype as usize) {
32        slot.0.fetch_add(1, Relaxed);
33        slot.1.fetch_add(bytes as u64, Relaxed);
34    }
35}
36
37/// Human-readable residency census: one line per qtype that took at least one 2D weight, plus a
38/// total. Callers print it right after load — see `run-gen`'s `MEMRA_RESIDENCY_CENSUS=1`.
39pub fn residency_census_report() -> String {
40    use std::sync::atomic::Ordering::Relaxed;
41    let name = |q: usize| -> &'static str {
42        match q as i32 {
43            QT_Q8_0 => "Q8_0", QT_Q4_K => "Q4_K", QT_Q6_K => "Q6_K", QT_Q5_K => "Q5_K",
44            QT_Q3_K => "Q3_K", QT_IQ4_XS => "IQ4_XS", QT_IQ3_S => "IQ3_S", QT_NVFP4 => "NVFP4",
45            QT_F32 => "F32", QT_NVFP4_RP => "NVFP4_RP", QT_F8_E4M3 => "F8_E4M3",
46            QT_BF16 => "BF16", QT_Q4_0 => "Q4_0", QT_Q2_K => "Q2_K",
47            crate::QT_F8_E4M3_BLK => "F8_E4M3_BLK", _ => "?",
48        }
49    };
50    let mut out = String::from("residency census (2D matmul weights, resident container):\n");
51    let (mut tn, mut tb) = (0usize, 0u64);
52    for (q, slot) in RESIDENCY_CENSUS.iter().enumerate() {
53        let (n, b) = (slot.0.load(Relaxed), slot.1.load(Relaxed));
54        if n == 0 { continue; }
55        tn += n; tb += b;
56        out += &format!("  {:>9}: {:>4} tensors  {:>9.3} MiB\n", name(q), n,
57                        b as f64 / (1024.0 * 1024.0));
58    }
59    out += &format!("  {:>9}: {:>4} tensors  {:>9.3} MiB", "TOTAL", tn,
60                    tb as f64 / (1024.0 * 1024.0));
61    out
62}
63
64/// A weight tensor resident on GPU. Quantized weights stay in GGUF block bytes (`Quant`);
65/// small non-quant tensors (norms, sometimes embed/lm_head) are kept dequantized as f32 (`Float`).
66/// This keeps VRAM ~= on-disk quant size (fixes the f32-on-load OOM).
67pub enum GpuTensor {
68    Quant {
69        bytes: CudaSlice<u8>,
70        qtype: i32,
71        row_bytes: usize,
72        ne: Vec<u64>,
73        scale: f32,
74        /// SPLIT-PLANE walk-order repack (A6, 2026-07-04): NVFP4 matmul weights are repacked at
75        /// load into [quant plane out_f x in_f/64 x 32B][scale plane out_f x in_f/64 x 4B] — same
76        /// bytes, same total size, but a lane's per-group weight read becomes ONE 16B-aligned
77        /// LDG.128 + a dense 4B scale word instead of 5 scattered 4B LDGs at 36B stride (the "18B
78        /// straggle"). Every consumer kernel has an `_rp` twin (bit-identical: pure byte
79        /// permutation, same dot order). `rp=false` = original GGUF block layout (all other
80        /// dtypes, MoE-staged expert bytes, MEMRA_RP=0 escape).
81        rp: bool,
82        /// CUTLASS NVFP4 prefill operand (repacked B + swizzled SFB), built ALONGSIDE `bytes` at load
83        /// when MEMRA_FP4_CUTLASS is set. `bytes` stays raw GGUF so decode (MMVQ/dp4a) is untouched;
84        /// prefill (m>=128) reads this. Only ever Some for NVFP4 weights under cfg(memra_cutlass).
85        #[cfg(memra_cutlass)]
86        cutlass: Option<CutlassWeight>,
87        /// FP8-ACT PREFILL operand (MEMRA_PP_FP8=1, probe verdict 2026-07-08): the checkpoint's RAW
88        /// e4m3 bytes + per-tensor f32 weight_scale, stashed ALONGSIDE the Q8_0 re-encode for the
89        /// F8-E4M3-origin 2D projections (~1 B/w extra on those layers). `bytes` stays Q8_0 so
90        /// decode (dp4a/MMVQ) is untouched; only the m>=16 prefill dispatch (cuBLASLt FP8 TN,
91        /// fp8_ffi.rs) reads this. None unless the env is set at load (zero VRAM cost by default).
92        fp8: Option<Fp8Weight>,
93        /// Q4_0 SPLIT-PLANE MIRROR (2026-07-10, the 18B-straggle cure for decode): qs plane
94        /// [out_f x nblk x 16B] + d plane [out_f x nblk x 2B] built device-side at model load
95        /// (q4_0_split_rp_build) for decode-hot trunk weights. Raw `bytes` stay resident —
96        /// prefill (gemm/MMQ) and Stage-A read those; the m<=8 mmvq/batched/fused dispatch
97        /// reads this when present (`_rp` twins; microprobe m=1 1.34x, m=3 1.17x, bitwise).
98        /// None everywhere except where the arch-load hook opted in (VRAM cost = weight size).
99        rp4: Option<CudaSlice<u8>>,
100        /// BLOCK-128 WEIGHT-SCALE GRID for a NATIVE e4m3 resident weight (lane/fp8-blk128-decode,
101        /// 2026-08-05). `Some` iff `qtype == QT_F8_E4M3_BLK`, and then `bytes` are the checkpoint's
102        /// raw e4m3 codes ([out_f, in_f], row_bytes == in_f), `scale == 1.0`, and THIS is the only
103        /// dequant scale in the tensor — decode reads it in-kernel (`qmatvec_e4m3_blk_mmvq`),
104        /// prefill reads it in the per-block MMQ tile. Distinct from `fp8: Some(Fp8Weight { blk })`,
105        /// which is the MEMRA_PP_FP8 *stash*: a SECOND e4m3 copy carried alongside a Q8_0 slab.
106        /// Here there is one copy and `fp8` stays None.
107        blk: Option<Fp8BlockScales>,
108        /// FP16 DEQUANT MIRROR (MEMRA_PP_F16=1, probe 2026-07-26): row-major fp16 of a 2D Q8_0
109        /// projection, built device-side at load (f16_ffi::build_q8_f16). `bytes` stay Q8_0 so
110        /// decode is untouched; the m>=16 prefill dispatch (cuBLASLt FP16 TN, 611-687 TF vs
111        /// MMQ's ~200 TF class) reads this. None unless the env is set (VRAM = 2 B/w extra).
112        f16: Option<CudaSlice<u8>>,
113    },
114    Float {
115        data: CudaSlice<f32>,
116        ne: Vec<u64>,
117    },
118    /// BF16-RESIDENT full-precision matmul weight (MEMRA_FULL_PREC only). Holds the checkpoint's raw
119    /// bf16 bytes (`u8`, little-endian u16 pairs) — 2 B/w vs the 4 B/w a `Float` f32 materialization
120    /// would cost, so the 9B trunk stays ~18GB in VRAM instead of ~36GB. Consumed via dequant-on-use:
121    /// each matmul expands this to a transient f32 scratch and rides the SAME cuBLASLt f32 GEMV the
122    /// `Float` arm uses (bit-identical to a load-time bf16->f32 dequant, just deferred). Never a norm
123    /// (norms stay `Float` f32); never on a fast/GEMM/MMQ path (uses_q8_1_fast/gemm_supports = false).
124    FloatBf16 {
125        data: CudaSlice<u8>,
126        ne: Vec<u64>,
127    },
128}
129
130/// FP8-native prefill operand: raw checkpoint e4m3 codes `[out_f, in_f]` row-major (EXACT — the
131/// weight side of the FP8 GEMM does no re-quantization) + its weight scale(s). Per-tensor class:
132/// `scale` is the dequant scalar folded into the GEMM's scale pointer together with the per-batch
133/// activation scale, `blk == None`. Block-128 class (Qwen official FP8): `blk == Some` and
134/// `scale == 1.0` — see `Fp8BlockScales` for the resident layout contract.
135pub struct Fp8Weight {
136    pub bytes: CudaSlice<u8>,
137    pub scale: f32,
138    pub blk: Option<Fp8BlockScales>,
139}
140
141/// Device-resident block-128 weight-scale grid for an e4m3 operand (B1b, lane fp8st 2026-08-03).
142///
143/// STORAGE LAYOUT (the canonical device layout every future consumer builds from): a flat f32
144/// buffer in the CHECKPOINT'S on-disk order — row-major `[rows = ceil(out_f/128),
145/// cols = ceil(in_f/128)]`, so `scales[ob * cols + kb]` scales the 128x128 weight tile at
146/// output-block `ob`, input-block `kb` (uploaded verbatim from `memra_gguf::source::F8BlockGrid`,
147/// no permutation — one host decode, one htod). Rationale: (1) the per-block-dequant mmvq twin
148/// (qmatvec_e4m3_mmvq extension, DECISION.md B1) indexes `(o >> 7) * cols + (e >> 7)` — natural
149/// in this order; (2) for cuBLASLt BLK128x128 the weight `[out, in]` row-major is the TN GEMM's
150/// column-major `[k=in, n=out]` A operand, and this same linear order IS that view's column-major
151/// block grid with ld = cols(=kblk) — probe P1 (`probe/fp8_lt_blk_probe.cu`) verifies whether
152/// sm_120 accepts it directly; if Lt wants a different order, the reorder happens at the GEMM
153/// plan build, NOT here. NO KERNEL CONSUMES THIS YET: the loader keeps every block-128 tensor's
154/// decode/prefill on the Q8_0 re-encode until the consuming kernels land (try_fp8_gemm skips
155/// blk operands; the QT_F8_E4M3 one-copy arm rejects them). This struct's job is bytes+scales
156/// resident and correct.
157pub struct Fp8BlockScales {
158    pub scales: CudaSlice<f32>,
159    pub rows: usize, // ceil(out_f/128)
160    pub cols: usize, // ceil(in_f/128)
161}
162
163/// Host-side split-plane repack of NVFP4 GGUF block bytes (A6). Input: out_f rows of in_f/64
164/// 36-byte blocks ([4B UE4M3 scales][32B packed e2m1]). Output (same length): quant plane
165/// (out_f x nsb64 x 32B) followed by scale plane (out_f x nsb64 x 4B). Pure byte permutation.
166pub fn repack_nvfp4_split(bytes: &[u8], out_f: usize) -> Vec<u8> {
167    let row_bytes = bytes.len() / out_f;
168    let nsb64 = row_bytes / 36;
169    debug_assert_eq!(
170        row_bytes % 36,
171        0,
172        "NVFP4 row_bytes must be a multiple of 36"
173    );
174    let qplane = out_f * nsb64 * 32;
175    let mut rp = vec![0u8; bytes.len()];
176    for o in 0..out_f {
177        for s in 0..nsb64 {
178            let src = &bytes[o * row_bytes + s * 36..o * row_bytes + s * 36 + 36];
179            rp[qplane + (o * nsb64 + s) * 4..qplane + (o * nsb64 + s) * 4 + 4]
180                .copy_from_slice(&src[0..4]);
181            rp[(o * nsb64 + s) * 32..(o * nsb64 + s) * 32 + 32].copy_from_slice(&src[4..36]);
182        }
183    }
184    rp
185}
186
187/// Inverse of `repack_nvfp4_split` (the roundtrip gate).
188pub fn unpack_nvfp4_split(rp: &[u8], out_f: usize) -> Vec<u8> {
189    let row_bytes = rp.len() / out_f;
190    let nsb64 = row_bytes / 36;
191    let qplane = out_f * nsb64 * 32;
192    let mut back = vec![0u8; rp.len()];
193    for o in 0..out_f {
194        for s in 0..nsb64 {
195            back[o * row_bytes + s * 36..o * row_bytes + s * 36 + 4].copy_from_slice(
196                &rp[qplane + (o * nsb64 + s) * 4..qplane + (o * nsb64 + s) * 4 + 4],
197            );
198            back[o * row_bytes + s * 36 + 4..o * row_bytes + s * 36 + 36]
199                .copy_from_slice(&rp[(o * nsb64 + s) * 32..(o * nsb64 + s) * 32 + 32]);
200        }
201    }
202    back
203}
204
205/// A6 repack seam: default ON, `MEMRA_RP=0` restores the GGUF block layout everywhere (rollback/A-B).
206pub fn rp_enabled() -> bool {
207    static ON: std::sync::OnceLock<bool> = std::sync::OnceLock::new();
208    *ON.get_or_init(|| std::env::var("MEMRA_RP").map(|v| v != "0").unwrap_or(true))
209}
210
211/// FULL-PRECISION LOADER MODE (MEMRA_FULL_PREC=1, default OFF — MTP-heal research platform).
212/// Bypasses the standing loader law (large BF16/F8 -> Q8_0/NVFP4 re-encode, the "Float-poison"
213/// tripwire). Under this flag every weight loads as Float and compute rides the Stage-A f32 oracle
214/// path end to end — SLOW IS FINE, this mode exists for exactness (the MTP acceptance CEILING at
215/// full precision), not speed. Large 2D matmul weights stay bf16-resident (`GpuTensor::FloatBf16`)
216/// with dequant-on-use so the 9B (~18GB bf16) + f32 activations fit 24GB instead of blowing to
217/// ~38GB as an all-f32 materialization. The Float-poison tripwire warnings are CORRECT behavior
218/// here and are suppressed. See docs/FLAGS.md and HANDOVER "MEMRA DUAL-SHAPE".
219pub fn full_prec_enabled() -> bool {
220    static ON: std::sync::OnceLock<bool> = std::sync::OnceLock::new();
221    *ON.get_or_init(|| {
222        std::env::var("MEMRA_FULL_PREC")
223            .map(|v| v == "1")
224            .unwrap_or(false)
225    })
226}
227
228/// LOADER-LAW allowlist (loadersweep audit 2026-07-08): 2D Float tensors that are DELIBERATELY
229/// Float despite being matmul-class. Every entry needs an audit rationale — this list silences
230/// the tripwire below, so an unjustified entry re-opens the trap.
231///   * ffn_gate_inp (MoE router, 35B GGUF F32 [2048,256] / M3 ST F32 [6144,64]): the router's
232///     top-k SELECTION is discontinuous — quantizing shifts logits and flips expert choice (a
233///     class change, not an FP-order change). llama.cpp keeps every router F32 (its converter
234///     forces F32) so Float is bench-parity, it sits on NO all-or-nothing predicate, and the
235///     decode-exact contract is already built around its cuBLASLt path
236///     (hybrid_forward.rs moe_ffn_sequential_zq8 router comment).
237fn float_2d_audited(name: &str) -> bool {
238    name.ends_with("ffn_gate_inp.weight")
239}
240
241/// Once-per-name-pattern loader-law warning (`blk.{il}.` collapses to `blk.*.` so a 48-layer
242/// offender prints ONE line, not 48). See the call site in `load_from_source` for the law.
243fn warn_float_2d_once(name: &str, ne: &[u64], src_type: GgmlType) {
244    use std::sync::{Mutex, OnceLock};
245    static SEEN: OnceLock<Mutex<std::collections::HashSet<String>>> = OnceLock::new();
246    let pat = match name.strip_prefix("blk.").and_then(|r| r.split_once('.')) {
247        Some((_, suffix)) => format!("blk.*.{suffix}"),
248        None => name.to_string(),
249    };
250    let mut seen = SEEN
251        .get_or_init(|| Mutex::new(std::collections::HashSet::new()))
252        .lock()
253        .unwrap();
254    if seen.insert(pat.clone()) {
255        eprintln!(
256            "[loader-law] WARNING: {pat} loads as 2D Float ne={ne:?} (src {src_type:?}) — \
257                   a Float matmul weight rides cuBLAS f32 GEMV and poisons all-or-nothing q8-fast \
258                   predicates (uses_q8_1_fast/mixer_in_q8_1_fast). If matmul-class: Q8_0-encode at \
259                   load (model.rs ssm arm / source.rs BF16+F8 gates). If deliberately Float: add \
260                   it to float_2d_audited with the audit rationale."
261        );
262    }
263}
264
265/// CUTLASS-layout NVFP4 weight (B operand) for the prefill FP4 GEMM. Built once at load from the raw
266/// GGUF bytes (de-interleave + SFB swizzle). Coexists with the raw `bytes` (decode reads bytes).
267#[cfg(memra_cutlass)]
268pub struct CutlassWeight {
269    /// Plain K-contiguous packed e2m1, [out_f, in_f/2] bytes.
270    pub b_packed: CudaSlice<u8>,
271    /// Swizzled SFB (CUTLASS SfAtom layout), sized via cutlass_sfb_size(out_f, in_f).
272    pub sfb_swizzled: CudaSlice<u8>,
273}
274
275impl GpuTensor {
276    pub fn ne(&self) -> &[u64] {
277        match self {
278            GpuTensor::Quant { ne, .. } => ne,
279            GpuTensor::Float { ne, .. } => ne,
280            GpuTensor::FloatBf16 { ne, .. } => ne,
281        }
282    }
283    pub fn in_features(&self) -> usize {
284        self.ne()[0] as usize
285    }
286    pub fn out_features(&self) -> usize {
287        self.ne()[1] as usize
288    }
289    /// Per-tensor post-matmul macro-scale (NVFP4 carries scale != 1.0; all others -> 1.0, a no-op).
290    /// Used by the fused SwiGLU epilogue to fold the gate/up scale into one kernel.
291    pub fn scale(&self) -> f32 {
292        match self {
293            GpuTensor::Quant { scale, .. } => *scale,
294            GpuTensor::Float { .. } | GpuTensor::FloatBf16 { .. } => 1.0,
295        }
296    }
297
298    /// Load a tensor, keeping quant types packed and float types as f32. (GGUF entry point —
299    /// thin wrapper over the source-agnostic `load_from_source`; behavior is unchanged.)
300    pub fn load(e: &Engine, g: &GgufFile, name: &str) -> Result<Self, Box<dyn std::error::Error>> {
301        Self::load_from_source(e, &GgufSource(g), name)
302    }
303
304    /// Source-agnostic load: works from any `TensorSource` (GGUF or safetensors). The engine's
305    /// forward graph only ever asks for ggml-style names; the source maps them to its own layout.
306    ///
307    /// RESIDENCY CENSUS (lane/fp8-decode-v1, 2026-08-05): the wrapper tallies what each 2D
308    /// matmul weight ACTUALLY became — resident qtype + resident bytes — so the FP8-ST decode
309    /// arm's claim ("e4m3 stays native instead of paying the Q8_0-slab tax") is a measured
310    /// per-checkpoint fact rather than an assumption about the checkpoint's dtype mix. Read it
311    /// with `residency_census_report()`; zero cost when never read.
312    pub fn load_from_source(
313        e: &Engine,
314        src: &dyn TensorSource,
315        name: &str,
316    ) -> Result<Self, Box<dyn std::error::Error>> {
317        let t = Self::load_from_source_inner(e, src, name)?;
318        if let GpuTensor::Quant { qtype, bytes, ne, .. } = &t {
319            if ne.len() == 2 {
320                residency_census_note(*qtype, bytes.len());
321            }
322        }
323        Ok(t)
324    }
325
326    fn load_from_source_inner(
327        e: &Engine,
328        src: &dyn TensorSource,
329        name: &str,
330    ) -> Result<Self, Box<dyn std::error::Error>> {
331        // A1 DIRECT NVFP4 IMPORT (2026-07-04): a PLAIN modelopt/Reza NVFP4 weight from a
332        // safetensors source repacks straight into the A6 split-plane resident layout in ONE host
333        // pass (nvfp4_repack::repack_modelopt_to_split — the scale plane is the file's
334        // weight_scale bytes verbatim), never materializing the GGUF 36B-block intermediate.
335        // The GGUF hop remains only for MEMRA_ST_DIRECT=0 (rollback/A-B seam — byte-identical
336        // resident weights either way), MEMRA_RP=0, the hybrid V-reorder transforms, and the
337        // opt-in CUTLASS resident operand (which is built from raw GGUF-layout bytes).
338        let cutlass_wants_raw = cfg!(memra_cutlass) && std::env::var("MEMRA_FP4_CUTLASS").is_ok();
339        let st_direct = std::env::var("MEMRA_ST_DIRECT")
340            .map(|v| v != "0")
341            .unwrap_or(true);
342        if rp_enabled() && st_direct && !cutlass_wants_raw {
343            if let Some(nv) = src.find_nvfp4_native(name) {
344                if nv.in_f % 64 == 0 && nv.out_f > 0 {
345                    // Same post-matmul macro-scale sibling lookup as the GGUF-layout arm below.
346                    let stem = name.strip_suffix(".weight").unwrap_or(name);
347                    let scale = match src.find(&format!("{stem}.scale")) {
348                        Some(sv) => f32::from_le_bytes(sv.bytes[..4].try_into().unwrap()),
349                        None => 1.0,
350                    };
351                    let bytes =
352                        e.htod_bytes(&memra_gguf::nvfp4_repack::repack_modelopt_to_split(
353                            nv.wbytes, nv.wscale, nv.out_f, nv.in_f,
354                        ))?;
355                    return Ok(GpuTensor::Quant {
356                        bytes,
357                        qtype: QT_NVFP4,
358                        row_bytes: nv.in_f / 64 * 36,
359                        ne: vec![nv.in_f as u64, nv.out_f as u64],
360                        scale,
361                        rp: true,
362                        #[cfg(memra_cutlass)]
363                        cutlass: None,
364                        fp8: None, blk: None, f16: None,
365                        rp4: None,
366                    });
367                }
368            }
369        }
370        // E4M3-DIRECT (DEFAULT since lane/fp8-decode-v1 2026-08-05; MEMRA_ST_E4M3=0 rolls back to the
371        // Q8_0 slab. Introduced default-off by lane e4m3dec 2026-07-08): F8-E4M3-origin 2D projections keep
372        // the checkpoint's RAW e4m3 device bytes + per-tensor weight_scale as the ONE resident copy
373        // (QT_F8_E4M3) instead of the Q8_0 re-encode — decode dequants e4m3 in-kernel
374        // (qmatvec_e4m3_mmvq, the checkpoint's own precision, no lossy re-quant hop), prefill
375        // (m>=16) rides the cuBLASLt FP8 GEMM on the SAME bytes (try_fp8_gemm). Frees the Q8_0
376        // duplicate the MEMRA_PP_FP8 stash needed (~3.4GB on the NV-27B) — full FP8 prefill coverage
377        // with no VRAM budget. Placed BEFORE `find` so the host-side F8->Q8_0 re-encode is skipped
378        // entirely (faster load). in_f%32 is the q8_1 activation block gate (every F8 projection in
379        // the NV-27B satisfies it; a violator falls through to the Q8_0 arm unchanged).
380        // BLOCK-128 CLASS: served by its OWN qtype since lane/fp8-blk128-decode (2026-08-05) —
381        // see the second arm below. It must not enter the per-tensor arm: the QT_F8_E4M3 kernel
382        // family consumes ONE scalar weight scale, so a block-128 operand through it would
383        // silently dequant every tile at scale 1.0.
384        if crate::fp8_ffi::st_e4m3_enabled() {
385            if let Some(f8) = src.find_fp8_native(name) {
386                if f8.blk.is_none() && f8.in_f % 32 == 0 && f8.out_f > 0 {
387                    return Ok(GpuTensor::Quant {
388                        bytes: e.htod_bytes(&f8.bytes)?,
389                        qtype: crate::QT_F8_E4M3,
390                        row_bytes: f8.in_f,
391                        ne: vec![f8.in_f as u64, f8.out_f as u64],
392                        scale: f8.scale,
393                        rp: false,
394                        #[cfg(memra_cutlass)]
395                        cutlass: None,
396                        fp8: None, blk: None, f16: None,
397                        rp4: None,
398                    });
399                }
400            }
401        }
402        // E4M3-BLK-DIRECT (lane/fp8-blk128-decode, 2026-08-05) — the block-128 twin of the arm
403        // above, and the Qwen-3.8 day-one path. A block-128 FP8 checkpoint (Qwen3.6-FP8's
404        // `weight_block_size [128,128]`, the DeepSeek-V3 lineage) keeps its RAW e4m3 codes plus its
405        // [ceil(out/128), ceil(in/128)] f32 scale grid as the ONE resident copy (QT_F8_E4M3_BLK)
406        // instead of the ARM B' Q8_0 slab: decode dequants per k128 block in-kernel
407        // (qmatvec_e4m3_blk_mmvq — the checkpoint's own precision, no lossy re-quant hop) at
408        // 1.0 B/weight instead of 1.0625, and prefill (m>=16) rides the per-block FP8 MMQ tile on
409        // the SAME bytes+grid (try_fp8_blk_mmq) with NO stash duplicate.
410        //
411        // ORDERING / DISJOINTNESS (the decode-v1 landmine, restated for this arm): the three FP8
412        // arms are mutually exclusive by their scale class, checked in this order —
413        //   1. `blk.is_none()`          -> QT_F8_E4M3      (per-tensor scalar; arm above)
414        //   2. `blk.is_some()` + native -> QT_F8_E4M3_BLK  (this arm)
415        //   3. `blk.is_some()`          -> ARM B' Q8_0 slab (MEMRA_FP8_BLK_GPU) / host re-encode
416        // so ARM B' KEEPS working wherever it is still the path: whenever this arm declines (env
417        // rollback, NaN codes present, ragged in_f, grid-shape mismatch) control falls through to
418        // it unchanged. It is not cross-gated on this arm's flag — a tensor this arm CLAIMS
419        // returns here and never reaches ARM B' at all, and one it declines must reach it.
420        //
421        // NaN PRECONDITION, enforced at LOAD (not asserted): the decode kernel decodes e4m3 with
422        // the HARDWARE intrinsic (magnitude 0x7F -> NaN) while the ARM B'/host reference decodes
423        // it to 0.0 (modelopt). A tensor carrying 0x7F/0xFF therefore cannot ride this kernel, so
424        // the bytes are scanned once on the device (fp8_blk_nan_count, the same precondition the
425        // prefill MMQ arm uses) and a non-zero count declines to the Q8_0 floor for THAT tensor.
426        // Real Qwen FP8 checkpoints carry none (the exporter saturates at +-448), so this is a
427        // guard, not a cost centre: one linear pass over bytes already on the device.
428        if crate::fp8_ffi::st_e4m3_blk_enabled() {
429            if let Some(f8) = src.find_fp8_native(name) {
430                if let Some(grid) = f8.blk.as_ref() {
431                    let (in_f, out_f) = (f8.in_f, f8.out_f);
432                    // in_f % 32: the q8_1 activation block gate (and the kernel's 2x LDG.128 line).
433                    // The grid dims must match the shape — a mismatch means operand and grid came
434                    // from different tensors; refuse rather than index a wrong block. scale == 1.0
435                    // is the block class's identity (source.rs sets it alongside a grid); anything
436                    // else would be a second, unapplied factor.
437                    if in_f % 32 == 0 && out_f > 0
438                        && f8.bytes.len() == out_f * in_f
439                        && grid.rows == out_f.div_ceil(128)
440                        && grid.cols == in_f.div_ceil(128)
441                        && grid.scales.len() == grid.rows * grid.cols
442                        && f8.scale == 1.0
443                    {
444                        let bytes = e.htod_bytes(&f8.bytes)?;
445                        if e.fp8_blk_nan_count(&bytes)? == 0 {
446                            let scales = e.htod(&grid.scales)?;
447                            return Ok(GpuTensor::Quant {
448                                bytes,
449                                qtype: crate::QT_F8_E4M3_BLK,
450                                row_bytes: in_f,
451                                ne: vec![in_f as u64, out_f as u64],
452                                scale: 1.0,
453                                rp: false,
454                                #[cfg(memra_cutlass)]
455                                cutlass: None,
456                                fp8: None,
457                                blk: Some(Fp8BlockScales {
458                                    scales,
459                                    rows: grid.rows,
460                                    cols: grid.cols,
461                                }),
462                                f16: None,
463                                rp4: None,
464                            });
465                        }
466                        crate::fp8_ffi::note_blk_native_nan_refused();
467                    }
468                }
469            }
470        }
471        // ARM B' — GPU BLOCK-128 DEQUANT (MEMRA_FP8_BLK_GPU=1, default OFF; lane fp8-gemm-arm
472        // 2026-08-03). A block-128 FP8 checkpoint (Qwen official FP8 / DeepSeek-V3 lineage)
473        // currently loads via the host path: full f32 dequant of the tensor (f8_deq_f32) then a
474        // host Q8_0 re-encode (f32_to_q8_0) — correct, but a serial CPU pass over every byte of
475        // every projection. This arm does the same math on the GPU in ONE pass
476        // (cu/fp8_blk_dequant.cu): upload the raw e4m3 codes + the scale grid, write Q8_0
477        // blocks directly. BYTE-IDENTICAL to the host path (kernel-check [fp8-blk-gpu] arm
478        // asserts it on ragged and aligned shapes), so the resident tensor, the MMQ/MMVQ
479        // dispatch, and decode are all bit-for-bit unchanged — this is a LOAD-TIME
480        // optimization only, not a numeric config change.
481        //
482        // Placed BEFORE `find` for exactly the reason the MEMRA_ST_E4M3 arm above is: `find`
483        // would otherwise do the host dequant+re-encode we are replacing. Per-tensor and
484        // per-row scale classes are NOT touched (find_fp8_native returns blk=None / None for
485        // them) and neither are V-reorder Transform targets (find_fp8_native rejects those with
486        // a grid — the permutation invalidates the on-disk grid, so they keep the host path).
487        //
488        // NO st_e4m3 EXCLUSION (lane/fp8-decode-v1 2026-08-05): this arm used to carry
489        // `&& !st_e4m3_enabled()`, written when MEMRA_ST_E4M3 was default OFF and meant only as
490        // "the native arm above already claimed this tensor". Once native residency became the
491        // DEFAULT that condition would have been true on every run and silently disabled ARM B'
492        // for the whole block-128 class — the exact silent-slow-path landmine the flags doctrine
493        // forbids. The two arms are already disjoint by construction and need no cross-gate: the
494        // arm above returns only when `f8.blk.is_none()`, this one runs only when `f8.blk` is
495        // Some, so a tensor that reaches here was never eligible for native residency.
496        if crate::fp8_ffi::fp8_blk_gpu_enabled() {
497            if let Some(f8) = src.find_fp8_native(name) {
498                if let Some(grid) = f8.blk.as_ref() {
499                    let (in_f, out_f) = (f8.in_f, f8.out_f);
500                    if in_f % 32 == 0 && out_f > 0 && f8.bytes.len() == out_f * in_f {
501                        let bytes =
502                            e.fp8_blk_dequant_q8_0(&f8.bytes, &grid.scales, out_f, in_f)?;
503                        return Ok(GpuTensor::Quant {
504                            bytes,
505                            qtype: QT_Q8_0,
506                            row_bytes: in_f / 32 * 34,
507                            ne: vec![in_f as u64, out_f as u64],
508                            scale: 1.0,
509                            rp: false,
510                            #[cfg(memra_cutlass)]
511                            cutlass: None,
512                            fp8: None, blk: None, f16: None,
513                            rp4: None,
514                        });
515                    }
516                }
517            }
518        }
519        let mut v = src
520            .find(name)
521            .unwrap_or_else(|| panic!("missing tensor {name}"));
522        // MEMRA_KQ_NVFP4=1 (opt-in, 2026-07-08): re-encode Q4_K/Q5_K 2D matmul weights to NVFP4 at
523        // load. The k-quant mmvq family runs at 61-70% of the bandwidth wall on this rig (measured
524        // BOTH engines — the kernels share ancestry) while the in-house NVFP4 path runs at 96%.
525        // The daily GGUF's quant mix was chosen for llama's kernels, not ours: Q4_K -> NVFP4 is
526        // 4-bit -> 4-bit at +26pp kernel efficiency; Q5_K -> NVFP4 also drops bytes (0.69 -> 0.56
527        // B/w) at a small real re-quant cost (5 -> 4 bit; gates + acceptance arbitrate). Q6_K/Q8_0
528        // excluded (6/8-bit -> 4-bit is a real quality cliff — the lm_head stays untouched).
529        // MEMRA_KQ_NVFP4 (opt-in SPEED-OVER-QUALITY mode, measured 2026-07-08 on the 9B):
530        // =2 (Q4_K+Q5_K -> NVFP4): +3.9% plain decode (129.5 -> 134.5, the Q5 bytes win),
531        //    acceptance tax ~3pts on hard content (p2 74.0 -> 70.7, p3 66.9 -> 64.9).
532        // =1 (Q4_K only): NO perf gain AND still ~3pts tax — Q4_K is ASYMMETRIC (6-bit
533        //    scale+min per 32); NVFP4 is symmetric e2m1: dropping the zero-point is real
534        //    error even 4-bit -> 4-bit. The "same bpw = same class" assumption is FALSE
535        //    across asymmetric/symmetric formats. Kept only for the record.
536        let kq = std::env::var("MEMRA_KQ_NVFP4")
537            .ok()
538            .and_then(|x| x.parse::<u8>().ok())
539            .unwrap_or(0);
540        if (kq >= 1 && v.ggml_type == GgmlType::Q4_K || kq >= 2 && v.ggml_type == GgmlType::Q5_K)
541            && v.ne.len() == 2
542            && v.ne[0] % 64 == 0
543            && !name.starts_with("output")
544        {
545            let n: u64 = v.ne.iter().product();
546            let f32v = dequant::dequantize(v.ggml_type, &v.bytes, n as usize);
547            let packed = memra_gguf::nvfp4_repack::f32_to_nvfp4(&f32v);
548            v = memra_gguf::source::TensorView {
549                bytes: std::borrow::Cow::Owned(packed),
550                ggml_type: GgmlType::NVFP4,
551                ne: v.ne.clone(),
552            };
553        }
554        let qtype = match v.ggml_type {
555            GgmlType::Q8_0 => Some(QT_Q8_0),
556            GgmlType::Q4_K => Some(QT_Q4_K),
557            GgmlType::Q6_K => Some(QT_Q6_K),
558            GgmlType::Q5_K => Some(QT_Q5_K),
559            GgmlType::Q3_K => Some(QT_Q3_K),
560            GgmlType::IQ4_XS => Some(QT_IQ4_XS),
561            GgmlType::IQ3_S => Some(QT_IQ3_S),
562            GgmlType::NVFP4 => Some(QT_NVFP4),
563            GgmlType::Q4_0 => Some(QT_Q4_0),
564            // F32/F16/BF16 (the dtypes safetensors carries) -> Float path below.
565            _ => None,
566        };
567        match qtype {
568            Some(qt) => {
569                let out_f = v.ne[1] as usize;
570                let row_bytes = v.bytes.len() / out_f;
571                // NVFP4 two-level scale: per-16 ue4m3 micro-scale is in the dequant; the per-tensor
572                // F32 macro-scale lives in a sibling "<stem>.scale" tensor, applied POST-matmul
573                // (llama build_lora_mm: ggml_mul(res, w_s)). ".input_scale" is the W4A4 activation
574                // scale — UNUSED on our W4A16/f32 path. Only NVFP4 carries it; others -> 1.0 (no-op).
575                let scale = if qt == QT_NVFP4 {
576                    let stem = name.strip_suffix(".weight").unwrap_or(name);
577                    match src.find(&format!("{stem}.scale")) {
578                        Some(sv) => f32::from_le_bytes(sv.bytes[..4].try_into().unwrap()),
579                        None => 1.0,
580                    }
581                } else {
582                    1.0
583                };
584                // A6 SPLIT-PLANE repack: NVFP4 2-D matmul weights upload in walk-order layout
585                // (host-side permutation before htod — zero VRAM spike, layer-streamed by
586                // construction). Every consumer kernel dispatches its `_rp` twin off the flag.
587                let rp = qt == QT_NVFP4
588                    && v.ne.len() == 2
589                    && (v.ne[0] as usize) % 64 == 0
590                    && v.bytes.len() % out_f == 0
591                    && (v.bytes.len() / out_f) % 36 == 0
592                    && rp_enabled();
593                let bytes = if rp {
594                    e.htod_bytes(&repack_nvfp4_split(&v.bytes, out_f))?
595                } else {
596                    e.htod_bytes(&v.bytes)?
597                };
598                // CUTLASS NVFP4 prefill operand, built from the RAW GGUF bytes (a temp raw upload
599                // when the resident `bytes` are repacked). Gated: only NVFP4 weights, only when
600                // MEMRA_FP4_CUTLASS is set, only under cfg(memra_cutlass). in_f%64==0 is the NVFP4
601                // K-block constraint (same as the dispatch).
602                #[cfg(memra_cutlass)]
603                let cutlass = {
604                    let in_f = v.ne[0] as usize;
605                    // Skip the resident repack when OTF is requested (per-call repack instead) — the
606                    // resident path ~doubles NVFP4 weight VRAM and OOMs larger models (e.g. 27B/24GB).
607                    if qt == QT_NVFP4
608                        && in_f % 64 == 0
609                        && v.ne.len() == 2
610                        && std::env::var("MEMRA_FP4_CUTLASS").is_ok()
611                        && std::env::var("MEMRA_FP4_CUTLASS_OTF").is_err()
612                    {
613                        let raw_dev;
614                        let src_dev = if rp {
615                            raw_dev = e.htod_bytes(&v.bytes)?;
616                            &raw_dev
617                        } else {
618                            &bytes
619                        };
620                        let (b_packed, sfb_swizzled) =
621                            e.build_cutlass_weight(src_dev, out_f, in_f, row_bytes)?;
622                        Some(CutlassWeight {
623                            b_packed,
624                            sfb_swizzled,
625                        })
626                    } else {
627                        None
628                    }
629                };
630                // FP8-ACT PREFILL operand (MEMRA_PP_FP8=1): for F8-E4M3-sourced projections (they
631                // surface as Q8_0 from the source's re-encode) ALSO stash the raw e4m3 device
632                // bytes + weight_scale. The source guarantees byte order matches `v` (the
633                // Transform arm's V-reorder is baked into both); the ne check guards a mixup.
634                // VRAM BUDGET (24GB rigs, 2026-07-08): the stash duplicates every F8-origin
635                // projection (~+3.4GB on the 27B) — fine on the 96GB box, OOM here. The stash
636                // spends from MEMRA_PP_FP8_BUDGET_MB (default 1536); once spent, remaining
637                // tensors ride the old path. Load order is layer order, so the budget covers a
638                // PREFIX of layers — coverage (and the prefill win) scales with the budget.
639                // MEMRA_FP8_MMQ=1 (lane/fp8-mmq) admits the SAME stash for the block-128 class:
640                // the per-block MMQ prefill kernel is that class's consumer, and it needs exactly
641                // what this arm makes resident (raw e4m3 bytes + the verbatim f32 grid). It shares
642                // the budget accounting below, so a 24GB rig still caps the duplicate.
643                // NOTE the gate here is `fp8_mmq_enabled` (the STASH gate, still opt-in) and NOT
644                // `fp8_blk_mmq_native_enabled` (default ON since 2026-08-05). That is deliberate:
645                // this arm's whole product is a DUPLICATE weight copy, and the native-resident route
646                // exists precisely to avoid one. A QT_F8_E4M3_BLK tensor already carries its own
647                // e4m3 bytes + grid, so it needs nothing from here; wiring the default-ON gate into
648                // this condition would spend the budget on copies no kernel reads.
649                let fp8 = if qt == QT_Q8_0
650                    && (crate::fp8_ffi::pp_fp8_enabled() || crate::fp8_ffi::fp8_mmq_enabled())
651                {
652                    match src.find_fp8_native(name) {
653                        Some(f8)
654                            if v.ne.len() == 2
655                                && f8.in_f as u64 == v.ne[0]
656                                && f8.out_f as u64 == v.ne[1] =>
657                        {
658                            use std::sync::atomic::{AtomicUsize, Ordering};
659                            static FP8_SPENT: AtomicUsize = AtomicUsize::new(0);
660                            static FP8_BUDGET: std::sync::OnceLock<usize> =
661                                std::sync::OnceLock::new();
662                            let budget = *FP8_BUDGET.get_or_init(|| {
663                                std::env::var("MEMRA_PP_FP8_BUDGET_MB")
664                                    .ok()
665                                    .and_then(|v| v.parse::<usize>().ok())
666                                    .unwrap_or(1536)
667                                    << 20
668                            });
669                            let sz = f8.bytes.len();
670                            if FP8_SPENT.fetch_add(sz, Ordering::Relaxed) + sz <= budget {
671                                // Block-128 grid rides along resident (checkpoint order,
672                                // Fp8BlockScales layout contract). try_fp8_gemm still skips blk
673                                // operands (cuBLASLt takes no block grid on sm_120, P1-VERDICT);
674                                // try_fp8_blk_mmq is their consumer under MEMRA_FP8_MMQ=1.
675                                let blk = match f8.blk {
676                                    Some(g) => Some(Fp8BlockScales {
677                                        scales: e.htod(&g.scales)?,
678                                        rows: g.rows,
679                                        cols: g.cols,
680                                    }),
681                                    None => None,
682                                };
683                                Some(Fp8Weight {
684                                    bytes: e.htod_bytes(&f8.bytes)?,
685                                    scale: f8.scale,
686                                    blk,
687                                })
688                            } else {
689                                FP8_SPENT.fetch_sub(sz, Ordering::Relaxed);
690                                None
691                            }
692                        }
693                        _ => None,
694                    }
695                } else {
696                    None
697                };
698                Ok(GpuTensor::Quant {
699                    bytes,
700                    qtype: qt,
701                    row_bytes,
702                    ne: v.ne.clone(),
703                    scale,
704                    rp,
705                    #[cfg(memra_cutlass)]
706                    cutlass,
707                    fp8,
708                    blk: None,
709                    rp4: None,
710                    f16: None,
711                })
712            }
713            None => {
714                let n: u64 = v.ne.iter().product();
715                // FULL-PRECISION MODE (MEMRA_FULL_PREC): NO re-encodes. Large 2D bf16 matmul weights
716                // stay bf16-resident (FloatBf16, dequant-on-use) so the trunk fits VRAM; everything
717                // else (small 2D, 1D norms, F16/F32) rides the exact f32 Float path below. The ssm
718                // Q8_0 re-encode and the Float-poison tripwire are BYPASSED here (both are the loader
719                // law this mode exists to suspend — the warnings would be correct but noise).
720                if full_prec_enabled() {
721                    // Only bf16 sources take the resident-bf16 arm; F16/F32 fall through to f32 Float
722                    // (exact, and tiny/absent in the bf16 ST checkpoints this mode targets). The 1M
723                    // threshold keeps small tensors (norms, gate_inp) on the proven f32 path — only
724                    // the big trunk matrices need the 2 B/w VRAM saving.
725                    if v.ggml_type == GgmlType::BF16 && v.ne.len() == 2 && n >= 1_000_000 {
726                        let data = e.htod_bytes(&v.bytes)?; // raw bf16 bytes, u16 LE pairs
727                        return Ok(GpuTensor::FloatBf16 {
728                            data,
729                            ne: v.ne.clone(),
730                        });
731                    }
732                    let f32v = dequant::dequantize(v.ggml_type, &v.bytes, n as usize);
733                    return Ok(GpuTensor::Float {
734                        data: e.htod(&f32v)?,
735                        ne: v.ne.clone(),
736                    });
737                }
738                let f32v = dequant::dequantize(v.ggml_type, &v.bytes, n as usize);
739                // ssm_beta/ssm_alpha stored F32 (the 35B GGUF): Q8_0-encode at load. F32 here
740                // fails `mixer_in_q8_1_fast` for the whole linear-attn mixer -> every linear
741                // layer falls off the fused norm+quantize chain onto cuBLAS f32 GEMV pairs
742                // (the NV-27B in_proj_a/b lesson, same all-or-nothing capability check; nsys
743                // 35B: 100 dot+reduce launches/token). Q8_0 of an F32 source is the same
744                // class-lossless step every 9B GGUF already ships for these tensors.
745                if v.ne.len() == 2
746                    && v.ne[0] % 32 == 0
747                    && (name.ends_with("ssm_beta.weight") || name.ends_with("ssm_alpha.weight")
748                        // E4B per_layer_model_proj (F16 [2560, 10752]): matmul-class — the
749                        // loader-law recipe (2026-07-12). As Float it rode cuBLAS f32 whose
750                        // m=1-vs-m=16 FP-order gap seeds inp_pl noise into EVERY layer's PLE
751                        // tail; the 42-layer stack amplifies it to logit maxdiff ~27 and the
752                        // chat-prompt prefill-vs-decode argmax gate fails.
753                        || name.ends_with("per_layer_model_proj.weight"))
754                {
755                    let q8 = memra_gguf::nvfp4_repack::f32_to_q8_0(&f32v);
756                    return GpuTensor::from_quant_bytes(
757                        e,
758                        &q8,
759                        GgmlType::Q8_0,
760                        v.ne[0],
761                        v.ne[1],
762                        1.0,
763                    );
764                }
765                // LOADER-LAW TRIPWIRE (loadersweep 2026-07-08): a 2D Float tensor with both dims
766                // >= 16 is almost certainly MATMUL-class, and a Float matmul weight (a) rides
767                // cuBLAS f32 GEMV pairs (dot_kernel + reduce_1Block in nsys) and (b) fails
768                // uses_q8_1_fast, poisoning every ALL-OR-NOTHING fast-path predicate it sits on
769                // (mixer_in_q8_1_fast etc.) — the trap that cost measurable perf 4 times (NV-27B
770                // in_proj_a/b BF16, 35B ssm_beta/alpha F32, M3 shexp cousin, M3 BF16 lm_head).
771                // Fix recipe: name-gated f32_to_q8_0 encode at load (see the ssm arm above /
772                // source.rs BF16+F8 gates). Norm-class tensors are 1D or have a dim < 16
773                // (conv1d ne[0]=4) and never reach this warning.
774                if v.ne.len() == 2 && v.ne[0] >= 16 && v.ne[1] >= 16 && !float_2d_audited(name) {
775                    warn_float_2d_once(name, &v.ne, v.ggml_type);
776                }
777                // F32/F16/BF16 (or as-yet-unhandled quant): dequant to f32. Small tensors only.
778                Ok(GpuTensor::Float {
779                    data: e.htod(&f32v)?,
780                    ne: v.ne.clone(),
781                })
782            }
783        }
784    }
785
786    /// Build a Quant tensor directly from raw ggml block bytes (FR-Spec self-trim: byte-level row
787    /// gather from an already-loaded weight — rows in every ggml quant are independent, so a
788    /// contiguous per-row byte copy is a lossless "trim"). `ne0` = in_features, `ne1` = rows.
789    pub fn from_quant_bytes(
790        e: &Engine,
791        bytes: &[u8],
792        ty: GgmlType,
793        ne0: u64,
794        ne1: u64,
795        scale: f32,
796    ) -> Result<Self, Box<dyn std::error::Error>> {
797        let qt = match ty {
798            GgmlType::Q8_0 => QT_Q8_0,
799            GgmlType::Q4_K => QT_Q4_K,
800            GgmlType::Q6_K => QT_Q6_K,
801            GgmlType::Q5_K => QT_Q5_K,
802            GgmlType::Q3_K => QT_Q3_K,
803            GgmlType::IQ4_XS => QT_IQ4_XS,
804            GgmlType::IQ3_S => QT_IQ3_S,
805            GgmlType::NVFP4 => QT_NVFP4,
806            GgmlType::Q4_0 => QT_Q4_0,
807            other => panic!("from_quant_bytes: unsupported dtype {other:?}"),
808        };
809        let row_bytes = bytes.len() / ne1 as usize;
810        // Same A6 repack as load_from_source: callers pass GGUF-layout host bytes (the FR-Spec
811        // self-trim row-gathers from the source file bytes, which are always original layout).
812        let rp = qt == QT_NVFP4 && ne0 % 64 == 0 && row_bytes % 36 == 0 && rp_enabled();
813        let dev = if rp {
814            e.htod_bytes(&repack_nvfp4_split(bytes, ne1 as usize))?
815        } else {
816            e.htod_bytes(bytes)?
817        };
818        Ok(GpuTensor::Quant {
819            bytes: dev,
820            qtype: qt,
821            row_bytes,
822            ne: vec![ne0, ne1],
823            scale,
824            rp,
825            #[cfg(memra_cutlass)]
826            cutlass: None,
827            fp8: None, blk: None, f16: None,
828            rp4: None,
829        })
830    }
831
832    pub fn load_opt(
833        e: &Engine,
834        g: &GgufFile,
835        name: &str,
836    ) -> Result<Option<Self>, Box<dyn std::error::Error>> {
837        Self::load_opt_from_source(e, &GgufSource(g), name)
838    }
839
840    pub fn load_opt_from_source(
841        e: &Engine,
842        src: &dyn TensorSource,
843        name: &str,
844    ) -> Result<Option<Self>, Box<dyn std::error::Error>> {
845        if src.has(name) {
846            Ok(Some(Self::load_from_source(e, src, name)?))
847        } else {
848            Ok(None)
849        }
850    }
851
852    /// Accessor for tensors that MUST be f32 (norm weights). Panics if quantized.
853    pub fn float_data(&self) -> &CudaSlice<f32> {
854        match self {
855            GpuTensor::Float { data, .. } => data,
856            GpuTensor::Quant { .. } => panic!("expected float tensor (norm), got quantized"),
857            GpuTensor::FloatBf16 { .. } => {
858                panic!("expected f32 float tensor (norm), got bf16-resident matmul weight")
859            }
860        }
861    }
862}
863
864pub struct Layer {
865    pub attn_norm: GpuTensor,
866    pub wq: GpuTensor,
867    pub wk: GpuTensor,
868    pub wv: GpuTensor,
869    pub wo: GpuTensor,
870    pub q_norm: Option<GpuTensor>,
871    pub k_norm: Option<GpuTensor>,
872    pub ffn_norm: GpuTensor,
873    /// FFN: dense SwiGLU or routed MoE (OLMoE — dense attention + MoE FFN). Reuses the hybrid
874    /// `Ffn` enum + `load_ffn` so the routed-expert forward is shared with `HybridModel::moe_ffn`.
875    pub ffn: crate::hybrid::Ffn,
876}
877
878/// Host-resident embedding table for row gather (dequant only the needed token rows).
879pub struct EmbedHost {
880    pub raw: Vec<u8>,
881    pub ggml_type: GgmlType,
882    pub n_embd: usize,
883}
884impl EmbedHost {
885    pub fn from_gguf(g: &GgufFile, name: &str) -> Self {
886        Self::from_source(&GgufSource(g), name)
887    }
888    pub fn from_source(src: &dyn TensorSource, name: &str) -> Self {
889        let v = src
890            .find(name)
891            .unwrap_or_else(|| panic!("missing embed {name}"));
892        EmbedHost {
893            raw: v.bytes.to_vec(),
894            ggml_type: v.ggml_type,
895            n_embd: v.ne[0] as usize,
896        }
897    }
898    /// QT int + row_bytes for this embed table's dtype (for the device embed-gather kernel).
899    /// CUDA-GRAPH-PLAN Phase 1. Mirrors the GpuTensor qtype mapping.
900    pub fn qt_and_row_bytes(&self, n_embd: usize) -> (i32, usize) {
901        let (blk, tsize) = self.ggml_type.block_and_type_size();
902        let row_bytes = (n_embd as u64 / blk * tsize) as usize;
903        let qt = match self.ggml_type {
904            GgmlType::Q8_0 => QT_Q8_0,
905            GgmlType::Q4_K => QT_Q4_K,
906            GgmlType::Q6_K => QT_Q6_K,
907            GgmlType::Q5_K => QT_Q5_K,
908            GgmlType::Q3_K => QT_Q3_K,
909            GgmlType::IQ4_XS => QT_IQ4_XS,
910            GgmlType::IQ3_S => QT_IQ3_S,
911            GgmlType::NVFP4 => QT_NVFP4,
912            GgmlType::F32 => QT_F32,
913            // BF16 embed table (FULL_PREC research mode: qwen35-9b-hf) — device gather does the
914            // exact bits<<16 expansion; 2 B/elem resident instead of an f32-doubled table.
915            GgmlType::BF16 => QT_BF16,
916            other => panic!("embed_gather: unsupported dtype {other:?}"),
917        };
918        (qt, row_bytes)
919    }
920
921    /// Gather rows for tokens -> [T, n_embd] f32. Dequant per-row from raw bytes.
922    pub fn gather(&self, n_embd: usize, tokens: &[u32]) -> Vec<f32> {
923        let (blk, tsize) = self.ggml_type.block_and_type_size();
924        let row_bytes = (n_embd as u64 / blk * tsize) as usize;
925        let mut x = vec![0f32; tokens.len() * n_embd];
926        for (ti, &tok) in tokens.iter().enumerate() {
927            let off = tok as usize * row_bytes;
928            let row = dequant::dequantize(self.ggml_type, &self.raw[off..off + row_bytes], n_embd);
929            x[ti * n_embd..ti * n_embd + n_embd].copy_from_slice(&row);
930        }
931        x
932    }
933}
934
935pub struct Model {
936    pub cfg: ModelConfig,
937    pub embd: EmbedHost,
938    pub output_norm: GpuTensor,
939    pub output: GpuTensor,
940    pub layers: Vec<Layer>,
941}
942
943impl Model {
944    /// Load a dense (vanilla-transformer) model from GGUF. Thin wrapper over
945    /// `load_dense_from_source`. Panics if the arch has SSM/MoE layers.
946    pub fn load_dense(e: &Engine, g: &GgufFile) -> Result<Self, Box<dyn std::error::Error>> {
947        Self::load_dense_from_source(e, &GgufSource(g))
948    }
949
950    /// Load a dense-attention model from any `TensorSource` — GGUF or a safetensors HF checkpoint.
951    /// The whole loop speaks ggml names; the source maps them. The FFN is dense SwiGLU OR routed MoE
952    /// (OLMoE: dense full-attention + MoE FFN). Panics on hybrid (SSM) arches — use the hybrid path.
953    pub fn load_dense_from_source(
954        e: &Engine,
955        src: &dyn TensorSource,
956    ) -> Result<Self, Box<dyn std::error::Error>> {
957        let cfg = src.config();
958        assert!(
959            cfg.full_attention_interval == 0,
960            "model has linear-attn layers; use hybrid path"
961        );
962        // FP8-KV per-model door: OFF everywhere by default (explicit MEMRA_KV_FP8 wins).
963        // The 2026-07-12 9B "+0.7-4% scaling with depth" did NOT reproduce on the
964        // 2026-07-28 build (12k A/B: fp8 117.0/118.2 vs q8 119.3/119.2 = −1%; d1736
965        // flat; the fa-v3/f16pv/PDL stack moved underneath it). Adoption reverted by
966        // measurement — fp8-KV's remaining value is bytes (~45% smaller KV) for
967        // ctx-limited serving, not speed. Gates all green under both formats.
968        crate::KV_FP8_FORCE.store(0, std::sync::atomic::Ordering::Relaxed);
969
970        let embd = EmbedHost::from_source(src, "token_embd.weight");
971        let output_norm = GpuTensor::load_from_source(e, src, "output_norm.weight")?;
972        // tied embeddings: fall back to tok_embd if output.weight absent (OLMoE has untied output).
973        let output = if src.has("output.weight") {
974            GpuTensor::load_from_source(e, src, "output.weight")?
975        } else {
976            GpuTensor::load_from_source(e, src, "token_embd.weight")?
977        };
978        let mut resident = crate::hybrid::ResidentPlan::unsharded(e, src, &cfg);
979
980        let mut layers = Vec::with_capacity(cfg.n_layer as usize);
981        for il in 0..cfg.n_layer {
982            let p = |s: &str| format!("blk.{il}.{s}");
983            let hy3_dense_ffn = cfg
984                .hy3
985                .as_ref()
986                .is_some_and(|h| il < h.first_k_dense_replace);
987            let ffn = if hy3_dense_ffn {
988                crate::hybrid::Ffn::Dense {
989                    ffn_gate: GpuTensor::load_from_source(e, src, &p("ffn_gate.weight"))?,
990                    ffn_up: GpuTensor::load_from_source(e, src, &p("ffn_up.weight"))?,
991                    ffn_down: GpuTensor::load_from_source(e, src, &p("ffn_down.weight"))?,
992                }
993            } else {
994                crate::hybrid::load_ffn(e, src, &cfg, il, None, &mut resident)?
995            };
996            layers.push(Layer {
997                attn_norm: GpuTensor::load_from_source(e, src, &p("attn_norm.weight"))?,
998                wq: GpuTensor::load_from_source(e, src, &p("attn_q.weight"))?,
999                wk: GpuTensor::load_from_source(e, src, &p("attn_k.weight"))?,
1000                wv: GpuTensor::load_from_source(e, src, &p("attn_v.weight"))?,
1001                wo: GpuTensor::load_from_source(e, src, &p("attn_output.weight"))?,
1002                q_norm: GpuTensor::load_opt_from_source(e, src, &p("attn_q_norm.weight"))?,
1003                k_norm: GpuTensor::load_opt_from_source(e, src, &p("attn_k_norm.weight"))?,
1004                ffn_norm: GpuTensor::load_from_source(e, src, &p("ffn_norm.weight"))?,
1005                ffn,
1006            });
1007        }
1008        Ok(Model {
1009            cfg,
1010            embd,
1011            output_norm,
1012            output,
1013            layers,
1014        })
1015    }
1016
1017    /// Largest expert block (bytes) across all MoE layers — the fixed cache-slot size (mirrors
1018    /// `HybridModel::max_moe_block`). 0 for a dense (non-MoE) model.
1019    pub(crate) fn max_moe_block(&self) -> usize {
1020        use crate::hybrid::Ffn;
1021        let mut mx = 0usize;
1022        for l in &self.layers {
1023            if let Ffn::Moe(m) = &l.ffn {
1024                mx = mx
1025                    .max(m.gate_exps.max_expert_bytes())
1026                    .max(m.up_exps.max_expert_bytes())
1027                    .max(m.down_exps.max_expert_bytes());
1028            }
1029        }
1030        mx
1031    }
1032
1033    /// Gather embedding rows into f32 [T, n_embd] (token-major) by dequantizing only the needed
1034    /// rows from the host-side embedding bytes (token_embd is [n_embd, n_vocab], row per token).
1035    pub fn embed_tokens(
1036        &self,
1037        e: &Engine,
1038        tokens: &[u32],
1039    ) -> Result<CudaSlice<f32>, Box<dyn std::error::Error>> {
1040        let n_embd = self.cfg.n_embd as usize;
1041        let x = self.embd.gather(n_embd, tokens);
1042        Ok(e.htod(&x)?)
1043    }
1044}
1045
1046pub type TensorMap = HashMap<String, GpuTensor>;
1047
1048/// One layer's stacked 256-expert tensor, raw GGUF quant bytes held HOST-RESIDENT.
1049///
1050/// EDGE-1: these bytes are NEVER uploaded at load (uploading 29.75GB would OOM a 24GB GPU —
1051/// this is BUG-4). Per token, only the 8 routed experts are staged H2D into a small GPU scratch.
1052///
1053/// ne = [in_f, out_f, n_expert]; the expert axis (ne[2]) is the slowest/highest-stride axis, so
1054/// expert `e` occupies the CONTIGUOUS byte block `bytes[e*expert_stride .. (e+1)*expert_stride]`.
1055///
1056/// THE 3D FIX: GpuTensor::load computes `row_bytes = raw.len()/ne[1]`, which for a stacked 3D
1057/// tensor ignores the 256-expert axis and is 256x too large (gate_exps -> 430080 instead of 1680).
1058/// load() here uses `row_bytes = raw.len() / (out_f * n_expert)` (= 1680 gate/up, 544 down).
1059/// Host byte storage for the expert blocks. Default = a pageable `Vec<u8>` (current behavior). Under
1060/// MEMRA_MOE_PINNED (auto-on when MEMRA_MOE_CACHE is set), the bytes live in CUDA pinned host memory so
1061/// the miss-path `memcpy_htod` is a true DMA, not a pageable bounce copy (MOE-SLRU-PLAN §C.1).
1062///
1063/// CAVEAT (§C.1): `alloc_pinned` uses CU_MEMHOSTALLOC_WRITECOMBINED — great for H2D-only (the expert
1064/// bytes are never read by the CPU on the hot path), but write-combined memory is SLOW for CPU reads.
1065/// A future CPU-VNNI cold-expert fallback must NOT read from this buffer.
1066pub enum HostBuf {
1067    Paged(Vec<u8>),
1068    /// Pinned host memory. We keep the `PinnedHostSlice` alive (it owns the allocation; Drop frees it)
1069    /// AND cache its raw base pointer + len so the hot-path `as_bytes()` needs no per-call event sync.
1070    Pinned {
1071        slice: std::sync::Arc<cudarc::driver::PinnedHostSlice<u8>>,
1072        base: *const u8,
1073        len: usize,
1074    },
1075    /// Alias into a shared pinned slab (ST pinned tier): `owner` keeps the slab alive; `base`/`len`
1076    /// select this expert's window. Same DMA class as `Pinned`.
1077    PinnedAlias {
1078        owner: std::sync::Arc<HostBuf>,
1079        base: *const u8,
1080        len: usize,
1081    },
1082    /// SPILLING-PLAN §1, Tier 2 (disk): the bytes live in an mmap'd region of the GGUF file, NOT in
1083    /// RAM. `map` is `MAP_SHARED`, no `MAP_POPULATE` — zero upfront copy. The first `memcpy_htod` of
1084    /// this slice page-faults → NVMe read → DMA (the demand-fault disk path). `off`/`len` select this
1085    /// expert's contiguous block within the shared file mmap. Bit-identical to `Paged`/`Pinned` —
1086    /// those copied FROM exactly these on-disk bytes, so the GEMM result is unchanged.
1087    Mmap {
1088        map: std::sync::Arc<memmap2::Mmap>,
1089        /// The same opened inode backing `map`. It must outlive the loader source so future explicit
1090        /// positioned reads cannot accidentally reopen a replaced path.
1091        file: std::sync::Arc<std::fs::File>,
1092        /// Absolute byte offset within both the whole-file mmap and `file`.
1093        off: usize,
1094        len: usize,
1095    },
1096}
1097// SAFETY: `base` is a stable pinned-host pointer owned by `slice`; the buffer is written once at load
1098// then only READ for H2D. HostExps is shared `&` across the (single per-Engine) forward, so Send/Sync
1099// mirror the underlying PinnedHostSlice (which is already Send+Sync). The `Mmap` arm holds
1100// `Arc<Mmap>` + `Arc<File>` (both Send+Sync) plus plain usize fields, so it does not weaken bounds.
1101unsafe impl Send for HostBuf {}
1102unsafe impl Sync for HostBuf {}
1103impl HostBuf {
1104    #[inline]
1105    pub fn as_bytes(&self) -> &[u8] {
1106        match self {
1107            HostBuf::Paged(v) => v.as_slice(),
1108            // SAFETY: base+len are the pinned allocation's stable extent; written once at load, then
1109            // read-only. We avoid `as_slice()` here because it would synchronize the buffer's event
1110            // on every hot-path call.
1111            HostBuf::Pinned { base, len, .. } => unsafe { std::slice::from_raw_parts(*base, *len) },
1112            HostBuf::PinnedAlias { base, len, .. } => unsafe {
1113                std::slice::from_raw_parts(*base, *len)
1114            },
1115            // Slicing the mmap is the same `&[u8]` the kernel DMAs; the read page-faults the NVMe.
1116            HostBuf::Mmap { map, off, len, .. } => &map[*off..*off + *len],
1117        }
1118    }
1119    #[inline]
1120    pub fn len(&self) -> usize {
1121        match self {
1122            HostBuf::Paged(v) => v.len(),
1123            HostBuf::Pinned { len, .. } => *len,
1124            HostBuf::PinnedAlias { len, .. } => *len,
1125            HostBuf::Mmap { len, .. } => *len,
1126        }
1127    }
1128
1129    /// Best-effort OS read-ahead for a future mmap-backed expert range. This does not touch or
1130    /// copy the bytes, so the zero-copy ownership contract is unchanged. Non-mmap buffers are
1131    /// already resident and need no advice. Kept fallible-at-the-OS but non-fatal at the call site:
1132    /// an unsupported/pressured kernel simply leaves the normal demand-fault path in place.
1133    #[inline]
1134    pub fn advise_willneed(&self, rel_off: usize, len: usize) -> bool {
1135        let HostBuf::Mmap {
1136            map,
1137            off,
1138            len: extent,
1139            ..
1140        } = self
1141        else {
1142            return false;
1143        };
1144        if len == 0 || rel_off > *extent || len > *extent - rel_off {
1145            return false;
1146        }
1147        #[cfg(unix)]
1148        {
1149            map.advise_range(memmap2::Advice::WillNeed, *off + rel_off, len)
1150                .is_ok()
1151        }
1152        #[cfg(not(unix))]
1153        {
1154            let _ = (map, off);
1155            false
1156        }
1157    }
1158
1159    #[inline]
1160    fn expert_source(&self, rel_off: usize, len: usize) -> ExpertSource<'_> {
1161        debug_assert!(rel_off <= self.len() && len <= self.len() - rel_off);
1162        match self {
1163            HostBuf::Mmap { map, file, off, .. } => {
1164                let offset = *off + rel_off;
1165                ExpertSource::Disk {
1166                    file,
1167                    offset: offset as u64,
1168                    len,
1169                    fallback: &map[offset..offset + len],
1170                    keepalive: ExpertKeepalive::Mmap(map.clone()),
1171                }
1172            }
1173            HostBuf::Pinned { slice, .. } => ExpertSource::Memory {
1174                bytes: &self.as_bytes()[rel_off..rel_off + len],
1175                keepalive: Some(ExpertKeepalive::Pinned(slice.clone())),
1176            },
1177            HostBuf::PinnedAlias { owner, .. } => ExpertSource::Memory {
1178                bytes: &self.as_bytes()[rel_off..rel_off + len],
1179                keepalive: Some(ExpertKeepalive::Buffer(owner.clone())),
1180            },
1181            HostBuf::Paged(_) => ExpertSource::Memory {
1182                bytes: &self.as_bytes()[rel_off..rel_off + len],
1183                // CUDA stages pageable input before returning from the async-copy API. Only true
1184                // pinned and mmap-backed sources need an explicit lifetime owner in the cache.
1185                keepalive: None,
1186            },
1187        }
1188    }
1189}
1190
1191/// Clonable ownership retained by asynchronous cache transfers. The payload is intentionally never
1192/// read: keeping it alive is the contract.
1193#[allow(dead_code)]
1194pub(crate) enum ExpertKeepalive {
1195    Pinned(std::sync::Arc<cudarc::driver::PinnedHostSlice<u8>>),
1196    Buffer(std::sync::Arc<HostBuf>),
1197    Mmap(std::sync::Arc<memmap2::Mmap>),
1198}
1199
1200/// Source-aware view of one expert block. The mmap fallback remains the byte oracle; retaining the
1201/// opened file enables a later explicit-read backend without changing tensor layout or numerics.
1202pub(crate) enum ExpertSource<'a> {
1203    Memory {
1204        bytes: &'a [u8],
1205        keepalive: Option<ExpertKeepalive>,
1206    },
1207    Disk {
1208        file: &'a std::sync::Arc<std::fs::File>,
1209        offset: u64,
1210        len: usize,
1211        fallback: &'a [u8],
1212        keepalive: ExpertKeepalive,
1213    },
1214}
1215
1216/// One layer's stacked 256-expert tensor, raw GGUF quant bytes held HOST-RESIDENT.
1217///
1218/// EDGE-1: these bytes are NEVER uploaded at load (uploading 29.75GB would OOM a 24GB GPU —
1219/// this is BUG-4). Per token, only the 8 routed experts are staged H2D into a small GPU scratch.
1220///
1221/// ne = [in_f, out_f, n_expert]; the expert axis (ne[2]) is the slowest/highest-stride axis, so
1222/// expert `e` occupies the CONTIGUOUS byte block `bytes[e*expert_stride .. (e+1)*expert_stride]`.
1223///
1224/// THE 3D FIX: GpuTensor::load computes `row_bytes = raw.len()/ne[1]`, which for a stacked 3D
1225/// tensor ignores the 256-expert axis and is 256x too large (gate_exps -> 430080 instead of 1680).
1226/// load() here uses `row_bytes = raw.len() / (out_f * n_expert)` (= 1680 gate/up, 544 down).
1227#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1228pub struct ExpertLayout {
1229    pub offset: usize,
1230    pub len: usize,
1231    pub qtype: i32,
1232    pub row_bytes: usize,
1233}
1234
1235fn staged_expert_qtype(ty: GgmlType) -> Option<i32> {
1236    Some(match ty {
1237        GgmlType::Q8_0 => QT_Q8_0,
1238        GgmlType::Q2_K => QT_Q2_K,
1239        GgmlType::Q4_K => QT_Q4_K,
1240        GgmlType::Q6_K => QT_Q6_K,
1241        GgmlType::Q5_K => QT_Q5_K,
1242        GgmlType::Q3_K => QT_Q3_K,
1243        GgmlType::IQ4_XS => QT_IQ4_XS,
1244        GgmlType::IQ3_S => QT_IQ3_S,
1245        GgmlType::NVFP4 => QT_NVFP4,
1246        GgmlType::F32 => QT_F32,
1247        GgmlType::BF16 => QT_BF16,
1248        _ => return None,
1249    })
1250}
1251
1252fn staged_expert_row_bytes(ty: GgmlType, in_f: usize) -> Option<usize> {
1253    staged_expert_qtype(ty)?;
1254    let (block, type_size) = ty.block_and_type_size();
1255    assert_eq!(
1256        in_f as u64 % block,
1257        0,
1258        "expert row width {in_f} is not divisible by {ty:?} block {block}"
1259    );
1260    Some((in_f as u64 / block * type_size) as usize)
1261}
1262
1263fn find_expert_disk_strict(
1264    src: &dyn TensorSource,
1265    name: &str,
1266) -> Result<Option<DiskExtent>, Box<dyn std::error::Error>> {
1267    if let Some(extent) = src.find_expert_disk(name) {
1268        return Ok(Some(extent));
1269    }
1270    if src.find_expert_mmap(name).is_some() {
1271        return Err(std::io::Error::new(
1272            std::io::ErrorKind::InvalidData,
1273            format!(
1274                "expert tensor {name} exposes legacy find_expert_mmap without find_expert_disk; \
1275                 disk-backed expert loading requires a retained Arc<File>"
1276            ),
1277        )
1278        .into());
1279    }
1280    Ok(None)
1281}
1282
1283pub struct HostExps {
1284    pub bytes: HostBuf, // raw GGUF block bytes (host); per-token DMA src for the 8 routed exps
1285    /// SPILLING-PLAN §1.1: per-expert backing tier. `None` => the layer fits in one `bytes` store and
1286    /// every expert slices it (the unchanged in-RAM path). `Some` => per-expert split: the hottest
1287    /// experts are `Pinned` (Tier 1, fast async DMA), the rest `Mmap` into the GGUF (Tier 2, disk
1288    /// demand-fault). `expert_bytes(e)` resolves `tiers[e]` if present, else slices `bytes`.
1289    pub tiers: Option<Vec<HostBuf>>,
1290    pub qtype: i32,           // QT_Q6_K (gate/up) | QT_Q8_0 (down)
1291    pub in_f: usize,          // ne[0]   (gate/up = 2048, down = 512)
1292    pub out_f: usize,         // ne[1]   (gate/up = 512,  down = 2048)
1293    pub n_expert: usize,      // ne[2] = 256
1294    pub row_bytes: usize,     // raw.len()/(out_f*n_expert)  -> 1680 (gate/up) / 544 (down)
1295    pub expert_stride: usize, // raw.len()/n_expert          -> 860160 (gate/up) / 1114112 (down)
1296    /// Per-expert encoding metadata when experts in this projection do not share one dtype/layout.
1297    /// `None` preserves the existing uniform slab contract and every resident/fused fast path.
1298    /// `Some` routes through the per-expert staged/cache path, using each entry's qtype/row size.
1299    pub layouts: Option<Vec<ExpertLayout>>,
1300    /// Per-expert post-matmul macro-scale (ModelOpt NVFP4 `weight_scale_2`, one scalar per expert
1301    /// tensor). `None` => all 1.0 (GGUF experts; block scales carry everything). The MoE forward
1302    /// folds gate/up macros into the activation epilogue (gs/us) and the down macro into the
1303    /// per-expert accumulate weight.
1304    pub macros: Option<Vec<f32>>,
1305}
1306
1307impl HostExps {
1308    /// Load a stacked 3D expert tensor, keeping its quant bytes on the HOST. `e` supplies the CUDA
1309    /// context for the optional pinned allocation (§C.1). Default storage is pageable `Vec<u8>`
1310    /// (identical to the prior behavior); pinned is chosen when MEMRA_MOE_PINNED or MEMRA_MOE_CACHE is set.
1311    pub fn load(e: &Engine, g: &GgufFile, name: &str) -> Result<Self, Box<dyn std::error::Error>> {
1312        Self::load_stacked_from_source(e, &GgufSource(g), name)
1313    }
1314
1315    /// Load a STACKED 3D expert tensor (`ne=[in_f,out_f,n_expert]`) from any source. GGUF stores the
1316    /// experts this way; the source returns the same mmap bytes (`GgufSource::find` == `tensor_data`),
1317    /// so the GGUF path is byte-identical to the prior direct-`GgufFile` loader. (Safetensors stores N
1318    /// 2D tensors instead — those go through `load_from_source`, which gathers them.)
1319    /// Row-range variant for FUSED stacked tensors (gemma4 ffn_gate_up_exps: gate = rows
1320    /// [0,ff), up = [ff,2ff) per expert — llama-graph view convention). Copies only the range.
1321    pub fn load_stacked_split_from_source(
1322        e: &Engine,
1323        src: &dyn TensorSource,
1324        name: &str,
1325        row0: usize,
1326        row1: usize,
1327    ) -> Result<Self, Box<dyn std::error::Error>> {
1328        let t = src
1329            .find(name)
1330            .unwrap_or_else(|| panic!("missing exps tensor {name}"));
1331        assert_eq!(t.ne.len(), 3, "{name} is not 3D (ne={:?})", t.ne);
1332        let qtype = match t.ggml_type {
1333            GgmlType::Q8_0 => QT_Q8_0,
1334            GgmlType::Q4_K => QT_Q4_K,
1335            GgmlType::Q6_K => QT_Q6_K,
1336            GgmlType::Q5_K => QT_Q5_K,
1337            GgmlType::Q3_K => QT_Q3_K,
1338            GgmlType::IQ4_XS => QT_IQ4_XS,
1339            GgmlType::IQ3_S => QT_IQ3_S,
1340            GgmlType::NVFP4 => QT_NVFP4,
1341            GgmlType::Q4_0 => QT_Q4_0,
1342            other => panic!("exps {name} unsupported quant {other:?}"),
1343        };
1344        let raw: &[u8] = &t.bytes;
1345        let in_f = t.ne[0] as usize;
1346        let out_full = t.ne[1] as usize;
1347        let n_expert = t.ne[2] as usize;
1348        let full_stride = raw.len() / n_expert;
1349        let row_bytes = raw.len() / (out_full * n_expert);
1350        assert_eq!(full_stride, out_full * row_bytes, "{name} stride mismatch");
1351        let out_f = row1 - row0;
1352        let expert_stride = out_f * row_bytes;
1353        let mut buf = vec![0u8; n_expert * expert_stride];
1354        for ex in 0..n_expert {
1355            let s0 = ex * full_stride + row0 * row_bytes;
1356            buf[ex * expert_stride..(ex + 1) * expert_stride]
1357                .copy_from_slice(&raw[s0..s0 + expert_stride]);
1358        }
1359        let pinned = std::env::var("MEMRA_MOE_PINNED").is_ok()
1360            || std::env::var("MEMRA_MOE_CACHE").as_deref() != Ok("0");
1361        let bytes = if pinned {
1362            let mut pn = unsafe { e.ctx().alloc_pinned::<u8>(buf.len())? };
1363            {
1364                let dst = pn.as_mut_slice()?;
1365                dst.copy_from_slice(&buf);
1366            }
1367            let base = pn.as_ptr()? as *const u8;
1368            let len = buf.len();
1369            HostBuf::Pinned {
1370                slice: std::sync::Arc::new(pn),
1371                base,
1372                len,
1373            }
1374        } else {
1375            HostBuf::Paged(buf)
1376        };
1377        Ok(HostExps {
1378            bytes,
1379            tiers: None,
1380            qtype,
1381            in_f,
1382            out_f,
1383            n_expert,
1384            row_bytes,
1385            expert_stride,
1386            layouts: None,
1387            macros: None,
1388        })
1389    }
1390
1391    /// Stacked per-expert macro-scale sidecar: `blk.N.ffn_{proj}_exps.scale` f32 [n_expert]
1392    /// (the qwen3.6 NVFP4 converter emits one per stacked expert tensor — compressed-tensors
1393    /// global scales, inverted to multipliers). Absent (every k-quant GGUF) => None.
1394    /// NOTE gemma4 consumes ffn_down_exps.scale through its OWN router-fold (Gemma4MoeBits) —
1395    /// its MoE forward does not read HostExps::macros, so a Some here is inert there.
1396    fn stacked_macros(src: &dyn TensorSource, name: &str) -> Option<Vec<f32>> {
1397        let stem = name.strip_suffix(".weight")?;
1398        let sv = src.find(&format!("{stem}.scale"))?;
1399        if sv.ggml_type != GgmlType::F32 { return None; }
1400        let macros: Vec<f32> = sv.bytes.chunks_exact(4)
1401            .map(|c| f32::from_le_bytes(c.try_into().unwrap())).collect();
1402        if macros.iter().all(|&m| m == 1.0) { None } else { Some(macros) }
1403    }
1404
1405    pub fn load_stacked_from_source(e: &Engine, src: &dyn TensorSource, name: &str)
1406                                    -> Result<Self, Box<dyn std::error::Error>> {
1407        let t = src.find(name).unwrap_or_else(|| panic!("missing exps tensor {name}"));
1408        assert_eq!(t.ne.len(), 3, "{name} is not a 3D stacked-expert tensor (ne={:?})", t.ne);
1409        // MMAP-BACKED SPILL TIER (Hy3 repack dir, 2026-07-09): when the source's on-disk layout IS
1410        // already the engine's expert layout (one expert-axis-slowest slab file per (layer, proj),
1411        // the transcoder's contract), back the HostExps with `HostBuf::Mmap` directly — ZERO host
1412        // copy. The default copy path below would pin/allocate the WHOLE stacked slab (80.5 GB for
1413        // Hy3-REAP50 on a 60 GB host = the M3 first-load OOM class); the mmap tier instead lets the
1414        // page cache carry the hot expert mass (RAM tier) and demand-faults the overflow from NVMe,
1415        // exactly like the proven M3 `.memra-repack` path (model.rs NVFP4 disk arm). Bit-identity:
1416        // `expert_bytes(e)` slices the same on-disk bytes the copy would have staged. The SLRU VRAM
1417        // cache stacks on top unchanged. The configured whole-map advice is applied at source open.
1418        if let Some(DiskExtent {
1419            map,
1420            file,
1421            offset,
1422            len,
1423        }) = find_expert_disk_strict(src, name)?
1424        {
1425            let off = usize::try_from(offset)
1426                .map_err(|_| format!("{name} disk offset {offset} does not fit usize"))?;
1427            let qtype = match t.ggml_type {
1428                GgmlType::Q8_0 => QT_Q8_0,
1429                GgmlType::Q4_K => QT_Q4_K,
1430                GgmlType::Q6_K => QT_Q6_K,
1431                GgmlType::Q5_K => QT_Q5_K,
1432                GgmlType::Q3_K => QT_Q3_K,
1433                GgmlType::IQ4_XS => QT_IQ4_XS,
1434                GgmlType::IQ3_S => QT_IQ3_S,
1435                GgmlType::NVFP4 => QT_NVFP4,
1436                GgmlType::Q4_0 => QT_Q4_0,
1437                other => panic!("exps {name} unsupported quant {other:?}"),
1438            };
1439            let in_f = t.ne[0] as usize;
1440            let out_f = t.ne[1] as usize;
1441            let n_expert = t.ne[2] as usize;
1442            let expert_stride = len / n_expert;
1443            let row_bytes = len / (out_f * n_expert);
1444            assert_eq!(expert_stride, out_f * row_bytes,
1445                "{name} stride mismatch: stride={expert_stride} out_f={out_f} row_bytes={row_bytes}");
1446            assert_eq!(
1447                len,
1448                n_expert * expert_stride,
1449                "{name} mmap len != n_expert*stride"
1450            );
1451            return Ok(HostExps {
1452                bytes: HostBuf::Mmap { map, file, off, len },
1453                tiers: None, qtype, in_f, out_f, n_expert, row_bytes, expert_stride,
1454                layouts: None, macros: Self::stacked_macros(src, name),
1455            });
1456        }
1457        let raw: &[u8] = &t.bytes;
1458        // All quant types the staged-expert qmatvec can decode (dp4a-fast or Stage-A f32).
1459        let qtype = match t.ggml_type {
1460            GgmlType::Q8_0 => QT_Q8_0,
1461            GgmlType::Q4_K => QT_Q4_K,
1462            GgmlType::Q6_K => QT_Q6_K,
1463            GgmlType::Q5_K => QT_Q5_K,
1464            GgmlType::Q3_K => QT_Q3_K,
1465            GgmlType::IQ4_XS => QT_IQ4_XS,
1466            GgmlType::IQ3_S => QT_IQ3_S,
1467            GgmlType::NVFP4 => QT_NVFP4,
1468            GgmlType::Q4_0 => QT_Q4_0,
1469            other => panic!("exps {name} unsupported quant {other:?}"),
1470        };
1471        let in_f = t.ne[0] as usize;
1472        let out_f = t.ne[1] as usize;
1473        let n_expert = t.ne[2] as usize;
1474        // VERIFIED: gate/up Q6_K total/256 = 860160; row = total/(512*256) = 1680.
1475        //           down  Q8_0 total/256 = 1114112; row = total/(2048*256) = 544.
1476        let expert_stride = raw.len() / n_expert;
1477        let row_bytes = raw.len() / (out_f * n_expert);
1478        // sanity: expert_stride must equal out_f * row_bytes exactly (catches a dim mixup)
1479        assert_eq!(
1480            expert_stride,
1481            out_f * row_bytes,
1482            "{name} stride mismatch: stride={expert_stride} out_f={out_f} row_bytes={row_bytes}"
1483        );
1484
1485        let pinned = std::env::var("MEMRA_MOE_PINNED").is_ok()
1486            || std::env::var("MEMRA_MOE_CACHE").as_deref() != Ok("0");
1487        let bytes = if pinned {
1488            // alloc pinned host memory, copy the GGUF block bytes in once, cache the base pointer.
1489            let mut p = unsafe { e.ctx().alloc_pinned::<u8>(raw.len())? };
1490            {
1491                let dst = p.as_mut_slice()?;
1492                dst.copy_from_slice(raw);
1493            }
1494            let base = p.as_ptr()? as *const u8; // syncs once here at load; stable afterward
1495            let len = raw.len();
1496            HostBuf::Pinned {
1497                slice: std::sync::Arc::new(p),
1498                base,
1499                len,
1500            }
1501        } else {
1502            HostBuf::Paged(raw.to_vec())
1503        };
1504        Ok(HostExps { bytes, tiers: None, qtype, in_f, out_f, n_expert, row_bytes,
1505                      expert_stride, layouts: None, macros: Self::stacked_macros(src, name) })
1506    }
1507
1508    /// SPILLING-PLAN §1.1, §2 step 4: load a stacked 3D expert tensor with a PER-EXPERT tier split.
1509    /// Under `MEMRA_SPILL_DISK`, the hottest experts (greedy in expert order, until the shared pinned
1510    /// budget in `ctx` is exhausted) get `HostBuf::Pinned` (Tier 1, fast async DMA); every remaining
1511    /// expert is `HostBuf::Mmap` into the GGUF (Tier 2, demand-faulted from disk on first H2D). The
1512    /// resulting bytes are bit-identical to the in-RAM path either way — `qmatvec_view` is untouched.
1513    ///
1514    /// `ctx.file_map` is ONE shared `MAP_SHARED` mmap of the whole GGUF (`Arc`-cloned per spilled
1515    /// expert), so the 120 expert tensors of a 40-layer MoE never open the file more than once.
1516    pub fn load_tiered(
1517        e: &Engine,
1518        g: &GgufFile,
1519        name: &str,
1520        ctx: &mut crate::spill::SpillCtx,
1521    ) -> Result<Self, Box<dyn std::error::Error>> {
1522        let t = g
1523            .find(name)
1524            .unwrap_or_else(|| panic!("missing exps tensor {name}"));
1525        assert_eq!(
1526            t.ne.len(),
1527            3,
1528            "{name} is not a 3D stacked-expert tensor (ne={:?})",
1529            t.ne
1530        );
1531        let raw = g.tensor_data(t);
1532        let qtype = match t.ggml_type {
1533            GgmlType::Q8_0 => QT_Q8_0,
1534            GgmlType::Q4_K => QT_Q4_K,
1535            GgmlType::Q6_K => QT_Q6_K,
1536            GgmlType::Q5_K => QT_Q5_K,
1537            GgmlType::Q3_K => QT_Q3_K,
1538            GgmlType::IQ4_XS => QT_IQ4_XS,
1539            GgmlType::IQ3_S => QT_IQ3_S,
1540            GgmlType::NVFP4 => QT_NVFP4,
1541            GgmlType::Q4_0 => QT_Q4_0,
1542            other => panic!("exps {name} unsupported quant {other:?}"),
1543        };
1544        let in_f = t.ne[0] as usize;
1545        let out_f = t.ne[1] as usize;
1546        let n_expert = t.ne[2] as usize;
1547        let expert_stride = raw.len() / n_expert;
1548        let row_bytes = raw.len() / (out_f * n_expert);
1549        assert_eq!(
1550            expert_stride,
1551            out_f * row_bytes,
1552            "{name} stride mismatch: stride={expert_stride} out_f={out_f} row_bytes={row_bytes}"
1553        );
1554
1555        // Byte offset of this tensor's data (start of expert 0) WITHIN ITS OWN SHARD's file; each
1556        // expert is the next `expert_stride` bytes. The `Mmap` arm slices `ctx.file_maps[t.shard]`
1557        // at these offsets — a split model's offsets are per-shard, not global.
1558        let (file_start, _file_end) = g.tensor_file_range(t);
1559
1560        // Per-expert tier decision under the shared running budget. `bytes` keeps a 0-byte sentinel
1561        // (`Paged(empty)`) since every read now goes through `tiers`.
1562        let mut tiers = Vec::with_capacity(n_expert);
1563        for ex in 0..n_expert {
1564            let blk = &raw[ex * expert_stride..(ex + 1) * expert_stride];
1565            let file_off = file_start + ex * expert_stride;
1566            tiers.push(crate::spill::place_expert(ctx, e, blk, file_off, t.shard)?);
1567        }
1568        Ok(HostExps {
1569            bytes: HostBuf::Paged(Vec::new()), // unused when `tiers` is Some
1570            tiers: Some(tiers),
1571            qtype, in_f, out_f, n_expert, row_bytes, expert_stride, layouts: None,
1572            macros: Self::stacked_macros(&GgufSource(g), name),
1573        })
1574    }
1575
1576    /// MoE expert GATHER from a `TensorSource` (the safetensors path; ST-MOE-PLAN §1.3). GGUF stacks
1577    /// all experts into ONE 3D tensor; HF stores them as N separate 2D tensors
1578    /// `model.layers.{il}.mlp.experts.{e}.{gate,up,down}_proj.weight`. `find` returns `None` for the
1579    /// ggml `*_exps` name on purpose, so the experts are gathered out-of-band here.
1580    ///
1581    /// PATH A (load-time only, no quantize): each HF 2D expert tensor is dequantized to f32 and the
1582    /// per-expert blocks are concatenated expert-axis-slowest into ONE contiguous buffer — exactly the
1583    /// layout `expert_bytes(e)` slices and the staged `qmatvec_view` (qtype=QT_F32) reads. The same
1584    /// `expert_stride == out_f*row_bytes` invariant as the GGUF path is asserted at the end.
1585    ///
1586    /// `ggml_exps_name` is `blk.{il}.ffn_{gate,up,down}_exps.weight`; it is split to recover `il` and
1587    /// the proj. `n_expert` comes from `cfg.moe`. The HF per-expert literal `mlp.experts.{e}.{p}_proj`
1588    /// is the qwen3moe / olmoe layout (a future arch with `block_sparse_moe.experts.*` would need a
1589    /// branch in `hf_expert_name`).
1590    pub fn load_from_source(
1591        e: &Engine,
1592        src: &dyn TensorSource,
1593        ggml_exps_name: &str,
1594        n_expert: usize,
1595    ) -> Result<Self, Box<dyn std::error::Error>> {
1596        // Recover il + proj from `blk.{il}.ffn_{gate,up,down}_exps.weight`.
1597        let rest = ggml_exps_name
1598            .strip_prefix("blk.")
1599            .unwrap_or_else(|| panic!("not a blk.* name: {ggml_exps_name}"));
1600        let (il_s, suffix) = rest.split_once('.').unwrap();
1601        let il: u32 = il_s.parse().unwrap();
1602        let proj = match suffix {
1603            "ffn_gate_exps.weight" => "gate",
1604            "ffn_up_exps.weight" => "up",
1605            "ffn_down_exps.weight" => "down",
1606            other => panic!("not a *_exps suffix: {other}"),
1607        };
1608
1609        // A mixed-precision safetensors/repack source exposes experts as separate 2D tensors.
1610        // Detect a dtype/layout change before the uniform gather paths normalize the whole layer
1611        // to one encoding. Uniform checkpoints take the unchanged optimized path below.
1612        let mut signatures = Vec::with_capacity(n_expert);
1613        let active = src.active_experts(il);
1614        for ex in 0..n_expert {
1615            if active.is_some_and(|mask| !mask[ex]) {
1616                signatures.push((i32::MIN, 0));
1617                continue;
1618            }
1619            let name = format!("blk.{il}.ffn_{proj}_exps.{ex}.weight");
1620            if let Some(nv) = src.find_nvfp4_native(&name) {
1621                signatures.push((QT_NVFP4, nv.in_f / 64 * 36));
1622            } else {
1623                let v = src
1624                    .find(&name)
1625                    .unwrap_or_else(|| panic!("missing expert tensor {name}"));
1626                let in_f = v.ne[0] as usize;
1627                signatures.push(match staged_expert_row_bytes(v.ggml_type, in_f) {
1628                    Some(row_bytes) => (staged_expert_qtype(v.ggml_type).unwrap(), row_bytes),
1629                    None => (QT_F32, in_f * 4),
1630                });
1631            }
1632        }
1633        let mixed_layout = signatures.windows(2).any(|pair| pair[0] != pair[1]);
1634        if src.preserve_expert_encodings() && !mixed_layout {
1635            if let Some(uniform) = Self::load_uniform_mmap_from_source(src, il, proj, n_expert)? {
1636                return Ok(uniform);
1637            }
1638        }
1639        if src.preserve_expert_encodings() || mixed_layout {
1640            return Self::load_mixed_from_source(src, il, proj, n_expert);
1641        }
1642
1643        // PATH B (NVFP4-NATIVE GATHER, 2026-07-05): when the source exposes the experts as packed
1644        // ModelOpt/Reza NVFP4 (find_nvfp4_native), keep them QUANTIZED — repack each expert's
1645        // modelopt bytes to the GGUF 36B-block layout the staged qmatvec decodes, and concatenate.
1646        // No f32 blow-up: a 129GB checkpoint gathers to ~the same bytes instead of ~8x (which is
1647        // what makes MiniMax-M3 REAP50 loadable on a 60GB-RAM host at all, with spill on top).
1648        // Per-expert `weight_scale_2` macros go to `macros` (folded post-matmul by the MoE forward).
1649        {
1650            let name0 = format!("blk.{il}.ffn_{proj}_exps.0.weight");
1651            if let Some(nv0) = src.find_nvfp4_native(&name0) {
1652                let (in_f, out_f) = (nv0.in_f, nv0.out_f);
1653                let row_bytes = in_f / 64 * 36;
1654                let expert_stride = out_f * row_bytes;
1655                // ST DISK TIER (2026-07-06, the MiniMax OOM fix): when the total expert bytes
1656                // exceed host RAM (M3 REAP50 = 122GB repacked on a 60GB host, first-load host-OOM
1657                // at layer ~24), repack each layer ONCE into an on-disk cache file next to the
1658                // checkpoint and mmap it (HostBuf::Mmap, MAP_SHARED no-populate — the same tier-2
1659                // mechanism the GGUF spill path uses). Reloads hit the cache (size-checked), pay
1660                // zero repack. MEMRA_ST_REPACK_DISK=0 forces the old in-RAM gather.
1661                let disk = std::env::var("MEMRA_ST_REPACK_DISK")
1662                    .map(|v| v != "0")
1663                    .unwrap_or(true)
1664                    && src.st_dir().is_some();
1665                let cache_path = src.st_dir().map(|d| {
1666                    let cd = d.join(".memra-repack");
1667                    let _ = std::fs::create_dir_all(&cd);
1668                    cd.join(format!("blk{il}-{proj}-{n_expert}x{out_f}x{in_f}.nvfp4"))
1669                });
1670                let total = n_expert * expert_stride;
1671                let mut macros = vec![1.0f32; n_expert];
1672                let read_macros = |macros: &mut Vec<f32>| {
1673                    for ex in 0..n_expert {
1674                        let stem = format!("blk.{il}.ffn_{proj}_exps.{ex}");
1675                        if let Some(sv) = src.find(&format!("{stem}.scale")) {
1676                            macros[ex] = f32::from_le_bytes(sv.bytes[..4].try_into().unwrap());
1677                        }
1678                    }
1679                };
1680                let bytes = if disk {
1681                    let cp = cache_path.as_ref().unwrap();
1682                    let fresh = std::fs::metadata(cp)
1683                        .map(|m| m.len() as usize == total)
1684                        .unwrap_or(false);
1685                    if !fresh {
1686                        // stream one expert at a time to disk — peak RAM = one expert (~8MB)
1687                        use std::io::Write;
1688                        let mut f = std::io::BufWriter::new(std::fs::File::create(cp)?);
1689                        for ex in 0..n_expert {
1690                            let name = format!("blk.{il}.ffn_{proj}_exps.{ex}.weight");
1691                            let nv = src.find_nvfp4_native(&name).unwrap_or_else(|| {
1692                                panic!("expert {name} lost NVFP4-native mid-gather")
1693                            });
1694                            assert_eq!(
1695                                (nv.in_f, nv.out_f),
1696                                (in_f, out_f),
1697                                "expert {ex} dims ({},{}) != expert 0 ({in_f},{out_f})",
1698                                nv.in_f,
1699                                nv.out_f
1700                            );
1701                            f.write_all(&memra_gguf::nvfp4_repack::repack_modelopt_to_gguf(
1702                                nv.wbytes, nv.wscale, out_f, in_f,
1703                            ))?;
1704                        }
1705                        f.flush()?;
1706                    }
1707                    read_macros(&mut macros);
1708                    let file = std::sync::Arc::new(std::fs::File::open(cp)?);
1709                    let map = unsafe { memmap2::Mmap::map(file.as_ref())? };
1710                    assert_eq!(map.len(), total, "repack cache {cp:?} size mismatch");
1711                    // Default random preserves the original policy; normal lets Linux readahead
1712                    // within each multi-megabyte expert on the spill-bound path.
1713                    let _ = memra_gguf::source::apply_expert_mmap_advice(&map);
1714                    let map = std::sync::Arc::new(map);
1715                    // ST PINNED TIER (2026-07-07, the M3 1.5-tok/s lever): mmap-only backing makes
1716                    // every SLRU miss a page-cache (or NVMe) synchronous read into the H2D copy.
1717                    // Pin as many experts as the live budget allows (same MemBudget probe + 0.6
1718                    // MemAvailable cap as the GGUF spill tier) — pinned pages upload via true
1719                    // async DMA at full PCIe. Budget is GLOBAL across layers (first-come: earlier
1720                    // layers pin first; routing is roughly uniform so early-layer bias is benign).
1721                    // MEMRA_ST_PINNED=0 disables (pure-mmap, the 2026-07-06 behavior).
1722                    // DEFAULT OFF (2026-07-07 measured): with a 122GB expert set on 60GB RAM,
1723                    // pinning 26GB EVICTED the page cache backing the mmap tier — every unpinned
1724                    // expert faulted cold from NVMe and gen fell 1.5 -> 0.05 tok/s (30x WORSE).
1725                    // Pinning only pays when (total - pinned) fits page cache; here it never can.
1726                    // MEMRA_ST_PINNED=1 opt-in for fits-in-RAM checkpoints (e.g. REAP-heavier cuts).
1727                    let tiers = if std::env::var("MEMRA_ST_PINNED")
1728                        .map(|v| v == "1")
1729                        .unwrap_or(false)
1730                    {
1731                        static PIN_BUDGET: std::sync::OnceLock<std::sync::Mutex<usize>> =
1732                            std::sync::OnceLock::new();
1733                        let budget = PIN_BUDGET.get_or_init(|| {
1734                            let b = crate::spill::MemBudget::probe(e)
1735                                .map(|b| b.free_pinnable_ram)
1736                                .unwrap_or(0);
1737                            eprintln!("[st-spill] free_pinnable_ram={} MiB", b >> 20);
1738                            std::sync::Mutex::new(b)
1739                        });
1740                        let mut rem = budget.lock().unwrap();
1741                        // ONE pinned slab per file prefix (n_pin experts contiguous): 1 alloc +
1742                        // 1 bulk copy instead of n_pin small allocs (per-expert cudaHostAllocs
1743                        // stalled the 122GB M3 load >10min).
1744                        let n_pin = (*rem / expert_stride).min(n_expert);
1745                        if n_pin == 0 {
1746                            None
1747                        } else {
1748                            let slab_len = n_pin * expert_stride;
1749                            let mut pn = unsafe { e.ctx().alloc_pinned::<u8>(slab_len)? };
1750                            {
1751                                let dst = pn.as_mut_slice()?;
1752                                dst.copy_from_slice(&map[..slab_len]);
1753                            }
1754                            let base = pn.as_ptr()? as *const u8;
1755                            *rem -= slab_len;
1756                            let slab = std::sync::Arc::new(HostBuf::Pinned {
1757                                slice: std::sync::Arc::new(pn),
1758                                base,
1759                                len: slab_len,
1760                            });
1761                            let mut tiers: Vec<HostBuf> = Vec::with_capacity(n_expert);
1762                            for ex in 0..n_expert {
1763                                let off = ex * expert_stride;
1764                                if ex < n_pin {
1765                                    tiers.push(HostBuf::PinnedAlias {
1766                                        owner: slab.clone(),
1767                                        base: unsafe { base.add(off) },
1768                                        len: expert_stride,
1769                                    });
1770                                } else {
1771                                    tiers.push(HostBuf::Mmap {
1772                                        map: map.clone(),
1773                                        file: file.clone(),
1774                                        off,
1775                                        len: expert_stride,
1776                                    });
1777                                }
1778                            }
1779                            Some(tiers)
1780                        }
1781                    } else {
1782                        None
1783                    };
1784                    if let Some(tiers) = tiers {
1785                        let all_one = macros.iter().all(|&m| m == 1.0);
1786                        return Ok(HostExps {
1787                            bytes: HostBuf::Mmap {
1788                                map,
1789                                file,
1790                                off: 0,
1791                                len: total,
1792                            },
1793                            tiers: Some(tiers),
1794                            qtype: QT_NVFP4,
1795                            in_f,
1796                            out_f,
1797                            n_expert,
1798                            row_bytes,
1799                            expert_stride,
1800                            layouts: None,
1801                            macros: if all_one { None } else { Some(macros) },
1802                        });
1803                    }
1804                    HostBuf::Mmap {
1805                        map,
1806                        file,
1807                        off: 0,
1808                        len: total,
1809                    }
1810                } else {
1811                    let mut buf: Vec<u8> = Vec::with_capacity(total);
1812                    for ex in 0..n_expert {
1813                        let name = format!("blk.{il}.ffn_{proj}_exps.{ex}.weight");
1814                        let nv = src.find_nvfp4_native(&name).unwrap_or_else(|| {
1815                            panic!("expert {name} lost NVFP4-native mid-gather")
1816                        });
1817                        assert_eq!(
1818                            (nv.in_f, nv.out_f),
1819                            (in_f, out_f),
1820                            "expert {ex} dims ({},{}) != expert 0 ({in_f},{out_f})",
1821                            nv.in_f,
1822                            nv.out_f
1823                        );
1824                        buf.extend_from_slice(&memra_gguf::nvfp4_repack::repack_modelopt_to_gguf(
1825                            nv.wbytes, nv.wscale, out_f, in_f,
1826                        ));
1827                    }
1828                    assert_eq!(buf.len(), total);
1829                    read_macros(&mut macros);
1830                    let pinned = std::env::var("MEMRA_MOE_PINNED").is_ok()
1831                        || std::env::var("MEMRA_MOE_CACHE").as_deref() != Ok("0");
1832                    if pinned {
1833                        let mut p = unsafe { e.ctx().alloc_pinned::<u8>(buf.len())? };
1834                        {
1835                            let dst = p.as_mut_slice()?;
1836                            dst.copy_from_slice(&buf);
1837                        }
1838                        let base = p.as_ptr()? as *const u8;
1839                        let len = buf.len();
1840                        HostBuf::Pinned {
1841                            slice: std::sync::Arc::new(p),
1842                            base,
1843                            len,
1844                        }
1845                    } else {
1846                        HostBuf::Paged(buf)
1847                    }
1848                };
1849                let all_one = macros.iter().all(|&m| m == 1.0);
1850                return Ok(HostExps {
1851                    bytes,
1852                    tiers: None,
1853                    qtype: QT_NVFP4,
1854                    in_f,
1855                    out_f,
1856                    n_expert,
1857                    row_bytes,
1858                    expert_stride,
1859                    layouts: None,
1860                    macros: if all_one { None } else { Some(macros) },
1861                });
1862            }
1863        }
1864
1865        // expert 0 fixes (in_f, out_f); every later expert must match (catches a layer/arch mixup).
1866        let mut buf: Vec<u8> = Vec::new();
1867        let mut in_f = 0usize;
1868        let mut out_f = 0usize;
1869        for ex in 0..n_expert {
1870            // Per-expert ggml name; the source maps it to the HF expert tensor (ST-MOE-PLAN §1.3).
1871            let name = format!("blk.{il}.ffn_{proj}_exps.{ex}.weight");
1872            let v = src
1873                .find(&name)
1874                .unwrap_or_else(|| panic!("missing expert tensor {name}"));
1875            assert_eq!(v.ne.len(), 2, "expert {name} is not 2D (ne={:?})", v.ne);
1876            let (cur_in, cur_out) = (v.ne[0] as usize, v.ne[1] as usize);
1877            if ex == 0 {
1878                in_f = cur_in;
1879                out_f = cur_out;
1880            } else {
1881                assert_eq!(
1882                    (cur_in, cur_out),
1883                    (in_f, out_f),
1884                    "expert {ex} dims {:?} != expert 0 [{in_f},{out_f}]",
1885                    (cur_in, cur_out)
1886                );
1887            }
1888            // PATH A: dequant the 2D expert (F32/F16/BF16) to f32, append its bytes verbatim. The
1889            // dequantized [out_f, in_f] row-major f32 block is exactly one expert_stride slow→fast.
1890            let n = cur_in * cur_out;
1891            let f32v = dequant::dequantize(v.ggml_type, &v.bytes, n);
1892            buf.reserve(n * 4);
1893            for f in &f32v {
1894                buf.extend_from_slice(&f.to_le_bytes());
1895            }
1896        }
1897        let row_bytes = in_f * 4; // one out-row = in_f contiguous f32s
1898        let expert_stride = out_f * row_bytes;
1899        assert_eq!(
1900            buf.len(),
1901            n_expert * expert_stride,
1902            "{ggml_exps_name} gather size {} != n_expert*stride {}",
1903            buf.len(),
1904            n_expert * expert_stride
1905        );
1906        // Hold to the identical invariant as the GGUF path (ST-MOE-PLAN §1.3 step 4).
1907        assert_eq!(expert_stride, out_f * row_bytes,
1908            "{ggml_exps_name} stride mismatch: stride={expert_stride} out_f={out_f} row_bytes={row_bytes}");
1909
1910        // Same pinned-vs-paged choice as the GGUF loader (the bytes are H2D-only on the hot path).
1911        let pinned = std::env::var("MEMRA_MOE_PINNED").is_ok()
1912            || std::env::var("MEMRA_MOE_CACHE").as_deref() != Ok("0");
1913        let bytes = if pinned {
1914            let mut p = unsafe { e.ctx().alloc_pinned::<u8>(buf.len())? };
1915            {
1916                let dst = p.as_mut_slice()?;
1917                dst.copy_from_slice(&buf);
1918            }
1919            let base = p.as_ptr()? as *const u8;
1920            let len = buf.len();
1921            HostBuf::Pinned {
1922                slice: std::sync::Arc::new(p),
1923                base,
1924                len,
1925            }
1926        } else {
1927            HostBuf::Paged(buf)
1928        };
1929        Ok(HostExps {
1930            bytes,
1931            tiers: None,
1932            qtype: QT_F32,
1933            in_f,
1934            out_f,
1935            n_expert,
1936            row_bytes,
1937            expert_stride,
1938            layouts: None,
1939            macros: None,
1940        })
1941    }
1942
1943    /// Coalesce a uniform v2 overlay back into the existing stacked-slab contract without copying.
1944    /// The artifact stores one record per original expert for coverage validation, but a full-bank
1945    /// uniform arm writes those records contiguously into one file. Keeping `layouts=None` preserves
1946    /// the uniform fused kernels while `HostBuf::Mmap` keeps the >RAM artifact zero-copy.
1947    fn load_uniform_mmap_from_source(
1948        src: &dyn TensorSource,
1949        il: u32,
1950        proj: &str,
1951        n_expert: usize,
1952    ) -> Result<Option<Self>, Box<dyn std::error::Error>> {
1953        if src
1954            .active_experts(il)
1955            .is_some_and(|mask| mask.iter().any(|&active| !active))
1956        {
1957            return Ok(None);
1958        }
1959        let mut first_map = None;
1960        let mut first_file = None;
1961        let mut base_offset = 0u64;
1962        let mut expert_stride = 0usize;
1963        let mut in_f = 0usize;
1964        let mut out_f = 0usize;
1965        let mut qtype = 0i32;
1966        let mut row_bytes = 0usize;
1967        let mut macros = vec![1.0f32; n_expert];
1968        for ex in 0..n_expert {
1969            let stem = format!("blk.{il}.ffn_{proj}_exps.{ex}");
1970            let name = format!("{stem}.weight");
1971            let Some(DiskExtent {
1972                map,
1973                file,
1974                offset,
1975                len,
1976            }) = find_expert_disk_strict(src, &name)?
1977            else {
1978                return Ok(None);
1979            };
1980            let Some(v) = src.find(&name) else {
1981                return Ok(None);
1982            };
1983            if v.ne.len() != 2 {
1984                return Ok(None);
1985            }
1986            let (cur_in, cur_out) = (v.ne[0] as usize, v.ne[1] as usize);
1987            let Some(cur_row_bytes) = staged_expert_row_bytes(v.ggml_type, cur_in) else {
1988                return Ok(None);
1989            };
1990            let cur_qtype = staged_expert_qtype(v.ggml_type).unwrap();
1991            if ex == 0 {
1992                base_offset = offset;
1993                expert_stride = len;
1994                in_f = cur_in;
1995                out_f = cur_out;
1996                qtype = cur_qtype;
1997                row_bytes = cur_row_bytes;
1998                first_map = Some(map);
1999                first_file = Some(file);
2000            } else if !std::sync::Arc::ptr_eq(first_map.as_ref().unwrap(), &map)
2001                || !std::sync::Arc::ptr_eq(first_file.as_ref().unwrap(), &file)
2002                || offset != base_offset + (ex * expert_stride) as u64
2003                || len != expert_stride
2004                || (cur_in, cur_out, cur_qtype, cur_row_bytes) != (in_f, out_f, qtype, row_bytes)
2005            {
2006                return Ok(None);
2007            }
2008            if let Some(scale) = src.find(&format!("{stem}.scale")) {
2009                macros[ex] = f32::from_le_bytes(scale.bytes[..4].try_into().unwrap());
2010            }
2011        }
2012        assert_eq!(expert_stride, out_f * row_bytes);
2013        let total = n_expert * expert_stride;
2014        let off = usize::try_from(base_offset)
2015            .map_err(|_| format!("uniform expert disk offset {base_offset} does not fit usize"))?;
2016        let all_one = macros.iter().all(|&scale| scale == 1.0);
2017        Ok(Some(HostExps {
2018            bytes: HostBuf::Mmap {
2019                map: first_map.unwrap(),
2020                file: first_file.unwrap(),
2021                off,
2022                len: total,
2023            },
2024            tiers: None,
2025            qtype,
2026            in_f,
2027            out_f,
2028            n_expert,
2029            row_bytes,
2030            expert_stride,
2031            layouts: None,
2032            macros: if all_one { None } else { Some(macros) },
2033        }))
2034    }
2035
2036    fn load_mixed_from_source(
2037        src: &dyn TensorSource,
2038        il: u32,
2039        proj: &str,
2040        n_expert: usize,
2041    ) -> Result<Self, Box<dyn std::error::Error>> {
2042        let mut tiers = Vec::with_capacity(n_expert);
2043        let mut layouts = Vec::with_capacity(n_expert);
2044        let mut macros = vec![1.0f32; n_expert];
2045        let mut in_f = 0usize;
2046        let mut out_f = 0usize;
2047        let active = src.active_experts(il);
2048        let mut first_active = None;
2049
2050        for ex in 0..n_expert {
2051            if active.is_some_and(|mask| !mask[ex]) {
2052                layouts.push(ExpertLayout {
2053                    offset: 0,
2054                    len: 0,
2055                    qtype: QT_F32,
2056                    row_bytes: 0,
2057                });
2058                tiers.push(HostBuf::Paged(Vec::new()));
2059                continue;
2060            }
2061            let name = format!("blk.{il}.ffn_{proj}_exps.{ex}.weight");
2062            let stem = format!("blk.{il}.ffn_{proj}_exps.{ex}");
2063            if let Some(scale) = src.find(&format!("{stem}.scale")) {
2064                macros[ex] = f32::from_le_bytes(scale.bytes[..4].try_into().unwrap());
2065            }
2066            let (host, byte_len, qtype, row_bytes, cur_in, cur_out) = if let Some(DiskExtent {
2067                map,
2068                file,
2069                offset,
2070                len,
2071            }) =
2072                find_expert_disk_strict(src, &name)?
2073            {
2074                let v = src
2075                    .find(&name)
2076                    .unwrap_or_else(|| panic!("missing expert tensor {name}"));
2077                assert_eq!(v.ne.len(), 2, "expert {name} is not 2D (ne={:?})", v.ne);
2078                let (cur_in, cur_out) = (v.ne[0] as usize, v.ne[1] as usize);
2079                let row_bytes = staged_expert_row_bytes(v.ggml_type, cur_in).ok_or_else(|| {
2080                    format!("mmap expert {name} has unsupported qtype {:?}", v.ggml_type)
2081                })?;
2082                let off = usize::try_from(offset).map_err(|_| {
2083                    format!("expert {name} disk offset {offset} does not fit usize")
2084                })?;
2085                (
2086                    HostBuf::Mmap {
2087                        map,
2088                        file,
2089                        off,
2090                        len,
2091                    },
2092                    len,
2093                    staged_expert_qtype(v.ggml_type).unwrap(),
2094                    row_bytes,
2095                    cur_in,
2096                    cur_out,
2097                )
2098            } else if let Some(nv) = src.find_nvfp4_native(&name) {
2099                let bytes = memra_gguf::nvfp4_repack::repack_modelopt_to_gguf(
2100                    nv.wbytes, nv.wscale, nv.out_f, nv.in_f,
2101                );
2102                let row_bytes = nv.in_f / 64 * 36;
2103                let byte_len = bytes.len();
2104                (
2105                    HostBuf::Paged(bytes),
2106                    byte_len,
2107                    QT_NVFP4,
2108                    row_bytes,
2109                    nv.in_f,
2110                    nv.out_f,
2111                )
2112            } else {
2113                let v = src
2114                    .find(&name)
2115                    .unwrap_or_else(|| panic!("missing expert tensor {name}"));
2116                assert_eq!(v.ne.len(), 2, "expert {name} is not 2D (ne={:?})", v.ne);
2117                let (cur_in, cur_out) = (v.ne[0] as usize, v.ne[1] as usize);
2118                if let Some(row_bytes) = staged_expert_row_bytes(v.ggml_type, cur_in) {
2119                    let bytes = v.bytes.into_owned();
2120                    let byte_len = bytes.len();
2121                    (
2122                        HostBuf::Paged(bytes),
2123                        byte_len,
2124                        staged_expert_qtype(v.ggml_type).unwrap(),
2125                        row_bytes,
2126                        cur_in,
2127                        cur_out,
2128                    )
2129                } else {
2130                    let f32v = dequant::dequantize(v.ggml_type, &v.bytes, cur_in * cur_out);
2131                    let mut bytes = Vec::with_capacity(f32v.len() * 4);
2132                    for f in f32v {
2133                        bytes.extend_from_slice(&f.to_le_bytes());
2134                    }
2135                    let byte_len = bytes.len();
2136                    (
2137                        HostBuf::Paged(bytes),
2138                        byte_len,
2139                        QT_F32,
2140                        cur_in * 4,
2141                        cur_in,
2142                        cur_out,
2143                    )
2144                }
2145            };
2146
2147            if first_active.is_none() {
2148                in_f = cur_in;
2149                out_f = cur_out;
2150                first_active = Some(ex);
2151            } else {
2152                assert_eq!(
2153                    (cur_in, cur_out),
2154                    (in_f, out_f),
2155                    "expert {ex} dims ({cur_in},{cur_out}) != first active expert ({in_f},{out_f})"
2156                );
2157            }
2158            assert_eq!(
2159                byte_len,
2160                cur_out * row_bytes,
2161                "expert {name} bytes {byte_len} != out_f*row_bytes {}",
2162                cur_out * row_bytes
2163            );
2164            layouts.push(ExpertLayout {
2165                offset: 0,
2166                len: byte_len,
2167                qtype,
2168                row_bytes,
2169            });
2170            tiers.push(host);
2171        }
2172
2173        let first = layouts[*first_active
2174            .as_ref()
2175            .expect("expert mask pruned every expert")];
2176        let expert_stride = layouts.iter().map(|layout| layout.len).max().unwrap_or(0);
2177        let all_one = macros.iter().all(|&scale| scale == 1.0);
2178        Ok(HostExps {
2179            bytes: HostBuf::Paged(Vec::new()),
2180            tiers: Some(tiers),
2181            qtype: first.qtype,
2182            in_f,
2183            out_f,
2184            n_expert,
2185            row_bytes: first.row_bytes,
2186            expert_stride,
2187            layouts: Some(layouts),
2188            macros: if all_one { None } else { Some(macros) },
2189        })
2190    }
2191
2192    /// Host byte slice for expert `e` (the H2D DMA source). Contiguous block, offset honored.
2193    /// Resolves the per-expert tier when spilling is active (`tiers` Some), else slices the single
2194    /// Per-expert post-matmul macro-scale (1.0 when absent).
2195    #[inline]
2196    pub fn macro_scale(&self, e: usize) -> f32 {
2197        self.macros.as_ref().map(|m| m[e]).unwrap_or(1.0)
2198    }
2199
2200    #[inline]
2201    pub fn is_uniform_layout(&self) -> bool {
2202        self.layouts.is_none()
2203    }
2204
2205    #[inline]
2206    pub fn expert_layout(&self, e: usize) -> ExpertLayout {
2207        debug_assert!(
2208            e < self.n_expert,
2209            "expert index {e} >= n_expert {}",
2210            self.n_expert
2211        );
2212        self.layouts
2213            .as_ref()
2214            .map(|layouts| layouts[e])
2215            .unwrap_or(ExpertLayout {
2216                offset: e * self.expert_stride,
2217                len: self.expert_stride,
2218                qtype: self.qtype,
2219                row_bytes: self.row_bytes,
2220            })
2221    }
2222
2223    #[inline]
2224    pub fn max_expert_bytes(&self) -> usize {
2225        self.layouts
2226            .as_ref()
2227            .and_then(|layouts| layouts.iter().map(|layout| layout.len).max())
2228            .unwrap_or(self.expert_stride)
2229    }
2230
2231    /// backing store (unchanged in-RAM path). Each `tiers[e]` is exactly one expert's stride.
2232    #[inline]
2233    pub fn expert_bytes(&self, e: usize) -> &[u8] {
2234        let layout = self.expert_layout(e);
2235        match &self.tiers {
2236            Some(tiers) => {
2237                debug_assert_eq!(tiers[e].len(), layout.len);
2238                tiers[e].as_bytes()
2239            }
2240            None => &self.bytes.as_bytes()[layout.offset..layout.offset + layout.len],
2241        }
2242    }
2243
2244    /// Source-aware twin of `expert_bytes`. Per-expert tiers already point at one exact block, while
2245    /// a uniform slab needs the expert layout offset added to its base. Keeping those cases separate
2246    /// prevents expert `e` from being offset twice when a tier vector is present.
2247    #[inline]
2248    pub(crate) fn expert_source(&self, e: usize) -> ExpertSource<'_> {
2249        let layout = self.expert_layout(e);
2250        match &self.tiers {
2251            Some(tiers) => tiers[e].expert_source(0, layout.len),
2252            None => self.bytes.expert_source(layout.offset, layout.len),
2253        }
2254    }
2255
2256    /// Hint that expert `e` will be staged soon. Uniform slabs advise only this expert's window;
2257    /// mixed/pruned layouts advise the selected per-expert mmap. Returns false for resident or
2258    /// empty buffers and on unsupported kernels; callers always retain the demand-fault fallback.
2259    #[inline]
2260    pub fn prefetch_expert_pages(&self, e: usize) -> bool {
2261        let layout = self.expert_layout(e);
2262        match &self.tiers {
2263            Some(tiers) => tiers[e].advise_willneed(0, layout.len),
2264            None => self.bytes.advise_willneed(layout.offset, layout.len),
2265        }
2266    }
2267}
2268
2269#[cfg(test)]
2270mod tests {
2271    use super::{
2272        repack_nvfp4_split, unpack_nvfp4_split, ExpertKeepalive, ExpertSource, HostBuf, HostExps,
2273        QT_BF16, QT_NVFP4, QT_Q2_K, QT_Q4_K,
2274    };
2275    use memra_gguf::nvfp4_repack::{repack_modelopt_to_gguf, repack_modelopt_to_split};
2276    use memra_gguf::source::{DiskExtent, TensorSource, TensorView};
2277    use memra_gguf::{config::ModelConfig, GgmlType};
2278    use std::borrow::Cow;
2279
2280    struct MixedExpertSource {
2281        bf16: Vec<u8>,
2282        q4k: Vec<u8>,
2283    }
2284
2285    impl TensorSource for MixedExpertSource {
2286        fn config(&self) -> ModelConfig {
2287            panic!("unused by HostExps mixed-loader test")
2288        }
2289
2290        fn find(&self, name: &str) -> Option<TensorView<'_>> {
2291            let (bytes, ggml_type) = if name == "blk.0.ffn_gate_exps.0.weight" {
2292                (&self.bf16, GgmlType::BF16)
2293            } else if name == "blk.0.ffn_gate_exps.1.weight" {
2294                (&self.q4k, GgmlType::Q4_K)
2295            } else {
2296                return None;
2297            };
2298            Some(TensorView {
2299                bytes: Cow::Borrowed(bytes),
2300                ggml_type,
2301                ne: vec![256, 2],
2302            })
2303        }
2304    }
2305
2306    struct PrunedExpertSource {
2307        q2k: Vec<u8>,
2308        nvfp4: Vec<u8>,
2309        active: Vec<bool>,
2310    }
2311
2312    struct MmapExpertSource {
2313        file: std::sync::Arc<std::fs::File>,
2314        map: std::sync::Arc<memmap2::Mmap>,
2315        base_offset: usize,
2316        expert_len: usize,
2317    }
2318
2319    struct LegacyMmapExpertSource {
2320        map: std::sync::Arc<memmap2::Mmap>,
2321        expert_len: usize,
2322    }
2323
2324    impl TensorSource for MmapExpertSource {
2325        fn config(&self) -> ModelConfig {
2326            panic!("unused by HostExps mmap-loader test")
2327        }
2328        fn preserve_expert_encodings(&self) -> bool {
2329            true
2330        }
2331        fn find(&self, name: &str) -> Option<TensorView<'_>> {
2332            let ex = match name {
2333                "blk.0.ffn_gate_exps.0.weight" => 0,
2334                "blk.0.ffn_gate_exps.1.weight" => 1,
2335                _ => return None,
2336            };
2337            let off = self.base_offset + ex * self.expert_len;
2338            Some(TensorView {
2339                bytes: Cow::Borrowed(&self.map[off..off + self.expert_len]),
2340                ggml_type: GgmlType::Q2_K,
2341                ne: vec![256, 2],
2342            })
2343        }
2344        fn find_expert_disk(&self, name: &str) -> Option<DiskExtent> {
2345            let ex = match name {
2346                "blk.0.ffn_gate_exps.0.weight" => 0,
2347                "blk.0.ffn_gate_exps.1.weight" => 1,
2348                _ => return None,
2349            };
2350            Some(DiskExtent {
2351                map: self.map.clone(),
2352                file: self.file.clone(),
2353                offset: (self.base_offset + ex * self.expert_len) as u64,
2354                len: self.expert_len,
2355            })
2356        }
2357    }
2358
2359    impl TensorSource for LegacyMmapExpertSource {
2360        fn config(&self) -> ModelConfig {
2361            panic!("unused by legacy mmap guard test")
2362        }
2363        fn preserve_expert_encodings(&self) -> bool {
2364            true
2365        }
2366        fn find(&self, name: &str) -> Option<TensorView<'_>> {
2367            let ex = match name {
2368                "blk.0.ffn_gate_exps.0.weight" => 0,
2369                "blk.0.ffn_gate_exps.1.weight" => 1,
2370                _ => return None,
2371            };
2372            let off = ex * self.expert_len;
2373            Some(TensorView {
2374                bytes: Cow::Borrowed(&self.map[off..off + self.expert_len]),
2375                ggml_type: GgmlType::Q2_K,
2376                ne: vec![256, 2],
2377            })
2378        }
2379        fn find_expert_mmap(
2380            &self,
2381            name: &str,
2382        ) -> Option<(std::sync::Arc<memmap2::Mmap>, usize, usize)> {
2383            let ex = match name {
2384                "blk.0.ffn_gate_exps.0.weight" => 0,
2385                "blk.0.ffn_gate_exps.1.weight" => 1,
2386                _ => return None,
2387            };
2388            Some((self.map.clone(), ex * self.expert_len, self.expert_len))
2389        }
2390    }
2391
2392    impl TensorSource for PrunedExpertSource {
2393        fn config(&self) -> ModelConfig {
2394            panic!("unused by HostExps pruned-loader test")
2395        }
2396        fn active_experts(&self, layer: u32) -> Option<&[bool]> {
2397            (layer == 0).then_some(self.active.as_slice())
2398        }
2399        fn find(&self, name: &str) -> Option<TensorView<'_>> {
2400            let (bytes, ggml_type) = match name {
2401                "blk.0.ffn_gate_exps.0.weight" => (&self.q2k, GgmlType::Q2_K),
2402                "blk.0.ffn_gate_exps.2.weight" => (&self.nvfp4, GgmlType::NVFP4),
2403                _ => return None,
2404            };
2405            Some(TensorView {
2406                bytes: Cow::Borrowed(bytes),
2407                ggml_type,
2408                ne: vec![256, 2],
2409            })
2410        }
2411    }
2412
2413    /// A1 direct-import gate (engine side): the fused modelopt->split repack must be byte-for-byte
2414    /// the composition of the two passes it replaces (modelopt->GGUF blocks, then the A6
2415    /// split-plane repack). Also pins the split roundtrip on the same buffers.
2416    #[test]
2417    fn direct_split_equals_chained() {
2418        for (out_f, in_f) in [(1usize, 64usize), (3, 128), (5, 320), (8, 1024)] {
2419            let mut w = vec![0u8; out_f * in_f / 2];
2420            let mut s = vec![0u8; out_f * in_f / 16];
2421            for (i, b) in w.iter_mut().enumerate() {
2422                *b = ((i * 41 + 7) & 0xFF) as u8;
2423            }
2424            for (i, b) in s.iter_mut().enumerate() {
2425                *b = (0x20 + ((i * 11 + 5) % 0x50)) as u8;
2426            }
2427            let gguf = repack_modelopt_to_gguf(&w, &s, out_f, in_f);
2428            let chained = repack_nvfp4_split(&gguf, out_f);
2429            let direct = repack_modelopt_to_split(&w, &s, out_f, in_f);
2430            assert_eq!(
2431                direct, chained,
2432                "fused != chained at out_f={out_f} in_f={in_f}"
2433            );
2434            assert_eq!(
2435                unpack_nvfp4_split(&direct, out_f),
2436                gguf,
2437                "split roundtrip broken at out_f={out_f} in_f={in_f}"
2438            );
2439        }
2440    }
2441
2442    #[test]
2443    fn mixed_expert_loader_keeps_each_encoding_and_extent() {
2444        let source = MixedExpertSource {
2445            bf16: vec![0x5a; 256 * 2 * 2],
2446            q4k: vec![0xa5; 2 * 144],
2447        };
2448        let exps = HostExps::load_mixed_from_source(&source, 0, "gate", 2).unwrap();
2449        assert!(!exps.is_uniform_layout());
2450        assert_eq!(exps.max_expert_bytes(), 1024);
2451        assert_eq!(exps.expert_layout(0).qtype, QT_BF16);
2452        assert_eq!(exps.expert_layout(0).row_bytes, 512);
2453        assert_eq!(exps.expert_layout(0).len, 1024);
2454        assert_eq!(exps.expert_layout(1).qtype, QT_Q4_K);
2455        assert_eq!(exps.expert_layout(1).row_bytes, 144);
2456        assert_eq!(exps.expert_layout(1).len, 288);
2457        assert_eq!(exps.expert_bytes(0), source.bf16);
2458        assert_eq!(exps.expert_bytes(1), source.q4k);
2459        match exps.expert_source(1) {
2460            ExpertSource::Memory { bytes, .. } => assert_eq!(bytes, source.q4k),
2461            ExpertSource::Disk { .. } => panic!("paged expert unexpectedly became disk-backed"),
2462        }
2463    }
2464
2465    #[test]
2466    fn mixed_expert_loader_omits_masked_expert_bytes() {
2467        let source = PrunedExpertSource {
2468            q2k: vec![0x22; 2 * 84],
2469            nvfp4: vec![0x44; 2 * 4 * 36],
2470            active: vec![true, false, true],
2471        };
2472        let exps = HostExps::load_mixed_from_source(&source, 0, "gate", 3).unwrap();
2473        assert_eq!(exps.expert_layout(0).qtype, QT_Q2_K);
2474        assert_eq!(exps.expert_layout(0).row_bytes, 84);
2475        assert_eq!(exps.expert_layout(1).len, 0);
2476        assert_eq!(exps.expert_bytes(1), &[]);
2477        assert_eq!(exps.expert_layout(2).qtype, QT_NVFP4);
2478        assert_eq!(exps.expert_layout(2).row_bytes, 4 * 36);
2479    }
2480
2481    #[test]
2482    fn mixed_expert_loader_keeps_mmap_backing_zero_copy() {
2483        let path = std::env::temp_dir().join(format!("memra-mixed-mmap-{}", std::process::id()));
2484        let base_offset = 3usize;
2485        let expert_len = 2 * 84;
2486        let mut bytes = vec![0xE1; base_offset];
2487        bytes.extend(vec![0x31; expert_len]);
2488        bytes.extend(vec![0x72; expert_len]);
2489        std::fs::write(&path, &bytes).unwrap();
2490        let file = std::sync::Arc::new(std::fs::File::open(&path).unwrap());
2491        let map = std::sync::Arc::new(unsafe { memmap2::Mmap::map(file.as_ref()).unwrap() });
2492        let source = MmapExpertSource {
2493            file: file.clone(),
2494            map,
2495            base_offset,
2496            expert_len,
2497        };
2498        let exps = HostExps::load_mixed_from_source(&source, 0, "gate", 2).unwrap();
2499        assert!(matches!(
2500            exps.tiers.as_ref().unwrap()[0],
2501            HostBuf::Mmap { .. }
2502        ));
2503        assert!(matches!(
2504            exps.tiers.as_ref().unwrap()[1],
2505            HostBuf::Mmap { .. }
2506        ));
2507        assert_eq!(
2508            exps.expert_bytes(0),
2509            &bytes[base_offset..base_offset + expert_len]
2510        );
2511        assert_eq!(exps.expert_bytes(1), &bytes[base_offset + expert_len..]);
2512        match exps.expert_source(1) {
2513            ExpertSource::Disk {
2514                file: got_file,
2515                offset,
2516                len,
2517                fallback,
2518                keepalive,
2519            } => {
2520                assert!(std::sync::Arc::ptr_eq(got_file, &file));
2521                assert_eq!(offset, (base_offset + expert_len) as u64);
2522                assert_eq!(len, expert_len);
2523                assert_eq!(fallback, &bytes[base_offset + expert_len..]);
2524                match keepalive {
2525                    ExpertKeepalive::Mmap(owner) => {
2526                        assert!(std::sync::Arc::ptr_eq(&owner, &source.map));
2527                    }
2528                    _ => panic!("mmap expert did not retain its mmap owner"),
2529                }
2530            }
2531            ExpertSource::Memory { .. } => panic!("mixed mmap tier lost its disk extent"),
2532        }
2533        #[cfg(unix)]
2534        assert!(exps.prefetch_expert_pages(1));
2535        std::fs::remove_file(path).ok();
2536    }
2537
2538    #[test]
2539    fn tiered_expert_source_does_not_double_apply_layout_offset() {
2540        let path =
2541            std::env::temp_dir().join(format!("memra-tiered-source-offset-{}", std::process::id()));
2542        let base_offset = 7usize;
2543        let expert_len = 2 * 84;
2544        let mut bytes = vec![0xE3; base_offset];
2545        bytes.extend(vec![0x41; expert_len]);
2546        bytes.extend(vec![0x82; expert_len]);
2547        std::fs::write(&path, &bytes).unwrap();
2548        let file = std::sync::Arc::new(std::fs::File::open(&path).unwrap());
2549        let map = std::sync::Arc::new(unsafe { memmap2::Mmap::map(file.as_ref()).unwrap() });
2550        let exps = HostExps {
2551            bytes: HostBuf::Paged(Vec::new()),
2552            tiers: Some(vec![
2553                HostBuf::Mmap {
2554                    map: map.clone(),
2555                    file: file.clone(),
2556                    off: base_offset,
2557                    len: expert_len,
2558                },
2559                HostBuf::Mmap {
2560                    map,
2561                    file: file.clone(),
2562                    off: base_offset + expert_len,
2563                    len: expert_len,
2564                },
2565            ]),
2566            qtype: QT_Q2_K,
2567            in_f: 256,
2568            out_f: 2,
2569            n_expert: 2,
2570            row_bytes: 84,
2571            expert_stride: expert_len,
2572            layouts: None,
2573            macros: None,
2574        };
2575
2576        // `expert_layout(1).offset == expert_len`, but tier 1 already starts at expert 1.
2577        assert_eq!(exps.expert_layout(1).offset, expert_len);
2578        match exps.expert_source(1) {
2579            ExpertSource::Disk {
2580                offset,
2581                len,
2582                fallback,
2583                ..
2584            } => {
2585                assert_eq!(offset, (base_offset + expert_len) as u64);
2586                assert_eq!(len, expert_len);
2587                assert_eq!(fallback, &bytes[base_offset + expert_len..]);
2588            }
2589            ExpertSource::Memory { .. } => panic!("tiered mmap expert lost its disk extent"),
2590        }
2591        std::fs::remove_file(path).ok();
2592    }
2593
2594    #[test]
2595    fn legacy_mmap_source_requires_retained_file_extent() {
2596        let path =
2597            std::env::temp_dir().join(format!("memra-legacy-mmap-source-{}", std::process::id()));
2598        let expert_len = 2 * 84;
2599        std::fs::write(&path, vec![0x64; 2 * expert_len]).unwrap();
2600        let file = std::fs::File::open(&path).unwrap();
2601        let map = std::sync::Arc::new(unsafe { memmap2::Mmap::map(&file).unwrap() });
2602        let source = LegacyMmapExpertSource { map, expert_len };
2603
2604        let err = match HostExps::load_uniform_mmap_from_source(&source, 0, "gate", 2) {
2605            Ok(_) => panic!("legacy mmap-only source silently fell back instead of failing"),
2606            Err(err) => err,
2607        };
2608        let message = err.to_string();
2609        assert!(
2610            message.contains("legacy find_expert_mmap without find_expert_disk"),
2611            "{message}"
2612        );
2613        assert!(message.contains("retained Arc<File>"), "{message}");
2614        std::fs::remove_file(path).ok();
2615    }
2616
2617    #[test]
2618    fn uniform_expert_loader_coalesces_contiguous_mmap() {
2619        let path = std::env::temp_dir().join(format!("memra-uniform-mmap-{}", std::process::id()));
2620        let base_offset = 5usize;
2621        let expert_len = 2 * 84;
2622        let mut bytes = vec![0xE2; base_offset];
2623        bytes.extend(vec![0x19; expert_len]);
2624        bytes.extend(vec![0x91; expert_len]);
2625        std::fs::write(&path, &bytes).unwrap();
2626        let file = std::sync::Arc::new(std::fs::File::open(&path).unwrap());
2627        let map = std::sync::Arc::new(unsafe { memmap2::Mmap::map(file.as_ref()).unwrap() });
2628        let source = MmapExpertSource {
2629            file: file.clone(),
2630            map,
2631            base_offset,
2632            expert_len,
2633        };
2634        let exps = HostExps::load_uniform_mmap_from_source(&source, 0, "gate", 2)
2635            .unwrap()
2636            .expect("contiguous mmap should coalesce");
2637        assert!(exps.is_uniform_layout());
2638        assert!(matches!(&exps.bytes, HostBuf::Mmap { .. }));
2639        assert_eq!(exps.expert_stride, expert_len);
2640        assert_eq!(
2641            exps.expert_bytes(0),
2642            &bytes[base_offset..base_offset + expert_len]
2643        );
2644        assert_eq!(exps.expert_bytes(1), &bytes[base_offset + expert_len..]);
2645        match exps.expert_source(1) {
2646            ExpertSource::Disk {
2647                file: got_file,
2648                offset,
2649                len,
2650                fallback,
2651                ..
2652            } => {
2653                assert!(std::sync::Arc::ptr_eq(got_file, &file));
2654                assert_eq!(offset, (base_offset + expert_len) as u64);
2655                assert_eq!(len, expert_len);
2656                assert_eq!(fallback, &bytes[base_offset + expert_len..]);
2657            }
2658            ExpertSource::Memory { .. } => panic!("uniform mmap slab lost its disk extent"),
2659        }
2660        #[cfg(unix)]
2661        assert!(exps.prefetch_expert_pages(1));
2662        std::fs::remove_file(path).ok();
2663    }
2664}