cubecl_runtime/tune/
util.rs1use core::sync::atomic::{AtomicI32, Ordering};
2
3static AUTOTUNE_LEVEL: AtomicI32 = AtomicI32::new(-1);
10static DEFAULT_LEVEL: u32 = 1;
11
12pub fn anchor(x: usize, max: Option<usize>, min: Option<usize>, base: Option<usize>) -> usize {
16 let autotune_level = load_autotune_level();
17 let factor = match autotune_level {
18 3 => return x, 2 => 0.75,
20 1 => 1.0,
21 0 => 1.25,
22 _ => panic!("Invalid autotune level {autotune_level:?}"),
23 };
24
25 let base = base.unwrap_or(2) as f64 * factor;
26 let base = f64::max(base, 1.1); let exp = (x as f64).log(base).ceil();
28 let power = base.powf(exp).ceil() as usize;
29
30 let result = if let Some(max) = max {
31 core::cmp::min(power, max)
32 } else {
33 power
34 };
35
36 if let Some(min) = min {
37 core::cmp::max(result, min)
38 } else {
39 result
40 }
41}
42
43fn load_autotune_level() -> u32 {
44 let autotune_level = AUTOTUNE_LEVEL.load(Ordering::Relaxed);
45 if autotune_level == -1 {
46 #[cfg(feature = "std")]
47 {
48 let level: u32 = std::env::var("CUBECL_AUTOTUNE_LEVEL")
49 .map(|value| {
50 value
51 .parse()
52 .expect("'CUBECL_AUTOTUNE_LEVEL' should be an integer.")
53 })
54 .unwrap_or(DEFAULT_LEVEL);
55 AUTOTUNE_LEVEL.store(level as i32, Ordering::Relaxed);
56 level
57 }
58 #[cfg(not(feature = "std"))]
59 DEFAULT_LEVEL
60 } else {
61 autotune_level as u32
62 }
63}