use std::time::{Duration, Instant};
use super::GpuMemoryMetrics;
#[derive(Debug, Clone, Copy, Default)]
pub struct GpuUtilization {
pub gpu_percent: u32,
pub memory_percent: u32,
pub encoder_percent: Option<u32>,
pub decoder_percent: Option<u32>,
}
#[derive(Debug, Clone, Copy, Default)]
pub struct GpuThermalMetrics {
pub temperature_celsius: u32,
pub temperature_threshold_shutdown: Option<u32>,
pub fan_speed_percent: Option<u32>,
}
impl GpuThermalMetrics {
#[must_use]
pub const fn is_safe(&self) -> bool {
self.temperature_celsius < 80
}
#[must_use]
pub const fn is_critical(&self) -> bool {
self.temperature_celsius >= 90
}
#[must_use]
pub const fn status(&self) -> &'static str {
match self.temperature_celsius {
0..=50 => "COOL",
51..=70 => "WARM",
71..=85 => "HOT",
86.. => "CRITICAL",
}
}
}
#[derive(Debug, Clone, Copy, Default)]
pub struct GpuPowerMetrics {
pub power_draw_watts: f32,
pub power_limit_watts: f32,
pub power_state: u32,
}
impl GpuPowerMetrics {
#[must_use]
pub fn usage_percent(&self) -> f64 {
if self.power_limit_watts <= 0.0 {
0.0
} else {
(self.power_draw_watts as f64 / self.power_limit_watts as f64) * 100.0
}
}
}
#[derive(Debug, Clone, Copy, Default)]
pub struct GpuClockMetrics {
pub graphics_mhz: u32,
pub memory_mhz: u32,
pub sm_mhz: Option<u32>,
}
#[derive(Debug, Clone, Copy, Default)]
pub struct GpuPcieMetrics {
pub tx_bytes_per_sec: u64,
pub rx_bytes_per_sec: u64,
pub link_gen: u32,
pub link_width: u32,
}
#[derive(Debug, Clone)]
pub struct GpuMetrics {
pub timestamp: Instant,
pub device_index: u32,
pub memory: GpuMemoryMetrics,
pub utilization: GpuUtilization,
pub thermal: Option<GpuThermalMetrics>,
pub power: Option<GpuPowerMetrics>,
pub clocks: Option<GpuClockMetrics>,
pub pcie: Option<GpuPcieMetrics>,
}
impl GpuMetrics {
#[must_use]
pub fn new(device_index: u32, memory: GpuMemoryMetrics) -> Self {
Self {
timestamp: Instant::now(),
device_index,
memory,
utilization: GpuUtilization::default(),
thermal: None,
power: None,
clocks: None,
pcie: None,
}
}
#[must_use]
pub fn age(&self) -> Duration {
self.timestamp.elapsed()
}
}