fix: Fix hwinfo bugs (#5164)
* add libnvidia-ml.so.1 fallback for linux * fix AMD memory usage on Linux * add os_type. use std::env::consts::ARCH directly
This commit is contained in:
parent
ae6d343d19
commit
8509479dfb
@ -20,41 +20,59 @@ impl GpuInfo {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
for card_idx in 0.. {
|
let closure = || -> Result<GpuUsage, Box<dyn std::error::Error>> {
|
||||||
let device_path = format!("/sys/class/drm/card{}/device", card_idx);
|
for subdir in fs::read_dir("/sys/class/drm")? {
|
||||||
if !Path::new(&device_path).exists() {
|
let device_path = subdir?.path().join("device");
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if this is an AMD GPU by looking for amdgpu directory
|
// Check if this is an AMD GPU by looking for amdgpu directory
|
||||||
if !Path::new(&format!("{}/driver/module/drivers/pci:amdgpu", device_path)).exists() {
|
if !device_path
|
||||||
|
.join("driver/module/drivers/pci:amdgpu")
|
||||||
|
.exists()
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// match device_id from Vulkan info
|
// match device_id from Vulkan info
|
||||||
let this_device_id = fs::read_to_string(format!("{}/device", device_path))
|
let this_device_id_str = fs::read_to_string(device_path.join("device"))?;
|
||||||
.map(|s| u32::from_str_radix(s.trim(), 16).unwrap_or(0))
|
let this_device_id = u32::from_str_radix(
|
||||||
.unwrap_or(0);
|
this_device_id_str
|
||||||
|
.strip_prefix("0x")
|
||||||
|
.unwrap_or(&this_device_id_str)
|
||||||
|
.trim(),
|
||||||
|
16,
|
||||||
|
)?;
|
||||||
if this_device_id != device_id {
|
if this_device_id != device_id {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let read_mem = |path: &str| -> u64 {
|
let read_mem = |path: &Path| -> u64 {
|
||||||
fs::read_to_string(path)
|
fs::read_to_string(path)
|
||||||
.map(|content| content.trim().parse::<u64>().unwrap_or(0))
|
.map(|content| content.trim().parse::<u64>().unwrap_or(0))
|
||||||
.unwrap_or(0)
|
.unwrap_or(0)
|
||||||
/ 1024
|
/ 1024
|
||||||
/ 1024 // Convert bytes to MiB
|
/ 1024 // Convert bytes to MiB
|
||||||
};
|
};
|
||||||
return GpuUsage {
|
return Ok(GpuUsage {
|
||||||
uuid: self.uuid.clone(),
|
uuid: self.uuid.clone(),
|
||||||
total_memory: read_mem(&format!("{}/mem_info_vram_total", device_path)),
|
total_memory: read_mem(&device_path.join("mem_info_vram_total")),
|
||||||
used_memory: read_mem(&format!("{}/mem_info_vram_used", device_path)),
|
used_memory: read_mem(&device_path.join("mem_info_vram_used")),
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
|
Err(format!("GPU not found").into())
|
||||||
|
};
|
||||||
|
|
||||||
|
match closure() {
|
||||||
|
Ok(usage) => usage,
|
||||||
|
Err(e) => {
|
||||||
|
log::error!(
|
||||||
|
"Failed to get memory usage for AMD GPU {:#x}: {}",
|
||||||
|
device_id,
|
||||||
|
e
|
||||||
|
);
|
||||||
self.get_usage_unsupported()
|
self.get_usage_unsupported()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
pub fn get_usage_amd(&self) -> GpuUsage {
|
pub fn get_usage_amd(&self) -> GpuUsage {
|
||||||
|
|||||||
@ -28,21 +28,10 @@ impl CpuStaticInfo {
|
|||||||
.unwrap_or("unknown")
|
.unwrap_or("unknown")
|
||||||
.to_string();
|
.to_string();
|
||||||
|
|
||||||
// cortex only returns amd64, arm64, or Unsupported
|
|
||||||
// TODO: find how Jan uses this value, if we can use
|
|
||||||
// std::env::consts::ARCH directly
|
|
||||||
let arch = match std::env::consts::ARCH {
|
|
||||||
"x86" => "amd64",
|
|
||||||
"x86_64" => "amd64",
|
|
||||||
"arm" => "arm64",
|
|
||||||
"aarch64" => "arm64",
|
|
||||||
_ => "Unsupported",
|
|
||||||
};
|
|
||||||
|
|
||||||
CpuStaticInfo {
|
CpuStaticInfo {
|
||||||
name,
|
name,
|
||||||
core_count: System::physical_core_count().unwrap_or(0),
|
core_count: System::physical_core_count().unwrap_or(0),
|
||||||
arch: arch.to_string(),
|
arch: std::env::consts::ARCH.to_string(),
|
||||||
extensions: CpuStaticInfo::get_extensions(),
|
extensions: CpuStaticInfo::get_extensions(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -220,7 +209,8 @@ impl GpuInfo {
|
|||||||
#[derive(serde::Serialize, Clone, Debug)]
|
#[derive(serde::Serialize, Clone, Debug)]
|
||||||
pub struct SystemInfo {
|
pub struct SystemInfo {
|
||||||
cpu: CpuStaticInfo,
|
cpu: CpuStaticInfo,
|
||||||
os: String,
|
os_type: String,
|
||||||
|
os_name: String,
|
||||||
total_memory: u64,
|
total_memory: u64,
|
||||||
gpus: Vec<GpuInfo>,
|
gpus: Vec<GpuInfo>,
|
||||||
}
|
}
|
||||||
@ -293,9 +283,21 @@ pub fn get_system_info<R: tauri::Runtime>(app: tauri::AppHandle<R>) -> SystemInf
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let os_type = if cfg!(target_os = "windows") {
|
||||||
|
"windows"
|
||||||
|
} else if cfg!(target_os = "macos") {
|
||||||
|
"macos"
|
||||||
|
} else if cfg!(target_os = "linux") {
|
||||||
|
"linux"
|
||||||
|
} else {
|
||||||
|
"unknown"
|
||||||
|
};
|
||||||
|
let os_name = System::long_os_version().unwrap_or("Unknown".to_string());
|
||||||
|
|
||||||
SystemInfo {
|
SystemInfo {
|
||||||
cpu: CpuStaticInfo::new(),
|
cpu: CpuStaticInfo::new(),
|
||||||
os: System::long_os_version().unwrap_or("Unknown".to_string()),
|
os_type: os_type.to_string(),
|
||||||
|
os_name,
|
||||||
total_memory: system.total_memory() / 1024 / 1024, // bytes to MiB
|
total_memory: system.total_memory() / 1024 / 1024, // bytes to MiB
|
||||||
gpus: gpu_map.into_values().collect(),
|
gpus: gpu_map.into_values().collect(),
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,9 +10,28 @@ pub struct NvidiaInfo {
|
|||||||
pub compute_capability: String,
|
pub compute_capability: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
// NvmlError doesn't implement Copy, so we have to store an Option in OnceLock
|
|
||||||
fn get_nvml() -> Option<&'static Nvml> {
|
fn get_nvml() -> Option<&'static Nvml> {
|
||||||
NVML.get_or_init(|| Nvml::init().ok()).as_ref()
|
NVML.get_or_init(|| {
|
||||||
|
let result = Nvml::init().or_else(|e| {
|
||||||
|
// fallback
|
||||||
|
if cfg!(target_os = "linux") {
|
||||||
|
let lib_path = std::ffi::OsStr::new("libnvidia-ml.so.1");
|
||||||
|
Nvml::builder().lib_path(lib_path).init()
|
||||||
|
} else {
|
||||||
|
Err(e)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// NvmlError doesn't implement Copy, so we have to store an Option in OnceLock
|
||||||
|
match result {
|
||||||
|
Ok(nvml) => Some(nvml),
|
||||||
|
Err(e) => {
|
||||||
|
log::error!("Unable to initialize NVML: {}", e);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GpuInfo {
|
impl GpuInfo {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user