#[cfg(target_os = "windows")]
use std::os::windows::process::CommandExt;
use std::process::Command;
use std::str;
use std::sync::OnceLock;
#[cfg(target_os = "windows")]
const CREATE_NO_WINDOW: u32 = 0x0800_0000;
static NVIDIA_SUPPORTED: OnceLock<bool> = OnceLock::new();
fn nvidia_smi_output() -> std::io::Result<std::process::Output> {
let mut cmd = Command::new("nvidia-smi");
cmd.args(["--format=csv,noheader,nounits", "--query-gpu=power.draw"]);
#[cfg(target_os = "windows")]
{
cmd.creation_flags(CREATE_NO_WINDOW);
}
cmd.output()
}
pub fn get_nvidia_power() -> f64 {
let output = nvidia_smi_output();
match output {
Ok(output) => {
let response = match str::from_utf8(&output.stdout) {
Ok(s) => s.trim(),
Err(e) => {
crate::logging::print_warning(&format!(
"Failed to read NVIDIA SMI output: {}",
e
));
return 0.0;
}
};
if response == "[N/A]" {
0.0
} else {
response
.lines()
.filter_map(|line| line.trim().parse::<f64>().ok())
.sum()
}
}
Err(e) => {
crate::logging::print_warning(&format!("Failed to execute NVIDIA SMI command: {}", e));
0.0
}
}
}
pub fn is_nvidia_supported() -> bool {
*NVIDIA_SUPPORTED.get_or_init(|| match nvidia_smi_output() {
Ok(output) => {
if !output.status.success() {
return false;
}
if let Ok(s) = str::from_utf8(&output.stdout) {
let trimmed = s.trim();
!trimmed.is_empty() && trimmed != "[N/A]"
} else {
false
}
}
Err(_) => false,
})
}