use alloc::sync::Arc;
use core::time::Duration;
use cubecl::{
config::{CubeClRuntimeConfig, RuntimeConfig, autotune::AutotuneLevel},
tune::{AutotuneKey, Bounds, Thresholds, TunableSet},
};
const fn thresholds_for_level(level: &AutotuneLevel) -> Option<Thresholds> {
match level {
AutotuneLevel::Minimal => Some(Thresholds::uniform(0.6)),
AutotuneLevel::Balanced => Some(Thresholds::uniform(0.8)),
AutotuneLevel::Extensive => Some(Thresholds::uniform(0.95)),
AutotuneLevel::Full => None,
}
}
fn configured_thresholds() -> Option<Thresholds> {
let config = CubeClRuntimeConfig::get();
thresholds_for_level(&config.autotune.level)
}
fn no_bounds() -> Bounds {
Bounds {
bounds: alloc::vec::Vec::new(),
launch_overhead: Duration::ZERO,
}
}
pub(crate) fn with_bounds<K, I, Out>(
set: TunableSet<K, I, Out>,
compute: impl Fn(&K, &I, Thresholds) -> Bounds + Send + Sync + 'static,
) -> TunableSet<K, I, Out>
where
K: AutotuneKey,
I: Clone + Send + Sync + 'static,
Out: 'static,
{
if configured_thresholds().is_none() {
return set;
}
set.with_bounds(Arc::new(move |key: &K, inputs: &I| {
match configured_thresholds() {
Some(thresholds) => compute(key, inputs, thresholds),
None => no_bounds(),
}
}))
}