burn_train/metric/processor/base.rs
1use burn_core::data::dataloader::Progress;
2use burn_optim::lr_scheduler::module_lr_scheduler::ModuleLearningRate;
3use burn_std::ExecutionError;
4
5use super::EventProcessorError;
6
7use crate::{
8 LearnerSummary,
9 renderer::{EvaluationName, MetricsRenderer},
10};
11
12/// Event happening during the training/validation process.
13pub enum LearnerEvent<T> {
14 /// Signal the start of the process (e.g., training start).
15 Start {
16 /// The total number of training epochs.
17 total_epochs: usize,
18 /// The starting epoch.
19 starting_epoch: usize,
20 /// An optional label for this training.
21 label: Option<String>,
22 },
23 /// Signal that an item have been processed.
24 ProcessedItem(TrainingItem<T>),
25 /// Signal the start of a split.
26 StartSplit {
27 /// The epoch number.
28 epoch_number: usize,
29 /// The total number of items to be processed during this split.
30 total_items: usize,
31 },
32 /// Signal the end of a split, carrying the current epoch number.
33 EndSplit(usize),
34 /// Signal the end of a full epoch.
35 EndEpoch(usize),
36 /// Signal the end of the process (e.g., training end).
37 End(Option<LearnerSummary>),
38}
39
40/// Event happening during the evaluation process.
41pub enum EvaluatorEvent<T> {
42 /// Signal the start of the process (e.g., evaluation start)
43 Start {
44 /// The total number of items to evaluate.
45 total_tests: usize,
46 },
47 /// Signal the start of a test split, carrying the split name and total number of items.
48 StartTest(EvaluationName, usize),
49 /// Signal that an item have been processed.
50 ProcessedItem(EvaluationName, EvaluationItem<T>),
51 /// Signal the end of a single test split.
52 EndTest,
53 /// Signal the end of the process (e.g., evaluation end).
54 End(Option<LearnerSummary>),
55}
56
57/// Items that are lazy are not ready to be processed by metrics.
58///
59/// We want to sync them on a different thread to avoid blocking training.
60pub trait ItemLazy: Send + Sized {
61 /// Sync the item.
62 ///
63 /// # Errors
64 ///
65 /// Returns an [`ExecutionError`] when the item's pending work cannot be dispatched, e.g. on a
66 /// device that is poisoned.
67 fn sync(self) -> Result<Self, ExecutionError>;
68}
69
70/// Process events happening during training and validation.
71pub trait EventProcessorTraining<TrainEvent, ValidEvent>: Send {
72 /// Collect a training event.
73 ///
74 /// # Errors
75 ///
76 /// Returns a [`EventProcessorError`] listing every metric that could not process the event.
77 /// The other metrics still processed it. Note that an asynchronous processor reports
78 /// it on a later call instead (see [`AsyncProcessorTraining`](super::AsyncProcessorTraining)).
79 fn process_train(&mut self, event: TrainEvent) -> Result<(), EventProcessorError>;
80 /// Collect a validation event.
81 ///
82 /// # Errors
83 ///
84 /// Same as [`process_train`](Self::process_train).
85 fn process_valid(&mut self, event: ValidEvent) -> Result<(), EventProcessorError>;
86 /// Wait until previously submitted events are processed (no-op for sync processors).
87 ///
88 /// # Errors
89 ///
90 /// Returns a [`EventProcessorError`] listing every metric failure among the events processed
91 /// since the last error was reported.
92 fn flush(&mut self) -> Result<(), EventProcessorError> {
93 Ok(())
94 }
95 /// Returns the renderer used for training.
96 fn renderer(self) -> Box<dyn MetricsRenderer>;
97}
98
99/// Process events happening during evaluation.
100pub trait EventProcessorEvaluation: Send {
101 /// The test item.
102 type ItemTest: ItemLazy;
103
104 /// Collect a test event.
105 ///
106 /// # Errors
107 ///
108 /// Returns a [`EventProcessorError`] listing every metric that could not process the event.
109 /// The other metrics still processed it. Note that an asynchronous processor reports
110 /// it on a later call instead (see [`AsyncProcessorEvaluation`](super::AsyncProcessorEvaluation)).
111 fn process_test(
112 &mut self,
113 event: EvaluatorEvent<Self::ItemTest>,
114 ) -> Result<(), EventProcessorError>;
115
116 /// Wait until previously submitted events are processed (no-op for sync processors).
117 ///
118 /// # Errors
119 ///
120 /// Returns a [`EventProcessorError`] listing every metric failure among the events processed
121 /// since the last error was reported.
122 fn flush(&mut self) -> Result<(), EventProcessorError> {
123 Ok(())
124 }
125
126 /// Returns the renderer used for evaluation.
127 fn renderer(self) -> Box<dyn MetricsRenderer>;
128}
129
130/// A learner item.
131#[derive(new)]
132pub struct TrainingItem<T> {
133 /// The item.
134 pub item: T,
135
136 /// The progress.
137 pub progress: Progress,
138
139 /// The iteration, if it it different from the items processed.
140 pub iteration: Option<usize>,
141
142 /// The learning rate for a module's parameters.
143 pub lr: Option<ModuleLearningRate>,
144}
145
146impl<T: ItemLazy> ItemLazy for TrainingItem<T> {
147 fn sync(self) -> Result<Self, ExecutionError> {
148 Ok(TrainingItem {
149 item: self.item.sync()?,
150 progress: self.progress,
151 iteration: self.iteration,
152 lr: self.lr,
153 })
154 }
155}
156
157/// An evaluation item.
158#[derive(new)]
159pub struct EvaluationItem<T> {
160 /// The item.
161 pub item: T,
162
163 /// The progress.
164 pub progress: Progress,
165
166 /// The iteration, if it it different from the items processed.
167 pub iteration: Option<usize>,
168}
169
170impl<T: ItemLazy> ItemLazy for EvaluationItem<T> {
171 fn sync(self) -> Result<Self, ExecutionError> {
172 Ok(EvaluationItem {
173 item: self.item.sync()?,
174 progress: self.progress,
175 iteration: self.iteration,
176 })
177 }
178}
179
180impl ItemLazy for () {
181 fn sync(self) -> Result<Self, ExecutionError> {
182 Ok(())
183 }
184}