cubecl_environment/stream/
policy.rs1use crate::sync::{AtomicU8, Ordering};
2
3#[non_exhaustive]
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, serde::Serialize, serde::Deserialize)]
10#[serde(rename_all = "kebab-case")]
11pub enum StreamPolicy {
12 #[default]
18 PerThread,
19 PerTask,
26 Single,
30}
31
32const SET_BY_USER: u8 = 0b1000_0000;
33
34static POLICY: AtomicU8 = AtomicU8::new(0);
35
36fn encode(policy: StreamPolicy) -> u8 {
37 match policy {
38 StreamPolicy::PerThread => 0,
39 StreamPolicy::PerTask => 1,
40 StreamPolicy::Single => 2,
41 }
42}
43
44fn decode(bits: u8) -> StreamPolicy {
45 match bits & !SET_BY_USER {
46 1 => StreamPolicy::PerTask,
47 2 => StreamPolicy::Single,
48 _ => StreamPolicy::PerThread,
49 }
50}
51
52pub fn set_policy(policy: StreamPolicy) {
58 POLICY.store(encode(policy) | SET_BY_USER, Ordering::Relaxed);
59}
60
61pub fn policy() -> StreamPolicy {
63 decode(POLICY.load(Ordering::Relaxed))
64}
65
66#[doc(hidden)]
71pub fn set_policy_from_config(policy: StreamPolicy) {
72 #[allow(
73 deprecated,
74 reason = "portable_atomic lacks try_update on targets without native atomics"
75 )]
76 let _ = POLICY.fetch_update(Ordering::Relaxed, Ordering::Relaxed, |current| {
77 if current & SET_BY_USER != 0 {
78 None
79 } else {
80 Some(encode(policy))
81 }
82 });
83}
84
85#[cfg(all(test, feature = "std"))]
90pub(crate) fn tests_reset_policy() {
91 POLICY.store(0, Ordering::Relaxed);
92}
93
94#[cfg(all(test, feature = "std"))]
96pub(crate) fn tests_policy_lock() -> std::sync::MutexGuard<'static, ()> {
97 static LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(());
98 LOCK.lock().unwrap_or_else(|poisoned| poisoned.into_inner())
99}
100
101#[cfg(all(test, feature = "std"))]
103mod tests {
104 use super::*;
105
106 #[test]
107 fn explicit_policy_wins_over_config() {
108 let _guard = tests_policy_lock();
109
110 set_policy_from_config(StreamPolicy::Single);
111 assert_eq!(policy(), StreamPolicy::Single);
112
113 set_policy(StreamPolicy::PerTask);
114 set_policy_from_config(StreamPolicy::Single);
115 assert_eq!(policy(), StreamPolicy::PerTask);
116
117 tests_reset_policy();
118 }
119}