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,40 +20,58 @@ impl GpuInfo {
|
||||
}
|
||||
};
|
||||
|
||||
for card_idx in 0.. {
|
||||
let device_path = format!("/sys/class/drm/card{}/device", card_idx);
|
||||
if !Path::new(&device_path).exists() {
|
||||
break;
|
||||
}
|
||||
let closure = || -> Result<GpuUsage, Box<dyn std::error::Error>> {
|
||||
for subdir in fs::read_dir("/sys/class/drm")? {
|
||||
let device_path = subdir?.path().join("device");
|
||||
|
||||
// Check if this is an AMD GPU by looking for amdgpu directory
|
||||
if !Path::new(&format!("{}/driver/module/drivers/pci:amdgpu", device_path)).exists() {
|
||||
continue;
|
||||
}
|
||||
// Check if this is an AMD GPU by looking for amdgpu directory
|
||||
if !device_path
|
||||
.join("driver/module/drivers/pci:amdgpu")
|
||||
.exists()
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// match device_id from Vulkan info
|
||||
let this_device_id = fs::read_to_string(format!("{}/device", device_path))
|
||||
.map(|s| u32::from_str_radix(s.trim(), 16).unwrap_or(0))
|
||||
.unwrap_or(0);
|
||||
if this_device_id != device_id {
|
||||
continue;
|
||||
}
|
||||
// match device_id from Vulkan info
|
||||
let this_device_id_str = fs::read_to_string(device_path.join("device"))?;
|
||||
let this_device_id = u32::from_str_radix(
|
||||
this_device_id_str
|
||||
.strip_prefix("0x")
|
||||
.unwrap_or(&this_device_id_str)
|
||||
.trim(),
|
||||
16,
|
||||
)?;
|
||||
if this_device_id != device_id {
|
||||
continue;
|
||||
}
|
||||
|
||||
let read_mem = |path: &str| -> u64 {
|
||||
fs::read_to_string(path)
|
||||
.map(|content| content.trim().parse::<u64>().unwrap_or(0))
|
||||
.unwrap_or(0)
|
||||
/ 1024
|
||||
/ 1024 // Convert bytes to MiB
|
||||
};
|
||||
return GpuUsage {
|
||||
uuid: self.uuid.clone(),
|
||||
total_memory: read_mem(&format!("{}/mem_info_vram_total", device_path)),
|
||||
used_memory: read_mem(&format!("{}/mem_info_vram_used", device_path)),
|
||||
};
|
||||
let read_mem = |path: &Path| -> u64 {
|
||||
fs::read_to_string(path)
|
||||
.map(|content| content.trim().parse::<u64>().unwrap_or(0))
|
||||
.unwrap_or(0)
|
||||
/ 1024
|
||||
/ 1024 // Convert bytes to MiB
|
||||
};
|
||||
return Ok(GpuUsage {
|
||||
uuid: self.uuid.clone(),
|
||||
total_memory: read_mem(&device_path.join("mem_info_vram_total")),
|
||||
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")]
|
||||
|
||||
@ -28,21 +28,10 @@ impl CpuStaticInfo {
|
||||
.unwrap_or("unknown")
|
||||
.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 {
|
||||
name,
|
||||
core_count: System::physical_core_count().unwrap_or(0),
|
||||
arch: arch.to_string(),
|
||||
arch: std::env::consts::ARCH.to_string(),
|
||||
extensions: CpuStaticInfo::get_extensions(),
|
||||
}
|
||||
}
|
||||
@ -220,7 +209,8 @@ impl GpuInfo {
|
||||
#[derive(serde::Serialize, Clone, Debug)]
|
||||
pub struct SystemInfo {
|
||||
cpu: CpuStaticInfo,
|
||||
os: String,
|
||||
os_type: String,
|
||||
os_name: String,
|
||||
total_memory: u64,
|
||||
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 {
|
||||
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
|
||||
gpus: gpu_map.into_values().collect(),
|
||||
}
|
||||
|
||||
@ -10,9 +10,28 @@ pub struct NvidiaInfo {
|
||||
pub compute_capability: String,
|
||||
}
|
||||
|
||||
// NvmlError doesn't implement Copy, so we have to store an Option in OnceLock
|
||||
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 {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user