1use serde::{Deserialize, Serialize};
4use std::collections::BTreeMap;
5
6#[derive(Debug, Clone, Eq, Hash, PartialEq, Serialize, Deserialize)]
8#[serde(rename_all = "snake_case")]
9pub enum TensorDtype {
10 Bool,
12 F32,
14 F16,
16 Bf16,
18 I8,
20 U8,
22 U16,
24 U32,
26 U64,
28 I16,
30 I32,
32 I64,
34 F64,
36 Complex64,
38 Encoded(String),
40}
41
42#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
44pub struct TensorStorage {
45 pub member: String,
47 pub offset: u64,
49 pub length: u64,
51}
52
53#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
55pub struct TensorDescriptor {
56 pub name: String,
58 pub shape: Vec<usize>,
60 pub dtype: TensorDtype,
62 pub storage: Option<TensorStorage>,
64}
65
66#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
68pub struct TensorCatalog {
69 tensors: BTreeMap<String, TensorDescriptor>,
70}
71
72impl TensorCatalog {
73 pub fn new(tensors: impl IntoIterator<Item = TensorDescriptor>) -> Result<Self, CatalogError> {
76 let mut map = BTreeMap::new();
77 for tensor in tensors {
78 if tensor.name.trim().is_empty() {
79 return Err(CatalogError::EmptyName);
80 }
81 if tensor.shape.contains(&0) {
82 return Err(CatalogError::InvalidShape(tensor.name));
83 }
84 let name = tensor.name.clone();
85 if map.insert(name.clone(), tensor).is_some() {
86 return Err(CatalogError::Duplicate(name));
87 }
88 }
89 Ok(Self { tensors: map })
90 }
91 pub fn get(&self, name: &str) -> Option<&TensorDescriptor> {
93 self.tensors.get(name)
94 }
95 pub fn descriptors(&self) -> impl Iterator<Item = &TensorDescriptor> {
97 self.tensors.values()
98 }
99 pub fn len(&self) -> usize {
101 self.tensors.len()
102 }
103 pub fn is_empty(&self) -> bool {
105 self.tensors.is_empty()
106 }
107}
108
109#[derive(Debug, Clone, Eq, PartialEq, thiserror::Error)]
111pub enum CatalogError {
112 #[error("checkpoint tensor name must not be empty")]
114 EmptyName,
115 #[error("duplicate checkpoint tensor {0}")]
117 Duplicate(String),
118 #[error("checkpoint tensor {0} has an invalid shape")]
120 InvalidShape(String),
121}