use super::logger::{LogLevel, LoggerConfig};
#[derive(Default, Clone, Debug, serde::Serialize, serde::Deserialize)]
pub struct AutotuneConfig {
#[serde(default)]
pub logger: LoggerConfig<AutotuneLogLevel>,
#[serde(default)]
#[serde(alias = "recorder")]
pub decisions: LoggerConfig<DecisionLevel>,
#[serde(default)]
pub level: AutotuneLevel,
#[serde(default)]
pub disable_cache: bool,
#[serde(default)]
pub disable_short_circuit: bool,
#[serde(default)]
pub bench: BenchConfig,
}
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
#[serde(default)]
pub struct BenchConfig {
pub min_samples: usize,
pub max_samples: usize,
pub short_circuit_samples: usize,
pub speed_factor: f64,
pub adaptive: bool,
}
impl Default for BenchConfig {
fn default() -> Self {
Self {
min_samples: 3,
max_samples: 10,
short_circuit_samples: 2,
speed_factor: 1.5,
adaptive: true,
}
}
}
impl BenchConfig {
pub fn samples(&self) -> (usize, usize) {
let min = self.min_samples.max(1);
(min, self.max_samples.max(min))
}
pub fn short_circuit_samples(&self) -> usize {
self.short_circuit_samples.max(1)
}
pub fn speed_factor(&self) -> f64 {
self.speed_factor.max(1.0)
}
}
#[derive(Default, Clone, Copy, Debug, serde::Serialize, serde::Deserialize)]
pub enum AutotuneLogLevel {
#[serde(rename = "disabled")]
Disabled,
#[default]
#[serde(rename = "minimal")]
Minimal,
#[serde(rename = "full")]
Full,
}
impl LogLevel for AutotuneLogLevel {}
#[derive(Default, Clone, Copy, Debug, serde::Serialize, serde::Deserialize)]
pub struct DecisionLevel;
impl LogLevel for DecisionLevel {}
impl AutotuneConfig {
pub fn decisions_enabled(&self) -> bool {
#[cfg(std_io)]
let has_file = self.decisions.file.is_some();
#[cfg(not(std_io))]
let has_file = false;
has_file || self.decisions.stdout || self.decisions.stderr
}
}
#[derive(Default, Clone, Debug, serde::Serialize, serde::Deserialize)]
pub enum AutotuneLevel {
#[serde(rename = "minimal")]
Minimal,
#[default]
#[serde(rename = "balanced")]
Balanced,
#[serde(rename = "extensive")]
Extensive,
#[serde(rename = "full")]
Full,
}
#[cfg(all(test, feature = "std"))]
mod tests {
use super::*;
#[test]
fn decisions_are_read_under_recorder_too() {
let config: AutotuneConfig = toml::from_str("[recorder]\nstdout = true").unwrap();
assert!(config.decisions.stdout);
assert!(config.decisions_enabled());
let config: AutotuneConfig = toml::from_str("[decisions]\nstderr = true").unwrap();
assert!(config.decisions.stderr);
}
}