1use alloc::{string::String, vec, vec::Vec};
2use core::{fmt, marker::PhantomData};
3
4use super::tensor::{BoolTensorSerde, FloatTensorSerde, IntTensorSerde};
5use super::{PrecisionSettings, Record};
6use crate::module::{Param, ParamId};
7
8use burn_tensor::{Bool, Int, Tensor, backend::Backend};
9
10use hashbrown::HashMap;
11use serde::{
12 Deserialize, Serialize,
13 de::{Error, SeqAccess, Visitor},
14 ser::SerializeTuple,
15};
16
17impl<B> Record<B> for ()
18where
19 B: Backend,
20{
21 type Item<S: PrecisionSettings> = ();
22
23 fn into_item<S: PrecisionSettings>(self) -> Self::Item<S> {}
24
25 fn from_item<S: PrecisionSettings>(_item: Self::Item<S>, _device: &B::Device) -> Self {}
26}
27
28impl<T, B> Record<B> for Vec<T>
29where
30 T: Record<B>,
31 B: Backend,
32{
33 type Item<S: PrecisionSettings> = Vec<T::Item<S>>;
34
35 fn into_item<S: PrecisionSettings>(self) -> Self::Item<S> {
36 self.into_iter().map(Record::into_item).collect()
37 }
38
39 fn from_item<S: PrecisionSettings>(item: Self::Item<S>, device: &B::Device) -> Self {
40 item.into_iter()
41 .map(|i| Record::from_item(i, device))
42 .collect()
43 }
44}
45
46impl<T, B> Record<B> for Option<T>
47where
48 T: Record<B>,
49 B: Backend,
50{
51 type Item<S: PrecisionSettings> = Option<T::Item<S>>;
52
53 fn into_item<S: PrecisionSettings>(self) -> Self::Item<S> {
54 self.map(Record::into_item)
55 }
56
57 fn from_item<S: PrecisionSettings>(item: Self::Item<S>, device: &B::Device) -> Self {
58 item.map(|i| Record::from_item(i, device))
59 }
60}
61
62impl<const N: usize, T, B> Record<B> for [T; N]
63where
64 T: Record<B>,
65 B: Backend,
66{
67 type Item<S: PrecisionSettings> = Array<N, T::Item<S>>;
73
74 fn into_item<S: PrecisionSettings>(self) -> Self::Item<S> {
75 Array(self.map(Record::into_item))
76 }
77
78 fn from_item<S: PrecisionSettings>(item: Self::Item<S>, device: &B::Device) -> Self {
79 item.0.map(|i| Record::from_item(i, device))
80 }
81}
82
83macro_rules! impl_record_tuple {
89 ([$($r:ident),*][$($i:tt),*]) => {
92 impl<B, $($r,)*> Record<B> for ($($r,)*)
93 where
94 B: Backend,
95 $($r: Record<B>),*
96 {
97 type Item<S: PrecisionSettings> = ($($r::Item<S>,)*);
98
99 fn into_item<S: PrecisionSettings>(self) -> Self::Item<S> {
100 ($(self.$i.into_item(),)*)
101 }
102
103 fn from_item<S: PrecisionSettings>(item: Self::Item<S>, device: &B::Device) -> Self {
104 ($(Record::from_item(item.$i, device),)*)
105 }
106 }
107 };
108}
109
110impl_record_tuple!([R0, R1][0, 1]);
111impl_record_tuple!([R0, R1, R2][0, 1, 2]);
112impl_record_tuple!([R0, R1, R2, R3][0, 1, 2, 3]);
113impl_record_tuple!([R0, R1, R2, R3, R4][0, 1, 2, 3, 4]);
114impl_record_tuple!([R0, R1, R2, R3, R4, R5][0, 1, 2, 3, 4, 5]);
115impl_record_tuple!([R0, R1, R2, R3, R4, R5, R6][0, 1, 2, 3, 4, 5, 6]);
116impl_record_tuple!([R0, R1, R2, R3, R4, R5, R6, R7][0, 1, 2, 3, 4, 5, 6, 7]);
117impl_record_tuple!([R0, R1, R2, R3, R4, R5, R6, R7, R8][0, 1, 2, 3, 4, 5, 6, 7, 8]);
118impl_record_tuple!([R0, R1, R2, R3, R4, R5, R6, R7, R8, R9][0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
119
120impl<T, B> Record<B> for HashMap<ParamId, T>
121where
122 T: Record<B>,
123 B: Backend,
124{
125 type Item<S: PrecisionSettings> = HashMap<String, T::Item<S>>;
126
127 fn into_item<S: PrecisionSettings>(self) -> Self::Item<S> {
128 let mut items = HashMap::with_capacity(self.len());
129 self.into_iter().for_each(|(id, record)| {
130 items.insert(id.serialize(), record.into_item());
131 });
132 items
133 }
134
135 fn from_item<S: PrecisionSettings>(item: Self::Item<S>, device: &B::Device) -> Self {
136 let mut record = HashMap::with_capacity(item.len());
137 item.into_iter().for_each(|(id, item)| {
138 record.insert(ParamId::deserialize(&id), T::from_item(item, device));
139 });
140 record
141 }
142}
143
144#[derive(new, Debug, Clone, Serialize, Deserialize)]
146pub struct ParamSerde<T> {
147 id: String,
148 param: T,
149}
150
151impl<B, const D: usize> Record<B> for Param<Tensor<B, D>>
152where
153 B: Backend,
154{
155 type Item<S: PrecisionSettings> = ParamSerde<FloatTensorSerde<S>>;
156
157 fn into_item<S: PrecisionSettings>(self) -> Self::Item<S> {
158 let (id, tensor) = self.consume();
159 ParamSerde::new(id.serialize(), tensor.into_item())
160 }
161
162 fn from_item<S: PrecisionSettings>(item: Self::Item<S>, device: &B::Device) -> Self {
163 Param::initialized(
164 ParamId::deserialize(&item.id),
165 Tensor::from_item(item.param, device).require_grad(), )
168 }
169}
170
171impl<B, const D: usize> Record<B> for Param<Tensor<B, D, Int>>
172where
173 B: Backend,
174{
175 type Item<S: PrecisionSettings> = ParamSerde<IntTensorSerde<S>>;
176
177 fn into_item<S: PrecisionSettings>(self) -> Self::Item<S> {
178 let (id, tensor) = self.consume();
179 ParamSerde::new(id.serialize(), tensor.into_item())
180 }
181
182 fn from_item<S: PrecisionSettings>(item: Self::Item<S>, device: &B::Device) -> Self {
183 Param::initialized(
184 ParamId::deserialize(&item.id),
185 Tensor::from_item(item.param, device),
186 )
187 }
188}
189
190impl<B, const D: usize> Record<B> for Param<Tensor<B, D, Bool>>
191where
192 B: Backend,
193{
194 type Item<S: PrecisionSettings> = ParamSerde<BoolTensorSerde>;
195
196 fn into_item<S: PrecisionSettings>(self) -> Self::Item<S> {
197 let (id, tensor) = self.consume();
198 ParamSerde::new(id.serialize(), tensor.into_item::<S>())
199 }
200
201 fn from_item<S: PrecisionSettings>(item: Self::Item<S>, device: &B::Device) -> Self {
202 Param::initialized(
203 ParamId::deserialize(&item.id),
204 Tensor::from_item::<S>(item.param, device),
205 )
206 }
207}
208
209macro_rules! primitive {
211 ($type:ty) => {
212 impl<B: Backend> Record<B> for $type {
213 type Item<S: PrecisionSettings> = $type;
214
215 fn into_item<S: PrecisionSettings>(self) -> Self::Item<S> {
216 self
217 }
218
219 fn from_item<S: PrecisionSettings>(item: Self::Item<S>, _device: &B::Device) -> Self {
220 item
221 }
222 }
223 };
224}
225
226primitive!(alloc::string::String);
228primitive!(bool);
229
230primitive!(f64);
232primitive!(f32);
233
234primitive!(half::bf16);
235primitive!(half::f16);
236
237primitive!(usize);
239primitive!(u64);
240primitive!(u32);
241primitive!(u16);
242primitive!(u8);
243
244primitive!(isize);
246primitive!(i64);
247primitive!(i32);
248primitive!(i16);
249primitive!(i8);
250
251pub struct Array<const N: usize, T>([T; N]);
259
260impl<T: Serialize, const N: usize> Serialize for Array<N, T> {
261 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
262 where
263 S: serde::Serializer,
264 {
265 let mut seq = serializer.serialize_tuple(self.0.len())?;
266 for element in &self.0 {
267 seq.serialize_element(element)?;
268 }
269 seq.end()
270 }
271}
272
273impl<'de, T, const N: usize> Deserialize<'de> for Array<N, T>
274where
275 T: Deserialize<'de>,
276{
277 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
278 where
279 D: serde::Deserializer<'de>,
280 {
281 struct ArrayVisitor<T, const N: usize> {
282 marker: PhantomData<T>,
283 }
284
285 impl<'de, T, const N: usize> Visitor<'de> for ArrayVisitor<T, N>
286 where
287 T: Deserialize<'de>,
288 {
289 type Value = Array<N, T>;
290
291 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
292 formatter.write_str("a fixed size array")
293 }
294
295 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
296 where
297 A: SeqAccess<'de>,
298 {
299 let mut items = vec![];
300
301 for i in 0..N {
302 let item = seq
303 .next_element()?
304 .ok_or_else(|| Error::invalid_length(i, &self))?;
305 items.push(item);
306 }
307
308 let array: [T; N] = items
309 .into_iter()
310 .collect::<Vec<_>>()
311 .try_into()
312 .map_err(|_| "An array of size {N}")
313 .unwrap();
314
315 Ok(Array(array))
316 }
317 }
318
319 deserializer.deserialize_tuple(
320 N,
321 ArrayVisitor {
322 marker: PhantomData,
323 },
324 )
325 }
326}