monitoring kit
Diffstat (limited to 'gpu/src/nvidia.rs')
-rw-r--r--gpu/src/nvidia.rs113
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(())
+}