metrale_cache/kv_cache/
catalog.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2
3//! 2026-09-25: The [`KvCacheDtype`] catalogue: every variant and its canonical
4//! `--kv-cache-dtype` spelling.
5//!
6//! The flag is an `Option<String>` in clap, so the list of valid values comes
7//! from here: the server's `options_for_flag` builds it from
8//! [`KvCacheDtype::ALL`] for the CLI manifest and the TUI option picker.
9//!
10//! Owner: cache.
11//! Invariants:
12//! - The `name` match has no wildcard arm, so a new variant does not compile
13//!   until it has a spelling.
14//! - Every `ALL` entry's `name` parses back to that entry (tested below).
15
16use super::KvCacheDtype;
17
18impl KvCacheDtype {
19    /// 2026-09-25: Every variant, in declaration order. Nothing checks that a
20    /// new variant is added here; add it together with its [`KvCacheDtype::name`]
21    /// arm, which the compiler does require.
22    pub const ALL: [KvCacheDtype; 16] = [
23        KvCacheDtype::Bf16,
24        KvCacheDtype::Fp8,
25        KvCacheDtype::Nvfp4,
26        KvCacheDtype::Turbo4,
27        KvCacheDtype::Turbo3,
28        KvCacheDtype::Turbo2,
29        KvCacheDtype::Turbo8,
30        KvCacheDtype::Turbo4KTurbo3V,
31        KvCacheDtype::Turbo4KTurbo8V,
32        KvCacheDtype::Turbo3KTurbo8V,
33        KvCacheDtype::Bf16KTurbo4V,
34        KvCacheDtype::Bf16KTurbo3V,
35        KvCacheDtype::Fp8KTurbo4V,
36        KvCacheDtype::Fp8KTurbo3V,
37        KvCacheDtype::Bf16KTurbo2V,
38        KvCacheDtype::Fp8KTurbo2V,
39    ];
40
41    /// 2026-09-25: The canonical `--kv-cache-dtype` spelling. `Display`
42    /// delegates here, so a listed value is the string `FromStr` accepts; the
43    /// tests below check that round trip.
44    pub const fn name(self) -> &'static str {
45        match self {
46            KvCacheDtype::Bf16 => "bf16",
47            KvCacheDtype::Fp8 => "fp8",
48            KvCacheDtype::Nvfp4 => "nvfp4",
49            KvCacheDtype::Turbo4 => "turbo4",
50            KvCacheDtype::Turbo3 => "turbo3",
51            KvCacheDtype::Turbo2 => "turbo2",
52            KvCacheDtype::Turbo8 => "turbo8",
53            KvCacheDtype::Turbo4KTurbo3V => "turbo4k_turbo3v",
54            KvCacheDtype::Turbo4KTurbo8V => "turbo4k_turbo8v",
55            KvCacheDtype::Turbo3KTurbo8V => "turbo3k_turbo8v",
56            KvCacheDtype::Bf16KTurbo4V => "bf16k_turbo4v",
57            KvCacheDtype::Bf16KTurbo3V => "bf16k_turbo3v",
58            KvCacheDtype::Fp8KTurbo4V => "fp8k_turbo4v",
59            KvCacheDtype::Fp8KTurbo3V => "fp8k_turbo3v",
60            KvCacheDtype::Bf16KTurbo2V => "bf16k_turbo2v",
61            KvCacheDtype::Fp8KTurbo2V => "fp8k_turbo2v",
62        }
63    }
64}
65
66#[cfg(test)]
67mod tests {
68    use super::KvCacheDtype;
69
70    #[test]
71    fn every_listed_name_parses_back_to_the_variant_that_produced_it() {
72        // 2026-09-25: Each listed name must parse, to the variant that
73        // produced it, and `Display` must print that same name.
74        for dtype in KvCacheDtype::ALL {
75            let parsed: KvCacheDtype = dtype
76                .name()
77                .parse()
78                .unwrap_or_else(|e| panic!("{} does not parse: {e:#}", dtype.name()));
79            assert_eq!(
80                parsed,
81                dtype,
82                "{} parses to a different dtype",
83                dtype.name()
84            );
85            assert_eq!(
86                dtype.to_string(),
87                dtype.name(),
88                "Display and the catalogue disagree"
89            );
90        }
91    }
92
93    #[test]
94    fn the_catalogue_has_no_duplicates() {
95        // 2026-09-25: A duplicate would show one choice twice in a picker.
96        for (i, a) in KvCacheDtype::ALL.iter().enumerate() {
97            for b in &KvCacheDtype::ALL[i + 1..] {
98                assert_ne!(a, b, "{} is listed twice", a.name());
99            }
100        }
101    }
102}