monitoring kit
Diffstat (limited to 'gpu/src/nvidia.rs')
| -rw-r--r-- | gpu/src/nvidia.rs | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/gpu/src/nvidia.rs b/gpu/src/nvidia.rs new file mode 100644 index 0000000..6b8be77 --- /dev/null +++ b/gpu/src/nvidia.rs @@ -0,0 +1,113 @@ +#![feature( + generic_arg_infer, + import_trait_associated_functions, + let_chains, + iter_array_chunks, + array_chunks, + portable_simd, + iter_chain +)] +use anyhow::*; +use grapher::inter; +use grapher::truncwrite; +use grapher::Grapher; +use nvml_wrapper::{ + enum_wrappers::device::{Clock, TemperatureSensor}, + Nvml, +}; +use pretty_bytes::converter::convert; +use std::array; +use std::convert::identity; +use std::io::Write; +use std::io::{stdout, Read}; +use std::thread::sleep; +use std::time::Duration; +use termion::color::*; +use termion::cursor::Hide; +use termion::raw::IntoRawMode; +use termion::screen::IntoAlternateScreen; +use termion::{async_stdin, clear, cursor, style}; +#[implicit_fn::implicit_fn] +fn main() -> Result<()> { + let vram = std::env::args().nth(1).is_some(); + let nvml = Nvml::init().context("nvml(nvidia) less")?; + let device = nvml.device_by_index(0).context("nvidialess")?; + let name = device.name()?; + let name = name.replace("NVIDIA GeForce RTX", "RTX"); + + let architecture = device.architecture()?; + let mut g = Grapher::new()?; + let mut d = 0.1; + let mut stdout = stdout().into_raw_mode()?.into_alternate_screen()?; + let mut stdin = async_stdin(); + write!(stdout, "{}{}{}", Hide, clear::All, style::Reset).unwrap(); + 'out: loop { + let (_, h) = termion::terminal_size()?; + + let mut key = 0; + while stdin.read(array::from_mut(&mut key)).unwrap() != 0 { + match key { + b'q' => break 'out, + b'+' => d = (d + 0.1f32).min(1.0), + b'-' if d >= 0.2 => d -= 0.1, + b'-' if d >= 0.02 => d -= 0.01, + b'-' => d = 0.00833, + _ => (), + } + } + + g.draw( + |y| { + Some( + inter( + [155, 221, 58].map(_ as f32 / 255.0), + [118, 185, 0].map(_ as f32 / 255.0), + y as f32 / (h - 1) as f32, + ) + .map(|x| (x * 255.0) as u8), + ) + }, + identity, + )?; + + write!(g.buffer, "{}{}", White.fg_str(), cursor::Goto(1, 1))?; + + let temperature = device.temperature(TemperatureSensor::Gpu)?; + let max = device.temperature_threshold( + nvml_wrapper::enum_wrappers::device::TemperatureThreshold::Slowdown, + )?; + + let mem_info = device.memory_info()?; + let util = device.utilization_rates()?.gpu; + + let graphics_clock = device.clock_info(Clock::Graphics)?; + let mem_clock = device.clock_info(Clock::Memory)?; + let usage = device.power_usage()? / 1000; + let of = device.power_management_limit()? / 1000; + + let used_mem = convert(mem_info.used as _); + let total_mem = convert(mem_info.total as _); + if vram { + truncwrite!( + g.buffer, + "{name} {used_mem}/ {total_mem} vRAM speed {mem_clock} MHZ" + )?; + } else { + truncwrite!(g.buffer, "{name} ({architecture}) @ {temperature}°C (max {max}°C) {usage}W/ {of}W {util}% usage\n\r")?; + truncwrite!(g.buffer, "{graphics_clock} MHz mem {mem_clock} MHz\n\r")?; + truncwrite!(g.buffer, "{used_mem}/ {total_mem} vRAM\n\r")?; + } + stdout.write_all(&g.buffer)?; + stdout.flush()?; + + sleep(Duration::from_secs_f32(d)); + if vram { + g.push_point(mem_info.used as f64 / mem_info.total as f64); + } else { + g.push_point(util as f64 / 1e2); + } + } + println!("\x1B[?7l"); + + Ok(()) +} |