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