Skip to main content

ftts_kernels/
selftest.rs

1//! Shipped integer-overflow proofs for the kernels this crate can dispatch.
2//!
3//! The canonical Q8 converter emits symmetric signed weights in `[-127, 127]`; `-128` is
4//! deliberately excluded. Dynamic unsigned activations can span `[0, 255]`. Every dot-product
5//! route therefore has to prove its i32 accumulator against `255 * 127 * K` at this checkpoint's
6//! real reduction lengths, not a bound borrowed from another model.
7//!
8//! Two proof families run at every census binding K:
9//!
10//! - **U8S8 envelope** (`255 * 127 * K`): the contract ceiling for a future unsigned-activation
11//!   route (x86 VNNI's +128 fold), executed on the checked scalar path. It strictly dominates the
12//!   S8S8 magnitude, so it remains the conservative bound for every row.
13//! - **S8S8 kernel** (`±127 * 127 * K`): executed through the *real* [`crate::int8::dot_i32`]
14//!   kernel on every tier this build can dispatch ([`crate::int8::Int8Tier::available`]), each
15//!   result compared against the independent i64 oracle and the scalar route's i32.
16//!
17//! A native tier must appear here, through its real kernel function, before it may be selected.
18//! The rows mirror the binding component maxima in `docs/truth-pack/EXECUTION_CENSUS.json`, plus
19//! the seq-16 microdecoder verifier, whose larger M does not alter its per-output reduction
20//! length.
21
22/// Largest unsigned activation byte accepted by the U8S8 contract.
23pub const U8_MAX: u8 = u8::MAX;
24/// Largest absolute signed Q8 weight byte under the canonical symmetric recipe.
25pub const S8_MAX_ABS: i8 = 127;
26
27/// A route that this build can actually execute and certify.
28///
29/// Do not add an ISA variant merely because the CPU can report that feature. A variant belongs
30/// here only after the corresponding implementation exists and its exact scalar comparison is
31/// wired into [`run_selftest`].
32#[derive(Clone, Copy, Debug, Eq, PartialEq)]
33pub enum KernelTier {
34    /// The portable, safe integer reference route.
35    Scalar,
36    /// The portable eight-lane route shaped for LLVM autovectorization.
37    Autovec,
38    /// The aarch64 SDOT island (`neon-dotprod` feature + runtime FEAT_DotProd).
39    NeonSdot,
40    /// The wasm32 SIMD128 island (`simd128` target feature).
41    WasmSimd128,
42}
43
44impl KernelTier {
45    /// Stable machine-readable route name.
46    #[must_use]
47    pub const fn as_str(self) -> &'static str {
48        match self {
49            Self::Scalar => "scalar",
50            Self::Autovec => "autovec",
51            Self::NeonSdot => "neon-sdot",
52            Self::WasmSimd128 => "wasm-simd128",
53        }
54    }
55
56    const fn from_int8(tier: crate::int8::Int8Tier) -> Self {
57        match tier {
58            crate::int8::Int8Tier::Scalar => Self::Scalar,
59            crate::int8::Int8Tier::Autovec => Self::Autovec,
60            crate::int8::Int8Tier::NeonSdot => Self::NeonSdot,
61            crate::int8::Int8Tier::WasmSimd128 => Self::WasmSimd128,
62        }
63    }
64}
65
66/// Which numeric contract a proof check exercised.
67#[derive(Clone, Copy, Debug, Eq, PartialEq)]
68pub enum DotContract {
69    /// `255 * 127 * K` on the checked scalar path — the conservative envelope for a future
70    /// unsigned-activation (VNNI +128 fold) route.
71    U8S8Envelope,
72    /// `±127 * 127 * K` executed through the real [`crate::int8::dot_i32`] kernel.
73    S8S8Kernel,
74}
75
76impl DotContract {
77    /// Stable machine-readable contract name.
78    #[must_use]
79    pub const fn as_str(self) -> &'static str {
80        match self {
81            Self::U8S8Envelope => "u8s8-envelope",
82            Self::S8S8Kernel => "s8s8-kernel",
83        }
84    }
85}
86
87/// The model component whose maximum reduction length a proof row represents.
88#[derive(Clone, Copy, Debug, Eq, PartialEq)]
89pub enum ExecutionScope {
90    /// Enrollment-only codec encoder.
91    Enrollment,
92    /// Per-frame decode path.
93    Decode,
94    /// Prompt-time text projection/embedding path.
95    Prefill,
96    /// The residual-code microdecoder's one-step execution.
97    Microdecoder,
98    /// The seq-16 residual-code verifier; it shares the microdecoder's per-output K.
99    MicrodecoderVerify,
100    /// Main Qwen talker.
101    Talker,
102}
103
104impl ExecutionScope {
105    /// Stable machine-readable scope name.
106    #[must_use]
107    pub const fn as_str(self) -> &'static str {
108        match self {
109            Self::Enrollment => "enrollment",
110            Self::Decode => "decode",
111            Self::Prefill => "prefill",
112            Self::Microdecoder => "microdecoder",
113            Self::MicrodecoderVerify => "microdecoder_verify_seq16",
114            Self::Talker => "talker",
115        }
116    }
117}
118
119/// One permanent, model-specific i32-overflow obligation.
120#[derive(Clone, Copy, Debug, Eq, PartialEq)]
121pub struct OverflowProofRow {
122    /// Stable row identifier consumed by selftest output and future release receipts.
123    pub id: &'static str,
124    /// Execution regime covered by this row.
125    pub scope: ExecutionScope,
126    /// Pinned census tensor that established this component maximum.
127    pub census_tensor: &'static str,
128    /// Actual reduction length for one output element.
129    pub reduction_k: u32,
130}
131
132/// Component maxima generated from the pinned execution census.
133///
134/// The global 8192 row is enrollment-only; the 7168 codec-decoder row is the binding decode
135/// maximum. Keeping both prevents the larger enrollment shape from accidentally shadowing the
136/// actual real-time requirement.
137pub const OVERFLOW_PROOF_ROWS: &[OverflowProofRow] = &[
138    OverflowProofRow {
139        id: "codec_encoder_global_k8192",
140        scope: ExecutionScope::Enrollment,
141        census_tensor: "encoder.encoder.layers.12.conv.weight",
142        reduction_k: 8192,
143    },
144    OverflowProofRow {
145        id: "codec_decoder_decode_k7168",
146        scope: ExecutionScope::Decode,
147        census_tensor: "decoder.decoder.0.conv.weight",
148        reduction_k: 7168,
149    },
150    OverflowProofRow {
151        id: "speaker_encoder_k4608",
152        scope: ExecutionScope::Enrollment,
153        census_tensor: "speaker_encoder.asp.tdnn.conv.weight",
154        reduction_k: 4608,
155    },
156    OverflowProofRow {
157        id: "microdecoder_step_k3072",
158        scope: ExecutionScope::Microdecoder,
159        census_tensor: "talker.code_predictor.model.layers.0.mlp.down_proj.weight",
160        reduction_k: 3072,
161    },
162    OverflowProofRow {
163        id: "microdecoder_verify_seq16_k3072",
164        scope: ExecutionScope::MicrodecoderVerify,
165        census_tensor: "talker.code_predictor.model.layers.0.mlp.down_proj.weight",
166        reduction_k: 3072,
167    },
168    OverflowProofRow {
169        id: "talker_down_proj_k3072",
170        scope: ExecutionScope::Talker,
171        census_tensor: "talker.model.layers.0.mlp.down_proj.weight",
172        reduction_k: 3072,
173    },
174    OverflowProofRow {
175        id: "text_projection_k2048",
176        scope: ExecutionScope::Prefill,
177        census_tensor: "talker.model.text_embedding.weight",
178        reduction_k: 2048,
179    },
180];
181
182/// One completed proof result.
183#[derive(Clone, Copy, Debug, Eq, PartialEq)]
184pub struct SelftestCheck {
185    /// Row selected from [`OVERFLOW_PROOF_ROWS`].
186    pub row: OverflowProofRow,
187    /// Route that executed the check.
188    pub tier: KernelTier,
189    /// Numeric contract this check exercised.
190    pub contract: DotContract,
191    /// Accumulation performed by that route using all-extreme operands.
192    ///
193    /// `None` means the route overflowed before producing an i32 result; that is a failed proof,
194    /// not a panic or an implicitly widened success.
195    pub accumulator_i32: Option<i32>,
196    /// Independent widened reference for the same dot product.
197    pub reference_i64: i64,
198    /// Whether the route retained exact i32 equality and fit in range.
199    pub passed: bool,
200}
201
202/// A complete selftest result for the dispatched routes in this build.
203#[derive(Clone, Debug, Eq, PartialEq)]
204pub struct SelftestReport {
205    /// Currently selected executable route.
206    pub dispatched: KernelTier,
207    /// Every binding row executed against that route.
208    pub checks: Vec<SelftestCheck>,
209}
210
211impl SelftestReport {
212    /// Whether every executed check has exact i32 equality with its widened reference.
213    #[must_use]
214    pub fn passed(&self) -> bool {
215        self.checks.iter().all(|check| check.passed)
216    }
217}
218
219/// Runs the permanent overflow proof against every route this build can dispatch.
220///
221/// This is deliberately not a compile-time arithmetic assertion. The deployed route executes the
222/// actual all-extreme dot loop and compares that i32 result with a separately widened i64 oracle,
223/// so the same entrypoint can later compare an intrinsic backend before dispatch enables it.
224#[must_use]
225pub fn run_selftest() -> SelftestReport {
226    run_selftest_inner(None)
227}
228
229fn run_selftest_inner(fault_row: Option<&str>) -> SelftestReport {
230    // The receipt must name the route the process actually RUNS, which is the autotuned plan's
231    // decode pick — Int8Tier::dispatch() reports raw capability (SDOT whenever present) and can
232    // disagree with a measured or persisted plan that chose scalar.
233    let dispatched = KernelTier::from_int8(crate::int8::autotuned_plan().decode_gemv);
234    let mut checks = Vec::new();
235    for row in OVERFLOW_PROOF_ROWS.iter().copied() {
236        // U8S8 envelope: the contract ceiling, on the checked scalar path.
237        let accumulator_i32 = scalar_all_extreme_dot_i32(row.reduction_k);
238        let reference_i64 = all_extreme_dot_i64(row.reduction_k);
239        let accumulator_i32 = if fault_row == Some(row.id) {
240            accumulator_i32.map(|accumulator| accumulator.saturating_sub(1))
241        } else {
242            accumulator_i32
243        };
244        checks.push(SelftestCheck {
245            row,
246            tier: KernelTier::Scalar,
247            contract: DotContract::U8S8Envelope,
248            accumulator_i32,
249            reference_i64,
250            passed: accumulator_i32
251                .is_some_and(|accumulator| i64::from(accumulator) == reference_i64),
252        });
253
254        // S8S8 kernel proof: the real dot kernel, on every tier this build can dispatch, at both
255        // all-extreme signs, against the independent i64 oracle and the scalar route's i32.
256        let k = row.reduction_k as usize;
257        let positive = vec![crate::int8::Q8_MAX_ABS; k];
258        let negative = vec![-crate::int8::Q8_MAX_ABS; k];
259        let s8_reference_i64 =
260            i64::from(S8_MAX_ABS) * i64::from(S8_MAX_ABS) * i64::from(row.reduction_k);
261        let scalar_positive =
262            crate::int8::dot_i32(&positive, &positive, crate::int8::Int8Tier::Scalar);
263        for tier in crate::int8::Int8Tier::available() {
264            let up = crate::int8::dot_i32(&positive, &positive, tier);
265            let down = crate::int8::dot_i32(&positive, &negative, tier);
266            let up = if fault_row == Some(row.id) {
267                up.saturating_sub(1)
268            } else {
269                up
270            };
271            let passed = i64::from(up) == s8_reference_i64
272                && i64::from(down) == -s8_reference_i64
273                && up == scalar_positive;
274            checks.push(SelftestCheck {
275                row,
276                tier: KernelTier::from_int8(tier),
277                contract: DotContract::S8S8Kernel,
278                accumulator_i32: Some(up),
279                reference_i64: s8_reference_i64,
280                passed,
281            });
282        }
283    }
284    SelftestReport { dispatched, checks }
285}
286
287fn scalar_all_extreme_dot_i32(reduction_k: u32) -> Option<i32> {
288    let term = i32::from(U8_MAX) * i32::from(S8_MAX_ABS);
289    (0..reduction_k).try_fold(0_i32, |accumulator, _| accumulator.checked_add(term))
290}
291
292fn all_extreme_dot_i64(reduction_k: u32) -> i64 {
293    i64::from(U8_MAX) * i64::from(S8_MAX_ABS) * i64::from(reduction_k)
294}
295
296#[cfg(test)]
297mod tests {
298    use super::*;
299
300    //  Crate-local pinned copy; byte-identity with the truth-pack canonical is asserted by a
301    //  unit test whenever the repository checkout is present (crates.io builds have no repo).
302    const CENSUS: &str = include_str!("../pinned/EXECUTION_CENSUS.json");
303
304    #[test]
305    fn every_deployed_row_equals_its_i64_reference_on_every_tier() {
306        let report = run_selftest();
307        assert!(report.passed(), "{report:#?}");
308
309        let envelope: Vec<_> = report
310            .checks
311            .iter()
312            .filter(|check| check.contract == DotContract::U8S8Envelope)
313            .collect();
314        assert_eq!(envelope.len(), OVERFLOW_PROOF_ROWS.len());
315        for check in &envelope {
316            assert_eq!(check.tier, KernelTier::Scalar, "{}", check.row.id);
317            assert_eq!(
318                check.accumulator_i32.map(i64::from),
319                Some(check.reference_i64),
320                "{}",
321                check.row.id
322            );
323        }
324
325        let tiers = crate::int8::Int8Tier::available();
326        let s8s8: Vec<_> = report
327            .checks
328            .iter()
329            .filter(|check| check.contract == DotContract::S8S8Kernel)
330            .collect();
331        assert_eq!(s8s8.len(), OVERFLOW_PROOF_ROWS.len() * tiers.len());
332        for check in &s8s8 {
333            assert_eq!(
334                check.accumulator_i32.map(i64::from),
335                Some(check.reference_i64),
336                "{} on {}",
337                check.row.id,
338                check.tier.as_str()
339            );
340        }
341
342        assert!(
343            tiers
344                .iter()
345                .any(|tier| KernelTier::from_int8(*tier) == report.dispatched),
346            "dispatched route {:?} is not among the available tiers",
347            report.dispatched
348        );
349    }
350
351    #[test]
352    fn the_sdot_island_is_proven_on_this_silicon_when_present() {
353        // On an Apple Silicon dev host the island must actually run — a silently absent
354        // FEAT_DotProd would turn every SDOT proof row into vacuous truth.
355        if cfg!(all(target_arch = "aarch64", feature = "neon-dotprod"))
356            && crate::int8::neon_sdot_available()
357        {
358            let report = run_selftest();
359            assert!(
360                report.checks.iter().any(|check| {
361                    check.tier == KernelTier::NeonSdot
362                        && check.contract == DotContract::S8S8Kernel
363                        && check.passed
364                }),
365                "FEAT_DotProd reported but no SDOT proof row executed"
366            );
367        }
368    }
369
370    #[test]
371    fn census_binding_rows_are_not_replaced_by_a_stale_talker_only_bound() {
372        for (tensor, reduction_k) in [
373            ("encoder.encoder.layers.12.conv.weight", 8192),
374            ("decoder.decoder.0.conv.weight", 7168),
375            ("speaker_encoder.asp.tdnn.conv.weight", 4608),
376            (
377                "talker.code_predictor.model.layers.0.mlp.down_proj.weight",
378                3072,
379            ),
380            ("talker.model.layers.0.mlp.down_proj.weight", 3072),
381            ("talker.model.text_embedding.weight", 2048),
382        ] {
383            assert!(
384                OVERFLOW_PROOF_ROWS
385                    .iter()
386                    .any(|row| { row.census_tensor == tensor && row.reduction_k == reduction_k }),
387                "proof row missing for {tensor} K={reduction_k}"
388            );
389            assert!(
390                CENSUS.contains(&format!("\"tensor\": \"{tensor}\"")),
391                "pinned census no longer contains {tensor}; regenerate the proof table"
392            );
393            assert!(
394                CENSUS.split('{').any(|object| {
395                    object.contains(&format!("\"tensor\": \"{tensor}\""))
396                        && object.contains(&format!("\"k\": {reduction_k}"))
397                }),
398                "pinned census no longer gives {tensor} reduction K={reduction_k}; regenerate the proof table"
399            );
400        }
401        assert!(
402            CENSUS.contains("\"decode_path_binding_row\""),
403            "proof table requires a separately named decode binding"
404        );
405    }
406
407    #[test]
408    fn a_corrupted_route_fails_the_selftest_instead_of_reporting_green() {
409        let report = run_selftest_inner(Some("codec_decoder_decode_k7168"));
410        assert!(
411            !report.passed(),
412            "fault injection must fail the aggregate verdict"
413        );
414        assert!(
415            report
416                .checks
417                .iter()
418                .any(|check| { check.row.id == "codec_decoder_decode_k7168" && !check.passed })
419        );
420    }
421
422    #[test]
423    fn i32_bound_remains_strictly_below_the_widened_limit() {
424        for row in OVERFLOW_PROOF_ROWS {
425            let reference = all_extreme_dot_i64(row.reduction_k);
426            assert!(
427                reference < i64::from(i32::MAX),
428                "{} no longer fits i32: {reference}",
429                row.id
430            );
431        }
432    }
433
434    #[test]
435    fn pinned_census_copy_matches_the_truth_pack_canonical() {
436        //  The crate-local copy exists because `cargo package` cannot ship the truth pack; the
437        //  truth pack stays canonical. A drifted copy silently pins the selftest to a stale
438        //  census, so equality is asserted byte-for-byte whenever the repo checkout is present.
439        let canonical = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
440            .join("../../docs/truth-pack/EXECUTION_CENSUS.json");
441        match std::fs::read_to_string(&canonical) {
442            Ok(bytes) => assert_eq!(
443                bytes, CENSUS,
444                "pinned/EXECUTION_CENSUS.json drifted from the truth-pack canonical; re-copy it"
445            ),
446            Err(_) => eprintln!(
447                "SKIP pinned_census_copy_matches_the_truth_pack_canonical: no repo checkout at {}",
448                canonical.display()
449            ),
450        }
451    }
452}