use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[allow(dead_code)]
pub type ProcessInfoResult = Option<(
f64,
f64,
u64,
u64,
String,
String,
String,
u64,
String,
u32,
u32,
)>;
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct GpuInfo {
pub uuid: String,
pub time: String,
pub name: String,
pub device_type: String, pub host_id: String, pub hostname: String, pub instance: String, pub utilization: f64,
pub ane_utilization: f64,
pub dla_utilization: Option<f64>,
pub tensorcore_utilization: Option<f64>, pub temperature: u32,
pub used_memory: u64,
pub total_memory: u64,
pub frequency: u32,
pub power_consumption: f64,
pub gpu_core_count: Option<u32>, #[serde(default)]
pub temperature_threshold_slowdown: Option<u32>,
#[serde(default)]
pub temperature_threshold_shutdown: Option<u32>,
#[serde(default)]
pub temperature_threshold_max_operating: Option<u32>,
#[serde(default)]
pub temperature_threshold_acoustic: Option<u32>,
#[serde(default)]
pub performance_state: Option<u32>,
#[serde(default)]
pub fan_speed_rpm: Option<u32>,
#[serde(default)]
pub numa_node_id: Option<i32>,
#[serde(default)]
pub gsp_firmware_mode: Option<u8>,
#[serde(default)]
pub gsp_firmware_version: Option<String>,
#[serde(default)]
pub nvlink_remote_devices: Vec<NvLinkRemoteDevice>,
#[serde(default)]
pub gpm_metrics: Option<GpmMetrics>,
pub detail: HashMap<String, String>,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub struct NvLinkRemoteDevice {
pub link_index: u32,
pub remote_type: NvLinkRemoteType,
#[serde(default)]
pub bandwidth_mb_s: Option<u32>,
}
#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Hash, Default)]
#[serde(rename_all = "lowercase")]
pub enum NvLinkRemoteType {
Gpu,
IbmNpu,
Switch,
#[default]
Unknown,
}
impl NvLinkRemoteType {
pub fn as_label(self) -> &'static str {
match self {
Self::Gpu => "gpu",
Self::IbmNpu => "ibmnpu",
Self::Switch => "switch",
Self::Unknown => "unknown",
}
}
pub fn from_label(value: &str) -> Self {
match value {
"gpu" => Self::Gpu,
"ibmnpu" => Self::IbmNpu,
"switch" => Self::Switch,
_ => Self::Unknown,
}
}
}
#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Default)]
pub struct GpmMetrics {
pub sm_occupancy: Option<f32>,
pub memory_bandwidth_utilization: Option<f32>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ThermalProximity {
Normal,
Slowdown,
Shutdown,
}
#[derive(Debug, Clone, Copy)]
pub struct ThermalProximityConfig {
pub slowdown_margin: u32,
pub shutdown_margin: u32,
}
impl Default for ThermalProximityConfig {
fn default() -> Self {
Self {
slowdown_margin: 5,
shutdown_margin: 2,
}
}
}
pub const GPU_METRIC_UNAVAILABLE: f64 = -1.0;
pub const MAX_GPU_FAN_RPM: u32 = 100_000;
impl GpuInfo {
pub fn utilization_reading(&self) -> Option<f64> {
(self.utilization >= 0.0).then_some(self.utilization)
}
pub fn ane_utilization_reading(&self) -> Option<f64> {
(self.ane_utilization >= 0.0).then_some(self.ane_utilization)
}
pub fn power_consumption_reading(&self) -> Option<f64> {
(self.power_consumption >= 0.0).then_some(self.power_consumption)
}
pub fn temperature_reading(&self) -> Option<u32> {
(self.temperature > 0).then_some(self.temperature)
}
pub fn frequency_reading(&self) -> Option<u32> {
(self.frequency > 0).then_some(self.frequency)
}
pub fn thermal_proximity(&self, cfg: ThermalProximityConfig) -> ThermalProximity {
if let Some(shutdown) = self.temperature_threshold_shutdown
&& shutdown > 0
&& self.temperature.saturating_add(cfg.shutdown_margin) >= shutdown
{
return ThermalProximity::Shutdown;
}
if let Some(slowdown) = self.temperature_threshold_slowdown
&& slowdown > 0
&& self.temperature.saturating_add(cfg.slowdown_margin) >= slowdown
{
return ThermalProximity::Slowdown;
}
ThermalProximity::Normal
}
}
#[derive(Clone, Serialize, Deserialize)]
pub struct ProcessInfo {
pub device_id: usize, pub device_uuid: String, pub pid: u32, pub process_name: String, pub used_memory: u64, pub cpu_percent: f64, pub memory_percent: f64, pub memory_rss: u64, pub memory_vms: u64, pub user: String, pub state: String, pub start_time: String, pub cpu_time: u64, pub command: String, pub ppid: u32, pub threads: u32, pub uses_gpu: bool, pub priority: i32, pub nice_value: i32, pub gpu_utilization: f64, }
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct CpuInfo {
#[serde(default)]
pub index: u32,
pub host_id: String, pub hostname: String, pub instance: String, pub cpu_model: String,
pub architecture: String, pub platform_type: CpuPlatformType,
pub socket_count: u32, pub total_cores: u32, pub total_threads: u32, pub base_frequency_mhz: u32, pub max_frequency_mhz: u32, pub cache_size_mb: u32, pub utilization: f64, pub temperature: Option<u32>, pub power_consumption: Option<f64>, pub per_socket_info: Vec<CpuSocketInfo>, pub apple_silicon_info: Option<AppleSiliconCpuInfo>, pub per_core_utilization: Vec<CoreUtilization>, pub time: String, }
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct CoreUtilization {
pub core_id: u32, pub core_type: CoreType, pub utilization: f64, }
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub enum CoreType {
Super, Performance, Efficiency, Standard, }
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub enum CpuPlatformType {
Intel,
Amd,
AppleSilicon,
Arm,
Other(String), }
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct CpuSocketInfo {
pub socket_id: u32, pub utilization: f64, pub cores: u32, pub threads: u32, pub temperature: Option<u32>, pub frequency_mhz: u32, }
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct AppleSiliconCpuInfo {
pub s_core_count: u32, pub p_core_count: u32, pub e_core_count: u32, pub gpu_core_count: u32, pub s_core_utilization: f64, pub p_core_utilization: f64, pub e_core_utilization: f64, pub ane_ops_per_second: Option<f64>, pub s_cluster_frequency_mhz: Option<u32>, pub p_cluster_frequency_mhz: Option<u32>, pub e_cluster_frequency_mhz: Option<u32>, pub s_core_l2_cache_mb: Option<u32>, pub p_core_l2_cache_mb: Option<u32>, pub e_core_l2_cache_mb: Option<u32>, }
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct MemoryInfo {
#[serde(default)]
pub index: u32,
pub host_id: String, pub hostname: String, pub instance: String, pub total_bytes: u64, pub used_bytes: u64, pub available_bytes: u64, pub free_bytes: u64, pub buffers_bytes: u64, pub cached_bytes: u64, pub swap_total_bytes: u64, pub swap_used_bytes: u64, pub swap_free_bytes: u64, pub utilization: f64, pub time: String, }
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
pub struct ChassisInfo {
pub host_id: String, pub hostname: String, pub instance: String,
pub total_power_watts: Option<f64>,
pub inlet_temperature: Option<f64>, pub outlet_temperature: Option<f64>, pub thermal_pressure: Option<String>,
pub fan_speeds: Vec<FanInfo>,
pub psu_status: Vec<PsuInfo>,
pub detail: HashMap<String, String>,
pub time: String, }
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub struct VgpuInfo {
pub instance_id: u32,
pub uuid: String,
pub vm_id: String,
pub vgpu_type_name: String,
pub fb_used_bytes: u64,
pub fb_total_bytes: u64,
pub gpu_utilization: Option<u32>,
pub memory_utilization: Option<u32>,
pub is_active: bool,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub struct VgpuHostInfo {
pub host_id: String,
pub hostname: String,
pub instance: String,
pub gpu_index: u32,
pub gpu_uuid: String,
pub gpu_name: String,
pub host_mode: String,
pub scheduler_policy: u32,
pub scheduler_arr_mode: u32,
pub is_arr_supported: bool,
pub vgpus: Vec<VgpuInfo>,
pub detail: HashMap<String, String>,
}
impl VgpuHostInfo {
pub fn is_vgpu_active(&self) -> bool {
!self.vgpus.is_empty() || self.host_mode != "Disabled"
}
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub struct MigInstanceInfo {
pub instance_id: u32,
pub gpu_instance_id: Option<u32>,
pub compute_instance_id: Option<u32>,
pub uuid: String,
pub profile_name: String,
pub utilization_gpu: Option<u32>,
pub utilization_memory: Option<u32>,
pub memory_used_bytes: u64,
pub memory_total_bytes: u64,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub struct MigGpuInfo {
pub host_id: String,
pub hostname: String,
pub instance: String,
pub gpu_index: u32,
pub gpu_uuid: String,
pub gpu_name: String,
pub mig_mode: bool,
pub instances: Vec<MigInstanceInfo>,
}
impl MigGpuInfo {
pub fn is_mig_active(&self) -> bool {
self.mig_mode || !self.instances.is_empty()
}
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct FanInfo {
pub id: u32, pub name: String, pub speed_rpm: u32, pub max_rpm: u32, }
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct PsuInfo {
pub id: u32, pub name: String, pub status: PsuStatus, pub power_watts: Option<f64>, }
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Default)]
pub enum PsuStatus {
#[default]
Unknown, Ok, Degraded, Failed, NotPresent, }