1use std::fmt;
15
16use super::author::{self, Authored, NotYet, RowState, TpAuthored};
17use super::spec::ModelSpec;
18use crate::crypto_accel::sha256;
19
20#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
22pub enum Cut {
23 Decode { ctx: usize },
25 Prefill { rows: usize, ctx: usize },
27 Batch { rows: usize, ctx: usize },
29 Forward,
31 ForwardLayer { layer: usize },
33 ForwardHead,
35 DecodeEmbed,
37 DecodeLayer { layer: usize, ctx: usize },
39 DecodeHead,
41 BatchEmbed { rows: usize },
43 BatchLayer { layer: usize, rows: usize, ctx: usize },
45 BatchHead { rows: usize },
47 PrefillLayer { layer: usize, rows: usize, ctx: usize },
49 PrefillHead { rows: usize },
51}
52
53impl Cut {
54 pub fn write(self, spec: &ModelSpec, dir: &str) -> Authored {
57 match self {
58 Cut::Decode { ctx } => author::decode_step(spec, dir, ctx, 1, 1),
59 Cut::Prefill { rows, ctx } => author::prefill(spec, dir, ctx, &vec![1; rows], 1),
60 Cut::Batch { rows, ctx } => author::decode_batch(spec, dir, ctx, &vec![(1, 1); rows]),
61 Cut::Forward => author::forward(spec, dir),
62 Cut::ForwardLayer { layer } => author::layer(spec, layer, dir),
63 Cut::ForwardHead => author::head(spec, dir),
64 Cut::DecodeEmbed => author::decode_embed(spec, dir, 1),
65 Cut::DecodeLayer { layer, ctx } => author::decode_layer(spec, layer, dir, ctx, 1),
66 Cut::DecodeHead => author::decode_head(spec, dir),
67 Cut::BatchEmbed { rows } => author::decode_batch_embed(spec, dir, &vec![1; rows]),
68 Cut::BatchLayer { layer, rows, ctx } => {
69 author::stacked_layer(spec, layer, dir, ctx, &vec![1; rows], RowState::PerSequence)
70 }
71 Cut::BatchHead { rows } => author::decode_batch_head(spec, dir, rows),
72 Cut::PrefillLayer { layer, rows, ctx } => {
73 author::stacked_layer(spec, layer, dir, ctx, &(1..=rows).collect::<Vec<_>>(), RowState::Shared)
74 }
75 Cut::PrefillHead { rows } => author::prefill_head(spec, dir, rows),
76 }
77 }
78
79 pub fn write_split(self, spec: &ModelSpec, dir: &str, tp: usize) -> Result<TpAuthored, NotYet> {
83 match self {
84 Cut::Decode { ctx } => author::tp_decode_step(spec, dir, ctx, 1, 1, tp),
85 Cut::Batch { rows, ctx } => author::tp_decode_batch(spec, dir, ctx, &vec![(1, 1); rows], tp),
86 Cut::DecodeLayer { layer, ctx } => author::tp_decode_layer(spec, layer, dir, ctx, 1, tp),
87 Cut::BatchLayer { layer, rows, ctx } => author::tp_stacked_layer(spec, layer, dir, ctx, &vec![1; rows], tp),
88 _ => Err(NotYet("a cut other than a decode step, a batch or a layer of either, split over chips")),
89 }
90 }
91}
92
93impl fmt::Display for Cut {
94 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
95 match self {
96 Cut::Decode { ctx } => write!(f, "decode step, ctx {ctx}"),
97 Cut::Prefill { rows, ctx } => write!(f, "prefill chunk of {rows} rows, ctx {ctx}"),
98 Cut::Batch { rows, ctx } => write!(f, "batch of {rows} sequences, ctx {ctx}"),
99 Cut::Forward => write!(f, "forward"),
100 Cut::ForwardLayer { layer } => write!(f, "forward layer {layer}"),
101 Cut::ForwardHead => write!(f, "forward head"),
102 Cut::DecodeEmbed => write!(f, "decode step's embedding"),
103 Cut::DecodeLayer { layer, ctx } => write!(f, "decode step's layer {layer}, ctx {ctx}"),
104 Cut::DecodeHead => write!(f, "decode step's head"),
105 Cut::BatchEmbed { rows } => write!(f, "batch of {rows} sequences' embedding"),
106 Cut::BatchLayer { layer, rows, ctx } => write!(f, "batch of {rows} sequences' layer {layer}, ctx {ctx}"),
107 Cut::BatchHead { rows } => write!(f, "batch of {rows} sequences' head"),
108 Cut::PrefillLayer { layer, rows, ctx } => write!(f, "prefill chunk of {rows} rows' layer {layer}, ctx {ctx}"),
109 Cut::PrefillHead { rows } => write!(f, "prefill chunk of {rows} rows' head"),
110 }
111 }
112}
113
114#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
117pub struct Identity {
118 pub cut: Cut,
119 pub chips: usize,
120 pub sha256: [u8; 32],
121}
122
123impl Identity {
124 pub fn of(cut: Cut, source: &str) -> Identity {
126 Identity::of_split(cut, 1, source)
127 }
128
129 pub fn of_split(cut: Cut, chips: usize, source: &str) -> Identity {
131 Identity { cut, chips, sha256: sha256(source.as_bytes()) }
132 }
133
134 pub fn hex(&self) -> String {
136 self.sha256.iter().map(|b| format!("{b:02x}")).collect()
137 }
138
139 pub fn line(&self) -> String {
142 match self.chips {
143 1 => format!("LOGOS program: {}, sha256 {}", self.cut, self.hex()),
144 n => format!("LOGOS program: {} over {n} chips, sha256 {}", self.cut, self.hex()),
145 }
146 }
147}
148
149pub fn written(spec: &ModelSpec, cut: Cut) -> (Authored, Identity) {
151 written_in(spec, cut, "")
152}
153
154pub fn written_in(spec: &ModelSpec, cut: Cut, dir: &str) -> (Authored, Identity) {
156 let authored = cut.write(spec, dir);
157 let identity = Identity::of(cut, &authored.0);
158 (authored, identity)
159}
160
161pub fn prefill_at(spec: &ModelSpec, dir: &str, ctx: usize, toks: &[usize], pos0: usize) -> Authored {
165 author::prefill(spec, dir, ctx, toks, pos0)
166}
167
168pub fn decode_at(spec: &ModelSpec, dir: &str, ctx: usize, tok: usize, pos: usize) -> Authored {
170 author::decode_step(spec, dir, ctx, tok, pos)
171}
172
173pub fn written_split(spec: &ModelSpec, cut: Cut, dir: &str, tp: usize) -> Result<(TpAuthored, Identity), NotYet> {
175 let authored = cut.write_split(spec, dir, tp)?;
176 let identity = Identity::of_split(cut, tp, &authored.0);
177 Ok((authored, identity))
178}
179
180#[cfg(test)]
181#[path = "../../../logicaffeine_tests/unit/logicaffeine_compile/model/program/tests.rs"]
182mod tests;