Skip to main content

cubecl_runtime/config/
logger.rs

1use super::{CubeClRuntimeConfig, RuntimeConfig};
2use crate::config::{
3    autotune::AutotuneLogLevel, compilation::CompilationLogLevel, memory::MemoryLogLevel,
4    profiling::ProfilingLogLevel, streaming::StreamingLogLevel,
5};
6use alloc::{sync::Arc, vec::Vec};
7use core::fmt::Display;
8
9use cubecl_environment::config::logger::LoggerSinks;
10pub(crate) use cubecl_environment::config::logger::{LogLevel, LoggerConfig};
11
12/// Central logging utility for `CubeCL`, managing multiple log outputs.
13#[derive(Debug)]
14pub struct Logger {
15    sinks: LoggerSinks,
16    compilation_index: Vec<usize>,
17    profiling_index: Vec<usize>,
18    autotune_index: Vec<usize>,
19    autotune_recorder_index: Vec<usize>,
20    streaming_index: Vec<usize>,
21    memory_index: Vec<usize>,
22    /// Global configuration for logging settings.
23    pub config: Arc<CubeClRuntimeConfig>,
24}
25
26impl Default for Logger {
27    fn default() -> Self {
28        Self::new()
29    }
30}
31
32impl Logger {
33    /// Creates a new `Logger` instance based on the global configuration.
34    ///
35    /// Note that creating a logger is quite expensive.
36    pub fn new() -> Self {
37        let config = CubeClRuntimeConfig::get();
38        let mut sinks = LoggerSinks::new();
39
40        let compilation_index = register_enabled(
41            &mut sinks,
42            &config.compilation.logger,
43            !matches!(
44                config.compilation.logger.level,
45                CompilationLogLevel::Disabled
46            ),
47        );
48        let profiling_index = register_enabled(
49            &mut sinks,
50            &config.profiling.logger,
51            !matches!(config.profiling.logger.level, ProfilingLogLevel::Disabled),
52        );
53        let autotune_index = register_enabled(
54            &mut sinks,
55            &config.autotune.logger,
56            !matches!(config.autotune.logger.level, AutotuneLogLevel::Disabled),
57        );
58        // The recorder is its own sink, so records land wherever it points regardless of what the
59        // logger above is set to, including with the logger disabled.
60        let autotune_recorder_index = register_enabled(
61            &mut sinks,
62            &config.autotune.recorder,
63            config.autotune.recording_enabled(),
64        );
65        let streaming_index = register_enabled(
66            &mut sinks,
67            &config.streaming.logger,
68            !matches!(config.streaming.logger.level, StreamingLogLevel::Disabled),
69        );
70        let memory_index = register_enabled(
71            &mut sinks,
72            &config.memory.logger,
73            !matches!(config.memory.logger.level, MemoryLogLevel::Disabled),
74        );
75
76        Self {
77            sinks,
78            compilation_index,
79            profiling_index,
80            autotune_index,
81            autotune_recorder_index,
82            streaming_index,
83            memory_index,
84            config,
85        }
86    }
87
88    /// Logs a message for streaming, directing it to all configured streaming loggers.
89    pub fn log_streaming<S: Display>(&mut self, msg: &S) {
90        self.sinks
91            .log(&self.streaming_index, "cubecl::streaming", msg);
92    }
93
94    /// Logs a message for memory, directing it to all configured memory loggers.
95    pub fn log_memory<S: Display>(&mut self, msg: &S) {
96        self.sinks.log(&self.memory_index, "cubecl::memory", msg);
97    }
98
99    /// Logs a message for compilation, directing it to all configured compilation loggers.
100    pub fn log_compilation<S: Display>(&mut self, msg: &S) {
101        self.sinks
102            .log(&self.compilation_index, "cubecl::compilation", msg);
103    }
104
105    /// Logs a message for profiling, directing it to all configured profiling loggers.
106    pub fn log_profiling<S: Display>(&mut self, msg: &S) {
107        self.sinks
108            .log(&self.profiling_index, "cubecl::profiling", msg);
109    }
110
111    /// Logs a message for autotuning, directing it to all configured autotuning loggers.
112    pub fn log_autotune<S: Display>(&mut self, msg: &S) {
113        self.sinks
114            .log(&self.autotune_index, "cubecl::autotune", msg);
115    }
116
117    /// Returns the current streaming log level from the global configuration.
118    pub fn log_level_streaming(&self) -> StreamingLogLevel {
119        self.config.streaming.logger.level
120    }
121
122    /// Writes one autotune record, directing it to all configured recorder sinks.
123    pub fn log_autotune_record<S: Display>(&mut self, msg: &S) {
124        self.sinks.log(
125            &self.autotune_recorder_index,
126            "cubecl::autotune::record",
127            msg,
128        );
129    }
130
131    /// Returns the current autotune log level from the global configuration.
132    pub fn log_level_autotune(&self) -> AutotuneLogLevel {
133        self.config.autotune.logger.level
134    }
135
136    /// Whether tuning decisions are being recorded. See [`AutotuneConfig::recording_enabled`].
137    pub fn autotune_recording_enabled(&self) -> bool {
138        self.config.autotune.recording_enabled()
139    }
140
141    /// Returns the current compilation log level from the global configuration.
142    pub fn log_level_compilation(&self) -> CompilationLogLevel {
143        self.config.compilation.logger.level
144    }
145
146    /// Returns the current profiling log level from the global configuration.
147    pub fn log_level_profiling(&self) -> ProfilingLogLevel {
148        self.config.profiling.logger.level
149    }
150}
151
152fn register_enabled<L: LogLevel>(
153    sinks: &mut LoggerSinks,
154    config: &LoggerConfig<L>,
155    enabled: bool,
156) -> Vec<usize> {
157    if enabled {
158        sinks.register(config)
159    } else {
160        Vec::new()
161    }
162}