Skip to main content

cubecl_runtime/config/
compilation.rs

1use super::logger::{LogLevel, LoggerConfig};
2
3/// Configuration for compilation settings in `CubeCL`.
4#[derive(Default, Clone, Debug, serde::Serialize, serde::Deserialize)]
5pub struct CompilationConfig {
6    /// Logger configuration for compilation logs, using binary log levels.
7    #[serde(default)]
8    pub logger: LoggerConfig<CompilationLogLevel>,
9    /// Whether compiled kernels are cached in the active environment.
10    #[serde(default)]
11    #[cfg(persistence)]
12    pub cache: bool,
13    /// Controls whether kernel launches enforce bounds checks.
14    #[serde(default)]
15    pub check_mode: BoundsCheckMode,
16    /// How far the CPU runtime carries an f16 intermediate in f32 before rounding it. `None`
17    /// chooses by whether the host computes in f16 directly. Other runtimes ignore it.
18    #[serde(default)]
19    pub f16_evaluation: Option<F16Evaluation>,
20}
21
22/// How far an f32 intermediate is allowed to travel before it is rounded back to f16.
23#[derive(Default, Clone, Copy, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
24pub enum F16Evaluation {
25    /// Round after every operation, which is what a GPU does. Where f16 is not native it costs a
26    /// convert pair per operation.
27    #[serde(rename = "per-operation")]
28    PerOperation,
29    /// Round where a value is stored, a `let mut` included, or read by anything but arithmetic.
30    /// The default where f16 is not native.
31    #[default]
32    #[serde(rename = "chain")]
33    Chain,
34    /// Also hold a private f16 variable in f32 where that removes more converts than it adds, so
35    /// a running total read often enough inside its loop stays in f16. Costs vector registers, so
36    /// a wide kernel may want a narrower line.
37    #[serde(rename = "accumulators")]
38    Accumulators,
39}
40
41impl F16Evaluation {
42    /// The mode for a host that does or does not compute in f16 directly. Where it does, a chain
43    /// held in f32 only adds converts.
44    pub fn for_native_f16(native: bool) -> Self {
45        match native {
46            true => Self::PerOperation,
47            false => Self::Chain,
48        }
49    }
50}
51
52impl core::fmt::Display for F16Evaluation {
53    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
54        f.write_str(match self {
55            Self::PerOperation => "per-operation",
56            Self::Chain => "chain",
57            Self::Accumulators => "accumulators",
58        })
59    }
60}
61
62/// Bounds checks options.
63#[derive(Default, Clone, Copy, Debug, serde::Serialize, serde::Deserialize)]
64pub enum BoundsCheckMode {
65    #[serde(rename = "enforce")]
66    /// Always enforce bounds checks on every kernel launch.
67    Enforce,
68    #[serde(rename = "validate")]
69    /// Always enforce bounds checks on every kernel launch, and validate unchecked kernels for OOB.
70    Validate,
71    /// Enforce bounds checking on standard launches, but skip checks on
72    /// explicitly unchecked launches for better performance.
73    #[default]
74    #[serde(rename = "auto")]
75    Auto,
76}
77
78/// Log levels for compilation in `CubeCL`.
79#[derive(Default, Clone, Copy, Debug, serde::Serialize, serde::Deserialize)]
80pub enum CompilationLogLevel {
81    /// Compilation logging is disabled.
82    #[default]
83    #[serde(rename = "disabled")]
84    Disabled,
85
86    /// Basic compilation information is logged such as when kernels are compiled.
87    #[serde(rename = "basic")]
88    Basic,
89
90    /// Full compilation details are logged including source code.
91    #[serde(rename = "full")]
92    Full,
93}
94
95impl LogLevel for CompilationLogLevel {}