Skip to main content

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}