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 Content, Devices, Module, ModuleDisplay, ModuleDisplayDefault, ModuleMapper, ModuleVisitor,
8};
9use burn_tensor::{Device, Tensor};
10
11#[macro_export]
13macro_rules! empty {
14 (module) => {
15 fn visit<V: burn::module::ModuleVisitor>(&self, _visitor: &mut V) {
16 }
18
19 fn map<M: burn::module::ModuleMapper>(self, _mapper: &mut M) -> Self {
20 self
21 }
22
23 fn to_device(self, _: &burn::tensor::Device) -> Self {
24 self
25 }
26
27 fn fork(self, _: &burn::tensor::Device) -> Self {
28 self
29 }
30
31 fn collect_devices(&self, devices: burn::module::Devices) -> burn::module::Devices {
32 devices
33 }
34
35 fn valid(&self) -> Self {
36 self.clone()
37 }
38
39 fn train(self) -> Self {
40 self
41 }
42 };
43
44 ($type:ty) => {
45 impl burn::module::Module for $type {
46 empty!(module);
47 }
48
49 impl burn::module::ModuleDisplayDefault for $type {
50 fn content(&self, content: burn::module::Content) -> Option<burn::module::Content> {
51 let string = format!("{}", self);
52 content.add_formatted(&string).optional()
53 }
54 }
55
56 impl burn::module::ModuleDisplay for $type {}
57 };
58}
59
60empty!(alloc::string::String);
64empty!(bool);
65
66empty!(f64);
68empty!(f32);
69empty!(half::bf16);
70empty!(half::f16);
71
72empty!(usize);
74empty!(u64);
75empty!(u32);
76empty!(u16);
77empty!(u8);
78
79empty!(isize);
81empty!(i64);
82empty!(i32);
83empty!(i16);
84empty!(i8);
85
86impl burn::module::ModuleDisplay for str {}
87impl burn::module::ModuleDisplayDefault for str {
88 fn content(&self, content: burn::module::Content) -> Option<burn::module::Content> {
89 content.add_formatted(&self).optional()
90 }
91}
92
93impl<const D: usize, K: Autodiff> Module for Tensor<D, K> {
95 fn visit<V: ModuleVisitor>(&self, _visitor: &mut V) {}
96
97 fn map<M: ModuleMapper>(self, _mapper: &mut M) -> Self {
98 self
99 }
100
101 fn to_device(self, device: &Device) -> Self {
102 self.to_device(device)
103 }
104
105 fn fork(self, device: &Device) -> Self {
106 self.to_device(device)
107 }
108
109 fn collect_devices(&self, mut devices: Devices) -> Devices {
110 let device = self.device();
111
112 if !devices.contains(&device) {
113 devices.push(device)
114 }
115
116 devices
117 }
118
119 fn valid(&self) -> Self {
120 self.clone().without_autodiff()
121 }
122
123 fn train(self) -> Self {
124 Tensor::from_inner(self)
125 }
126}
127
128impl<const D: usize, K: Basic> ModuleDisplayDefault for Tensor<D, K> {
129 fn content(&self, content: Content) -> Option<Content> {
130 let string = format!("Tensor {{rank: {D}, shape: {:?}}}", self.shape().as_slice());
131 content.add_single(&string).optional()
132 }
133}
134
135impl<const D: usize, K: Basic> ModuleDisplay for Tensor<D, K> {}
136
137#[derive(Clone, Debug)]
139#[deprecated(
140 since = "0.21.0",
141 note = "Ignored<T> is deprecated. Use #[module(skip)] for non-persistent fields (same behavior)."
142)]
143pub struct Ignored<T>(pub T);
144
145#[allow(deprecated)]
146impl<T> Module for Ignored<T>
147where
148 T: Sync + Send + core::fmt::Debug + Clone,
149{
150 fn visit<V: ModuleVisitor>(&self, _visitor: &mut V) {
151 }
153
154 fn map<M: ModuleMapper>(self, _mapper: &mut M) -> Self {
155 self
156 }
157
158 fn to_device(self, _: &Device) -> Self {
159 self
160 }
161
162 fn fork(self, _: &Device) -> Self {
163 self
164 }
165
166 fn collect_devices(&self, devices: Devices) -> Devices {
167 devices
168 }
169
170 fn valid(&self) -> Self {
171 self.clone()
172 }
173
174 fn train(self) -> Self {
175 self
176 }
177}
178
179#[allow(deprecated)]
180impl<T> ModuleDisplayDefault for Ignored<T>
181where
182 T: Sync + Send + core::fmt::Debug + Clone,
183{
184 fn content(&self, content: Content) -> Option<Content> {
185 content.add_single(&format!("{:?}", self.0)).optional()
187 }
188}
189
190#[allow(deprecated)]
191impl<T> ModuleDisplay for Ignored<T> where T: Sync + Send + core::fmt::Debug + Clone {}
192
193#[allow(deprecated)]
194impl<T> Display for Ignored<T>
195where
196 T: Sync + Send + core::fmt::Debug + Clone,
197{
198 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
199 write!(f, "{:?}", self.0)
200 }
201}
202
203#[allow(deprecated)]
204impl<T> core::ops::Deref for Ignored<T> {
206 type Target = T;
207
208 fn deref(&self) -> &Self::Target {
209 &self.0
210 }
211}
212
213#[cfg(all(test, feature = "std"))]
214mod tests {
215 use core::marker::PhantomData;
216
217 use burn::module::Module;
218
219 use crate as burn;
220
221 #[test]
222 fn empty_module_with_phantom() {
223 #[derive(Module, Debug, new)]
224 struct EmptyModule<T: core::fmt::Debug + Clone + Send> {
225 #[module(skip)]
226 _phantom: PhantomData<T>,
227 }
228
229 let _module = EmptyModule::<bool>::new();
230
231 assert_eq!(core::mem::size_of::<EmptyModule<bool>>(), 0);
232 }
233}