Skip to content

Commit 988076b

Browse files
committed
shorten "CARDS" var; fix some linting
1 parent 479d00c commit 988076b

File tree

4 files changed

+56
-49
lines changed

4 files changed

+56
-49
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ Introduction:
3737
```python
3838
In [1]: import amdgpu_stats.utils
3939

40-
In [2]: amdgpu_stats.utils.AMDGPU_CARDS
40+
In [2]: amdgpu_stats.utils.CARDS
4141
Out[2]: {'card0': '/sys/class/drm/card0/device/hwmon/hwmon9'}
4242

4343
In [3]: amdgpu_stats.utils.get_core_stats('card0')

src/amdgpu_stats/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import sys
44
from .tui import app
55
from .utils import (
6-
AMDGPU_CARDS,
6+
CARDS,
77
)
88

99

@@ -12,7 +12,7 @@ def check_for_cards() -> bool:
1212
1313
Returns:
1414
bool: If any AMD cards found or not"""
15-
if len(AMDGPU_CARDS) > 0:
15+
if len(CARDS) > 0:
1616
return True
1717
return False
1818

src/amdgpu_stats/tui.py

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
)
3636

3737
from .utils import (
38-
AMDGPU_CARDS,
38+
CARDS,
3939
get_fan_rpm,
4040
get_power_stats,
4141
get_temp_stat,
@@ -46,6 +46,7 @@
4646
# rich markup reference:
4747
# https://rich.readthedocs.io/en/stable/markup.html
4848

49+
4950
class GPUStatsWidget(Static):
5051
"""The main stats widget."""
5152

@@ -89,7 +90,7 @@ def get_column_data_mapping(self, card: Optional[str] = None) -> dict:
8990
"Card": "",
9091
"Core clock": "",
9192
"Memory clock": "",
92-
"Utilization": "",
93+
"Usage": "",
9394
"Voltage": "",
9495
"Power": "",
9596
"Limit": "",
@@ -104,7 +105,7 @@ def get_column_data_mapping(self, card: Optional[str] = None) -> dict:
104105
"Card": card,
105106
"Core clock": get_clock('core', card=card, format_freq=True),
106107
"Memory clock": get_clock('memory', card=card, format_freq=True),
107-
"Utilization": f'{get_gpu_usage(card=card)}%',
108+
"Usage": f'{get_gpu_usage(card=card)}%',
108109
"Voltage": f'{get_voltage(card=card)}V',
109110
"Power": power_stats['usage'],
110111
"Limit": power_stats['lim'],
@@ -162,7 +163,7 @@ def compose(self) -> ComposeResult:
162163
with TabPane("Stats", id="tab_stats"):
163164
yield self.stats_table
164165
with TabPane("Graphs", id="tab_graphs", classes="tab_graphs"):
165-
for card in AMDGPU_CARDS:
166+
for card in CARDS:
166167
yield Vertical(
167168
Label(f'[bold]{card}'),
168169
Label('Core:'),
@@ -189,9 +190,7 @@ async def get_stats(self):
189190
'''Function to fetch stats / update the table for each AMD GPU found'''
190191
for card in self.cards:
191192
self.data = self.get_column_data_mapping(card)
192-
# Update usage bars
193-
if self.data['Utilization'] is not None:
194-
self.query_one(f'#bar_{card}_util').update(total=100, progress=float(self.data['Utilization'].replace('%', '')))
193+
195194
# handle the table data appopriately
196195
# if needs populated anew or updated
197196
if self.table_needs_init:
@@ -201,13 +200,22 @@ async def get_stats(self):
201200
Text(str(cell), style="normal", justify="right") for cell in self.data.values()
202201
]
203202
self.stats_table.add_row(*styled_row, key=card)
204-
hwmon_dir = AMDGPU_CARDS[card]
203+
hwmon_dir = CARDS[card]
205204
self.update_log(f"Added row for '{card}', stats dir: '{hwmon_dir}'")
206205
else:
207-
# Update existing rows, retaining styling/justification
206+
# Update existing table rows, retaining styling/justification
208207
for column, value in self.data.items():
209-
styled_cell = Text(str(value), style="normal", justify="right")
210-
self.stats_table.update_cell(card, column, styled_cell)
208+
self.stats_table.update_cell(card,
209+
column,
210+
Text(str(value),
211+
style="normal",
212+
justify="right"))
213+
214+
# Update usage bars
215+
if self.data['Usage'] is not None:
216+
self.query_one(f'#bar_{card}_util').update(total=100,
217+
progress=float(self.data['Usage'].replace('%', '')))
218+
211219
if self.table_needs_init:
212220
# if this is the first time updating the table, mark it initialized
213221
self.table_needs_init = False
@@ -224,7 +232,7 @@ class app(App): # pylint: disable=invalid-name
224232
TITLE = 'AMD GPU Stats'
225233

226234
# set a default subtitle, will change with the active tab
227-
SUB_TITLE = f'cards: {list(AMDGPU_CARDS)}'
235+
SUB_TITLE = f'cards: {list(CARDS)}'
228236

229237
# setup keybinds
230238
BINDINGS = [
@@ -239,7 +247,7 @@ class app(App): # pylint: disable=invalid-name
239247
]
240248

241249
# create an instance of the stats widget with all cards
242-
stats_widget = GPUStatsWidget(cards=AMDGPU_CARDS,
250+
stats_widget = GPUStatsWidget(cards=CARDS,
243251
name="stats_widget")
244252

245253
def compose(self) -> ComposeResult:
@@ -322,4 +330,4 @@ def on_tabbed_content_tab_activated(self, event: TabbedContent.TabActivated):
322330
if active_tab == "logs":
323331
self.sub_title = active_tab # pylint: disable=attribute-defined-outside-init
324332
elif active_tab == "stats":
325-
self.sub_title = f'cards: {list(AMDGPU_CARDS)}' # pylint: disable=attribute-defined-outside-init
333+
self.sub_title = f'cards: {list(CARDS)}' # pylint: disable=attribute-defined-outside-init

src/amdgpu_stats/utils.py

Lines changed: 31 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
This module contains utility functions/variables used throughout the 'amdgpu-stats' TUI
55
66
Variables:
7-
- AMDGPU_CARDS (dict): discovered AMD GPUs and their `hwmon` stats directories
7+
- CARDS (dict): discovered AMD GPUs and their `hwmon` stats directories
88
- Example: `{'card0': '/sys/class/drm/card0/device/hwmon/hwmon9'}`
99
- If no *AMD* cards are found, this will be empty.
1010
- CLOCK_DOMAINS (tuple): supported clock domains, ie: `('core', 'memory')`
@@ -44,7 +44,7 @@ def find_cards() -> dict:
4444

4545

4646
# discover all available AMD GPUs
47-
AMDGPU_CARDS = find_cards()
47+
CARDS = find_cards()
4848
# supported clock domains by 'get_clock' func
4949
# is concatenated with 'clock_' to index SRC_FILES for the relevant data file
5050
CLOCK_DOMAINS = ('core', 'memory')
@@ -53,7 +53,7 @@ def find_cards() -> dict:
5353

5454
def validate_card(card: Optional[str] = None) -> str:
5555
"""
56-
Checks the provided `card` identifier -- if present in `AMDGPU_CARDS`
56+
Checks the provided `card` identifier -- if present in `CARDS`
5757
5858
If `card` is not provided, will yield the first AMD GPU *(if any installed)*
5959
@@ -62,24 +62,24 @@ def validate_card(card: Optional[str] = None) -> str:
6262
6363
Raises:
6464
ValueError: If *no* AMD cards are found, or `card` is not one of them.
65-
Determined with `AMDGPU_CARDS`
65+
Determined with `CARDS`
6666
6767
Returns:
6868
str: Validated card identifier.
6969
If `card` is provided and valid: original identifier `card` is returned
7070
If `card` is omitted: the first AMD GPU identifier is returned
7171
"""
72-
if card in AMDGPU_CARDS:
72+
if card in CARDS:
7373
# card was provided and checks out, send it back
7474
return card
7575
if card is None:
7676
# if no card provided and we know some, send the first one we know back
77-
if len(AMDGPU_CARDS) > 0:
78-
return list(AMDGPU_CARDS.keys())[0]
77+
if len(CARDS) > 0:
78+
return list(CARDS.keys())[0]
7979
# if no AMD cards found, toss an errror
8080
raise ValueError("No AMD GPUs or hwmon directories found")
81-
# if 'card' was specified (not None) but invalid (not in 'AMDGPU_CARDS'), raise a helpful error
82-
raise ValueError(f"Invalid card: '{card}'. Must be one of: {list(AMDGPU_CARDS.keys())}")
81+
# if 'card' was specified (not None) but invalid (not in 'CARDS'), raise a helpful error
82+
raise ValueError(f"Invalid card: '{card}'. Must be one of: {list(CARDS.keys())}")
8383

8484

8585
def read_stat(file: str, stat_type: Optional[str] = None) -> str:
@@ -104,7 +104,6 @@ def read_stat(file: str, stat_type: Optional[str] = None) -> str:
104104
return None
105105

106106

107-
108107
def format_frequency(frequency_hz: int) -> str:
109108
"""
110109
Takes a frequency (in Hz) and normalizes it: `Hz`, `MHz`, or `GHz`
@@ -122,11 +121,11 @@ def format_frequency(frequency_hz: int) -> str:
122121
def get_power_stats(card: Optional[str] = None) -> dict:
123122
"""
124123
Args:
125-
card (str, optional): ie: `card0`. See `AMDGPU_CARDS` or `find_cards()`
124+
card (str, optional): ie: `card0`. See `CARDS` or `find_cards()`
126125
127126
Raises:
128127
ValueError: If *no* AMD cards are found, or `card` is not one of them.
129-
Determined with `AMDGPU_CARDS`
128+
Determined with `CARDS`
130129
131130
Returns:
132131
dict: A dictionary of current GPU *power* related statistics.
@@ -135,7 +134,7 @@ def get_power_stats(card: Optional[str] = None) -> dict:
135134
`{'limit': int, 'average': int, 'capability': int, 'default': int}`
136135
"""
137136
card = validate_card(card)
138-
hwmon_dir = AMDGPU_CARDS[card]
137+
hwmon_dir = CARDS[card]
139138
_pwr = {"limit": read_stat(path.join(hwmon_dir, "power1_cap"), stat_type='power'),
140139
"limit_pct": 0,
141140
"average": read_stat(path.join(hwmon_dir, "power1_average"), stat_type='power'),
@@ -151,11 +150,11 @@ def get_power_stats(card: Optional[str] = None) -> dict:
151150
def get_core_stats(card: Optional[str] = None) -> dict:
152151
"""
153152
Args:
154-
card (str, optional): ie: `card0`. See `AMDGPU_CARDS` or `find_cards()`
153+
card (str, optional): ie: `card0`. See `CARDS` or `find_cards()`
155154
156155
Raises:
157156
ValueError: If *no* AMD cards are found, or `card` is not one of them.
158-
Determined with `AMDGPU_CARDS`
157+
Determined with `CARDS`
159158
160159
Returns:
161160
dict: A dictionary of current GPU *core/memory* related statistics.
@@ -179,14 +178,14 @@ def get_clock(domain: str, card: Optional[str] = None, format_freq: Optional[boo
179178
domain (str): The GPU part of interest RE: clock speed.
180179
Must be either 'core' or 'memory'
181180
182-
card (str, optional): ie: `card0`. See `AMDGPU_CARDS` or `find_cards()`
181+
card (str, optional): ie: `card0`. See `CARDS` or `find_cards()`
183182
184183
format_freq (bool, optional): If True, a formatted string will be returned instead of an int.
185184
Defaults to False.
186185
187186
Raises:
188187
ValueError: If *no* AMD cards are found, or `card` is not one of them.
189-
Determined with `AMDGPU_CARDS`
188+
Determined with `CARDS`
190189
191190
Returns:
192191
Union[int, str]: The clock value for the specified domain.
@@ -197,7 +196,7 @@ def get_clock(domain: str, card: Optional[str] = None, format_freq: Optional[boo
197196
"""
198197
# verify card -- is it AMD, do we know the hwmon directory?
199198
card = validate_card(card)
200-
hwmon_dir = AMDGPU_CARDS[card]
199+
hwmon_dir = CARDS[card]
201200
if domain not in CLOCK_DOMAINS:
202201
raise ValueError(f"Invalid clock domain: '{domain}'. Must be one of: {CLOCK_DOMAINS}")
203202
# set the clock file based on requested domain
@@ -217,29 +216,29 @@ def get_clock(domain: str, card: Optional[str] = None, format_freq: Optional[boo
217216
def get_voltage(card: Optional[str] = None) -> float:
218217
"""
219218
Args:
220-
card (str, optional): ie: `card0`. See `AMDGPU_CARDS` or `find_cards()`
219+
card (str, optional): ie: `card0`. See `CARDS` or `find_cards()`
221220
222221
Raises:
223222
ValueError: If *no* AMD cards are found, or `card` is not one of them.
224-
Determined with `AMDGPU_CARDS`
223+
Determined with `CARDS`
225224
226225
Returns:
227226
float: The current GPU core voltage
228227
"""
229228
# verify card -- is it AMD, do we know the hwmon directory?
230229
card = validate_card(card)
231-
hwmon_dir = AMDGPU_CARDS[card]
230+
hwmon_dir = CARDS[card]
232231
return round(int(read_stat(path.join(hwmon_dir, "in0_input"))) / 1000.0, 2)
233232

234233

235234
def get_fan_rpm(card: Optional[str] = None) -> int:
236235
"""
237236
Args:
238-
card (str, optional): ie: `card0`. See `AMDGPU_CARDS` or `find_cards()`
237+
card (str, optional): ie: `card0`. See `CARDS` or `find_cards()`
239238
240239
Raises:
241240
ValueError: If *no* AMD cards are found, or `card` is not one of them.
242-
Determined with `AMDGPU_CARDS`
241+
Determined with `CARDS`
243242
244243
245244
Returns:
@@ -248,7 +247,7 @@ def get_fan_rpm(card: Optional[str] = None) -> int:
248247
"""
249248
# verify card -- is it AMD, do we know the hwmon directory?
250249
card = validate_card(card)
251-
hwmon_dir = AMDGPU_CARDS[card]
250+
hwmon_dir = CARDS[card]
252251
_val = read_stat(path.join(hwmon_dir, "fan1_input"))
253252
if _val is not None:
254253
_val = int(_val)
@@ -258,29 +257,29 @@ def get_fan_rpm(card: Optional[str] = None) -> int:
258257
def get_fan_target(card: Optional[str] = None) -> int:
259258
"""
260259
Args:
261-
card (str, optional): ie: `card0`. See `AMDGPU_CARDS` or `find_cards()`
260+
card (str, optional): ie: `card0`. See `CARDS` or `find_cards()`
262261
263262
Raises:
264263
ValueError: If *no* AMD cards are found, or `card` is not one of them.
265-
Determined with `AMDGPU_CARDS`
264+
Determined with `CARDS`
266265
267266
Returns:
268267
int: The *target* fan RPM
269268
"""
270269
# verify card -- is it AMD, do we know the hwmon directory?
271270
card = validate_card(card)
272-
hwmon_dir = AMDGPU_CARDS[card]
271+
hwmon_dir = CARDS[card]
273272
return int(read_stat(path.join(hwmon_dir, "fan1_target")))
274273

275274

276275
def get_gpu_usage(card: Optional[str] = None) -> int:
277276
"""
278277
Args:
279-
card (str, optional): ie: `card0`. See `AMDGPU_CARDS` or `find_cards()`
278+
card (str, optional): ie: `card0`. See `CARDS` or `find_cards()`
280279
281280
Raises:
282281
ValueError: If *no* AMD cards are found, or `card` is not one of them.
283-
Determined with `AMDGPU_CARDS`
282+
Determined with `CARDS`
284283
285284
Returns:
286285
int: The current GPU usage/utilization as a percentage
@@ -293,7 +292,7 @@ def get_gpu_usage(card: Optional[str] = None) -> int:
293292
def get_available_temps(card: Optional[str] = None) -> dict:
294293
"""
295294
Args:
296-
card (str, optional): ie: `card0`. See `AMDGPU_CARDS` or `find_cards()`
295+
card (str, optional): ie: `card0`. See `CARDS` or `find_cards()`
297296
298297
Raises:
299298
ValueError: If *no* AMD cards are found, or `card` is not one of them.
@@ -307,7 +306,7 @@ def get_available_temps(card: Optional[str] = None) -> dict:
307306
`{'edge': '/.../temp1_input', 'junction': '/.../temp2_input', 'mem': '/.../temp3_input'}`
308307
"""
309308
card = validate_card(card)
310-
hwmon_dir = AMDGPU_CARDS[card]
309+
hwmon_dir = CARDS[card]
311310
# determine temperature nodes/types, construct a dict to store them
312311
temp_files = {}
313312
temp_node_labels = glob.glob(path.join(hwmon_dir, "temp*_label"))
@@ -326,7 +325,7 @@ def get_available_temps(card: Optional[str] = None) -> dict:
326325
def get_temp_stat(name: str, card: Optional[str] = None) -> dict:
327326
"""
328327
Args:
329-
card (str, optional): ie: `card0`. See `AMDGPU_CARDS` or `find_cards()`
328+
card (str, optional): ie: `card0`. See `CARDS` or `find_cards()`
330329
name (str): temperature *name*, ie: `edge`, `junction`, or `mem`
331330
332331
Raises:

0 commit comments

Comments
 (0)