use std::{
fmt,
sync::atomic::{AtomicU8, Ordering},
};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(u8)]
pub enum GpuRuntimePolicy {
Auto = 0,
Disabled = 1,
Required = 2,
}
impl GpuRuntimePolicy {
#[must_use]
pub(crate) fn label(self) -> &'static str {
match self {
Self::Auto => "auto",
Self::Disabled => "off",
Self::Required => "required",
}
}
fn from_u8(value: u8) -> Self {
match value {
1 => Self::Disabled,
2 => Self::Required,
_ => Self::Auto,
}
}
}
impl fmt::Display for GpuRuntimePolicy {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str((*self).label())
}
}
static GPU_RUNTIME_POLICY: AtomicU8 = AtomicU8::new(GpuRuntimePolicy::Auto as u8);
#[derive(Debug, Clone, Default)]
pub(crate) struct GpuRuntimeProbe {
pub(crate) available: bool,
pub(crate) name: Option<String>,
pub(crate) buffer_limit_mb: Option<u64>,
pub(crate) runtime_identity: Option<String>,
pub(crate) is_software: bool,
}
pub fn set_gpu_runtime_policy(policy: GpuRuntimePolicy) {
GPU_RUNTIME_POLICY.store(policy as u8, Ordering::SeqCst);
}
#[must_use]
pub fn gpu_runtime_policy() -> GpuRuntimePolicy {
GpuRuntimePolicy::from_u8(GPU_RUNTIME_POLICY.load(Ordering::SeqCst))
}
#[must_use]
pub(crate) fn gpu_probe() -> GpuRuntimeProbe {
if gpu_disabled_by_policy() {
return GpuRuntimeProbe::default();
}
#[cfg(feature = "gpu")]
if let Some(gpu) = super::gpu_adapter_probe() {
return GpuRuntimeProbe {
available: !gpu.is_software,
name: Some(gpu.name.clone()),
buffer_limit_mb: Some(gpu.buffer_limit_mb),
runtime_identity: Some(gpu.runtime_identity.clone()),
is_software: gpu.is_software,
};
}
GpuRuntimeProbe::default()
}
#[must_use]
pub fn gpu_required_by_policy() -> bool {
gpu_runtime_policy() == GpuRuntimePolicy::Required
}
pub fn require_gpu_preflight() -> Result<(), String> {
if !gpu_required_by_policy() {
return Ok(());
}
if let Err(reason) = super::gpu_region_presence_self_test() {
return Err(format!(
"--require-gpu requested but no complete production GPU peer set passed region-presence parity ({reason}); \
refusing to run on CPU. Fix the GPU stack or run without \
--require-gpu."
));
}
Ok(())
}
pub(crate) fn gpu_disabled_by_policy() -> bool {
matches!(gpu_runtime_policy(), GpuRuntimePolicy::Disabled)
}