gpu_histop/backend/
mod.rs1mod amdgpu;
2mod apple;
3mod nvidia_smi;
4mod nvml;
5
6use anyhow::{Result, anyhow, bail};
7
8use crate::config::BackendChoice;
9use crate::model::{GpuInfo, GpuSample};
10
11pub trait GpuBackend: Send {
12 fn label(&self) -> &str;
13 fn devices(&self) -> &[GpuInfo];
14 fn sample(&mut self) -> Result<Vec<GpuSample>>;
15}
16
17pub fn create_backend(kind: BackendChoice) -> Result<Box<dyn GpuBackend>> {
18 match kind {
19 BackendChoice::Auto => create_auto_backend(),
20 BackendChoice::Nvml => Ok(Box::new(nvml::NvmlBackend::new()?)),
21 BackendChoice::NvidiaSmi => Ok(Box::new(nvidia_smi::NvidiaSmiBackend::new()?)),
22 BackendChoice::Amdgpu => Ok(Box::new(amdgpu::AmdGpuBackend::new()?)),
23 BackendChoice::Apple => Ok(Box::new(apple::AppleBackend::new()?)),
24 }
25}
26
27fn create_auto_backend() -> Result<Box<dyn GpuBackend>> {
28 if cfg!(all(target_os = "macos", target_arch = "aarch64")) {
29 return apple::AppleBackend::new()
30 .map(|backend| Box::new(backend) as Box<dyn GpuBackend>)
31 .map_err(|error| {
32 anyhow!("no real GPU metrics backend is available on Apple Silicon: {error:#}")
33 });
34 }
35
36 let mut errors = Vec::new();
37
38 match nvml::NvmlBackend::new() {
39 Ok(backend) => return Ok(Box::new(backend)),
40 Err(error) => errors.push(format!("NVML: {error:#}")),
41 }
42
43 match nvidia_smi::NvidiaSmiBackend::new() {
44 Ok(backend) => return Ok(Box::new(backend)),
45 Err(error) => errors.push(format!("nvidia-smi: {error:#}")),
46 }
47
48 match amdgpu::AmdGpuBackend::new() {
49 Ok(backend) => return Ok(Box::new(backend)),
50 Err(error) => errors.push(format!("AMDGPU sysfs: {error:#}")),
51 }
52
53 match apple::AppleBackend::new() {
54 Ok(backend) => return Ok(Box::new(backend)),
55 Err(error) => errors.push(format!("Apple Silicon: {error:#}")),
56 }
57
58 Err(anyhow!(
59 "no real GPU metrics backend is available; tried {}",
60 errors.join("; ")
61 ))
62}
63
64fn require_devices(devices: &[GpuInfo], backend: &str) -> Result<()> {
65 if devices.is_empty() {
66 bail!("{backend} reported no GPUs");
67 }
68 Ok(())
69}