PowerCap

Struct PowerCap 

Source
pub struct PowerCap {
    pub type_: PowerCapType,
    pub current: u32,
    pub default: u32,
    pub min: u32,
    pub max: u32,
}

Fields§

§type_: PowerCapType§current: u32§default: u32§min: u32§max: u32

Implementations§

Source§

impl PowerCap

Source

pub fn from_hwmon_path<P: Into<PathBuf>>(path: P) -> Option<Self>

Examples found in repository?
examples/amdgpu_info.rs (line 360)
3fn info(libdrm_amdgpu: &LibDrmAmdgpu, pci_bus: &PCI::BUS_INFO) {
4    let Ok(device_path) = pci_bus.get_drm_render_path() else { return };
5    let (amdgpu_dev, _major, _minor) = {
6        use std::fs::File;
7        use std::os::fd::IntoRawFd;
8
9        let fd = File::open(device_path).unwrap();
10
11        libdrm_amdgpu.init_device_handle(fd.into_raw_fd()).unwrap()
12    };
13
14    if let Ok(drm_ver) = amdgpu_dev.get_drm_version_struct() {
15        println!("{drm_ver:#?}");
16    }
17
18    if let Ok(ext_info) = amdgpu_dev.device_info() {
19        use AMDGPU::GPU_INFO;
20
21        println!("Marketing Name: [{}]", ext_info.find_device_name_or_default());
22        // println!("\n{ext_info:#X?}\n");
23        let gpu_type = if ext_info.is_apu() { "APU" } else { "dGPU" };
24        let asic = ext_info.get_asic_name();
25
26        println!(
27            "DeviceID.RevID: {:#0X}.{:#0X}",
28            ext_info.device_id(),
29            ext_info.pci_rev_id()
30        );
31
32        println!();
33        println!("Family:\t\t{}", ext_info.get_family_name());
34        println!("ASIC Name:\t{asic}");
35        println!("Chip class:\t{}", ext_info.get_chip_class());
36        println!("GPU Type:\t{gpu_type}");
37
38        if let Some(gfx_ver) = ext_info.get_gfx_target_version() {
39            println!("gfx_target_version: {gfx_ver}");
40        }
41
42        let max_good_cu_per_sa = ext_info.get_max_good_cu_per_sa();
43        let min_good_cu_per_sa = ext_info.get_min_good_cu_per_sa();
44
45        println!();
46        println!("Shader Engine (SE):\t\t{:3}", ext_info.max_se());
47        println!("Shader Array (SA/SH) per SE:\t{:3}", ext_info.max_sa_per_se());
48        if max_good_cu_per_sa != min_good_cu_per_sa {
49            println!("CU per SA[0]:\t\t\t{:3}", max_good_cu_per_sa);
50            println!("CU per SA[1]:\t\t\t{:3}", min_good_cu_per_sa);
51        } else {
52            println!("CU per SA:\t\t\t{:3}", max_good_cu_per_sa);
53        }
54        println!("Total Compute Unit:\t\t{:3}", ext_info.cu_active_number());
55
56        if let Some((min, max)) = amdgpu_dev.get_min_max_gpu_clock() {
57            println!("Engine Clock:\t\t{min}-{max} MHz");
58        }
59
60        println!("Peak FP32:\t\t{} GFLOPS", ext_info.peak_gflops());
61
62        println!();
63        println!("VRAM Type:\t\t{}", ext_info.get_vram_type());
64        println!("VRAM Bit Width:\t\t{}-bit", ext_info.vram_bit_width);
65
66        if let Some((min, max)) = amdgpu_dev.get_min_max_memory_clock() {
67            println!("Memory Clock:\t\t{min}-{max} MHz");
68        }
69
70        println!("Peak Memory BW:\t\t{} GB/s", ext_info.peak_memory_bw_gb());
71
72        println!();
73        println!("L1cache (per CU):\t{:4} KiB", ext_info.get_l1_cache_size() >> 10);
74        if 0 < ext_info.sqc_data_cache_size {
75            println!("SQC Data Cache:\t\t{:4} KiB", ext_info.sqc_data_cache_size);
76        }
77        if 0 < ext_info.sqc_inst_cache_size {
78            println!("SQC Inst Cache:\t\t{:4} KiB", ext_info.sqc_inst_cache_size);
79        }
80        let gl1_cache_size = ext_info.get_gl1_cache_size();
81        let l3_cache_size = ext_info.calc_l3_cache_size_mb();
82        if 0 < gl1_cache_size {
83            println!("GL1cache (per SA/SH):\t{:4} KiB", gl1_cache_size >> 10);
84        }
85        if 0 < ext_info.gl1c_cache_size {
86            println!("Total GL1cache:\t\t{gl1_cache_size:4} KiB");
87        }
88        println!(
89            "L2cache:\t\t{:4} KiB ({} Banks)",
90            ext_info.calc_l2_cache_size() >> 10,
91            ext_info.get_actual_num_tcc_blocks(),
92        );
93        if 0 < l3_cache_size {
94            println!("L3cache:\t\t{l3_cache_size:4} MiB");
95        }
96    }
97
98    if let Ok(info) = amdgpu_dev.memory_info() {
99        println!();
100        println!(
101            "VRAM Usage:\t\t\t{usage}/{total} MiB",
102            usage = info.vram.heap_usage >> 20,
103            total = info.vram.total_heap_size >> 20,
104        );
105        println!(
106            "CPU Accessible VRAM Usage:\t{usage}/{total} MiB",
107            usage = info.cpu_accessible_vram.heap_usage >> 20,
108            total = info.cpu_accessible_vram.total_heap_size >> 20,
109        );
110        println!(
111            "GTT Usage:\t\t\t{usage}/{total} MiB",
112            usage = info.gtt.heap_usage >> 20,
113            total = info.gtt.total_heap_size >> 20,
114        );
115        let re_bar = if info.check_resizable_bar() { "Enabled" } else { "Disabled" };
116        println!("ResizableBAR:\t\t\t{re_bar}");
117
118        if let Ok(moved) = amdgpu_dev.num_bytes_moved() {
119            println!("Number of bytes moved for TTM migration: {moved}");
120        }
121
122        if let Ok(fault_count) = amdgpu_dev.num_vram_cpu_page_faults() {
123            println!("Number of VRAM page faults on CPU access: {fault_count}");
124        }
125
126        if let Ok(e) = amdgpu_dev.num_evictions() {
127            println!("Number of TTM buffer evictions: {e}");
128        }
129
130        if let Ok(lost) = amdgpu_dev.vram_lost_counter() {
131            println!("VRAM lost counter: {lost}");
132        }
133
134        if let Ok(ras) = amdgpu_dev.ras_enabled_features() {
135            use AMDGPU::RasBlock;
136
137            println!("ECC Memory: {}", if ras.is_supported(RasBlock::UMC) {
138                "supported"
139            } else {
140                "not supported"
141            });
142        }
143    }
144
145    {
146        use AMDGPU::HW_IP::*;
147
148        let ip_list = [
149            HW_IP_TYPE::GFX,
150            HW_IP_TYPE::COMPUTE,
151            HW_IP_TYPE::DMA,
152            HW_IP_TYPE::UVD,
153            HW_IP_TYPE::VCE,
154            HW_IP_TYPE::UVD_ENC,
155            HW_IP_TYPE::VCN_DEC,
156            HW_IP_TYPE::VCN_ENC,
157            HW_IP_TYPE::VCN_JPEG,
158            HW_IP_TYPE::VPE,
159        ];
160
161        println!("\nHardware IP info:");
162
163        for ip_type in &ip_list {
164            if let (Ok(ip_info), Ok(ip_count)) = (
165                amdgpu_dev.query_hw_ip_info(*ip_type, 0),
166                amdgpu_dev.query_hw_ip_count(*ip_type),
167            ) {
168                let (major, minor) = ip_info.version();
169                let queues = ip_info.num_queues();
170
171                if queues == 0 {
172                    continue;
173                }
174
175                println!(
176                    "{ip_type:8} count: {ip_count}, ver: {major:2}.{minor}, queues: {queues}",
177                    ip_type = ip_type.to_string(),
178                );
179            }
180        }
181    }
182
183    {
184        use AMDGPU::FW_VERSION::*;
185
186        let fw_list = [
187            FW_TYPE::VCE,
188            FW_TYPE::UVD,
189            FW_TYPE::GMC,
190            FW_TYPE::GFX_ME,
191            FW_TYPE::GFX_PFP,
192            FW_TYPE::GFX_CE,
193            FW_TYPE::GFX_RLC,
194            FW_TYPE::GFX_MEC,
195            FW_TYPE::SMC,
196            FW_TYPE::SDMA,
197            FW_TYPE::SOS,
198            FW_TYPE::ASD,
199            FW_TYPE::VCN,
200            FW_TYPE::GFX_RLC_RESTORE_LIST_CNTL,
201            FW_TYPE::GFX_RLC_RESTORE_LIST_GPM_MEM,
202            FW_TYPE::GFX_RLC_RESTORE_LIST_SRM_MEM,
203            FW_TYPE::DMCU,
204            FW_TYPE::TA,
205            FW_TYPE::DMCUB,
206            FW_TYPE::TOC,
207            FW_TYPE::VPE,
208        ];
209
210        println!("\nFirmware info:");
211
212        for fw_type in &fw_list {
213            let fw_info = match amdgpu_dev.query_firmware_version(*fw_type, 0, 0) {
214                Ok(v) => v,
215                Err(_) => continue,
216            };
217
218            let (ver, ftr) = (fw_info.version, fw_info.feature);
219
220            if ver == 0 {
221                continue;
222            }
223
224            println!(
225                "{fw_type:<8} ver: {ver:>#10X}, feature: {ftr:>3}",
226                fw_type = fw_type.to_string(),
227            );
228        }
229    }
230
231    {
232        use AMDGPU::VIDEO_CAPS::CAP_TYPE;
233
234        println!("\nVideo caps:");
235        if let Ok(codec_info) = amdgpu_dev.get_video_caps_info(CAP_TYPE::DECODE) {
236            println!("{codec_info:#?}");
237        }
238        if let Ok(codec_info) = amdgpu_dev.get_video_caps_info(CAP_TYPE::ENCODE) {
239            println!("{codec_info:#?}");
240        }
241    }
242
243    if let Ok(bus_info) = amdgpu_dev.get_pci_bus_info() {
244        println!("\nPCI (domain:bus:dev.func): {bus_info}");
245
246        if let Ok(render) = bus_info.get_drm_render_path() {
247            println!("Render: {render:?}");
248        }
249        if let Ok(card) = bus_info.get_drm_card_path() {
250            println!("Card: {card:?}");
251        }
252    }
253
254    match amdgpu_dev.get_min_max_link_info_from_dpm() { Some([min, max]) => {
255        println!(
256            "PCIe Link Speed     (DPM)    : Gen{}x{} - Gen{}x{}",
257            min.r#gen,
258            min.width,
259            max.r#gen,
260            max.width,
261        );
262
263        if let Some(max_gpu_link) = amdgpu_dev.get_max_gpu_link() {
264            println!(
265                "PCIe Link Speed (GPU, Max)   : Gen{}x{}",
266                max_gpu_link.r#gen,
267                max_gpu_link.width,
268            );
269        }
270
271        if let Some(max_system_link) = amdgpu_dev.get_max_system_link() {
272            println!(
273                "PCIe Link Speed (System, Max): Gen{}x{}",
274                max_system_link.r#gen,
275                max_system_link.width,
276            );
277        }
278    } _ => {
279        println!("PCIe Link Speed     (DPM)    : None");
280    }}
281
282    if let Ok(vbios) = amdgpu_dev.get_vbios_info() {
283        println!("\nVBIOS info:");
284        println!("name: [{}]", vbios.name);
285        println!("pn: [{}]", vbios.pn);
286        println!("ver: [{}]", vbios.ver);
287        println!("date: [{}]", vbios.date);
288    }
289
290/*
291    if let Ok(vce_clock) = amdgpu_dev.vce_clock_info() {
292        println!("\n{vce_clock:#?}");
293    }
294*/
295
296    {
297        use AMDGPU::SENSOR_INFO::*;
298
299        let sensors = [
300            SENSOR_TYPE::GFX_SCLK,
301            SENSOR_TYPE::GFX_MCLK,
302            SENSOR_TYPE::GPU_TEMP,
303            SENSOR_TYPE::GPU_LOAD,
304            SENSOR_TYPE::GPU_AVG_POWER,
305            SENSOR_TYPE::GPU_INPUT_POWER,
306            SENSOR_TYPE::VDDNB,
307            SENSOR_TYPE::VDDGFX,
308            SENSOR_TYPE::STABLE_PSTATE_GFX_SCLK,
309            SENSOR_TYPE::STABLE_PSTATE_GFX_MCLK,
310            SENSOR_TYPE::PEAK_PSTATE_GFX_SCLK,
311            SENSOR_TYPE::PEAK_PSTATE_GFX_MCLK,
312        ];
313
314        println!("\nSensors:");
315
316        for s in &sensors {
317            match amdgpu_dev.sensor_info(*s) { Ok(val) => {
318                println!("{s:?}: {val}");
319            } _ => {
320                println!("{s:?}: not supported");
321            }}
322        }
323    }
324
325    if let Ok(sysfs) = amdgpu_dev.get_sysfs_path() {
326        // let f = AMDGPU::DpmClockRange::from_sysfs(AMDGPU::DpmClockType::FCLK, &sysfs);
327        // println!("{f:?}");
328        use AMDGPU::{DpmForcedLevel, PowerProfile};
329
330        let profiles: Vec<String> = PowerProfile::get_all_supported_profiles_from_sysfs(&sysfs)
331            .iter()
332            .map(|p| p.to_string())
333            .collect();
334
335        println!("Supported Power Profiles: {profiles:?}");
336
337        if let Some(profiles) = PowerProfile::get_current_profile_from_sysfs(&sysfs) {
338            println!("Current Power Profiles: {profiles}");
339        }
340
341        if let Ok(level) = DpmForcedLevel::get_from_sysfs(&sysfs) {
342            println!("power_dpm_force_performance_level: {level:?}");
343        }
344
345        use AMDGPU::{RasErrorCount, RasBlock};
346
347        if let Ok(cnt) = RasErrorCount::get_from_sysfs_with_ras_block(&sysfs, RasBlock::UMC) {
348            println!(
349                "Memory Error Count: uncorrected {}, corrected {}",
350                cnt.uncorrected,
351                cnt.corrected,
352            );
353        }
354    }
355
356    if let Some(hwmon) = amdgpu_dev.get_hwmon_path() {
357        println!("hwmon: {hwmon:?}");
358
359        use AMDGPU::{HwmonTemp, HwmonTempType, PowerCap};
360        if let Some(power_cap) = PowerCap::from_hwmon_path(&hwmon) {
361            let PowerCap { type_, current, default, min, max } = power_cap;
362            println!("PowerCap ({type_}): {current} W (Current), {default} W (Default), {min}-{max} W (Range)");
363        }
364        if let Some(edge_temp) = HwmonTemp::from_hwmon_path(&hwmon, HwmonTempType::Edge) {
365            println!("{edge_temp:?}");
366        }
367        if let Some(junction_temp) = HwmonTemp::from_hwmon_path(&hwmon, HwmonTempType::Junction) {
368            println!("{junction_temp:?}");
369        }
370        if let Some(mem_temp) = HwmonTemp::from_hwmon_path(&hwmon, HwmonTempType::Memory) {
371            println!("{mem_temp:?}");
372        }
373    }
374
375    println!();
376}
Source

pub fn check_if_secondary_die(&self) -> bool

ref: drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c ref: https://github.com/RadeonOpenCompute/rocm_smi_lib/blob/master/python_smi_tools/rocm_smi.py

Trait Implementations§

Source§

impl Clone for PowerCap

Source§

fn clone(&self) -> PowerCap

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for PowerCap

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl PartialEq for PowerCap

Source§

fn eq(&self, other: &PowerCap) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Eq for PowerCap

Source§

impl StructuralPartialEq for PowerCap

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.