burn_core/module/param/
constant.rs1use alloc::format;
2use burn_tensor::kind::{Autodiff, Basic};
3use core::fmt::Display;
4
5use crate as burn;
6use crate::module::{
7 AutodiffModule, Content, Devices, Module, ModuleDisplay, ModuleDisplayDefault, ModuleMapper,
8 ModuleVisitor,
9};
10use burn_tensor::{Device, Tensor};
11
12#[macro_export]
14macro_rules! empty {
15 (module) => {
16 fn visit<V: burn::module::ModuleVisitor>(&self, _visitor: &mut V) {
17 }
19
20 fn map<M: burn::module::ModuleMapper>(self, _mapper: &mut M) -> Self {
21 self
22 }
23
24 fn to_device(self, _: &burn::tensor::Device) -> Self {
25 self
26 }
27
28 fn fork(self, _: &burn::tensor::Device) -> Self {
29 self
30 }
31
32 fn collect_devices(&self, devices: burn::module::Devices) -> burn::module::Devices {
33 devices
34 }
35 };
36
37 (ad_module, $type:ty) => {
38 fn valid(&self) -> Self {
39 self.clone()
40 }
41
42 fn from_inner(module: Self) -> Self {
43 module
44 }
45 };
46
47 ($type:ty) => {
48 impl burn::module::Module for $type {
49 empty!(module);
50 }
51
52 impl burn::module::AutodiffModule for $type {
53 empty!(ad_module, $type);
54 }
55
56 impl burn::module::ModuleDisplayDefault for $type {
57 fn content(&self, content: burn::module::Content) -> Option<burn::module::Content> {
58 let string = format!("{}", self);
59 content.add_formatted(&string).optional()
60 }
61 }
62
63 impl burn::module::ModuleDisplay for $type {}
64 };
65}
66
67empty!(alloc::string::String);
71empty!(bool);
72
73empty!(f64);
75empty!(f32);
76empty!(half::bf16);
77empty!(half::f16);
78
79empty!(usize);
81empty!(u64);
82empty!(u32);
83empty!(u16);
84empty!(u8);
85
86empty!(isize);
88empty!(i64);
89empty!(i32);
90empty!(i16);
91empty!(i8);
92
93impl burn::module::ModuleDisplay for str {}
94impl burn::module::ModuleDisplayDefault for str {
95 fn content(&self, content: burn::module::Content) -> Option<burn::module::Content> {
96 content.add_formatted(&self).optional()
97 }
98}
99
100impl<const D: usize, K: Basic> Module for Tensor<D, K> {
102 fn visit<V: ModuleVisitor>(&self, _visitor: &mut V) {}
103
104 fn map<M: ModuleMapper>(self, _mapper: &mut M) -> Self {
105 self
106 }
107
108 fn to_device(self, device: &Device) -> Self {
109 self.to_device(device)
110 }
111
112 fn fork(self, device: &Device) -> Self {
113 self.to_device(device)
114 }
115
116 fn collect_devices(&self, mut devices: Devices) -> Devices {
117 let device = self.device();
118
119 if !devices.contains(&device) {
120 devices.push(device)
121 }
122
123 devices
124 }
125}
126
127impl<const D: usize, K: Basic> ModuleDisplayDefault for Tensor<D, K> {
128 fn content(&self, content: Content) -> Option<Content> {
129 let string = format!("Tensor {{rank: {D}, shape: {:?}}}", self.shape().as_slice());
130 content.add_single(&string).optional()
131 }
132}
133
134impl<const D: usize, K: Basic> ModuleDisplay for Tensor<D, K> {}
135
136impl<const D: usize, K: Autodiff> AutodiffModule for Tensor<D, K> {
137 fn valid(&self) -> Self {
138 self.clone().inner()
139 }
140
141 fn from_inner(tensor: Self) -> Self {
142 Tensor::from_inner(tensor)
143 }
144}
145
146#[derive(Clone, Debug)]
199#[deprecated(
200 since = "0.21.0",
201 note = "Ignored<T> is deprecated. Use #[module(skip)] for non-persistent fields (same behavior)."
202)]
203pub struct Ignored<T>(pub T);
204
205#[allow(deprecated)]
206impl<T> Module for Ignored<T>
207where
208 T: Sync + Send + core::fmt::Debug + Clone,
209{
210 fn visit<V: ModuleVisitor>(&self, _visitor: &mut V) {
211 }
213
214 fn map<M: ModuleMapper>(self, _mapper: &mut M) -> Self {
215 self
216 }
217
218 fn to_device(self, _: &Device) -> Self {
219 self
220 }
221
222 fn fork(self, _: &Device) -> Self {
223 self
224 }
225
226 fn collect_devices(&self, devices: Devices) -> Devices {
227 devices
228 }
229}
230
231#[allow(deprecated)]
232impl<T> ModuleDisplayDefault for Ignored<T>
233where
234 T: Sync + Send + core::fmt::Debug + Clone,
235{
236 fn content(&self, content: Content) -> Option<Content> {
237 content.add_single(&format!("{:?}", self.0)).optional()
239 }
240}
241
242#[allow(deprecated)]
243impl<T> ModuleDisplay for Ignored<T> where T: Sync + Send + core::fmt::Debug + Clone {}
244
245#[allow(deprecated)]
246impl<T> Display for Ignored<T>
247where
248 T: Sync + Send + core::fmt::Debug + Clone,
249{
250 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
251 write!(f, "{:?}", self.0)
252 }
253}
254
255#[allow(deprecated)]
256impl<T> AutodiffModule for Ignored<T>
257where
258 T: Sync + Send + core::fmt::Debug + Clone,
259{
260 fn valid(&self) -> Self {
261 self.clone()
262 }
263
264 fn from_inner(module: Self) -> Self {
265 module
266 }
267}
268
269#[allow(deprecated)]
270impl<T> core::ops::Deref for Ignored<T> {
272 type Target = T;
273
274 fn deref(&self) -> &Self::Target {
275 &self.0
276 }
277}
278
279#[cfg(all(test, feature = "std"))]
280mod tests {
281 use core::marker::PhantomData;
282
283 use burn::module::Module;
284
285 use crate as burn;
286
287 #[test]
288 fn empty_module_with_phantom() {
289 #[derive(Module, Debug, new)]
290 struct EmptyModule<T: core::fmt::Debug + Clone + Send> {
291 #[module(skip)]
292 _phantom: PhantomData<T>,
293 }
294
295 let _module = EmptyModule::<bool>::new();
296
297 assert_eq!(core::mem::size_of::<EmptyModule<bool>>(), 0);
298 }
299}