use nvml_wrapper::{error::NvmlError, Nvml};
use std::vec::IntoIter;
use sysinfo::{Pid, System};
#[derive(Clone)]
pub enum ProcessType {
GpuGraphic,
GpuCompute,
}
impl ToString for ProcessType {
fn to_string(&self) -> String {
match self {
ProcessType::GpuGraphic => "GRAPHIC".to_string(),
ProcessType::GpuCompute => "COMPUTE".to_string(),
}
}
}
#[derive(Clone)]
pub struct Process {
pub pid: u32,
pub type_: ProcessType,
pub command: String,
pub cpu_usage: f32,
pub memory: u64,
pub memory_usage: f32,
}
#[derive(Clone)]
pub struct Processes(pub Vec<Process>);
impl Processes {
pub fn read(sys: &System, nvml: &Option<Nvml>) -> Result<Processes, NvmlError> {
if nvml.is_none() {
return Ok(Processes(Vec::new()));
}
let nvml = nvml.as_ref().unwrap();
let device = nvml.device_by_index(0)?;
let mut processes = Vec::new();
let total_memory = sys.total_memory();
processes.extend(device.running_compute_processes()?.iter().filter_map(|x| {
match sys.process(Pid::from(x.pid as usize)) {
None => None,
Some(p) => Some({
let memory = p.memory();
Process {
pid: x.pid,
type_: ProcessType::GpuCompute,
command: String::from(p.exe().unwrap().to_str().unwrap()),
memory,
memory_usage: (memory as f32 / total_memory as f32) * 100.0,
cpu_usage: p.cpu_usage(),
}
}),
}
}));
processes.extend(device.running_graphics_processes()?.iter().filter_map(|x| {
match sys.process(Pid::from(x.pid as usize)) {
None => None,
Some(p) => Some({
let memory = p.memory();
Process {
pid: x.pid,
type_: ProcessType::GpuGraphic,
command: String::from(p.exe().unwrap().to_str().unwrap()),
memory,
memory_usage: (memory as f32 / total_memory as f32) * 100.0,
cpu_usage: p.cpu_usage(),
}
}),
}
}));
Ok(Processes(processes))
}
pub fn into_iter(&self) -> IntoIter<Process> {
self.0.clone().into_iter()
}
}