use anyhow::Result;
use std::sync::{Arc, Mutex, OnceLock};
#[derive(Debug, Clone, Default)]
pub struct GpuStats {
pub utilization: f32,
pub memory_utilization: f32,
pub temperature: f32,
pub power_usage: f32,
pub memory_free_mb: u64,
pub memory_total_mb: u64,
}
pub struct GpuMonitor {}
static GPU_MONITOR: OnceLock<Arc<Mutex<GpuMonitor>>> = OnceLock::new();
impl GpuMonitor {
pub fn new() -> Self {
Self::with_device(0)
}
pub fn with_device(device_index: u32) -> Self {
let _ = device_index; Self {}
}
pub fn global() -> Arc<Mutex<GpuMonitor>> {
GPU_MONITOR
.get_or_init(|| Arc::new(Mutex::new(GpuMonitor::new())))
.clone()
}
pub fn get_stats(&self) -> Result<GpuStats> {
Ok(GpuStats::default())
}
pub fn get_utilization(&self) -> f32 {
self.get_stats()
.map(|stats| stats.utilization)
.unwrap_or(0.0)
}
pub fn is_available(&self) -> bool {
false
}
pub fn device_count() -> u32 {
0
}
}
impl Default for GpuMonitor {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_gpu_monitor_creation() {
let monitor = GpuMonitor::new();
let _ = monitor.is_available();
}
#[test]
fn test_gpu_stats() {
let monitor = GpuMonitor::new();
let stats = monitor.get_stats();
assert!(stats.is_ok());
if monitor.is_available() {
let stats = stats.expect("stats should be available");
assert!(stats.utilization >= 0.0 && stats.utilization <= 100.0);
}
}
#[test]
fn test_device_count() {
let _count = GpuMonitor::device_count();
}
#[test]
fn test_global_monitor() {
let monitor1 = GpuMonitor::global();
let monitor2 = GpuMonitor::global();
assert!(Arc::ptr_eq(&monitor1, &monitor2));
}
}