Commit be036ead authored by one's avatar one
Browse files

[hytop] Rename `--showhcuclocks` to `--showsclk` and update help texts for show flags

parent 15f150c7
...@@ -85,12 +85,12 @@ Designed to be script-friendly: ...@@ -85,12 +85,12 @@ Designed to be script-friendly:
- `--showtemp`: GPU core temperature (`Temp`) - `--showtemp`: GPU core temperature (`Temp`)
- `--showpower`: average package power (`AvgPwr`, plus `AvgPwr@window`) - `--showpower`: average package power (`AvgPwr`, plus `AvgPwr@window`)
- `--showhcuclocks`: sclk frequency (`sclk`) - `--showsclk`: sclk frequency (`sclk`)
- `--showmemuse`: VRAM usage (`VRAM%`) - `--showmemuse`: VRAM usage (`VRAM%`)
- `--showuse`: GPU utilization (`GPU%`, plus `GPU%@window`) - `--showuse`: GPU utilization (`GPU%`, plus `GPU%@window`)
If no `--show*` flags are specified, hytop defaults to: If no `--show*` flags are specified, hytop defaults to:
`--showtemp --showpower --showhcuclocks --showmemuse --showuse`. `--showtemp --showpower --showsclk --showmemuse --showuse`.
## Development ## Development
......
...@@ -4,7 +4,12 @@ from typing import Optional, Set ...@@ -4,7 +4,12 @@ from typing import Optional, Set
import typer import typer
from hytop.gpu.metrics import SUPPORTED_SHOW_FLAGS, normalized_show_flags from hytop.gpu.metrics import (
SHOW_FLAG_HELP,
SUPPORTED_SHOW_FLAGS,
is_supported_show_flag,
normalized_show_flags,
)
from hytop.gpu.service import run_monitor from hytop.gpu.service import run_monitor
from hytop.core.validators import parse_csv_ints from hytop.core.validators import parse_csv_ints
...@@ -22,7 +27,7 @@ def remember_show_flag_callback(ctx: typer.Context, param: object, value: bool) ...@@ -22,7 +27,7 @@ def remember_show_flag_callback(ctx: typer.Context, param: object, value: bool)
if not value: if not value:
return value return value
flag = getattr(param, "name", None) flag = getattr(param, "name", None)
if not isinstance(flag, str) or flag not in SUPPORTED_SHOW_FLAGS: if not isinstance(flag, str) or not is_supported_show_flag(flag):
return value return value
ordered = ctx.meta.setdefault(SHOW_FLAG_ORDER_KEY, []) ordered = ctx.meta.setdefault(SHOW_FLAG_ORDER_KEY, [])
if flag not in ordered: if flag not in ordered:
...@@ -53,31 +58,31 @@ def gpu( ...@@ -53,31 +58,31 @@ def gpu(
False, False,
"--showtemp", "--showtemp",
callback=remember_show_flag_callback, callback=remember_show_flag_callback,
help="Display GPU core temperature.", help=SHOW_FLAG_HELP["showtemp"],
), ),
showpower: bool = typer.Option( showpower: bool = typer.Option(
False, False,
"--showpower", "--showpower",
callback=remember_show_flag_callback, callback=remember_show_flag_callback,
help="Display average GPU power.", help=SHOW_FLAG_HELP["showpower"],
), ),
showhcuclocks: bool = typer.Option( showsclk: bool = typer.Option(
False, False,
"--showhcuclocks", "--showsclk",
callback=remember_show_flag_callback, callback=remember_show_flag_callback,
help="Display GPU sclk frequency.", help=SHOW_FLAG_HELP["showsclk"],
), ),
showmemuse: bool = typer.Option( showmemuse: bool = typer.Option(
False, False,
"--showmemuse", "--showmemuse",
callback=remember_show_flag_callback, callback=remember_show_flag_callback,
help="Display GPU VRAM usage.", help=SHOW_FLAG_HELP["showmemuse"],
), ),
showuse: bool = typer.Option( showuse: bool = typer.Option(
False, False,
"--showuse", "--showuse",
callback=remember_show_flag_callback, callback=remember_show_flag_callback,
help="Display GPU utilization.", help=SHOW_FLAG_HELP["showuse"],
), ),
) -> None: ) -> None:
"""GPU monitoring commands.""" """GPU monitoring commands."""
...@@ -91,12 +96,9 @@ def gpu( ...@@ -91,12 +96,9 @@ def gpu(
interval = ctx.obj["interval"] interval = ctx.obj["interval"]
window_value = ctx.obj["window"] window_value = ctx.obj["window"]
timeout_value = ctx.obj.get("timeout") timeout_value = ctx.obj.get("timeout")
local_flags = locals()
selected_show_flags = { selected_show_flags = {
"showtemp": showtemp, flag: bool(local_flags.get(flag, False)) for flag in SUPPORTED_SHOW_FLAGS
"showpower": showpower,
"showhcuclocks": showhcuclocks,
"showmemuse": showmemuse,
"showuse": showuse,
} }
requested_order = [ requested_order = [
flag flag
......
from __future__ import annotations from __future__ import annotations
from dataclasses import dataclass from dataclasses import dataclass
from typing import Final, Iterable from typing import Final, Iterable, Literal, TypeAlias, TypeGuard
ShowFlag: TypeAlias = Literal[
"showtemp",
"showpower",
"showsclk",
"showmemuse",
"showuse",
]
@dataclass(frozen=True) @dataclass(frozen=True)
...@@ -13,9 +22,11 @@ class RenderColumn: ...@@ -13,9 +22,11 @@ class RenderColumn:
@dataclass(frozen=True) @dataclass(frozen=True)
class ShowSpec: class ShowSpec:
flag: str flag: ShowFlag
metric_json_keys: dict[str, str] metric_json_keys: dict[str, str]
columns: tuple[RenderColumn, ...] columns: tuple[RenderColumn, ...]
cli_help: str
hy_smi_flag: str | None = None
SHOW_SPECS: Final[tuple[ShowSpec, ...]] = ( SHOW_SPECS: Final[tuple[ShowSpec, ...]] = (
...@@ -23,34 +34,44 @@ SHOW_SPECS: Final[tuple[ShowSpec, ...]] = ( ...@@ -23,34 +34,44 @@ SHOW_SPECS: Final[tuple[ShowSpec, ...]] = (
flag="showtemp", flag="showtemp",
metric_json_keys={"temp_c": "Temperature (Sensor core) (C)"}, metric_json_keys={"temp_c": "Temperature (Sensor core) (C)"},
columns=(RenderColumn(label="Temp", metric="temp_c"),), columns=(RenderColumn(label="Temp", metric="temp_c"),),
cli_help="Display GPU core temperature.",
), ),
ShowSpec( ShowSpec(
flag="showpower", flag="showpower",
metric_json_keys={"avg_pwr_w": "Average Graphics Package Power (W)"}, metric_json_keys={"avg_pwr_w": "Average Graphics Package Power (W)"},
columns=(RenderColumn(label="AvgPwr", metric="avg_pwr_w", avg_label="AvgPwr"),), columns=(RenderColumn(label="AvgPwr", metric="avg_pwr_w", avg_label="AvgPwr"),),
cli_help="Display average GPU power.",
), ),
ShowSpec( ShowSpec(
flag="showhcuclocks", flag="showsclk",
metric_json_keys={"sclk_mhz": "sclk clock speed"}, metric_json_keys={"sclk_mhz": "sclk clock speed"},
columns=(RenderColumn(label="sclk", metric="sclk_mhz"),), columns=(RenderColumn(label="sclk", metric="sclk_mhz"),),
cli_help="Display GPU sclk frequency.",
hy_smi_flag="showhcuclocks",
), ),
ShowSpec( ShowSpec(
flag="showmemuse", flag="showmemuse",
metric_json_keys={"vram_pct": "HCU memory use (%)"}, metric_json_keys={"vram_pct": "HCU memory use (%)"},
columns=(RenderColumn(label="VRAM%", metric="vram_pct"),), columns=(RenderColumn(label="VRAM%", metric="vram_pct"),),
cli_help="Display GPU VRAM usage.",
), ),
ShowSpec( ShowSpec(
flag="showuse", flag="showuse",
metric_json_keys={"hcu_pct": "HCU use (%)"}, metric_json_keys={"hcu_pct": "HCU use (%)"},
columns=(RenderColumn(label="GPU%", metric="hcu_pct", avg_label="GPU%"),), columns=(RenderColumn(label="GPU%", metric="hcu_pct", avg_label="GPU%"),),
cli_help="Display GPU utilization.",
), ),
) )
SPEC_BY_FLAG: Final[dict[str, ShowSpec]] = {spec.flag: spec for spec in SHOW_SPECS} SPEC_BY_FLAG: Final[dict[ShowFlag, ShowSpec]] = {spec.flag: spec for spec in SHOW_SPECS}
SUPPORTED_SHOW_FLAGS: Final[tuple[ShowFlag, ...]] = tuple(spec.flag for spec in SHOW_SPECS)
DEFAULT_SHOW_FLAGS: Final[tuple[ShowFlag, ...]] = SUPPORTED_SHOW_FLAGS
SUPPORTED_SHOW_FLAGS: Final[tuple[str, ...]] = tuple(spec.flag for spec in SHOW_SPECS) SHOW_FLAG_HELP: Final[dict[ShowFlag, str]] = {spec.flag: spec.cli_help for spec in SHOW_SPECS}
DEFAULT_SHOW_FLAGS: Final[tuple[str, ...]] = SUPPORTED_SHOW_FLAGS WAIT_IDLE_REQUIRED_SHOW_FLAGS: Final[tuple[ShowFlag, ...]] = ("showmemuse", "showuse")
JSON_KEY_BY_METRIC: Final[dict[str, str]] = { JSON_KEY_BY_METRIC: Final[dict[str, str]] = {
metric: json_key metric: json_key
...@@ -59,17 +80,24 @@ JSON_KEY_BY_METRIC: Final[dict[str, str]] = { ...@@ -59,17 +80,24 @@ JSON_KEY_BY_METRIC: Final[dict[str, str]] = {
} }
def normalized_show_flags(show_flags: Iterable[str] | None) -> list[str]: def is_supported_show_flag(flag: str) -> TypeGuard[ShowFlag]:
"""Return True when the provided flag belongs to the supported show-flag set."""
return flag in SPEC_BY_FLAG
def normalized_show_flags(show_flags: Iterable[str] | None) -> list[ShowFlag]:
"""Normalize user-selected show flags, preserving order and uniqueness.""" """Normalize user-selected show flags, preserving order and uniqueness."""
if not show_flags: if not show_flags:
return list(DEFAULT_SHOW_FLAGS) return list(DEFAULT_SHOW_FLAGS)
output: list[str] = [] output: list[ShowFlag] = []
for flag in show_flags: for flag in show_flags:
if flag not in SPEC_BY_FLAG: spec = SPEC_BY_FLAG.get(flag)
if spec is None:
continue continue
if flag not in output: if spec.flag not in output:
output.append(flag) output.append(spec.flag)
return output if output else list(DEFAULT_SHOW_FLAGS) return output if output else list(DEFAULT_SHOW_FLAGS)
...@@ -79,11 +107,15 @@ def hy_smi_args_for_show_flags(show_flags: Iterable[str], wait_idle: bool) -> li ...@@ -79,11 +107,15 @@ def hy_smi_args_for_show_flags(show_flags: Iterable[str], wait_idle: bool) -> li
ordered_flags = normalized_show_flags(show_flags) ordered_flags = normalized_show_flags(show_flags)
if wait_idle: if wait_idle:
# wait-idle relies on usage+memory metrics even when not displayed. # wait-idle relies on usage+memory metrics even when not displayed.
for required in ("showmemuse", "showuse"): for required in WAIT_IDLE_REQUIRED_SHOW_FLAGS:
if required not in ordered_flags: if required not in ordered_flags:
ordered_flags.append(required) ordered_flags.append(required)
args = ["--json"] args = ["--json"]
args.extend(f"--{flag}" for flag in ordered_flags) for flag in ordered_flags:
spec = SPEC_BY_FLAG.get(flag)
if spec:
hy_flag = spec.hy_smi_flag or flag
args.append(f"--{hy_flag}")
return args return args
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment