1use std::collections::hash_map::DefaultHasher;
11use std::hash::{Hash, Hasher};
12
13use crate::dynamic::sym;
14use crate::shape::DimBinding;
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18pub enum ModelPhase {
19 Prefill,
20 Decode,
21 Encoder,
22 Inference,
23}
24
25#[derive(Debug, Clone, PartialEq, Eq)]
27pub struct ModelVariant {
28 pub batch: usize,
29 pub seq: usize,
30 pub past_seq: Option<usize>,
31 pub phase: ModelPhase,
32 pub extra: Vec<(u32, usize)>,
34}
35
36impl ModelVariant {
37 pub fn prefill(batch: usize, seq: usize) -> Self {
38 Self {
39 batch,
40 seq,
41 past_seq: None,
42 phase: ModelPhase::Prefill,
43 extra: Vec::new(),
44 }
45 }
46
47 pub fn decode(batch: usize, past_seq: usize, new_tokens: usize) -> Self {
49 Self {
50 batch,
51 seq: new_tokens,
52 past_seq: Some(past_seq),
53 phase: ModelPhase::Decode,
54 extra: Vec::new(),
55 }
56 }
57
58 pub fn encoder(batch: usize, seq: usize) -> Self {
59 Self {
60 batch,
61 seq,
62 past_seq: None,
63 phase: ModelPhase::Encoder,
64 extra: Vec::new(),
65 }
66 }
67
68 pub fn with_extra(mut self, symbol: u32, size: usize) -> Self {
69 self.extra.push((symbol, size));
70 self
71 }
72
73 pub fn cache_key(&self) -> u64 {
75 let mut h = DefaultHasher::new();
76 self.phase.hash(&mut h);
77 self.batch.hash(&mut h);
78 self.seq.hash(&mut h);
79 self.past_seq.hash(&mut h);
80 for (sym, size) in &self.extra {
81 sym.hash(&mut h);
82 size.hash(&mut h);
83 }
84 h.finish()
85 }
86
87 pub fn dim_binding(&self) -> DimBinding {
89 let mut b = match (self.phase, self.past_seq) {
90 (ModelPhase::Decode, Some(past)) => DimBinding::batch_past_seq(self.batch, past),
91 _ => DimBinding::batch_seq(self.batch, self.seq),
92 };
93 if self.phase == ModelPhase::Decode {
94 b.set(sym::SEQ, self.seq);
95 }
96 for (sym, size) in &self.extra {
97 b.set(*sym, *size);
98 }
99 b
100 }
101}
102
103#[cfg(test)]
104mod tests {
105 use super::*;
106
107 #[test]
108 fn prefill_binding_sets_batch_seq() {
109 let v = ModelVariant::prefill(2, 128);
110 let b = v.dim_binding();
111 assert_eq!(b.get(sym::BATCH), Some(2));
112 assert_eq!(b.get(sym::SEQ), Some(128));
113 }
114
115 #[test]
116 fn decode_binding_sets_past_and_new_seq() {
117 let v = ModelVariant::decode(1, 64, 1);
118 let b = v.dim_binding();
119 assert_eq!(b.get(sym::BATCH), Some(1));
120 assert_eq!(b.get(sym::PAST_SEQ), Some(64));
121 assert_eq!(b.get(sym::SEQ), Some(1));
122 }
123
124 #[test]
125 fn cache_key_differs_by_phase() {
126 let a = ModelVariant::prefill(1, 8).cache_key();
127 let b = ModelVariant::decode(1, 7, 1).cache_key();
128 assert_ne!(a, b);
129 }
130}