metrale_circuit/
model_buffer.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2
3//! 2026-09-30: The model buffers a circuit's declared outputs bind to (M5, LIFECYCLE-DESIGN.md
4//! section 3.4): a block's `outputs` name each edge read outside the program and the buffer it
5//! lands in, so the executor places external edges by declaration, never by guessing from the
6//! producing op.
7//!
8//! Owner: metrale-circuit.
9//! Invariants: the stream edges are the model's hidden buffer by construction and are not
10//! listed here.
11
12/// 2026-09-30: A buffer the model owns that a program's output lands in.
13#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
14pub enum ModelBuffer {
15    /// 2026-09-30: The vocabulary logits the sampler (or the host) reads.
16    Logits,
17    /// 2026-09-30: The sampled tokens.
18    Tokens,
19    /// 2026-09-30: The MTP draft head's token embedding, which the draft runner fills.
20    DraftEmbed,
21}
22
23impl ModelBuffer {
24    const NAMES: [(ModelBuffer, &'static str); 3] = [
25        (ModelBuffer::Logits, "logits"),
26        (ModelBuffer::Tokens, "tokens"),
27        (ModelBuffer::DraftEmbed, "draft_embed"),
28    ];
29
30    /// 2026-09-30: The spelling in the circuit TOML (`outputs = [{ edge, buffer }]`).
31    pub fn parse(s: &str) -> Option<Self> {
32        Self::NAMES.iter().find(|(_, n)| *n == s).map(|(b, _)| *b)
33    }
34
35    /// 2026-09-30: The spelling.
36    pub fn name(self) -> &'static str {
37        Self::NAMES
38            .iter()
39            .find(|(b, _)| *b == self)
40            .map(|(_, n)| *n)
41            .unwrap_or("?")
42    }
43}