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}