#[derive(Debug, Clone)]
pub struct HwReport {
pub has_gpu: bool,
pub has_vulkan: bool,
pub gpu_name: String,
pub gpu_memory_mb: u64,
pub gpu_free_memory_mb: u64,
pub gpu_utilization_percent: Option<u32>,
pub temperature_c: Option<u32>,
pub total_accel_memory_mb: u64,
}
#[must_use]
pub fn probe() -> HwReport {
let registry = ai_hwaccel::AcceleratorRegistry::detect();
let best = registry.best_available();
let has_gpu = registry.available().iter().any(|p| p.accelerator.is_gpu());
let has_vulkan = registry
.by_family(ai_hwaccel::AcceleratorFamily::Gpu)
.iter()
.any(|p| p.available);
let (gpu_name, gpu_memory_mb, gpu_free_memory_mb, gpu_utilization_percent, temperature_c) =
match best {
Some(p) if p.accelerator.is_gpu() => {
let name = p
.driver_version
.clone()
.unwrap_or_else(|| format!("{:?}", p.accelerator));
let free_mb = p.memory_free_bytes.unwrap_or(0) / (1024 * 1024);
(
name,
p.memory_bytes / (1024 * 1024),
free_mb,
p.gpu_utilization_percent,
p.temperature_c,
)
}
_ => (String::new(), 0, 0, None, None),
};
HwReport {
has_gpu,
has_vulkan,
gpu_name,
gpu_memory_mb,
gpu_free_memory_mb,
gpu_utilization_percent,
temperature_c,
total_accel_memory_mb: registry.total_accelerator_memory() / (1024 * 1024),
}
}
#[must_use]
pub fn should_use_gpu(width: u32, height: u32) -> bool {
let report = probe();
if !report.has_gpu {
return false;
}
let pixels = width as u64 * height as u64;
if pixels < 65_536 {
return false;
}
if report.gpu_free_memory_mb > 0 {
let buffer_mb = pixels * 4 * 3 / (1024 * 1024);
if buffer_mb > report.gpu_free_memory_mb {
return false;
}
}
if let Some(util) = report.gpu_utilization_percent
&& util > 90
{
return false;
}
true
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn probe_returns_report() {
let report = probe();
let _ = report.has_gpu;
let _ = report.gpu_name;
}
#[test]
fn small_images_stay_on_cpu() {
let _ = should_use_gpu(4, 4);
}
#[test]
fn report_has_new_fields() {
let report = probe();
let _ = report.gpu_free_memory_mb;
let _ = report.gpu_utilization_percent;
let _ = report.temperature_c;
}
}