Skip to content

Commit 3fa6bf8

Browse files
feat: basic CLI command for fetching stats
1 parent 3d50c4d commit 3fa6bf8

File tree

3 files changed

+104
-2
lines changed

3 files changed

+104
-2
lines changed

lact-cli/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ mod subcommands;
22

33
use crate::subcommands::{
44
current_auto_switch, current_profile, info, list_gpus, list_profiles, power_limit,
5-
set_auto_switch, set_profile, snapshot,
5+
set_auto_switch, set_profile, snapshot, stats,
66
};
77
use anyhow::{bail, Context, Result};
88
use lact_client::DaemonClient;
@@ -28,6 +28,7 @@ pub fn run(args: CliArgs) -> Result<()> {
2828
match &args.subcommand {
2929
CliCommand::List => list_gpus(ctx).await,
3030
CliCommand::Info => info(ctx).await,
31+
CliCommand::Stats => stats(ctx).await,
3132
CliCommand::Snapshot => snapshot(ctx).await,
3233
CliCommand::PowerLimit { cmd } => power_limit(ctx, cmd.as_ref()).await,
3334
CliCommand::Profile(profile_args) => match &profile_args.subcommand {

lact-cli/src/subcommands.rs

Lines changed: 100 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
use crate::CliContext;
22
use anyhow::{Context, Result};
3-
use lact_schema::args::cli::{PowerLimitCmd, ProfileArgs, ProfileAutoSwitchArgs, SetProfileArgs};
3+
use lact_schema::{
4+
args::cli::{PowerLimitCmd, ProfileArgs, ProfileAutoSwitchArgs, SetProfileArgs},
5+
FanControlMode,
6+
};
7+
use std::fmt::Write;
48

59
const PROFILE_DEFAULT: &str = "Default";
610

@@ -39,6 +43,101 @@ pub async fn info(ctx: CliContext<'_>) -> Result<()> {
3943
Ok(())
4044
}
4145

46+
pub async fn stats(ctx: CliContext<'_>) -> Result<()> {
47+
let id = ctx.current_gpu_id().await?;
48+
49+
let gpu_line = format!("GPU {id}:");
50+
println!("{gpu_line}");
51+
println!("{}", "=".repeat(gpu_line.len()));
52+
53+
// let info = ctx.client.get_device_info(&id).await?;
54+
let stats = ctx.client.get_device_stats(&id).await?;
55+
56+
if let Some(gpu_clock) = stats.clockspeed.gpu_clockspeed {
57+
println!("GPU Clockspeed: {gpu_clock} MHz");
58+
}
59+
60+
if let Some(vram_clock) = stats.clockspeed.vram_clockspeed {
61+
println!("VRAM Clockspeed: {vram_clock} MHz");
62+
}
63+
64+
if let Some(gpu_voltage) = stats.voltage.gpu {
65+
println!("GPU Voltage: {gpu_voltage} mV");
66+
}
67+
68+
if let (Some(power_usage), Some(power_cap)) = (stats.power.current, stats.power.cap_current) {
69+
println!("Power Usage: {power_usage:.1}/{power_cap} W");
70+
}
71+
72+
if !stats.temps.is_empty() {
73+
print!("Temperatures: ");
74+
for (i, (name, value)) in stats.temps.iter().enumerate() {
75+
if i > 0 {
76+
print!(", ");
77+
}
78+
if let Some(value) = value.current {
79+
print!("{name}: {value}°C");
80+
}
81+
}
82+
println!();
83+
}
84+
85+
if let (Some(vram_current), Some(vram_total)) = (stats.vram.used, stats.vram.total) {
86+
println!(
87+
"VRAM Usage: {}/{} MiB",
88+
vram_current / 1024 / 1024,
89+
vram_total / 1024 / 1024
90+
);
91+
}
92+
93+
if let Some(throttle_info) = stats.throttle_info {
94+
let type_text: Vec<String> = throttle_info
95+
.iter()
96+
.map(|(throttle_type, details)| {
97+
let mut out = throttle_type.to_string();
98+
if !details.is_empty() {
99+
let _ = write!(out, "({})", details.join(", "));
100+
}
101+
out
102+
})
103+
.collect();
104+
105+
println!(
106+
"Throttling: {}",
107+
if type_text.is_empty() {
108+
"No".to_owned()
109+
} else {
110+
type_text.join(", ")
111+
}
112+
);
113+
}
114+
115+
if let Some(pwm) = stats.fan.pwm_current {
116+
print!("Fan Speed: {:.0}%", pwm as f64 / 255.0 * 100.0);
117+
118+
if let Some(rpm) = stats.fan.speed_current {
119+
print!(" ({rpm} RPM)");
120+
}
121+
122+
println!();
123+
}
124+
125+
println!(
126+
"Fan Control Mode: {}",
127+
if stats.fan.control_enabled {
128+
match stats.fan.control_mode {
129+
Some(FanControlMode::Curve) => "Curve",
130+
Some(FanControlMode::Static) => "Static",
131+
None => panic!("Invalid fan control config"),
132+
}
133+
} else {
134+
"Automatic"
135+
}
136+
);
137+
138+
Ok(())
139+
}
140+
42141
pub async fn snapshot(ctx: CliContext<'_>) -> Result<()> {
43142
let path = ctx.client.generate_debug_snapshot().await?;
44143
println!("Generated debug snapshot in {path}");

lact-schema/src/args/cli.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ pub enum CliCommand {
1616
List,
1717
/// Show GPU info
1818
Info,
19+
/// Show GPU stats
20+
Stats,
1921
/// Generate debug snapshot
2022
Snapshot,
2123
/// Manage GPU power limit

0 commit comments

Comments
 (0)