Skip to content

Commit c61957a

Browse files
feat: use same hardware info list for GUI and CLI
1 parent 02ea252 commit c61957a

File tree

3 files changed

+167
-165
lines changed

3 files changed

+167
-165
lines changed

lact-cli/src/lib.rs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use anyhow::{Context, Result};
1+
use anyhow::Result;
22
use lact_client::DaemonClient;
33
use lact_schema::args::{CliArgs, CliCommand};
44

@@ -33,20 +33,19 @@ async fn list_gpus(_: &CliArgs, client: &DaemonClient) -> Result<()> {
3333

3434
async fn info(args: &CliArgs, client: &DaemonClient) -> Result<()> {
3535
for id in extract_gpu_ids(args, client).await {
36+
let gpu_line = format!("GPU {id}:");
37+
println!("{gpu_line}");
38+
println!("{}", "=".repeat(gpu_line.len()));
39+
3640
let info = client.get_device_info(&id).await?;
37-
let pci_info = info.pci_info.context("GPU reports no pci info")?;
41+
let stats = client.get_device_stats(&id).await?;
3842

39-
if let Some(ref vendor) = pci_info.device_pci_info.vendor {
40-
println!("GPU Vendor: {vendor}");
41-
}
42-
if let Some(ref model) = pci_info.device_pci_info.model {
43-
println!("GPU Model: {model}");
44-
}
45-
println!("Driver in use: {}", info.driver);
46-
if let Some(ref vbios_version) = info.vbios_version {
47-
println!("VBIOS version: {vbios_version}");
43+
let elements = info.info_elements(Some(&stats));
44+
for (name, value) in elements {
45+
if let Some(value) = value {
46+
println!("{name}: {value}");
47+
}
4848
}
49-
println!("Link: {:?}", info.link_info);
5049
}
5150
Ok(())
5251
}

lact-gui/src/app/pages/info_page/hardware_info.rs

Lines changed: 2 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
use crate::app::{info_row::InfoRow, page_section::PageSection, pages::PageUpdate};
22
use gtk::prelude::{BoxExt, OrientableExt, WidgetExt};
3-
use lact_schema::{DeviceInfo, DeviceStats, DrmInfo};
3+
use lact_schema::{DeviceInfo, DeviceStats};
44
use relm4::RelmWidgetExt;
55
use relm4::{prelude::FactoryVecDeque, ComponentParts, ComponentSender};
6-
use std::fmt::Write;
76
use std::sync::Arc;
87

98
pub struct HardwareInfoSection {
@@ -64,157 +63,8 @@ impl HardwareInfoSection {
6463
self.values_list.guard().clear();
6564

6665
if let Some(info) = &self.device_info {
67-
let pci_info = info.pci_info.as_ref();
68-
69-
let mut gpu_model = info
70-
.drm_info
71-
.as_ref()
72-
.and_then(|drm| drm.device_name.as_deref())
73-
.or_else(|| pci_info.and_then(|pci_info| pci_info.device_pci_info.model.as_deref()))
74-
.unwrap_or("Unknown")
75-
.to_owned();
76-
77-
let mut card_manufacturer = pci_info
78-
.and_then(|info| info.subsystem_pci_info.vendor.as_deref())
79-
.unwrap_or("Unknown")
80-
.to_owned();
81-
82-
let mut card_model = pci_info
83-
.and_then(|info| info.subsystem_pci_info.model.as_deref())
84-
.unwrap_or("Unknown")
85-
.to_owned();
86-
87-
if let Some(pci_info) = &info.pci_info {
88-
match &info.drm_info {
89-
Some(DrmInfo {
90-
pci_revision_id: Some(pci_rev),
91-
..
92-
}) => {
93-
let _ = write!(
94-
gpu_model,
95-
" (0x{}:0x{}:0x{pci_rev:X})",
96-
pci_info.device_pci_info.vendor_id, pci_info.device_pci_info.model_id,
97-
);
98-
}
99-
_ => {
100-
let _ = write!(
101-
gpu_model,
102-
" (0x{}:0x{})",
103-
pci_info.device_pci_info.vendor_id, pci_info.device_pci_info.model_id
104-
);
105-
}
106-
}
107-
108-
let _ = write!(
109-
card_manufacturer,
110-
" (0x{})",
111-
pci_info.subsystem_pci_info.vendor_id
112-
);
113-
114-
let _ = write!(card_model, " (0x{})", pci_info.subsystem_pci_info.model_id);
115-
};
116-
117-
let mut elements = vec![
118-
("GPU Model", Some(gpu_model)),
119-
("Card Manufacturer", Some(card_manufacturer)),
120-
("Card Model", Some(card_model)),
121-
("Driver Used", Some(info.driver.clone())),
122-
("VBIOS Version", info.vbios_version.clone()),
123-
];
124-
125-
if let Some(stats) = &self.device_stats {
126-
elements.push((
127-
"VRAM Size",
128-
stats
129-
.vram
130-
.total
131-
.map(|size| format!("{} MiB", size / 1024 / 1024)),
132-
));
133-
}
134-
135-
if let Some(drm_info) = &info.drm_info {
136-
elements.extend([
137-
("GPU Family", drm_info.family_name.clone()),
138-
("ASIC Name", drm_info.asic_name.clone()),
139-
(
140-
"Compute Units",
141-
drm_info.compute_units.map(|count| count.to_string()),
142-
),
143-
(
144-
"Execution Units",
145-
drm_info
146-
.intel
147-
.execution_units
148-
.map(|count| count.to_string()),
149-
),
150-
(
151-
"Subslices",
152-
drm_info
153-
.intel
154-
.execution_units
155-
.map(|count| count.to_string()),
156-
),
157-
(
158-
"Cuda Cores",
159-
drm_info.cuda_cores.map(|count| count.to_string()),
160-
),
161-
(
162-
"Streaming Multiprocessors",
163-
drm_info
164-
.streaming_multiprocessors
165-
.map(|count| count.to_string()),
166-
),
167-
(
168-
"ROP Count",
169-
drm_info.rop_info.as_ref().map(|rop| {
170-
format!(
171-
"{} ({} * {})",
172-
rop.operations_count, rop.unit_count, rop.operations_factor
173-
)
174-
}),
175-
),
176-
("VRAM Type", drm_info.vram_type.clone()),
177-
("VRAM Manufacturer", drm_info.vram_vendor.clone()),
178-
("Theoretical VRAM Bandwidth", drm_info.vram_max_bw.clone()),
179-
(
180-
"L1 Cache (Per CU)",
181-
drm_info
182-
.l1_cache_per_cu
183-
.map(|cache| format!("{} KiB", cache / 1024)),
184-
),
185-
(
186-
"L2 Cache",
187-
drm_info
188-
.l2_cache
189-
.map(|cache| format!("{} KiB", cache / 1024)),
190-
),
191-
(
192-
"L3 Cache",
193-
drm_info.l3_cache_mb.map(|cache| format!("{cache} MiB")),
194-
),
195-
]);
196-
197-
if let Some(memory_info) = &drm_info.memory_info {
198-
if let Some(rebar) = memory_info.resizeable_bar {
199-
let rebar = if rebar { "Enabled" } else { "Disabled" };
200-
elements.push(("Resizeable bar", Some(rebar.to_owned())));
201-
}
202-
203-
elements.push((
204-
"CPU Accessible VRAM",
205-
Some((memory_info.cpu_accessible_total / 1024 / 1024).to_string()),
206-
));
207-
}
208-
}
209-
210-
if let (Some(link_speed), Some(link_width)) =
211-
(&info.link_info.current_speed, &info.link_info.current_width)
212-
{
213-
elements.push(("Link Speed", Some(format!("{link_speed} x{link_width}"))));
214-
}
215-
21666
let mut values_list = self.values_list.guard();
217-
for (name, value) in elements {
67+
for (name, value) in info.info_elements(self.device_stats.as_deref()) {
21868
if let Some(value) = value {
21969
let note = if name == "Card Model" && !value.starts_with("Unknown ") {
22070
Some("The card displayed here may be of a sibling model, e.g. XT vs XTX variety. This is normal, as such models often use the same device ID, and it is not possible to differentiate between them.)")

lact-schema/src/lib.rs

Lines changed: 154 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use serde::{Deserialize, Serialize};
2323
use serde_with::skip_serializing_none;
2424
use std::{
2525
collections::{BTreeMap, HashMap, HashSet},
26-
fmt,
26+
fmt::{self, Write},
2727
str::FromStr,
2828
sync::Arc,
2929
};
@@ -109,6 +109,159 @@ impl DeviceInfo {
109109
.map(|info| info.vram_clock_ratio)
110110
.unwrap_or(1.0)
111111
}
112+
113+
pub fn info_elements(&self, stats: Option<&DeviceStats>) -> Vec<(&str, Option<String>)> {
114+
let pci_info = self.pci_info.as_ref();
115+
116+
let mut gpu_model = self
117+
.drm_info
118+
.as_ref()
119+
.and_then(|drm| drm.device_name.as_deref())
120+
.or_else(|| pci_info.and_then(|pci_info| pci_info.device_pci_info.model.as_deref()))
121+
.unwrap_or("Unknown")
122+
.to_owned();
123+
124+
let mut card_manufacturer = pci_info
125+
.and_then(|info| info.subsystem_pci_info.vendor.as_deref())
126+
.unwrap_or("Unknown")
127+
.to_owned();
128+
129+
let mut card_model = pci_info
130+
.and_then(|info| info.subsystem_pci_info.model.as_deref())
131+
.unwrap_or("Unknown")
132+
.to_owned();
133+
134+
if let Some(pci_info) = &self.pci_info {
135+
match self.drm_info {
136+
Some(DrmInfo {
137+
pci_revision_id: Some(pci_rev),
138+
..
139+
}) => {
140+
let _ = write!(
141+
gpu_model,
142+
" (0x{}:0x{}:0x{pci_rev:X})",
143+
pci_info.device_pci_info.vendor_id, pci_info.device_pci_info.model_id,
144+
);
145+
}
146+
_ => {
147+
let _ = write!(
148+
gpu_model,
149+
" (0x{}:0x{})",
150+
pci_info.device_pci_info.vendor_id, pci_info.device_pci_info.model_id
151+
);
152+
}
153+
}
154+
155+
let _ = write!(
156+
card_manufacturer,
157+
" (0x{})",
158+
pci_info.subsystem_pci_info.vendor_id
159+
);
160+
161+
let _ = write!(card_model, " (0x{})", pci_info.subsystem_pci_info.model_id);
162+
};
163+
164+
let mut elements = vec![
165+
("GPU Model", Some(gpu_model)),
166+
("Card Manufacturer", Some(card_manufacturer)),
167+
("Card Model", Some(card_model)),
168+
("Driver Used", Some(self.driver.clone())),
169+
("VBIOS Version", self.vbios_version.clone()),
170+
];
171+
172+
if let Some(stats) = stats {
173+
elements.push((
174+
"VRAM Size",
175+
stats
176+
.vram
177+
.total
178+
.map(|size| format!("{} MiB", size / 1024 / 1024)),
179+
));
180+
}
181+
182+
if let Some(drm_info) = &self.drm_info {
183+
elements.extend([
184+
("GPU Family", drm_info.family_name.clone()),
185+
("ASIC Name", drm_info.asic_name.clone()),
186+
(
187+
"Compute Units",
188+
drm_info.compute_units.map(|count| count.to_string()),
189+
),
190+
(
191+
"Execution Units",
192+
drm_info
193+
.intel
194+
.execution_units
195+
.map(|count| count.to_string()),
196+
),
197+
(
198+
"Subslices",
199+
drm_info
200+
.intel
201+
.execution_units
202+
.map(|count| count.to_string()),
203+
),
204+
(
205+
"Cuda Cores",
206+
drm_info.cuda_cores.map(|count| count.to_string()),
207+
),
208+
(
209+
"SM Count",
210+
drm_info
211+
.streaming_multiprocessors
212+
.map(|count| count.to_string()),
213+
),
214+
(
215+
"ROP Count",
216+
drm_info.rop_info.as_ref().map(|rop| {
217+
format!(
218+
"{} ({} * {})",
219+
rop.operations_count, rop.unit_count, rop.operations_factor
220+
)
221+
}),
222+
),
223+
("VRAM Type", drm_info.vram_type.clone()),
224+
("VRAM Manufacturer", drm_info.vram_vendor.clone()),
225+
("Theoretical VRAM Bandwidth", drm_info.vram_max_bw.clone()),
226+
(
227+
"L1 Cache (Per CU)",
228+
drm_info
229+
.l1_cache_per_cu
230+
.map(|cache| format!("{} KiB", cache / 1024)),
231+
),
232+
(
233+
"L2 Cache",
234+
drm_info
235+
.l2_cache
236+
.map(|cache| format!("{} KiB", cache / 1024)),
237+
),
238+
(
239+
"L3 Cache",
240+
drm_info.l3_cache_mb.map(|cache| format!("{cache} MiB")),
241+
),
242+
]);
243+
244+
if let Some(memory_info) = &drm_info.memory_info {
245+
if let Some(rebar) = memory_info.resizeable_bar {
246+
let rebar = if rebar { "Enabled" } else { "Disabled" };
247+
elements.push(("Resizeable bar", Some(rebar.to_owned())));
248+
}
249+
250+
elements.push((
251+
"CPU Accessible VRAM",
252+
Some((memory_info.cpu_accessible_total / 1024 / 1024).to_string()),
253+
));
254+
}
255+
}
256+
257+
if let (Some(link_speed), Some(link_width)) =
258+
(&self.link_info.current_speed, &self.link_info.current_width)
259+
{
260+
elements.push(("Link Speed", Some(format!("{link_speed} x{link_width}"))));
261+
}
262+
263+
elements
264+
}
112265
}
113266

114267
#[skip_serializing_none]

0 commit comments

Comments
 (0)