amd-smi-wsl 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- amd_smi_wsl-0.2.0/CHANGELOG.md +69 -0
- amd_smi_wsl-0.2.0/CONTRIBUTING.md +39 -0
- amd_smi_wsl-0.2.0/LICENSE +29 -0
- amd_smi_wsl-0.2.0/MANIFEST.in +5 -0
- amd_smi_wsl-0.2.0/PKG-INFO +166 -0
- amd_smi_wsl-0.2.0/README.md +132 -0
- amd_smi_wsl-0.2.0/pyproject.toml +50 -0
- amd_smi_wsl-0.2.0/setup.cfg +4 -0
- amd_smi_wsl-0.2.0/src/amd_smi_wsl.egg-info/PKG-INFO +166 -0
- amd_smi_wsl-0.2.0/src/amd_smi_wsl.egg-info/SOURCES.txt +23 -0
- amd_smi_wsl-0.2.0/src/amd_smi_wsl.egg-info/dependency_links.txt +1 -0
- amd_smi_wsl-0.2.0/src/amd_smi_wsl.egg-info/requires.txt +3 -0
- amd_smi_wsl-0.2.0/src/amd_smi_wsl.egg-info/top_level.txt +1 -0
- amd_smi_wsl-0.2.0/src/amdsmi/__init__.py +80 -0
- amd_smi_wsl-0.2.0/src/amdsmi/_backend.py +331 -0
- amd_smi_wsl-0.2.0/src/amdsmi/_constants.py +468 -0
- amd_smi_wsl-0.2.0/src/amdsmi/_device_map.py +90 -0
- amd_smi_wsl-0.2.0/src/amdsmi/_enums.py +528 -0
- amd_smi_wsl-0.2.0/src/amdsmi/_event.py +25 -0
- amd_smi_wsl-0.2.0/src/amdsmi/_exceptions.py +164 -0
- amd_smi_wsl-0.2.0/src/amdsmi/_func_list.py +192 -0
- amd_smi_wsl-0.2.0/src/amdsmi/_handles.py +42 -0
- amd_smi_wsl-0.2.0/src/amdsmi/_interface.py +440 -0
- amd_smi_wsl-0.2.0/src/amdsmi/py.typed +0 -0
- amd_smi_wsl-0.2.0/tests/test_dropin.py +224 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.2.0] - 2026-06-11
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- **Critical:** infinite recursion / `RecursionError` when used with a real
|
|
14
|
+
PyTorch ROCm build. torch's ROCm device enumeration resolves the device count
|
|
15
|
+
*through* `amdsmi` (`amdsmi_init` + `amdsmi_get_processor_handles`), which this
|
|
16
|
+
package shadows, so `amdsmi_init()` -> backend probe -> `torch.cuda` ->
|
|
17
|
+
`amdsmi_init()` looped forever. A thread-local re-entrancy guard now makes the
|
|
18
|
+
re-entrant `amdsmi_init()` raise so torch falls back to its native HIP device
|
|
19
|
+
count. This was the blocker that prevented the package (and vLLM through it)
|
|
20
|
+
from working at all on the target WSL2 + torch-ROCm environment.
|
|
21
|
+
- `amdsmi_get_clock_info` / `amdsmi_get_temp_metric` / `amdsmi_get_power_info`
|
|
22
|
+
could leak `AMDSMI_STATUS_NOT_FOUND` (and risk re-entrancy) when torch routed
|
|
23
|
+
the sensor query back through amdsmi; they now degrade cleanly to
|
|
24
|
+
`AMDSMI_STATUS_NOT_SUPPORTED`.
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
- `amdsmi_get_gpu_asic_info` now returns `device_id`, `vendor_id`,
|
|
28
|
+
`subvendor_id`, `subsystem_id` and `rev_id` as lowercase, zero-padded hex
|
|
29
|
+
strings (e.g. `"0x1586"`, `"0xc1"`), matching the upstream contract. This lets
|
|
30
|
+
vLLM resolve the canonical device name from its hex-keyed
|
|
31
|
+
`_ROCM_DEVICE_ID_NAME_MAP` (e.g. `AMD_Radeon_8060S`) instead of falling back
|
|
32
|
+
to the raw marketing string. `amdsmi_get_gpu_subsystem_id` /
|
|
33
|
+
`amdsmi_get_gpu_revision` likewise return hex strings.
|
|
34
|
+
- `driver_date` from the Windows probe is parsed from the raw WMI
|
|
35
|
+
`/Date(ms)/` serialization into a readable `YYYY-MM-DD` string.
|
|
36
|
+
- The Windows interop probe is cached persistently (PCI metadata is static), so
|
|
37
|
+
vLLM's `with_amdsmi_context` no longer re-spawns `powershell.exe` on every
|
|
38
|
+
call.
|
|
39
|
+
- Degenerate placeholder UUIDs reported by torch on WSL2 (e.g.
|
|
40
|
+
`66666666-...`) are detected and replaced with a stable synthesized id, kept
|
|
41
|
+
consistent across `device_uuid`, `asic_serial`, and board `product_serial`.
|
|
42
|
+
|
|
43
|
+
### Tested
|
|
44
|
+
- Verified end-to-end on WSL2 + AMD Radeon 8060S (Strix Halo, gfx1151) +
|
|
45
|
+
ROCm 7.2.4 + PyTorch 2.9.1: `import amdsmi` works, vLLM ROCm platform
|
|
46
|
+
detection succeeds, and `RocmPlatform.get_device_name(0)` returns
|
|
47
|
+
`AMD_Radeon_8060S`.
|
|
48
|
+
|
|
49
|
+
## [0.1.0] - 2026-06-04
|
|
50
|
+
|
|
51
|
+
### Added
|
|
52
|
+
- Initial release: a drop-in replacement for the `amdsmi` Python package that
|
|
53
|
+
works on WSL2 / Windows, where the native AMD SMI library cannot run because
|
|
54
|
+
the KFD interface (`/dev/kfd`, `/sys/class/kfd`) is unavailable.
|
|
55
|
+
- Full API parity with upstream `amdsmi`: all 189 `amdsmi_*` functions, 37
|
|
56
|
+
`AmdSmi*` enums, the complete exception hierarchy, and `AmdSmiEventReader`.
|
|
57
|
+
- Real implementations for the queryable subset, backed by:
|
|
58
|
+
- the HIP runtime via `torch.cuda` (device count, name, gfx arch, VRAM, compute
|
|
59
|
+
units, live memory usage), and
|
|
60
|
+
- Windows interop (`powershell.exe Get-CimInstance Win32_VideoController`) to
|
|
61
|
+
recover the real PCI device id, subsystem id, and driver version.
|
|
62
|
+
- a static `gfx -> metadata` fallback table.
|
|
63
|
+
- Faithful degradation: capabilities that genuinely do not exist on WSL2 raise
|
|
64
|
+
`AmdSmiLibraryException(AMDSMI_STATUS_NOT_SUPPORTED)`, matching native behavior.
|
|
65
|
+
- `AMDSMI_WSL_DISABLE` environment variable to disable the shim.
|
|
66
|
+
|
|
67
|
+
[Unreleased]: https://github.com/JoursBleu/amd-smi-wsl/compare/v0.2.0...HEAD
|
|
68
|
+
[0.2.0]: https://github.com/JoursBleu/amd-smi-wsl/compare/v0.1.0...v0.2.0
|
|
69
|
+
[0.1.0]: https://github.com/JoursBleu/amd-smi-wsl/releases/tag/v0.1.0
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Thanks for your interest in improving `amd-smi-wsl`.
|
|
4
|
+
|
|
5
|
+
## Scope
|
|
6
|
+
|
|
7
|
+
This package is a **drop-in replacement** for the upstream `amdsmi` Python
|
|
8
|
+
binding, targeted at WSL2 / Windows environments where the native AMD SMI
|
|
9
|
+
library cannot run. The guiding principle is **API fidelity**: the public
|
|
10
|
+
surface (function names, signatures, return shapes, enums, exceptions) must
|
|
11
|
+
match upstream `amdsmi`. Where a capability cannot be supported on WSL2, the
|
|
12
|
+
corresponding function should raise
|
|
13
|
+
`AmdSmiLibraryException(AMDSMI_STATUS_NOT_SUPPORTED)` rather than returning
|
|
14
|
+
fabricated data.
|
|
15
|
+
|
|
16
|
+
## Development setup
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
git clone git@github.com:JoursBleu/amd-smi-wsl.git
|
|
20
|
+
cd amd-smi-wsl
|
|
21
|
+
python -m venv .venv && . .venv/bin/activate
|
|
22
|
+
pip install -e ".[test]"
|
|
23
|
+
pytest
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Guidelines
|
|
27
|
+
|
|
28
|
+
- Keep full parity with upstream `amdsmi` — do not rename or drop public symbols.
|
|
29
|
+
- Constants and enums are extracted verbatim from upstream; do not edit their
|
|
30
|
+
values by hand.
|
|
31
|
+
- New real implementations must degrade gracefully when no GPU / no torch is
|
|
32
|
+
present.
|
|
33
|
+
- Add or update tests in `tests/` for any behavior change.
|
|
34
|
+
- Run `pytest` before opening a pull request.
|
|
35
|
+
|
|
36
|
+
## Reporting issues
|
|
37
|
+
|
|
38
|
+
Please include: OS (Windows version + WSL distro), ROCm version, GPU model,
|
|
39
|
+
`python -c "import torch; print(torch.version.hip)"`, and the full traceback.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 JoursBleu
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
Portions of this project (the AMDSMI_* status constants, the AmdSmi* enum
|
|
26
|
+
value definitions, and the exception classes) are derived from the ROCm/amdsmi
|
|
27
|
+
project, which is also distributed under the MIT License:
|
|
28
|
+
|
|
29
|
+
Copyright (C) Advanced Micro Devices. All rights reserved.
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: amd-smi-wsl
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Drop-in amdsmi replacement for WSL2 / Windows (HIP + Windows interop backed).
|
|
5
|
+
Author: JoursBleu
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://joursbleu.github.io/amd-smi-wsl/
|
|
8
|
+
Project-URL: Documentation, https://joursbleu.github.io/amd-smi-wsl/
|
|
9
|
+
Project-URL: Repository, https://github.com/JoursBleu/amd-smi-wsl
|
|
10
|
+
Project-URL: Issues, https://github.com/JoursBleu/amd-smi-wsl/issues
|
|
11
|
+
Project-URL: Changelog, https://github.com/JoursBleu/amd-smi-wsl/blob/main/CHANGELOG.md
|
|
12
|
+
Keywords: amdsmi,amd-smi,rocm,wsl2,wsl,hip,gpu,vllm
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Environment :: GPU
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
18
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
19
|
+
Classifier: Programming Language :: Python :: 3
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
25
|
+
Classifier: Topic :: System :: Hardware
|
|
26
|
+
Classifier: Topic :: System :: Monitoring
|
|
27
|
+
Classifier: Typing :: Typed
|
|
28
|
+
Requires-Python: >=3.9
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
License-File: LICENSE
|
|
31
|
+
Provides-Extra: test
|
|
32
|
+
Requires-Dist: pytest; extra == "test"
|
|
33
|
+
Dynamic: license-file
|
|
34
|
+
|
|
35
|
+
# amd-smi-wsl
|
|
36
|
+
|
|
37
|
+
A **drop-in replacement for the `amdsmi` Python package** that works inside
|
|
38
|
+
**WSL2 / Windows**, where the native AMD SMI library cannot run.
|
|
39
|
+
|
|
40
|
+
This is a property of the WSL2 GPU stack rather than of any single card, so it
|
|
41
|
+
applies broadly to AMD GPUs used with ROCm under WSL2 — across RDNA
|
|
42
|
+
generations (e.g. RDNA3 / RDNA3.5 / RDNA4 desktop Radeon and Radeon PRO cards,
|
|
43
|
+
as well as Ryzen AI APUs). The data sources it builds on (the HIP runtime and
|
|
44
|
+
Windows interop) are GPU-agnostic; only the per-device details (PCI id, market
|
|
45
|
+
name, gfx arch) differ from card to card.
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
import amdsmi # this package, not the native one
|
|
49
|
+
amdsmi.amdsmi_init()
|
|
50
|
+
h = amdsmi.amdsmi_get_processor_handles()[0]
|
|
51
|
+
print(amdsmi.amdsmi_get_gpu_asic_info(h)["market_name"])
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Why
|
|
55
|
+
|
|
56
|
+
On WSL2 **any** AMD GPU is exposed through DirectX para-virtualisation
|
|
57
|
+
(`/dev/dxg` + `dxgkrnl`), **not** the native `amdgpu` KFD driver. The Linux
|
|
58
|
+
`/dev/kfd` device and its sysfs topology simply do not exist, so — regardless
|
|
59
|
+
of which Radeon / Ryzen GPU you have:
|
|
60
|
+
|
|
61
|
+
- `import amdsmi` (native) fails / `amdsmi_init()` raises, and
|
|
62
|
+
- downstream code such as **vLLM** then fails ROCm platform detection and
|
|
63
|
+
device-name / topology queries at startup,
|
|
64
|
+
|
|
65
|
+
even though the HIP runtime itself works perfectly via `/dev/dxg`.
|
|
66
|
+
|
|
67
|
+
This package restores the `amdsmi` import surface and re-implements the
|
|
68
|
+
*queryable* subset on top of data sources that **do** work in WSL2:
|
|
69
|
+
|
|
70
|
+
| Source | Provides |
|
|
71
|
+
| --- | --- |
|
|
72
|
+
| `torch.cuda` (HIP runtime) | device count, name, GCN arch, total VRAM, compute units, UUID, live mem usage |
|
|
73
|
+
| Windows interop (`Get-CimInstance Win32_VideoController`) | real PCI device id, subsystem id, revision, driver version/date |
|
|
74
|
+
| Static `gfx -> metadata` table | marketing name / VRAM type / device id fallbacks |
|
|
75
|
+
|
|
76
|
+
> **Note on `torch` re-entrancy.** PyTorch's ROCm build resolves its device
|
|
77
|
+
> count *through* `amdsmi` itself. Since this package replaces `amdsmi`, a
|
|
78
|
+
> naive probe would recurse (`amdsmi_init` -> `torch.cuda` -> `amdsmi_init` ...).
|
|
79
|
+
> A thread-local re-entrancy guard breaks that cycle so `torch` falls back to
|
|
80
|
+
> its native HIP device count. See the v0.2.0 entry in the changelog.
|
|
81
|
+
|
|
82
|
+
## API coverage
|
|
83
|
+
|
|
84
|
+
The package exposes **every** public symbol of the upstream binding —
|
|
85
|
+
all 189 `amdsmi_*` functions, all 37 `AmdSmi*` enums, and the full
|
|
86
|
+
exception hierarchy — so `import amdsmi` is binary-compatible at the
|
|
87
|
+
Python level.
|
|
88
|
+
|
|
89
|
+
- **Implemented for real** (read-only queries that map cleanly to HIP /
|
|
90
|
+
Windows data): init / shutdown, processor & socket handle enumeration,
|
|
91
|
+
`asic_info`, `board_info`, `vram_info`, `vram_usage`, `memory_total`,
|
|
92
|
+
`memory_usage`, `device_uuid`, `device_bdf`, `driver_info`, `gpu_id`,
|
|
93
|
+
`subsystem_id`/`name`, `revision`, `vendor_name`, `topo_get_link_type`,
|
|
94
|
+
`topo_get_numa_node_number`, `lib_version`, `rocm_version`,
|
|
95
|
+
`status_code_to_string`, and best-effort `activity` / `clock_info` /
|
|
96
|
+
`temp_metric` / `power_info` (when the running `torch` build exposes them).
|
|
97
|
+
- **Faithful `NOT_SUPPORTED` stubs** for everything the platform genuinely
|
|
98
|
+
lacks under WSL2: the entire CPU/HSMP/EPYC surface, performance counters,
|
|
99
|
+
RAS/ECC, compute/memory partitioning, every `set_*` mutator, GPU reset,
|
|
100
|
+
KFD info, XGMI status, and event notification. These raise
|
|
101
|
+
`AmdSmiLibraryException(AMDSMI_STATUS_NOT_SUPPORTED)` — exactly what the
|
|
102
|
+
native library does for unsupported features.
|
|
103
|
+
|
|
104
|
+
## Install
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
pip install amd-smi-wsl
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
`torch` (ROCm build) is expected to already be present in your environment and
|
|
111
|
+
is therefore **not** declared as a hard dependency.
|
|
112
|
+
|
|
113
|
+
> Only install this where the real `amdsmi` cannot be used. In a normal
|
|
114
|
+
> native-Linux ROCm install you should keep the official `amdsmi`.
|
|
115
|
+
|
|
116
|
+
## Environment variables
|
|
117
|
+
|
|
118
|
+
- `AMDSMI_WSL_DISABLE=1` — make `amdsmi_init()` raise `NOT_SUPPORTED`, useful
|
|
119
|
+
to test a caller's fallback path.
|
|
120
|
+
|
|
121
|
+
## Relationship to vLLM
|
|
122
|
+
|
|
123
|
+
This package makes the native-`amdsmi` code paths in vLLM's
|
|
124
|
+
`vllm/platforms/rocm.py` and `vllm/platforms/__init__.py` work unchanged on
|
|
125
|
+
WSL2, as an alternative to patching vLLM with `torch.cuda` fallbacks
|
|
126
|
+
(cf. vLLM PR #37189).
|
|
127
|
+
|
|
128
|
+
With this package installed, vLLM resolves the **canonical** device name from
|
|
129
|
+
its hex-keyed `_ROCM_DEVICE_ID_NAME_MAP` (because `asic_info["device_id"]` is
|
|
130
|
+
returned as a lowercase hex string such as `"0x1586"`), e.g.:
|
|
131
|
+
|
|
132
|
+
```python
|
|
133
|
+
from vllm.platforms import rocm_platform_plugin
|
|
134
|
+
import vllm.platforms.rocm as rocm
|
|
135
|
+
rocm_platform_plugin() # -> 'vllm.platforms.rocm.RocmPlatform'
|
|
136
|
+
rocm.RocmPlatform.get_device_name(0) # -> 'AMD_Radeon_8060S'
|
|
137
|
+
rocm._GCN_ARCH # -> 'gfx1151'
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Verified environment
|
|
141
|
+
|
|
142
|
+
The mechanism is GPU-agnostic (it only relies on the HIP runtime + Windows
|
|
143
|
+
interop, which behave the same for any Radeon / Ryzen GPU under WSL2). The
|
|
144
|
+
numbers below are from one fully validated end-to-end setup — **WSL2 + AMD
|
|
145
|
+
Radeon 8060S (Strix Halo, gfx1151) + ROCm 7.2.4 + PyTorch 2.9.1** — and the
|
|
146
|
+
device-specific values (name, `device_id`, gfx arch) will naturally differ on
|
|
147
|
+
other cards:
|
|
148
|
+
|
|
149
|
+
| Check | Result |
|
|
150
|
+
| --- | --- |
|
|
151
|
+
| `import amdsmi` + `amdsmi_init()` | OK (no recursion) |
|
|
152
|
+
| `amdsmi_get_gpu_asic_info()["market_name"]` | `AMD Radeon(TM) 8060S Graphics` |
|
|
153
|
+
| `amdsmi_get_gpu_asic_info()["device_id"]` | `0x1586` (hex string) |
|
|
154
|
+
| `target_graphics_version` | `gfx1151` |
|
|
155
|
+
| test suite (`pytest`) | **16 passed** |
|
|
156
|
+
| vLLM `rocm_platform_plugin()` | `vllm.platforms.rocm.RocmPlatform` |
|
|
157
|
+
| vLLM `RocmPlatform.get_device_name(0)` | `AMD_Radeon_8060S` |
|
|
158
|
+
| vLLM `is_fully_connected([0])` | `True` |
|
|
159
|
+
|
|
160
|
+
Telemetry that the platform does not expose (`clock_info`, `temp_metric`,
|
|
161
|
+
`power_info`, `gpu_activity`) raises `AMDSMI_STATUS_NOT_SUPPORTED`, as expected.
|
|
162
|
+
|
|
163
|
+
## License
|
|
164
|
+
|
|
165
|
+
MIT. Status constants, enum values and exception classes are derived from the
|
|
166
|
+
MIT-licensed [ROCm/amdsmi](https://github.com/ROCm/amdsmi) project.
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# amd-smi-wsl
|
|
2
|
+
|
|
3
|
+
A **drop-in replacement for the `amdsmi` Python package** that works inside
|
|
4
|
+
**WSL2 / Windows**, where the native AMD SMI library cannot run.
|
|
5
|
+
|
|
6
|
+
This is a property of the WSL2 GPU stack rather than of any single card, so it
|
|
7
|
+
applies broadly to AMD GPUs used with ROCm under WSL2 — across RDNA
|
|
8
|
+
generations (e.g. RDNA3 / RDNA3.5 / RDNA4 desktop Radeon and Radeon PRO cards,
|
|
9
|
+
as well as Ryzen AI APUs). The data sources it builds on (the HIP runtime and
|
|
10
|
+
Windows interop) are GPU-agnostic; only the per-device details (PCI id, market
|
|
11
|
+
name, gfx arch) differ from card to card.
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
import amdsmi # this package, not the native one
|
|
15
|
+
amdsmi.amdsmi_init()
|
|
16
|
+
h = amdsmi.amdsmi_get_processor_handles()[0]
|
|
17
|
+
print(amdsmi.amdsmi_get_gpu_asic_info(h)["market_name"])
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Why
|
|
21
|
+
|
|
22
|
+
On WSL2 **any** AMD GPU is exposed through DirectX para-virtualisation
|
|
23
|
+
(`/dev/dxg` + `dxgkrnl`), **not** the native `amdgpu` KFD driver. The Linux
|
|
24
|
+
`/dev/kfd` device and its sysfs topology simply do not exist, so — regardless
|
|
25
|
+
of which Radeon / Ryzen GPU you have:
|
|
26
|
+
|
|
27
|
+
- `import amdsmi` (native) fails / `amdsmi_init()` raises, and
|
|
28
|
+
- downstream code such as **vLLM** then fails ROCm platform detection and
|
|
29
|
+
device-name / topology queries at startup,
|
|
30
|
+
|
|
31
|
+
even though the HIP runtime itself works perfectly via `/dev/dxg`.
|
|
32
|
+
|
|
33
|
+
This package restores the `amdsmi` import surface and re-implements the
|
|
34
|
+
*queryable* subset on top of data sources that **do** work in WSL2:
|
|
35
|
+
|
|
36
|
+
| Source | Provides |
|
|
37
|
+
| --- | --- |
|
|
38
|
+
| `torch.cuda` (HIP runtime) | device count, name, GCN arch, total VRAM, compute units, UUID, live mem usage |
|
|
39
|
+
| Windows interop (`Get-CimInstance Win32_VideoController`) | real PCI device id, subsystem id, revision, driver version/date |
|
|
40
|
+
| Static `gfx -> metadata` table | marketing name / VRAM type / device id fallbacks |
|
|
41
|
+
|
|
42
|
+
> **Note on `torch` re-entrancy.** PyTorch's ROCm build resolves its device
|
|
43
|
+
> count *through* `amdsmi` itself. Since this package replaces `amdsmi`, a
|
|
44
|
+
> naive probe would recurse (`amdsmi_init` -> `torch.cuda` -> `amdsmi_init` ...).
|
|
45
|
+
> A thread-local re-entrancy guard breaks that cycle so `torch` falls back to
|
|
46
|
+
> its native HIP device count. See the v0.2.0 entry in the changelog.
|
|
47
|
+
|
|
48
|
+
## API coverage
|
|
49
|
+
|
|
50
|
+
The package exposes **every** public symbol of the upstream binding —
|
|
51
|
+
all 189 `amdsmi_*` functions, all 37 `AmdSmi*` enums, and the full
|
|
52
|
+
exception hierarchy — so `import amdsmi` is binary-compatible at the
|
|
53
|
+
Python level.
|
|
54
|
+
|
|
55
|
+
- **Implemented for real** (read-only queries that map cleanly to HIP /
|
|
56
|
+
Windows data): init / shutdown, processor & socket handle enumeration,
|
|
57
|
+
`asic_info`, `board_info`, `vram_info`, `vram_usage`, `memory_total`,
|
|
58
|
+
`memory_usage`, `device_uuid`, `device_bdf`, `driver_info`, `gpu_id`,
|
|
59
|
+
`subsystem_id`/`name`, `revision`, `vendor_name`, `topo_get_link_type`,
|
|
60
|
+
`topo_get_numa_node_number`, `lib_version`, `rocm_version`,
|
|
61
|
+
`status_code_to_string`, and best-effort `activity` / `clock_info` /
|
|
62
|
+
`temp_metric` / `power_info` (when the running `torch` build exposes them).
|
|
63
|
+
- **Faithful `NOT_SUPPORTED` stubs** for everything the platform genuinely
|
|
64
|
+
lacks under WSL2: the entire CPU/HSMP/EPYC surface, performance counters,
|
|
65
|
+
RAS/ECC, compute/memory partitioning, every `set_*` mutator, GPU reset,
|
|
66
|
+
KFD info, XGMI status, and event notification. These raise
|
|
67
|
+
`AmdSmiLibraryException(AMDSMI_STATUS_NOT_SUPPORTED)` — exactly what the
|
|
68
|
+
native library does for unsupported features.
|
|
69
|
+
|
|
70
|
+
## Install
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
pip install amd-smi-wsl
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
`torch` (ROCm build) is expected to already be present in your environment and
|
|
77
|
+
is therefore **not** declared as a hard dependency.
|
|
78
|
+
|
|
79
|
+
> Only install this where the real `amdsmi` cannot be used. In a normal
|
|
80
|
+
> native-Linux ROCm install you should keep the official `amdsmi`.
|
|
81
|
+
|
|
82
|
+
## Environment variables
|
|
83
|
+
|
|
84
|
+
- `AMDSMI_WSL_DISABLE=1` — make `amdsmi_init()` raise `NOT_SUPPORTED`, useful
|
|
85
|
+
to test a caller's fallback path.
|
|
86
|
+
|
|
87
|
+
## Relationship to vLLM
|
|
88
|
+
|
|
89
|
+
This package makes the native-`amdsmi` code paths in vLLM's
|
|
90
|
+
`vllm/platforms/rocm.py` and `vllm/platforms/__init__.py` work unchanged on
|
|
91
|
+
WSL2, as an alternative to patching vLLM with `torch.cuda` fallbacks
|
|
92
|
+
(cf. vLLM PR #37189).
|
|
93
|
+
|
|
94
|
+
With this package installed, vLLM resolves the **canonical** device name from
|
|
95
|
+
its hex-keyed `_ROCM_DEVICE_ID_NAME_MAP` (because `asic_info["device_id"]` is
|
|
96
|
+
returned as a lowercase hex string such as `"0x1586"`), e.g.:
|
|
97
|
+
|
|
98
|
+
```python
|
|
99
|
+
from vllm.platforms import rocm_platform_plugin
|
|
100
|
+
import vllm.platforms.rocm as rocm
|
|
101
|
+
rocm_platform_plugin() # -> 'vllm.platforms.rocm.RocmPlatform'
|
|
102
|
+
rocm.RocmPlatform.get_device_name(0) # -> 'AMD_Radeon_8060S'
|
|
103
|
+
rocm._GCN_ARCH # -> 'gfx1151'
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Verified environment
|
|
107
|
+
|
|
108
|
+
The mechanism is GPU-agnostic (it only relies on the HIP runtime + Windows
|
|
109
|
+
interop, which behave the same for any Radeon / Ryzen GPU under WSL2). The
|
|
110
|
+
numbers below are from one fully validated end-to-end setup — **WSL2 + AMD
|
|
111
|
+
Radeon 8060S (Strix Halo, gfx1151) + ROCm 7.2.4 + PyTorch 2.9.1** — and the
|
|
112
|
+
device-specific values (name, `device_id`, gfx arch) will naturally differ on
|
|
113
|
+
other cards:
|
|
114
|
+
|
|
115
|
+
| Check | Result |
|
|
116
|
+
| --- | --- |
|
|
117
|
+
| `import amdsmi` + `amdsmi_init()` | OK (no recursion) |
|
|
118
|
+
| `amdsmi_get_gpu_asic_info()["market_name"]` | `AMD Radeon(TM) 8060S Graphics` |
|
|
119
|
+
| `amdsmi_get_gpu_asic_info()["device_id"]` | `0x1586` (hex string) |
|
|
120
|
+
| `target_graphics_version` | `gfx1151` |
|
|
121
|
+
| test suite (`pytest`) | **16 passed** |
|
|
122
|
+
| vLLM `rocm_platform_plugin()` | `vllm.platforms.rocm.RocmPlatform` |
|
|
123
|
+
| vLLM `RocmPlatform.get_device_name(0)` | `AMD_Radeon_8060S` |
|
|
124
|
+
| vLLM `is_fully_connected([0])` | `True` |
|
|
125
|
+
|
|
126
|
+
Telemetry that the platform does not expose (`clock_info`, `temp_metric`,
|
|
127
|
+
`power_info`, `gpu_activity`) raises `AMDSMI_STATUS_NOT_SUPPORTED`, as expected.
|
|
128
|
+
|
|
129
|
+
## License
|
|
130
|
+
|
|
131
|
+
MIT. Status constants, enum values and exception classes are derived from the
|
|
132
|
+
MIT-licensed [ROCm/amdsmi](https://github.com/ROCm/amdsmi) project.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=64", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "amd-smi-wsl"
|
|
7
|
+
version = "0.2.0"
|
|
8
|
+
description = "Drop-in amdsmi replacement for WSL2 / Windows (HIP + Windows interop backed)."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
authors = [{ name = "JoursBleu" }]
|
|
13
|
+
keywords = ["amdsmi", "amd-smi", "rocm", "wsl2", "wsl", "hip", "gpu", "vllm"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 4 - Beta",
|
|
16
|
+
"Environment :: GPU",
|
|
17
|
+
"Intended Audience :: Developers",
|
|
18
|
+
"License :: OSI Approved :: MIT License",
|
|
19
|
+
"Operating System :: Microsoft :: Windows",
|
|
20
|
+
"Operating System :: POSIX :: Linux",
|
|
21
|
+
"Programming Language :: Python :: 3",
|
|
22
|
+
"Programming Language :: Python :: 3.9",
|
|
23
|
+
"Programming Language :: Python :: 3.10",
|
|
24
|
+
"Programming Language :: Python :: 3.11",
|
|
25
|
+
"Programming Language :: Python :: 3.12",
|
|
26
|
+
"Programming Language :: Python :: 3.13",
|
|
27
|
+
"Topic :: System :: Hardware",
|
|
28
|
+
"Topic :: System :: Monitoring",
|
|
29
|
+
"Typing :: Typed",
|
|
30
|
+
]
|
|
31
|
+
dependencies = []
|
|
32
|
+
|
|
33
|
+
[project.optional-dependencies]
|
|
34
|
+
# torch is the runtime data source but is intentionally NOT a hard dependency:
|
|
35
|
+
# it is already present in any ROCm/vLLM environment and pinning it here would
|
|
36
|
+
# fight the user's existing install.
|
|
37
|
+
test = ["pytest"]
|
|
38
|
+
|
|
39
|
+
[project.urls]
|
|
40
|
+
Homepage = "https://joursbleu.github.io/amd-smi-wsl/"
|
|
41
|
+
Documentation = "https://joursbleu.github.io/amd-smi-wsl/"
|
|
42
|
+
Repository = "https://github.com/JoursBleu/amd-smi-wsl"
|
|
43
|
+
Issues = "https://github.com/JoursBleu/amd-smi-wsl/issues"
|
|
44
|
+
Changelog = "https://github.com/JoursBleu/amd-smi-wsl/blob/main/CHANGELOG.md"
|
|
45
|
+
|
|
46
|
+
[tool.setuptools.packages.find]
|
|
47
|
+
where = ["src"]
|
|
48
|
+
|
|
49
|
+
[tool.setuptools.package-data]
|
|
50
|
+
amdsmi = ["py.typed"]
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: amd-smi-wsl
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Drop-in amdsmi replacement for WSL2 / Windows (HIP + Windows interop backed).
|
|
5
|
+
Author: JoursBleu
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://joursbleu.github.io/amd-smi-wsl/
|
|
8
|
+
Project-URL: Documentation, https://joursbleu.github.io/amd-smi-wsl/
|
|
9
|
+
Project-URL: Repository, https://github.com/JoursBleu/amd-smi-wsl
|
|
10
|
+
Project-URL: Issues, https://github.com/JoursBleu/amd-smi-wsl/issues
|
|
11
|
+
Project-URL: Changelog, https://github.com/JoursBleu/amd-smi-wsl/blob/main/CHANGELOG.md
|
|
12
|
+
Keywords: amdsmi,amd-smi,rocm,wsl2,wsl,hip,gpu,vllm
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Environment :: GPU
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
18
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
19
|
+
Classifier: Programming Language :: Python :: 3
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
25
|
+
Classifier: Topic :: System :: Hardware
|
|
26
|
+
Classifier: Topic :: System :: Monitoring
|
|
27
|
+
Classifier: Typing :: Typed
|
|
28
|
+
Requires-Python: >=3.9
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
License-File: LICENSE
|
|
31
|
+
Provides-Extra: test
|
|
32
|
+
Requires-Dist: pytest; extra == "test"
|
|
33
|
+
Dynamic: license-file
|
|
34
|
+
|
|
35
|
+
# amd-smi-wsl
|
|
36
|
+
|
|
37
|
+
A **drop-in replacement for the `amdsmi` Python package** that works inside
|
|
38
|
+
**WSL2 / Windows**, where the native AMD SMI library cannot run.
|
|
39
|
+
|
|
40
|
+
This is a property of the WSL2 GPU stack rather than of any single card, so it
|
|
41
|
+
applies broadly to AMD GPUs used with ROCm under WSL2 — across RDNA
|
|
42
|
+
generations (e.g. RDNA3 / RDNA3.5 / RDNA4 desktop Radeon and Radeon PRO cards,
|
|
43
|
+
as well as Ryzen AI APUs). The data sources it builds on (the HIP runtime and
|
|
44
|
+
Windows interop) are GPU-agnostic; only the per-device details (PCI id, market
|
|
45
|
+
name, gfx arch) differ from card to card.
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
import amdsmi # this package, not the native one
|
|
49
|
+
amdsmi.amdsmi_init()
|
|
50
|
+
h = amdsmi.amdsmi_get_processor_handles()[0]
|
|
51
|
+
print(amdsmi.amdsmi_get_gpu_asic_info(h)["market_name"])
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Why
|
|
55
|
+
|
|
56
|
+
On WSL2 **any** AMD GPU is exposed through DirectX para-virtualisation
|
|
57
|
+
(`/dev/dxg` + `dxgkrnl`), **not** the native `amdgpu` KFD driver. The Linux
|
|
58
|
+
`/dev/kfd` device and its sysfs topology simply do not exist, so — regardless
|
|
59
|
+
of which Radeon / Ryzen GPU you have:
|
|
60
|
+
|
|
61
|
+
- `import amdsmi` (native) fails / `amdsmi_init()` raises, and
|
|
62
|
+
- downstream code such as **vLLM** then fails ROCm platform detection and
|
|
63
|
+
device-name / topology queries at startup,
|
|
64
|
+
|
|
65
|
+
even though the HIP runtime itself works perfectly via `/dev/dxg`.
|
|
66
|
+
|
|
67
|
+
This package restores the `amdsmi` import surface and re-implements the
|
|
68
|
+
*queryable* subset on top of data sources that **do** work in WSL2:
|
|
69
|
+
|
|
70
|
+
| Source | Provides |
|
|
71
|
+
| --- | --- |
|
|
72
|
+
| `torch.cuda` (HIP runtime) | device count, name, GCN arch, total VRAM, compute units, UUID, live mem usage |
|
|
73
|
+
| Windows interop (`Get-CimInstance Win32_VideoController`) | real PCI device id, subsystem id, revision, driver version/date |
|
|
74
|
+
| Static `gfx -> metadata` table | marketing name / VRAM type / device id fallbacks |
|
|
75
|
+
|
|
76
|
+
> **Note on `torch` re-entrancy.** PyTorch's ROCm build resolves its device
|
|
77
|
+
> count *through* `amdsmi` itself. Since this package replaces `amdsmi`, a
|
|
78
|
+
> naive probe would recurse (`amdsmi_init` -> `torch.cuda` -> `amdsmi_init` ...).
|
|
79
|
+
> A thread-local re-entrancy guard breaks that cycle so `torch` falls back to
|
|
80
|
+
> its native HIP device count. See the v0.2.0 entry in the changelog.
|
|
81
|
+
|
|
82
|
+
## API coverage
|
|
83
|
+
|
|
84
|
+
The package exposes **every** public symbol of the upstream binding —
|
|
85
|
+
all 189 `amdsmi_*` functions, all 37 `AmdSmi*` enums, and the full
|
|
86
|
+
exception hierarchy — so `import amdsmi` is binary-compatible at the
|
|
87
|
+
Python level.
|
|
88
|
+
|
|
89
|
+
- **Implemented for real** (read-only queries that map cleanly to HIP /
|
|
90
|
+
Windows data): init / shutdown, processor & socket handle enumeration,
|
|
91
|
+
`asic_info`, `board_info`, `vram_info`, `vram_usage`, `memory_total`,
|
|
92
|
+
`memory_usage`, `device_uuid`, `device_bdf`, `driver_info`, `gpu_id`,
|
|
93
|
+
`subsystem_id`/`name`, `revision`, `vendor_name`, `topo_get_link_type`,
|
|
94
|
+
`topo_get_numa_node_number`, `lib_version`, `rocm_version`,
|
|
95
|
+
`status_code_to_string`, and best-effort `activity` / `clock_info` /
|
|
96
|
+
`temp_metric` / `power_info` (when the running `torch` build exposes them).
|
|
97
|
+
- **Faithful `NOT_SUPPORTED` stubs** for everything the platform genuinely
|
|
98
|
+
lacks under WSL2: the entire CPU/HSMP/EPYC surface, performance counters,
|
|
99
|
+
RAS/ECC, compute/memory partitioning, every `set_*` mutator, GPU reset,
|
|
100
|
+
KFD info, XGMI status, and event notification. These raise
|
|
101
|
+
`AmdSmiLibraryException(AMDSMI_STATUS_NOT_SUPPORTED)` — exactly what the
|
|
102
|
+
native library does for unsupported features.
|
|
103
|
+
|
|
104
|
+
## Install
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
pip install amd-smi-wsl
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
`torch` (ROCm build) is expected to already be present in your environment and
|
|
111
|
+
is therefore **not** declared as a hard dependency.
|
|
112
|
+
|
|
113
|
+
> Only install this where the real `amdsmi` cannot be used. In a normal
|
|
114
|
+
> native-Linux ROCm install you should keep the official `amdsmi`.
|
|
115
|
+
|
|
116
|
+
## Environment variables
|
|
117
|
+
|
|
118
|
+
- `AMDSMI_WSL_DISABLE=1` — make `amdsmi_init()` raise `NOT_SUPPORTED`, useful
|
|
119
|
+
to test a caller's fallback path.
|
|
120
|
+
|
|
121
|
+
## Relationship to vLLM
|
|
122
|
+
|
|
123
|
+
This package makes the native-`amdsmi` code paths in vLLM's
|
|
124
|
+
`vllm/platforms/rocm.py` and `vllm/platforms/__init__.py` work unchanged on
|
|
125
|
+
WSL2, as an alternative to patching vLLM with `torch.cuda` fallbacks
|
|
126
|
+
(cf. vLLM PR #37189).
|
|
127
|
+
|
|
128
|
+
With this package installed, vLLM resolves the **canonical** device name from
|
|
129
|
+
its hex-keyed `_ROCM_DEVICE_ID_NAME_MAP` (because `asic_info["device_id"]` is
|
|
130
|
+
returned as a lowercase hex string such as `"0x1586"`), e.g.:
|
|
131
|
+
|
|
132
|
+
```python
|
|
133
|
+
from vllm.platforms import rocm_platform_plugin
|
|
134
|
+
import vllm.platforms.rocm as rocm
|
|
135
|
+
rocm_platform_plugin() # -> 'vllm.platforms.rocm.RocmPlatform'
|
|
136
|
+
rocm.RocmPlatform.get_device_name(0) # -> 'AMD_Radeon_8060S'
|
|
137
|
+
rocm._GCN_ARCH # -> 'gfx1151'
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Verified environment
|
|
141
|
+
|
|
142
|
+
The mechanism is GPU-agnostic (it only relies on the HIP runtime + Windows
|
|
143
|
+
interop, which behave the same for any Radeon / Ryzen GPU under WSL2). The
|
|
144
|
+
numbers below are from one fully validated end-to-end setup — **WSL2 + AMD
|
|
145
|
+
Radeon 8060S (Strix Halo, gfx1151) + ROCm 7.2.4 + PyTorch 2.9.1** — and the
|
|
146
|
+
device-specific values (name, `device_id`, gfx arch) will naturally differ on
|
|
147
|
+
other cards:
|
|
148
|
+
|
|
149
|
+
| Check | Result |
|
|
150
|
+
| --- | --- |
|
|
151
|
+
| `import amdsmi` + `amdsmi_init()` | OK (no recursion) |
|
|
152
|
+
| `amdsmi_get_gpu_asic_info()["market_name"]` | `AMD Radeon(TM) 8060S Graphics` |
|
|
153
|
+
| `amdsmi_get_gpu_asic_info()["device_id"]` | `0x1586` (hex string) |
|
|
154
|
+
| `target_graphics_version` | `gfx1151` |
|
|
155
|
+
| test suite (`pytest`) | **16 passed** |
|
|
156
|
+
| vLLM `rocm_platform_plugin()` | `vllm.platforms.rocm.RocmPlatform` |
|
|
157
|
+
| vLLM `RocmPlatform.get_device_name(0)` | `AMD_Radeon_8060S` |
|
|
158
|
+
| vLLM `is_fully_connected([0])` | `True` |
|
|
159
|
+
|
|
160
|
+
Telemetry that the platform does not expose (`clock_info`, `temp_metric`,
|
|
161
|
+
`power_info`, `gpu_activity`) raises `AMDSMI_STATUS_NOT_SUPPORTED`, as expected.
|
|
162
|
+
|
|
163
|
+
## License
|
|
164
|
+
|
|
165
|
+
MIT. Status constants, enum values and exception classes are derived from the
|
|
166
|
+
MIT-licensed [ROCm/amdsmi](https://github.com/ROCm/amdsmi) project.
|