Merge amd-dev into amd-master 20230925
Signed-off-by: Maisam Arif <maisarif@amd.com>
Change-Id: Ib60e35c5b8e40229d6da61af2b748f90d8d54417
[ROCm/amdsmi commit: 535f93c1cf]
此提交包含在:
@@ -36,6 +36,8 @@ return_logrotateToOrigConfig() {
|
||||
|
||||
case "$1" in
|
||||
( remove | upgrade)
|
||||
# remove old gpuv-smi symlink
|
||||
rm -f @CPACK_PACKAGING_INSTALL_PREFIX@/bin/gpuv-smi &> /dev/null
|
||||
rm_ldconfig
|
||||
rm_pyc
|
||||
rm_logFolder
|
||||
|
||||
+49
-10
@@ -127,35 +127,74 @@ The output will be in `docs/_build/html`.
|
||||
|
||||
For additional details, see the [ROCm Contributing Guide](https://rocm.docs.amd.com/en/latest/contributing.html#building-documentation)
|
||||
|
||||
## Install Python Library and CLI Tool
|
||||
## Install CLI Tool and Python Library
|
||||
|
||||
### Requirements
|
||||
|
||||
* python 3.7+ 64-bit
|
||||
* driver must be loaded for amdsmi_init() to pass
|
||||
|
||||
### Installation
|
||||
### CLI Installation
|
||||
|
||||
Follow user permissions best practices if installing AMDSMI as any user than root.
|
||||
Before amd-smi install, ensure previous versions of amdsmi library are uninstalled using pip:
|
||||
|
||||
```bash
|
||||
python3 -m pip list | grep amd
|
||||
python3 -m pip uninstall amdsmi
|
||||
```
|
||||
|
||||
* Install amdgpu driver
|
||||
* Install amd-smi-lib package through package manager
|
||||
* amd-smi --help
|
||||
|
||||
Before amd-smi install, uninstall current versions of amdsmi using pip:
|
||||
#### Install Example for Ubuntu 22.04
|
||||
|
||||
```bash
|
||||
pip3 list | grep amd
|
||||
pip3 uninstall amdsmi
|
||||
``` bash
|
||||
python3 -m pip list | grep amd
|
||||
python3 -m pip uninstall amdsmi
|
||||
apt install amd-smi-lib
|
||||
amd-smi --help
|
||||
```
|
||||
|
||||
```bash
|
||||
### Python Library Installation
|
||||
|
||||
This option is for users who want to develop their own scripts using amd-smi's python library
|
||||
|
||||
Verify that your python version is 3.7+ to install the python library
|
||||
|
||||
* Install amdgpu driver
|
||||
* Install amd-smi-lib package through package manager
|
||||
* cd /opt/rocm/share/amd_smi
|
||||
* python3 -m pip install --upgrade pip
|
||||
* python3 -m pip install --user .
|
||||
* import amdsmi in python to start development
|
||||
|
||||
Warning: this will take precedence over the cli tool's library install, to avoid issues run these steps after every amd-smi-lib update.
|
||||
|
||||
#### RHEL 8 & SLES 15
|
||||
|
||||
The default python versions in RHEL 8 and SLES 15 are 3.6.8 and 3.6.15
|
||||
|
||||
While the CLI will work with these python versions, to install the python library you need to upgrade to python 3.7+
|
||||
|
||||
#### Python Library Install Example for Ubuntu 22.04
|
||||
|
||||
``` bash
|
||||
apt install amd-smi-lib
|
||||
amd-smi --help
|
||||
cd /opt/rocm/share/amd_smi
|
||||
python3 -m pip install --upgrade pip
|
||||
python3 -m pip install --user .
|
||||
/opt/rocm/bin/amd-smi --help
|
||||
```
|
||||
|
||||
after installing amd-smi-lib, amd-smi is also available as a binary in /opt/rocm/bin
|
||||
``` bash
|
||||
python3
|
||||
Python 3.8.10 (default, May 26 2023, 14:05:08)
|
||||
[GCC 9.4.0] on linux
|
||||
Type "help", "copyright", "credits" or "license" for more information.
|
||||
>>> import amdsmi
|
||||
>>>
|
||||
```
|
||||
|
||||
### Rebuilding Python wrapper
|
||||
|
||||
|
||||
@@ -27,6 +27,8 @@ return_logrotateToOrigConfig() {
|
||||
|
||||
if [ "$1" -le 1 ]; then
|
||||
# perform the below actions for rpm remove($1=0) or upgrade($1=1) operations
|
||||
# remove old gpuv-smi symlink
|
||||
rm -f @CPACK_PACKAGING_INSTALL_PREFIX@/bin/gpuv-smi &> /dev/null
|
||||
rm_pyc
|
||||
rm_logFolder
|
||||
return_logrotateToOrigConfig
|
||||
|
||||
@@ -72,17 +72,12 @@ add_custom_target(
|
||||
link_amdsmi_cli ALL
|
||||
DEPENDS amdsmi_cli
|
||||
BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/bin/amd-smi
|
||||
${CMAKE_CURRENT_BINARY_DIR}/bin/gpuv-smi
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMAND ${CMAKE_COMMAND} -E create_symlink
|
||||
../${PY_CLI_INSTALL_DIR}/${PY_PACKAGE_DIR}/amdsmi_cli.py
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}/amd-smi
|
||||
COMMAND ${CMAKE_COMMAND} -E create_symlink
|
||||
amd-smi
|
||||
${CMAKE_CURRENT_BINARY_DIR}/bin/gpuv-smi)
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}/amd-smi)
|
||||
|
||||
install(
|
||||
FILES ${CMAKE_CURRENT_BINARY_DIR}/bin/amd-smi
|
||||
${CMAKE_CURRENT_BINARY_DIR}/bin/gpuv-smi
|
||||
DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
COMPONENT dev)
|
||||
|
||||
+160
-71
@@ -6,44 +6,73 @@ and deprecate the existing rocm_smi CLI tool & gpuv-smi tool.
|
||||
It uses Ctypes to call the amd_smi_lib API.
|
||||
Recommended: At least one AMD GPU with AMD driver installed
|
||||
|
||||
## Requirements
|
||||
## Install CLI Tool and Python Library
|
||||
|
||||
### Requirements
|
||||
|
||||
* python 3.7+ 64-bit
|
||||
* driver must be loaded for amdsmi_init() to pass
|
||||
* amdgpu driver must be loaded for amdsmi_init() to pass
|
||||
|
||||
## Installation
|
||||
### CLI Installation
|
||||
|
||||
Before amd-smi install, ensure previous versions of amdsmi library are uninstalled using pip:
|
||||
|
||||
```bash
|
||||
python3 -m pip list | grep amd
|
||||
python3 -m pip uninstall amdsmi
|
||||
```
|
||||
|
||||
* Install amdgpu driver
|
||||
* Install amd-smi-lib package through package manager
|
||||
* amd-smi --help
|
||||
|
||||
#### Install Example for Ubuntu 22.04
|
||||
|
||||
``` bash
|
||||
python3 -m pip list | grep amd
|
||||
python3 -m pip uninstall amdsmi
|
||||
apt install amd-smi-lib
|
||||
amd-smi --help
|
||||
```
|
||||
|
||||
### Python Library Installation
|
||||
|
||||
This option is for users who want to develop their own scripts using amd-smi's python library
|
||||
|
||||
Verify that your python version is 3.7+ to install the python library
|
||||
|
||||
* Install amdgpu driver
|
||||
* Install amd-smi-lib package through package manager
|
||||
* cd /opt/rocm/share/amd_smi
|
||||
* python3 -m pip install --upgrade pip
|
||||
* python3 -m pip install --user .
|
||||
* /opt/rocm/bin/amd-smi --help
|
||||
* import amdsmi in python to start development
|
||||
|
||||
Add /opt/rocm/bin to your shell's path to access amd-smi via the cmdline
|
||||
Warning: this will take precedence over the cli tool's library install, to avoid issues run these steps after every amd-smi-lib update.
|
||||
|
||||
### RHEL 8 & SLES 15
|
||||
#### RHEL 8 & SLES 15
|
||||
|
||||
The default python versions in RHEL 8 and SLES 15 are 3.6.8 and 3.6.15
|
||||
|
||||
While the CLI may work with these python versions, to install the python library you need to upgrade to python 3.7+
|
||||
While the CLI will work with these python versions, to install the python library you need to upgrade to python 3.7+
|
||||
|
||||
Verify that your python version is 3.7+ to install the python library
|
||||
|
||||
### Install Example for Ubuntu 22.04
|
||||
#### Python Library Install Example for Ubuntu 22.04
|
||||
|
||||
``` bash
|
||||
apt install amd-smi-lib
|
||||
amd-smi --help
|
||||
cd /opt/rocm/share/amd_smi
|
||||
python3 -m pip install --upgrade pip
|
||||
python3 -m pip install --user .
|
||||
/opt/rocm/bin/amd-smi
|
||||
```
|
||||
|
||||
Add /opt/rocm/bin to your shell's path to access amd-smi via the cmdline
|
||||
|
||||
``` bash
|
||||
export PATH=$PATH:/opt/rocm/bin
|
||||
python3
|
||||
Python 3.8.10 (default, May 26 2023, 14:05:08)
|
||||
[GCC 9.4.0] on linux
|
||||
Type "help", "copyright", "credits" or "license" for more information.
|
||||
>>> import amdsmi
|
||||
>>>
|
||||
```
|
||||
|
||||
## Usage
|
||||
@@ -54,26 +83,27 @@ amd-smi will report the version and current platform detected when running the c
|
||||
amd-smi
|
||||
usage: amd-smi [-h] ...
|
||||
|
||||
AMD System Management Interface | Version: 23.2.1.0 | Platform: Linux Baremetal
|
||||
AMD System Management Interface | Version: 23.3.1.0 | Platform: Linux Baremetal
|
||||
|
||||
optional arguments:
|
||||
-h, --help show this help message and exit
|
||||
-h, --help show this help message and exit
|
||||
|
||||
AMD-SMI Commands:
|
||||
Descriptions:
|
||||
version Display version information
|
||||
list List GPU information
|
||||
static Gets static information about the specified GPU
|
||||
firmware Gets ucode/firmware information about the specified GPU
|
||||
bad-pages Gets bad page information about the specified GPU
|
||||
metric Gets metric/performance information about the specified GPU
|
||||
process Lists general process information running on the specified GPU
|
||||
topology Displays topology information of the devices.
|
||||
set Set options for devices.
|
||||
reset Reset options for devices.
|
||||
Descriptions:
|
||||
version Display version information
|
||||
list List GPU information
|
||||
static Gets static information about the specified GPU
|
||||
firmware Gets firmware information about the specified GPU
|
||||
bad-pages
|
||||
Gets bad page information about the specified GPU
|
||||
metric Gets metric/performance information about the specified GPU
|
||||
process Lists general process information running on the specified GPU
|
||||
topology Displays topology information of the devices
|
||||
set Set options for devices
|
||||
reset Reset options for devices
|
||||
```
|
||||
|
||||
More detailed verison information can be give when running `amd-smi version`
|
||||
More detailed verison information is available from `amd-smi version`
|
||||
|
||||
Each command will have detailed information via `amd-smi [command] --help`
|
||||
|
||||
@@ -82,10 +112,8 @@ Each command will have detailed information via `amd-smi [command] --help`
|
||||
For convenience, here is the help output for each command
|
||||
|
||||
``` bash
|
||||
amd-smi list --help
|
||||
usage: amd-smi list [-h] [--json | --csv] [--file FILE]
|
||||
[--loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL}]
|
||||
[-g GPU [GPU ...]]
|
||||
[--loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL}] [-g GPU [GPU ...]]
|
||||
|
||||
Lists all the devices on the system and the links between devices.
|
||||
Lists all the sockets and for each socket, GPUs and/or CPUs associated to
|
||||
@@ -96,13 +124,14 @@ GPU with some basic information for each VF.
|
||||
optional arguments:
|
||||
-h, --help show this help message and exit
|
||||
-g GPU [GPU ...], --gpu GPU [GPU ...] Select a GPU ID, BDF, or UUID from the possible choices:
|
||||
ID:0 | BDF:0000:23:00.0 | UUID:ffffffff-ffff-ffff-ffff-ffffffffffff
|
||||
ID:0 | BDF:0000:23:00.0 | UUID:c4ff73bf-0000-1000-80ff-ffffffffffff
|
||||
all | Selects all devices
|
||||
|
||||
Command Modifiers:
|
||||
--json Displays output in JSON format (human readable by default).
|
||||
--csv Displays output in CSV format (human readable by default).
|
||||
--file FILE Saves output into a file on the provided path (stdout by default).
|
||||
--loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL} Set the logging level for the parser commands
|
||||
--loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL} Set the logging level for the parser commands (ERROR by default).
|
||||
```
|
||||
|
||||
``` bash
|
||||
@@ -116,21 +145,22 @@ If no GPU is specified, return firmware information for all GPUs on the system.
|
||||
Firmware Arguments:
|
||||
-h, --help show this help message and exit
|
||||
-g GPU [GPU ...], --gpu GPU [GPU ...] Select a GPU ID, BDF, or UUID from the possible choices:
|
||||
ID:0 | BDF:0000:23:00.0 | UUID:ffffffff-ffff-ffff-ffff-ffffffffffff
|
||||
ID:0 | BDF:0000:23:00.0 | UUID:c4ff73bf-0000-1000-80ff-ffffffffffff
|
||||
all | Selects all devices
|
||||
-f, --ucode-list, --fw-list All FW list information
|
||||
|
||||
Command Modifiers:
|
||||
--json Displays output in JSON format (human readable by default).
|
||||
--csv Displays output in CSV format (human readable by default).
|
||||
--file FILE Saves output into a file on the provided path (stdout by default).
|
||||
--loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL} Set the logging level for the parser commands
|
||||
--loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL} Set the logging level for the parser commands (ERROR by default).
|
||||
```
|
||||
|
||||
```bash
|
||||
amd-smi static --help
|
||||
usage: amd-smi static [-h] [--json | --csv] [--file FILE]
|
||||
[--loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL}] [-g GPU [GPU ...]]
|
||||
[-a] [-b] [-V] [-l] [-d] [-c] [-r] [-B] [-u]
|
||||
[-a] [-b] [-V] [-d] [-r] [-v] [-B] [-l] [-u]
|
||||
|
||||
If no GPU is specified, returns static information for all GPUs on the system.
|
||||
If no static argument is provided, all static information will be displayed.
|
||||
@@ -138,22 +168,23 @@ If no static argument is provided, all static information will be displayed.
|
||||
Static Arguments:
|
||||
-h, --help show this help message and exit
|
||||
-g GPU [GPU ...], --gpu GPU [GPU ...] Select a GPU ID, BDF, or UUID from the possible choices:
|
||||
ID:0 | BDF:0000:23:00.0 | UUID:ffffffff-ffff-ffff-ffff-ffffffffffff
|
||||
ID:0 | BDF:0000:23:00.0 | UUID:c4ff73bf-0000-1000-80ff-ffffffffffff
|
||||
all | Selects all devices
|
||||
-a, --asic All asic information
|
||||
-b, --bus All bus information
|
||||
-V, --vbios All video bios information (if available)
|
||||
-l, --limit All limit metric values (i.e. power and thermal limits)
|
||||
-d, --driver Displays driver version
|
||||
-r, --ras Displays RAS features information
|
||||
-B, --board All board information
|
||||
-u, --numa All numa node information
|
||||
-v, --vram All vram information
|
||||
-B, --board All board information
|
||||
-l, --limit All limit metric values (i.e. power and thermal limits)
|
||||
-u, --numa All numa node information
|
||||
|
||||
Command Modifiers:
|
||||
--json Displays output in JSON format (human readable by default).
|
||||
--csv Displays output in CSV format (human readable by default).
|
||||
--file FILE Saves output into a file on the provided path (stdout by default).
|
||||
--loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL} Set the logging level for the parser commands
|
||||
--loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL} Set the logging level for the parser commands (ERROR by default).
|
||||
```
|
||||
|
||||
```bash
|
||||
@@ -167,7 +198,8 @@ If no GPU is specified, return bad page information for all GPUs on the system.
|
||||
Bad Pages Arguments:
|
||||
-h, --help show this help message and exit
|
||||
-g GPU [GPU ...], --gpu GPU [GPU ...] Select a GPU ID, BDF, or UUID from the possible choices:
|
||||
ID:0 | BDF:0000:23:00.0 | UUID:ffffffff-ffff-ffff-ffff-ffffffffffff
|
||||
ID:0 | BDF:0000:23:00.0 | UUID:c4ff73bf-0000-1000-80ff-ffffffffffff
|
||||
all | Selects all devices
|
||||
-p, --pending Displays all pending retired pages
|
||||
-r, --retired Displays retired pages
|
||||
-u, --un-res Displays unreservable pages
|
||||
@@ -176,16 +208,15 @@ Command Modifiers:
|
||||
--json Displays output in JSON format (human readable by default).
|
||||
--csv Displays output in CSV format (human readable by default).
|
||||
--file FILE Saves output into a file on the provided path (stdout by default).
|
||||
--loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL} Set the logging level for the parser commands
|
||||
--loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL} Set the logging level for the parser commands (ERROR by default).
|
||||
```
|
||||
|
||||
```bash
|
||||
amd-smi metric --help
|
||||
usage: amd-smi metric [-h] [--json | --csv] [--file FILE]
|
||||
[--loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL}] [-g GPU [GPU ...]]
|
||||
[-w loop_time] [-W total_loop_time] [-i number_of_iterations] [-u]
|
||||
[-b] [-p] [-c] [-t] [-e] [-P] [-f] [-C] [-o] [-l] [-r] [-x]
|
||||
[-E] [-m]
|
||||
[-w loop_time] [-W total_loop_time] [-i number_of_iterations] [-m]
|
||||
[-u] [-p] [-c] [-t] [-e] [-k] [-P] [-f] [-C] [-o] [-l] [-x] [-E]
|
||||
|
||||
If no GPU is specified, returns metric information for all GPUs on the system.
|
||||
If no metric argument is provided all metric information will be displayed.
|
||||
@@ -193,15 +224,18 @@ If no metric argument is provided all metric information will be displayed.
|
||||
Metric arguments:
|
||||
-h, --help show this help message and exit
|
||||
-g GPU [GPU ...], --gpu GPU [GPU ...] Select a GPU ID, BDF, or UUID from the possible choices:
|
||||
ID:0 | BDF:0000:23:00.0 | UUID:ffffffff-ffff-ffff-ffff-ffffffffffff
|
||||
ID:0 | BDF:0000:23:00.0 | UUID:c4ff73bf-0000-1000-80ff-ffffffffffff
|
||||
all | Selects all devices
|
||||
-w loop_time, --watch loop_time Reprint the command in a loop of Interval seconds
|
||||
-W total_loop_time, --watch_time total_loop_time The total time to watch the given command
|
||||
-i number_of_iterations, --iterations number_of_iterations Total number of iterations to loop on the given command
|
||||
-m, --mem-usage Memory usage per block
|
||||
-u, --usage Displays engine usage information
|
||||
-p, --power Current power usage
|
||||
-c, --clock Average, max, and current clock frequencies
|
||||
-t, --temperature Current temperatures
|
||||
-e, --ecc Number of ECC errors
|
||||
-k, --ecc-block Number of ECC errors per block
|
||||
-P, --pcie Current PCIe speed, width, and replay count
|
||||
-f, --fan Current fan speed
|
||||
-C, --voltage-curve Display voltage curve
|
||||
@@ -209,13 +243,12 @@ Metric arguments:
|
||||
-l, --perf-level Current DPM performance level
|
||||
-x, --xgmi-err XGMI error information since last read
|
||||
-E, --energy Amount of energy consumed
|
||||
-m, --mem-usage Memory usage per block
|
||||
|
||||
Command Modifiers:
|
||||
--json Displays output in JSON format (human readable by default).
|
||||
--csv Displays output in CSV format (human readable by default).
|
||||
--file FILE Saves output into a file on the provided path (stdout by default).
|
||||
--loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL} Set the logging level for the parser commands
|
||||
--loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL} Set the logging level for the parser commands (ERROR by default).
|
||||
```
|
||||
|
||||
```bash
|
||||
@@ -225,27 +258,28 @@ usage: amd-smi process [-h] [--json | --csv] [--file FILE]
|
||||
[-w loop_time] [-W total_loop_time] [-i number_of_iterations] [-G]
|
||||
[-e] [-p PID] [-n NAME]
|
||||
|
||||
If no GPU is specified, returns information for all GPUs on the system.
|
||||
If no GPU is specified, returns information for all GPUs on the system.
|
||||
If no process argument is provided all process information will be displayed.
|
||||
|
||||
Process arguments:
|
||||
-h, --help show this help message and exit
|
||||
-g GPU [GPU ...], --gpu GPU [GPU ...] Select a GPU ID, BDF, or UUID from the possible choices:
|
||||
ID:0 | BDF:0000:23:00.0 | UUID:ffffffff-ffff-ffff-ffff-ffffffffffff
|
||||
ID:0 | BDF:0000:23:00.0 | UUID:c4ff73bf-0000-1000-80ff-ffffffffffff
|
||||
all | Selects all devices
|
||||
-w loop_time, --watch loop_time Reprint the command in a loop of Interval seconds
|
||||
-W total_loop_time, --watch_time total_loop_time The total time to watch the given command
|
||||
-i number_of_iterations, --iterations number_of_iterations Total number of iterations to loop on the given command
|
||||
-G, --general pid, process name, memory usage
|
||||
-e, --engine All engine usages
|
||||
-p PID, --pid PID Gets all process information about the specified process based on Process ID
|
||||
-n NAME, --name NAME Gets all process information about the specified process based on Process Name.
|
||||
-n NAME, --name NAME Gets all process information about the specified process based on Process Name.
|
||||
If multiple processes have the same name information is returned for all of them.
|
||||
|
||||
Command Modifiers:
|
||||
--json Displays output in JSON format (human readable by default).
|
||||
--csv Displays output in CSV format (human readable by default).
|
||||
--file FILE Saves output into a file on the provided path (stdout by default).
|
||||
--loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL} Set the logging level for the parser commands
|
||||
--loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL} Set the logging level for the parser commands (ERROR by default).
|
||||
```
|
||||
|
||||
```bash
|
||||
@@ -254,13 +288,14 @@ usage: amd-smi topology [-h] [--json | --csv] [--file FILE]
|
||||
[--loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL}]
|
||||
[-g GPU [GPU ...]] [-a] [-w] [-o] [-t] [-b]
|
||||
|
||||
If no GPU is specified, returns information for all GPUs on the system.
|
||||
If no GPU is specified, returns information for all GPUs on the system.
|
||||
If no topology argument is provided all topology information will be displayed.
|
||||
|
||||
Topology arguments:
|
||||
-h, --help show this help message and exit
|
||||
-g GPU [GPU ...], --gpu GPU [GPU ...] Select a GPU ID, BDF, or UUID from the possible choices:
|
||||
ID:0 | BDF:0000:23:00.0 | UUID:ffffffff-ffff-ffff-ffff-ffffffffffff
|
||||
ID:0 | BDF:0000:23:00.0 | UUID:c4ff73bf-0000-1000-80ff-ffffffffffff
|
||||
all | Selects all devices
|
||||
-a, --access Displays link accessibility between GPUs
|
||||
-w, --weight Displays relative weight between GPUs
|
||||
-o, --hops Displays the number of hops between GPUs
|
||||
@@ -271,7 +306,7 @@ Command Modifiers:
|
||||
--json Displays output in JSON format (human readable by default).
|
||||
--csv Displays output in CSV format (human readable by default).
|
||||
--file FILE Saves output into a file on the provided path (stdout by default).
|
||||
--loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL} Set the logging level for the parser commands
|
||||
--loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL} Set the logging level for the parser commands (ERROR by default).
|
||||
```
|
||||
|
||||
```bash
|
||||
@@ -280,23 +315,24 @@ usage: amd-smi set [-h] [--json | --csv] [--file FILE]
|
||||
[--loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL}] -g GPU [GPU ...]
|
||||
[-f %] [-l LEVEL] [-P SETPROFILE] [-d SCLKMAX]
|
||||
|
||||
A GPU must be specified to set a configuration.
|
||||
A GPU must be specified to set a configuration.
|
||||
A set argument must be provided; Multiple set arguments are accepted
|
||||
|
||||
Set Arguments:
|
||||
-h, --help show this help message and exit
|
||||
-g GPU [GPU ...], --gpu GPU [GPU ...] Select a GPU ID, BDF, or UUID from the possible choices:
|
||||
ID:0 | BDF:0000:23:00.0 | UUID:ffffffff-ffff-ffff-ffff-ffffffffffff
|
||||
-f %, --fan % Sets GPU fan speed (0-255 or 0-100%)
|
||||
-l LEVEL, --perflevel LEVEL Sets performance level
|
||||
-P SETPROFILE, --profile SETPROFILE Set power profile level (#) or a quoted string of custom profile attributes
|
||||
-d SCLKMAX, --perfdeterminism SCLKMAX Sets GPU clock frequency limit and performance level to determinism to get minimal performance variation
|
||||
-h, --help show this help message and exit
|
||||
-g GPU [GPU ...], --gpu GPU [GPU ...] Select a GPU ID, BDF, or UUID from the possible choices:
|
||||
ID:0 | BDF:0000:23:00.0 | UUID:c4ff73bf-0000-1000-80ff-ffffffffffff
|
||||
all | Selects all devices
|
||||
-f %, --fan % Sets GPU fan speed (0-255 or 0-100%)
|
||||
-l LEVEL, --perflevel LEVEL Sets performance level
|
||||
-P SETPROFILE, --profile SETPROFILE Set power profile level (#) or a quoted string of custom profile attributes
|
||||
-d SCLKMAX, --perfdeterminism SCLKMAX Sets GPU clock frequency limit and performance level to determinism to get minimal performance variation
|
||||
|
||||
Command Modifiers:
|
||||
--json Displays output in JSON format (human readable by default).
|
||||
--csv Displays output in CSV format (human readable by default).
|
||||
--file FILE Saves output into a file on the provided path (stdout by default).
|
||||
--loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL} Set the logging level for the parser commands
|
||||
--json Displays output in JSON format (human readable by default).
|
||||
--csv Displays output in CSV format (human readable by default).
|
||||
--file FILE Saves output into a file on the provided path (stdout by default).
|
||||
--loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL} Set the logging level for the parser commands (ERROR by default).
|
||||
```
|
||||
|
||||
```bash
|
||||
@@ -305,13 +341,14 @@ usage: amd-smi reset [-h] [--json | --csv] [--file FILE]
|
||||
[--loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL}] -g GPU [GPU ...]
|
||||
[-G] [-c] [-f] [-p] [-x] [-d]
|
||||
|
||||
A GPU must be specified to reset a configuration.
|
||||
A GPU must be specified to reset a configuration.
|
||||
A reset argument must be provided; Multiple reset arguments are accepted
|
||||
|
||||
Reset Arguments:
|
||||
-h, --help show this help message and exit
|
||||
-g GPU [GPU ...], --gpu GPU [GPU ...] Select a GPU ID, BDF, or UUID from the possible choices:
|
||||
ID:0 | BDF:0000:23:00.0 | UUID:ffffffff-ffff-ffff-ffff-ffffffffffff
|
||||
ID:0 | BDF:0000:23:00.0 | UUID:c4ff73bf-0000-1000-80ff-ffffffffffff
|
||||
all | Selects all devices
|
||||
-G, --gpureset Reset the specified GPU
|
||||
-c, --clocks Reset clocks and overdrive to default
|
||||
-f, --fans Reset fans to automatic (driver) control
|
||||
@@ -323,7 +360,59 @@ Command Modifiers:
|
||||
--json Displays output in JSON format (human readable by default).
|
||||
--csv Displays output in CSV format (human readable by default).
|
||||
--file FILE Saves output into a file on the provided path (stdout by default).
|
||||
--loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL} Set the logging level for the parser commands
|
||||
--loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL} Set the logging level for the parser commands (ERROR by default).
|
||||
```
|
||||
|
||||
### Example output from amd-smi static
|
||||
|
||||
Here is some example output from the tool:
|
||||
|
||||
```bash
|
||||
amd-smi static
|
||||
GPU: 0
|
||||
ASIC:
|
||||
MARKET_NAME: 0x73bf
|
||||
VENDOR_ID: 0x1002
|
||||
VENDOR_NAME: Advanced Micro Devices, Inc. [AMD/ATI]
|
||||
SUBVENDOR_ID: 0
|
||||
DEVICE_ID: 0x73bf
|
||||
REV_ID: 0xc3
|
||||
ASIC_SERIAL: 0xffffffffffffffff
|
||||
BUS:
|
||||
BDF: 0000:23:00.0
|
||||
MAX_PCIE_SPEED: 16 GT/s
|
||||
MAX_PCIE_LANES: 16
|
||||
PCIE_INTERFACE_VERSION: Gen 4
|
||||
SLOT_TYPE: PCIE
|
||||
VBIOS:
|
||||
NAME: NAVI21 Gaming XL D41209
|
||||
BUILD_DATE: 2020/10/29 13:30
|
||||
PART_NUMBER: 113-D4120900-101
|
||||
VERSION: 020.001.000.038.015720
|
||||
BOARD:
|
||||
SERIAL_NUMBER: 0xffffffffffffffff
|
||||
MODEL_NUMBER: ffffffffffffffff
|
||||
PRODUCT_NAME: ffffffffffffffff
|
||||
LIMIT:
|
||||
MAX_POWER: 203 W
|
||||
CURRENT_POWER: 203 W
|
||||
SLOWDOWN_EDGE_TEMPERATURE: 100 °C
|
||||
SLOWDOWN_HOTSPOT_TEMPERATURE: 110 °C
|
||||
SLOWDOWN_VRAM_TEMPERATURE: 100 °C
|
||||
SHUTDOWN_EDGE_TEMPERATURE: 105 °C
|
||||
SHUTDOWN_HOTSPOT_TEMPERATURE: 115 °C
|
||||
SHUTDOWN_VRAM_TEMPERATURE: 105 °C
|
||||
DRIVER:
|
||||
DRIVER_VERSION: 6.1.10
|
||||
DRIVER_DATE: 2015/01/01 00:00
|
||||
RAS: N/A
|
||||
VRAM:
|
||||
VRAM_TYPE: MAX
|
||||
VRAM_VENDOR: SAMSUNG
|
||||
VRAM_SIZE_MB: 16368 MB
|
||||
NUMA:
|
||||
NODE: 0
|
||||
AFFINITY: -1
|
||||
```
|
||||
|
||||
## Disclaimer
|
||||
|
||||
@@ -4,6 +4,11 @@
|
||||
|
||||
Documentation for AMDSMI-CLI is available post install in /opt/<rocm_instance>/libexec/amdsmi_cli/README.md
|
||||
|
||||
## AMDSMI-CLI 23.3.1.0
|
||||
|
||||
- not all ecc fields are currently supported
|
||||
- RHEL 8 & SLES 15 may have extra install steps
|
||||
|
||||
## AMDSMI-CLI 23.0.1.1
|
||||
|
||||
### Known Issues
|
||||
@@ -44,4 +49,4 @@ Documentation for AMDSMI-CLI is available post install in /opt/<rocm_instance>/l
|
||||
- csv modifier does not work
|
||||
- topology information is not yet enabled
|
||||
- watch modifier not fully enabled
|
||||
- limited guest support
|
||||
- limited guest support
|
||||
|
||||
@@ -1 +1 @@
|
||||
__version__ = "23.2.1.0"
|
||||
__version__ = "23.3.1.0"
|
||||
|
||||
@@ -1 +1 @@
|
||||
__version__ = "23.2.1.0"
|
||||
__version__ = "23.3.1.0"
|
||||
|
||||
@@ -42,15 +42,7 @@ def _print_error(e, destination):
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Set compatability mode based on which cli mapping user selects
|
||||
if 'gpuv-smi' in sys.argv[0]:
|
||||
compatibility = AMDSMILogger.LoggerCompatibility.gpuvsmi.value
|
||||
elif 'rocm-smi' in sys.argv[0]:
|
||||
compatibility = AMDSMILogger.LoggerCompatibility.rocmsmi.value
|
||||
else:
|
||||
compatibility = AMDSMILogger.LoggerCompatibility.amdsmi.value
|
||||
|
||||
amd_smi_commands = AMDSMICommands(compatibility=compatibility)
|
||||
amd_smi_commands = AMDSMICommands()
|
||||
amd_smi_parser = AMDSMIParser(amd_smi_commands.version,
|
||||
amd_smi_commands.list,
|
||||
amd_smi_commands.static,
|
||||
@@ -74,14 +66,22 @@ if __name__ == "__main__":
|
||||
amd_smi_commands.logger.format = amd_smi_commands.logger.LoggerFormat.csv.value
|
||||
if args.file:
|
||||
amd_smi_commands.logger.destination = args.file
|
||||
if args.loglevel:
|
||||
logging_dict = {'DEBUG' : logging.DEBUG,
|
||||
'INFO' : logging.INFO,
|
||||
'WARNING': logging.WARNING,
|
||||
'ERROR': logging.ERROR,
|
||||
'CRITICAL': logging.CRITICAL}
|
||||
# Enable debug logs on amdsmi library ie. RSMI_LOGGING = 1 in environment or otherwise
|
||||
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging_dict[args.loglevel])
|
||||
|
||||
# Remove previous log handlers
|
||||
for handler in logging.root.handlers[:]:
|
||||
logging.root.removeHandler(handler)
|
||||
|
||||
logging_dict = {'DEBUG' : logging.DEBUG,
|
||||
'INFO' : logging.INFO,
|
||||
'WARNING': logging.WARNING,
|
||||
'ERROR': logging.ERROR,
|
||||
'CRITICAL': logging.CRITICAL}
|
||||
# To enable debug logs on rocm-smi library set RSMI_LOGGING = 1 in environment
|
||||
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging_dict[args.loglevel])
|
||||
|
||||
# Disable traceback for non-debug log levels
|
||||
if args.loglevel != "DEBUG":
|
||||
sys.tracebacklimit = -1
|
||||
|
||||
# Execute subcommands
|
||||
args.func(args)
|
||||
|
||||
@@ -34,16 +34,11 @@ from amdsmi import amdsmi_exception
|
||||
class AMDSMICommands():
|
||||
"""This class contains all the commands corresponding to AMDSMIParser
|
||||
Each command function will interact with AMDSMILogger to handle
|
||||
displaying the output to the specified compatibility, format, and
|
||||
destination.
|
||||
displaying the output to the specified format and destination.
|
||||
"""
|
||||
def __init__(self, compatibility='amdsmi',
|
||||
format='human_readable',
|
||||
destination='stdout') -> None:
|
||||
def __init__(self, format='human_readable', destination='stdout') -> None:
|
||||
self.helpers = AMDSMIHelpers()
|
||||
self.logger = AMDSMILogger(compatibility=compatibility,
|
||||
format=format,
|
||||
destination=destination)
|
||||
self.logger = AMDSMILogger(format=format, destination=destination)
|
||||
try:
|
||||
self.device_handles = amdsmi_interface.amdsmi_get_processor_handles()
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
@@ -125,12 +120,7 @@ class AMDSMICommands():
|
||||
self.logger.store_multiple_device_output()
|
||||
return # Skip printing when there are multiple devices
|
||||
|
||||
# compatibility with gpuvsmi needs a list for single gpu
|
||||
if self.logger.is_gpuvsmi_compatibility() and not multiple_devices:
|
||||
self.logger.store_multiple_device_output()
|
||||
self.logger.print_output(multiple_device_enabled=True)
|
||||
else:
|
||||
self.logger.print_output()
|
||||
self.logger.print_output()
|
||||
|
||||
|
||||
def static(self, args, multiple_devices=False, gpu=None, asic=None,
|
||||
@@ -201,6 +191,9 @@ class AMDSMICommands():
|
||||
|
||||
static_dict = {}
|
||||
|
||||
# Get gpu_id for logging
|
||||
gpu_id = self.helpers.get_gpu_id_from_device_handle(args.gpu)
|
||||
|
||||
if args.asic:
|
||||
try:
|
||||
asic_info = amdsmi_interface.amdsmi_get_gpu_asic_info(args.gpu)
|
||||
@@ -213,7 +206,7 @@ class AMDSMICommands():
|
||||
static_dict['asic'] = asic_info
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
static_dict['asic'] = "N/A"
|
||||
logging.debug("Failed to get asic info for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get asic info for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
if args.bus:
|
||||
bus_output_info = {}
|
||||
|
||||
@@ -249,28 +242,23 @@ class AMDSMICommands():
|
||||
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
bus_info = "N/A"
|
||||
logging.debug("Failed to get bus info for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get bus info for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
try:
|
||||
bus_output_info['bdf'] = amdsmi_interface.amdsmi_get_gpu_device_bdf(args.gpu)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
bus_output_info['bdf'] = "N/A"
|
||||
logging.debug("Failed to get bdf for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get bdf for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
bus_output_info.update(bus_info)
|
||||
static_dict['bus'] = bus_output_info
|
||||
if args.vbios:
|
||||
try:
|
||||
vbios_info = amdsmi_interface.amdsmi_get_gpu_vbios_info(args.gpu)
|
||||
if self.logger.is_gpuvsmi_compatibility():
|
||||
vbios_info['version'] = vbios_info.pop('version')
|
||||
vbios_info['build_date'] = vbios_info.pop('build_date')
|
||||
vbios_info['part_number'] = vbios_info.pop('part_number')
|
||||
|
||||
static_dict['vbios'] = vbios_info
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
static_dict['vbios'] = "N/A"
|
||||
logging.debug("Failed to get vbios info for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get vbios info for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
if self.helpers.is_linux() and self.helpers.is_baremetal():
|
||||
if args.board:
|
||||
@@ -286,7 +274,7 @@ class AMDSMICommands():
|
||||
static_dict['board'] = board_info
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
static_dict['board'] = "N/A"
|
||||
logging.debug("Failed to get board info for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get board info for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
if args.limit:
|
||||
# Power limits
|
||||
try:
|
||||
@@ -298,7 +286,7 @@ class AMDSMICommands():
|
||||
power_limit_error = True
|
||||
max_power_limit = "N/A"
|
||||
current_power_limit = "N/A"
|
||||
logging.debug("Failed to get power cap info for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get power cap info for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
# Edge temperature limits
|
||||
try:
|
||||
@@ -308,7 +296,7 @@ class AMDSMICommands():
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
slowdown_temp_edge_limit_error = True
|
||||
slowdown_temp_edge_limit = "N/A"
|
||||
logging.debug("Failed to get edge temperature slowdown metric for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get edge temperature slowdown metric for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
if slowdown_temp_edge_limit == 0:
|
||||
slowdown_temp_edge_limit_error = True
|
||||
@@ -321,7 +309,7 @@ class AMDSMICommands():
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
shutdown_temp_edge_limit_error = True
|
||||
shutdown_temp_edge_limit = "N/A"
|
||||
logging.debug("Failed to get edge temperature shutdown metrics for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get edge temperature shutdown metrics for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
if shutdown_temp_edge_limit == 0:
|
||||
shutdown_temp_edge_limit_error = True
|
||||
@@ -335,7 +323,7 @@ class AMDSMICommands():
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
slowdown_temp_hotspot_limit_error = True
|
||||
slowdown_temp_hotspot_limit = "N/A"
|
||||
logging.debug("Failed to get hotspot temperature slowdown metrics for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get hotspot temperature slowdown metrics for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
try:
|
||||
shutdown_temp_hotspot_limit_error = False
|
||||
@@ -344,7 +332,7 @@ class AMDSMICommands():
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
shutdown_temp_hotspot_limit_error = True
|
||||
shutdown_temp_hotspot_limit = "N/A"
|
||||
logging.debug("Failed to get hotspot temperature shutdown metrics for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get hotspot temperature shutdown metrics for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
|
||||
# VRAM temperature limits
|
||||
@@ -355,7 +343,7 @@ class AMDSMICommands():
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
slowdown_temp_vram_limit_error = True
|
||||
slowdown_temp_vram_limit = "N/A"
|
||||
logging.debug("Failed to get vram temperature slowdown metrics for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get vram temperature slowdown metrics for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
try:
|
||||
shutdown_temp_vram_limit_error = False
|
||||
@@ -364,7 +352,7 @@ class AMDSMICommands():
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
shutdown_temp_vram_limit_error = True
|
||||
shutdown_temp_vram_limit = "N/A"
|
||||
logging.debug("Failed to get vram temperature shutdown metrics for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get vram temperature shutdown metrics for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
if self.logger.is_human_readable_format():
|
||||
unit = 'W'
|
||||
@@ -407,7 +395,7 @@ class AMDSMICommands():
|
||||
static_dict['driver'] = driver_info
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
static_dict['driver'] = "N/A"
|
||||
logging.debug("Failed to get driver info for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get driver info for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
if self.helpers.is_hypervisor() or self.helpers.is_baremetal():
|
||||
if args.ras:
|
||||
@@ -415,7 +403,7 @@ class AMDSMICommands():
|
||||
static_dict['ras'] = amdsmi_interface.amdsmi_get_gpu_ras_block_features_enabled(args.gpu)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
static_dict['ras'] = "N/A"
|
||||
logging.debug("Failed to get ras block features for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get ras block features for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
if args.vram:
|
||||
try:
|
||||
vram_info = amdsmi_interface.amdsmi_get_gpu_vram_info(args.gpu)
|
||||
@@ -426,13 +414,13 @@ class AMDSMICommands():
|
||||
|
||||
# Remove amdsmi enum prefix
|
||||
vram_info['vram_type'] = vram_type.replace('VRAM_TYPE_', '').replace('_', '')
|
||||
vram_info['vram_vendor'] = vram_type.replace('AMDSMI_VRAM_VENDOR__', '')
|
||||
vram_info['vram_vendor'] = vram_vendor.replace('AMDSMI_VRAM_VENDOR__', '')
|
||||
if self.logger.is_human_readable_format():
|
||||
vram_info['vram_size_mb'] = f"{vram_info['vram_size_mb']} MB"
|
||||
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
vram_info = "N/A"
|
||||
logging.debug("Failed to get vram info for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get vram info for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
static_dict['vram'] = vram_info
|
||||
|
||||
@@ -442,13 +430,13 @@ class AMDSMICommands():
|
||||
numa_node_number = amdsmi_interface.amdsmi_topo_get_numa_node_number(args.gpu)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
numa_node_number = "N/A"
|
||||
logging.debug("Failed to get numa node number for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get numa node number for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
try:
|
||||
numa_affinity = amdsmi_interface.amdsmi_get_gpu_topo_numa_affinity(args.gpu)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
numa_affinity = "N/A"
|
||||
logging.debug("Failed to get numa affinity for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get numa affinity for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
static_dict['numa'] = {'node' : numa_node_number,
|
||||
'affinity' : numa_affinity}
|
||||
@@ -500,7 +488,7 @@ class AMDSMICommands():
|
||||
"""
|
||||
if gpu:
|
||||
args.gpu = gpu
|
||||
if fw_list: # Currently a compatiblity option of gpuv-smi
|
||||
if fw_list:
|
||||
args.fw_list = fw_list
|
||||
|
||||
# Handle No GPU passed
|
||||
@@ -515,6 +503,10 @@ class AMDSMICommands():
|
||||
args.gpu = device_handle
|
||||
|
||||
fw_list = {}
|
||||
|
||||
# Get gpu_id for logging
|
||||
gpu_id = self.helpers.get_gpu_id_from_device_handle(args.gpu)
|
||||
|
||||
if args.fw_list:
|
||||
try:
|
||||
fw_info = amdsmi_interface.amdsmi_get_fw_info(args.gpu)
|
||||
@@ -525,33 +517,21 @@ class AMDSMICommands():
|
||||
fw_entry['fw_version'] = fw_entry.pop('fw_version')
|
||||
firmware_identifier = 'FW'
|
||||
|
||||
if self.logger.is_gpuvsmi_compatibility():
|
||||
firmware_identifier = 'UCODE'
|
||||
fw_entry['name'] = fw_entry.pop('fw_id')
|
||||
fw_entry['version'] = fw_entry.pop('fw_version')
|
||||
|
||||
# Add custom human readable formatting
|
||||
if self.logger.is_human_readable_format():
|
||||
fw_info['fw_list'][fw_index] = {f'{firmware_identifier} {fw_index}': fw_entry}
|
||||
else:
|
||||
fw_info['fw_list'][fw_index] = fw_entry
|
||||
|
||||
if self.logger.is_gpuvsmi_compatibility():
|
||||
fw_info['ucode_list'] = fw_info.pop('fw_list')
|
||||
|
||||
fw_list.update(fw_info)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
fw_list['fw_list'] = "N/A"
|
||||
logging.debug("Failed to get firmware info for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get firmware info for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
multiple_devices_csv_override = False
|
||||
# Convert and store output by pid for csv format
|
||||
if self.logger.is_csv_format():
|
||||
if self.logger.is_gpuvsmi_compatibility():
|
||||
fw_key = 'ucode_list'
|
||||
else:
|
||||
fw_key = 'fw_list'
|
||||
|
||||
fw_key = 'fw_list'
|
||||
for fw_info_dict in fw_list[fw_key]:
|
||||
for key, value in fw_info_dict.items():
|
||||
multiple_devices_csv_override = True
|
||||
@@ -613,13 +593,16 @@ class AMDSMICommands():
|
||||
values_dict = {}
|
||||
bad_page_err_output = ''
|
||||
|
||||
# Get gpu_id for logging
|
||||
gpu_id = self.helpers.get_gpu_id_from_device_handle(args.gpu)
|
||||
|
||||
try:
|
||||
bad_page_info = amdsmi_interface.amdsmi_get_gpu_bad_page_info(args.gpu)
|
||||
bad_page_error = False
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
bad_page_error = True
|
||||
bad_page_err_output = "N/A"
|
||||
logging.debug("Failed to get bad page info for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get bad page info for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
if bad_page_info == "No bad pages found.":
|
||||
bad_page_error = True
|
||||
@@ -825,6 +808,10 @@ class AMDSMICommands():
|
||||
|
||||
# Add timestamp and store values for specified arguments
|
||||
values_dict = {}
|
||||
|
||||
# Get gpu_id for logging
|
||||
gpu_id = self.helpers.get_gpu_id_from_device_handle(args.gpu)
|
||||
|
||||
if self.helpers.is_linux() and self.helpers.is_baremetal():
|
||||
if args.usage:
|
||||
try:
|
||||
@@ -845,7 +832,7 @@ class AMDSMICommands():
|
||||
values_dict['usage'] = engine_usage
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
values_dict['usage'] = "N/A"
|
||||
logging.debug("Failed to get gpu activity for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get gpu activity for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
if args.power:
|
||||
power_dict = {'current_power': "N/A",
|
||||
'current_gfx_voltage': "N/A",
|
||||
@@ -872,7 +859,7 @@ class AMDSMICommands():
|
||||
power_dict['power_limit'] = power_info['power_limit']
|
||||
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
logging.debug("Failed to get power info for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get power info for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
try:
|
||||
is_power_management_enabled = amdsmi_interface.amdsmi_is_gpu_power_management_enabled(args.gpu)
|
||||
@@ -881,7 +868,7 @@ class AMDSMICommands():
|
||||
else:
|
||||
power_dict['power_management'] = "DISABLED"
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
logging.debug("Failed to get power management status for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get power management status for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
values_dict['power'] = power_dict
|
||||
if args.clock:
|
||||
@@ -897,20 +884,20 @@ class AMDSMICommands():
|
||||
|
||||
clocks['gfx'] = gfx_clock
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
logging.debug("Failed to get gfx clock info for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get gfx clock info for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
try:
|
||||
# is_clk_locked = amdsmi_interface.amdsmi_is_clk_locked(args.gpu, amdsmi_interface.AmdSmiClkType.GFX)
|
||||
is_clk_locked = "N/A"
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
is_clk_locked = "N/A"
|
||||
logging.debug("Failed to get gfx clock lock status info for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
|
||||
logging.debug("Failed to get gfx clock lock status info for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
if isinstance(clocks['gfx'], dict):
|
||||
clocks['gfx']['is_clk_locked'] = is_clk_locked
|
||||
else:
|
||||
clocks['gfx'] = {'is_clk_locked': is_clk_locked}
|
||||
|
||||
|
||||
try:
|
||||
mem_clock = amdsmi_interface.amdsmi_get_clock_info(args.gpu, amdsmi_interface.AmdSmiClkType.MEM)
|
||||
|
||||
@@ -921,7 +908,7 @@ class AMDSMICommands():
|
||||
|
||||
clocks['mem'] = mem_clock
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
logging.debug("Failed to get mem clock info for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get mem clock info for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
values_dict['clock'] = clocks
|
||||
if args.temperature:
|
||||
@@ -930,14 +917,14 @@ class AMDSMICommands():
|
||||
args.gpu, amdsmi_interface.AmdSmiTemperatureType.EDGE, amdsmi_interface.AmdSmiTemperatureMetric.CURRENT)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
temperature_edge_current = "N/A"
|
||||
logging.debug("Failed to get current edge temperature for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get current edge temperature for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
try:
|
||||
temperature_edge_limit = amdsmi_interface.amdsmi_get_temp_metric(
|
||||
args.gpu, amdsmi_interface.AmdSmiTemperatureType.EDGE, amdsmi_interface.AmdSmiTemperatureMetric.CRITICAL)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
temperature_edge_limit = "N/A"
|
||||
logging.debug("Failed to get edge temperature limit for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get edge temperature limit for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
# If edge limit is reporting 0 then set the current edge temp to N/A
|
||||
if temperature_edge_limit == 0:
|
||||
@@ -948,28 +935,21 @@ class AMDSMICommands():
|
||||
args.gpu, amdsmi_interface.AmdSmiTemperatureType.HOTSPOT, amdsmi_interface.AmdSmiTemperatureMetric.CURRENT)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
temperature_hotspot_current = "N/A"
|
||||
logging.debug("Failed to get current hotspot temperature for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get current hotspot temperature for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
try:
|
||||
temperature_vram_current = amdsmi_interface.amdsmi_get_temp_metric(
|
||||
args.gpu, amdsmi_interface.AmdSmiTemperatureType.VRAM, amdsmi_interface.AmdSmiTemperatureMetric.CURRENT)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
temperature_vram_current = "N/A"
|
||||
logging.debug("Failed to get current vram temperature for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get current vram temperature for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
temperatures = {'edge': temperature_edge_current,
|
||||
'hotspot': temperature_hotspot_current,
|
||||
'mem': temperature_vram_current}
|
||||
|
||||
if self.logger.is_gpuvsmi_compatibility():
|
||||
temperatures = {'edge_temperature': temperature_edge_current,
|
||||
'hotspot_temperature': temperature_hotspot_current,
|
||||
'mem_temperature': temperature_vram_current}
|
||||
|
||||
if self.logger.is_human_readable_format():
|
||||
unit = '\N{DEGREE SIGN}C'
|
||||
if self.logger.is_gpuvsmi_compatibility():
|
||||
unit = 'C'
|
||||
for temperature_key, temperature_value in temperatures.items():
|
||||
if 'AMD_SMI_STATUS' not in str(temperature_value):
|
||||
temperatures[temperature_key] = f"{temperature_value} {unit}"
|
||||
@@ -984,7 +964,7 @@ class AMDSMICommands():
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
ecc_count['correctable'] = "N/A"
|
||||
ecc_count['uncorrectable'] = "N/A"
|
||||
logging.debug("Failed to get ecc count for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get ecc count for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
values_dict['ecc'] = ecc_count
|
||||
if args.ecc_block:
|
||||
@@ -1000,16 +980,14 @@ class AMDSMICommands():
|
||||
'uncorrectable': ecc_count['uncorrectable_count']}
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
ecc_count = "N/A"
|
||||
logging.debug("Failed to get ecc count for gpu %s at block %s | %s", args.gpu, gpu_block, e.get_error_info())
|
||||
if self.logger.is_gpuvsmi_compatibility():
|
||||
ecc_count = "N/A"
|
||||
logging.debug("Failed to get ecc count for gpu %s at block %s | %s", gpu_id, gpu_block, e.get_error_info())
|
||||
|
||||
ecc_dict[state['block']] = {'correctable' : ecc_count,
|
||||
'uncorrectable': ecc_count}
|
||||
values_dict['ecc_block'] = ecc_dict
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
values_dict['ecc_block'] = "N/A"
|
||||
logging.debug("Failed to get ecc block features for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get ecc block features for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
if args.pcie:
|
||||
pcie_dict = {'current_width': "N/A",
|
||||
'current_speed': "N/A",
|
||||
@@ -1033,13 +1011,13 @@ class AMDSMICommands():
|
||||
unit = 'GT/s'
|
||||
pcie_link_status['current_speed'] = f"{pcie_link_status['pcie_speed']} {unit}"
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
logging.debug("Failed to get pcie link status for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get pcie link status for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
try:
|
||||
pci_replay_counter = amdsmi_interface.amdsmi_get_gpu_pci_replay_counter(args.gpu)
|
||||
pcie_dict['replay_count'] = pci_replay_counter
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
logging.debug("Failed to get pci replay counter for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get pci replay counter for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
try:
|
||||
pcie_bw = amdsmi_interface.amdsmi_get_gpu_pci_throughput(args.gpu)
|
||||
@@ -1060,7 +1038,7 @@ class AMDSMICommands():
|
||||
pcie_dict['current_bandwith_received'] = received
|
||||
pcie_dict['max_packet_size'] = pcie_bw['max_pkt_sz']
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
logging.debug("Failed to get pcie bandwidth for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get pcie bandwidth for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
values_dict['pcie'] = pcie_dict
|
||||
if args.fan:
|
||||
@@ -1113,7 +1091,7 @@ class AMDSMICommands():
|
||||
values_dict['voltage_curve'] = voltage_point_dict
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
values_dict['voltage_curve'] = "N/A"
|
||||
logging.debug("Failed to get voltage curve for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get voltage curve for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
if args.overdrive:
|
||||
try:
|
||||
overdrive_level = amdsmi_interface.amdsmi_get_gpu_overdrive_level(args.gpu)
|
||||
@@ -1125,24 +1103,39 @@ class AMDSMICommands():
|
||||
values_dict['overdrive'] = overdrive_level
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
values_dict['overdrive'] = "N/A"
|
||||
logging.debug("Failed to get overdrive level for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get overdrive level for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
if args.perf_level:
|
||||
try:
|
||||
perf_level = amdsmi_interface.amdsmi_get_gpu_perf_level(args.gpu)
|
||||
values_dict['perf_level'] = perf_level
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
values_dict['perf_level'] = "N/A"
|
||||
logging.debug("Failed to get perf level for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get perf level for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
if self.helpers.is_linux() and self.helpers.is_baremetal():
|
||||
if args.xgmi_err:
|
||||
try:
|
||||
values_dict['xgmi_err'] = amdsmi_interface.amdsmi_gpu_xgmi_error_status(args.gpu)
|
||||
except amdsmi_interface.AmdSmiLibraryException as e:
|
||||
xgmi_err_status = amdsmi_interface.amdsmi_gpu_xgmi_error_status(args.gpu)
|
||||
values_dict['xgmi_err'] = amdsmi_interface.amdsmi_wrapper.amdsmi_xgmi_status_t__enumvalues[xgmi_err_status]
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
values_dict['xgmi_err'] = "N/A"
|
||||
logging.debug("Failed to get xgmi error status for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get xgmi error status for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
if args.energy:
|
||||
pass
|
||||
try:
|
||||
energy_dict = amdsmi_interface.amdsmi_get_energy_count(args.gpu)
|
||||
|
||||
energy = energy_dict['power'] * round(energy_dict['counter_resolution'], 1)
|
||||
energy /= 1000000
|
||||
energy = round(energy, 3)
|
||||
|
||||
if self.logger.is_human_readable_format():
|
||||
unit = 'J'
|
||||
energy = f"{energy} {unit}"
|
||||
|
||||
values_dict['energy'] = {"total_energy_consumption" : energy}
|
||||
except amdsmi_interface.AmdSmiLibraryException as e:
|
||||
values_dict['energy'] = "N/A"
|
||||
logging.debug("Failed to get energy usage for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
|
||||
if self.helpers.is_linux() and (self.helpers.is_baremetal() or self.helpers.is_virtual_os()):
|
||||
if args.mem_usage:
|
||||
@@ -1162,19 +1155,19 @@ class AMDSMICommands():
|
||||
total_vram = amdsmi_interface.amdsmi_get_gpu_memory_total(args.gpu, amdsmi_interface.AmdSmiMemoryType.VRAM)
|
||||
memory_usage['total_vram'] = total_vram // (1024*1024)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
logging.debug("Failed to get total VRAM memory for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get total VRAM memory for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
try:
|
||||
total_visible_vram = amdsmi_interface.amdsmi_get_gpu_memory_total(args.gpu, amdsmi_interface.AmdSmiMemoryType.VIS_VRAM)
|
||||
memory_usage['total_visible_vram'] = total_visible_vram // (1024*1024)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
logging.debug("Failed to get total VIS VRAM memory for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get total VIS VRAM memory for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
try:
|
||||
total_gtt = amdsmi_interface.amdsmi_get_gpu_memory_total(args.gpu, amdsmi_interface.AmdSmiMemoryType.GTT)
|
||||
memory_usage['total_gtt'] = total_gtt // (1024*1024)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
logging.debug("Failed to get total GTT memory for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get total GTT memory for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
# Used VRAM
|
||||
try:
|
||||
@@ -1182,19 +1175,19 @@ class AMDSMICommands():
|
||||
memory_usage['used_vram'] = used_vram // (1024*1024)
|
||||
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
logging.debug("Failed to get used VRAM memory for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get used VRAM memory for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
try:
|
||||
used_visible_vram = amdsmi_interface.amdsmi_get_gpu_memory_usage(args.gpu, amdsmi_interface.AmdSmiMemoryType.VIS_VRAM)
|
||||
memory_usage['used_visible_vram'] = used_visible_vram // (1024*1024)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
logging.debug("Failed to get used VIS VRAM memory for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get used VIS VRAM memory for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
try:
|
||||
used_gtt = amdsmi_interface.amdsmi_get_gpu_memory_usage(args.gpu, amdsmi_interface.AmdSmiMemoryType.GTT)
|
||||
memory_usage['used_gtt'] = used_gtt // (1024*1024)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
logging.debug("Failed to get used GTT memory for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get used GTT memory for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
# Free VRAM
|
||||
if memory_usage['total_vram'] != "N/A" and memory_usage['used_vram'] != "N/A":
|
||||
@@ -1310,11 +1303,14 @@ class AMDSMICommands():
|
||||
else:
|
||||
raise IndexError("args.gpu should not be an empty list")
|
||||
|
||||
# Get gpu_id for logging
|
||||
gpu_id = self.helpers.get_gpu_id_from_device_handle(args.gpu)
|
||||
|
||||
# Populate initial processes
|
||||
try:
|
||||
process_list = amdsmi_interface.amdsmi_get_gpu_process_list(args.gpu)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
logging.debug("Failed to get process list for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to get process list for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
raise e
|
||||
|
||||
filtered_process_values = []
|
||||
@@ -1323,7 +1319,7 @@ class AMDSMICommands():
|
||||
process_info = amdsmi_interface.amdsmi_get_gpu_process_info(args.gpu, process_handle)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
process_info = "N/A"
|
||||
logging.debug("Failed to get process info for gpu %s on process_handle %s | %s", args.gpu, process_handle, e.get_error_info())
|
||||
logging.debug("Failed to get process info for gpu %s on process_handle %s | %s", gpu_id, process_handle, e.get_error_info())
|
||||
filtered_process_values.append({'process_info': process_info})
|
||||
continue
|
||||
|
||||
@@ -1434,7 +1430,6 @@ class AMDSMICommands():
|
||||
def topology(self, args, multiple_devices=False, gpu=None, access=None,
|
||||
weight=None, hops=None, link_type=None, numa_bw=None):
|
||||
""" Get topology information for target gpus
|
||||
The compatibility mode for this will only be in amdsmi & rocm-smi
|
||||
params:
|
||||
args - argparser args to pass to subcommand
|
||||
multiple_devices (bool) - True if checking for multiple devices
|
||||
@@ -1490,7 +1485,10 @@ class AMDSMICommands():
|
||||
src_gpu_links[dest_gpu_key] = bool(dest_gpu_link_status)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
src_gpu_links[dest_gpu_key] = "N/A"
|
||||
logging.debug("Failed to get link status for %s to %s | %s", src_gpu, dest_gpu, e.get_error_info())
|
||||
logging.debug("Failed to get link status for %s to %s | %s",
|
||||
self.helpers.get_gpu_id_from_device_handle(src_gpu),
|
||||
self.helpers.get_gpu_id_from_device_handle(dest_gpu),
|
||||
e.get_error_info())
|
||||
|
||||
topo_values[src_gpu_index]['link_accessibility'] = src_gpu_links
|
||||
|
||||
@@ -1510,7 +1508,10 @@ class AMDSMICommands():
|
||||
src_gpu_weight[dest_gpu_key] = dest_gpu_link_weight
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
src_gpu_weight[dest_gpu_key] = "N/A"
|
||||
logging.debug("Failed to get link weight for %s to %s | %s", src_gpu, dest_gpu, e.get_error_info())
|
||||
logging.debug("Failed to get link weight for %s to %s | %s",
|
||||
self.helpers.get_gpu_id_from_device_handle(src_gpu),
|
||||
self.helpers.get_gpu_id_from_device_handle(dest_gpu),
|
||||
e.get_error_info())
|
||||
|
||||
topo_values[src_gpu_index]['weight'] = src_gpu_weight
|
||||
|
||||
@@ -1530,7 +1531,10 @@ class AMDSMICommands():
|
||||
src_gpu_hops[dest_gpu_key] = dest_gpu_hops
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
src_gpu_hops[dest_gpu_key] = "N/A"
|
||||
logging.debug("Failed to get link hops for %s to %s | %s", src_gpu, dest_gpu, e.get_error_info())
|
||||
logging.debug("Failed to get link hops for %s to %s | %s",
|
||||
self.helpers.get_gpu_id_from_device_handle(src_gpu),
|
||||
self.helpers.get_gpu_id_from_device_handle(dest_gpu),
|
||||
e.get_error_info())
|
||||
|
||||
topo_values[src_gpu_index]['hops'] = src_gpu_hops
|
||||
|
||||
@@ -1555,7 +1559,10 @@ class AMDSMICommands():
|
||||
src_gpu_link_type[dest_gpu_key] = "XGMI"
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
src_gpu_link_type[dest_gpu_key] = "N/A"
|
||||
logging.debug("Failed to get link type for %s to %s | %s", src_gpu, dest_gpu, e.get_error_info())
|
||||
logging.debug("Failed to get link type for %s to %s | %s",
|
||||
self.helpers.get_gpu_id_from_device_handle(src_gpu),
|
||||
self.helpers.get_gpu_id_from_device_handle(dest_gpu),
|
||||
e.get_error_info())
|
||||
|
||||
topo_values[src_gpu_index]['link_type'] = src_gpu_link_type
|
||||
|
||||
@@ -1579,7 +1586,10 @@ class AMDSMICommands():
|
||||
continue
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
src_gpu_link_type[dest_gpu_key] = "N/A"
|
||||
logging.debug("Failed to get link type for %s to %s | %s", src_gpu, dest_gpu, e.get_error_info())
|
||||
logging.debug("Failed to get link type for %s to %s | %s",
|
||||
self.helpers.get_gpu_id_from_device_handle(src_gpu),
|
||||
self.helpers.get_gpu_id_from_device_handle(dest_gpu),
|
||||
e.get_error_info())
|
||||
|
||||
try:
|
||||
min_bw = amdsmi_interface.amdsmi_get_minmax_bandwidth_between_processors(src_gpu, dest_gpu)['min_bandwidth']
|
||||
@@ -1588,6 +1598,10 @@ class AMDSMICommands():
|
||||
src_gpu_link_type[dest_gpu_key] = f'{min_bw}-{max_bw}'
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
src_gpu_link_type[dest_gpu_key] = e.get_error_info()
|
||||
logging.debug("Failed to get min max bandwidth for %s to %s | %s",
|
||||
self.helpers.get_gpu_id_from_device_handle(src_gpu),
|
||||
self.helpers.get_gpu_id_from_device_handle(dest_gpu),
|
||||
e.get_error_info())
|
||||
|
||||
topo_values[src_gpu_index]['numa_bandwidth'] = src_gpu_link_type
|
||||
|
||||
@@ -1661,7 +1675,7 @@ class AMDSMICommands():
|
||||
try:
|
||||
amdsmi_interface.amdsmi_set_gpu_fan_speed(args.gpu, 0, args.fan)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.get_error_code() == amdsmi_exception.AmdSmiRetCode.STATUS_NO_PERM:
|
||||
if e.get_error_code() == amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NO_PERM:
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
raise ValueError(f"Unable to set fan speed {args.fan} on {gpu_string}") from e
|
||||
|
||||
@@ -1671,7 +1685,7 @@ class AMDSMICommands():
|
||||
try:
|
||||
amdsmi_interface.amdsmi_set_gpu_perf_level(args.gpu, perf_level)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.get_error_code() == amdsmi_exception.AmdSmiRetCode.STATUS_NO_PERM:
|
||||
if e.get_error_code() == amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NO_PERM:
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
raise ValueError(f"Unable to set performance level {args.perflevel} on {gpu_string}") from e
|
||||
|
||||
@@ -1682,7 +1696,7 @@ class AMDSMICommands():
|
||||
try:
|
||||
amdsmi_interface.amdsmi_set_gpu_perf_determinism_mode(args.gpu, args.perfdeterminism)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.get_error_code() == amdsmi_exception.AmdSmiRetCode.STATUS_NO_PERM:
|
||||
if e.get_error_code() == amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NO_PERM:
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
raise ValueError(f"Unable to set performance determinism and clock frequency to {args.perfdeterminism} on {gpu_string}") from e
|
||||
|
||||
@@ -1744,13 +1758,16 @@ class AMDSMICommands():
|
||||
|
||||
args.gpu = device_handle
|
||||
|
||||
# Get gpu_id for logging
|
||||
gpu_id = self.helpers.get_gpu_id_from_device_handle(args.gpu)
|
||||
|
||||
if args.gpureset:
|
||||
if self.helpers.is_amd_device(args.gpu):
|
||||
try:
|
||||
amdsmi_interface.amdsmi_reset_gpu(args.gpu)
|
||||
result = 'Successfully reset GPU'
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.get_error_code() == amdsmi_exception.AmdSmiRetCode.STATUS_NO_PERM:
|
||||
if e.get_error_code() == amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NO_PERM:
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
result = "Failed to reset GPU"
|
||||
else:
|
||||
@@ -1765,30 +1782,30 @@ class AMDSMICommands():
|
||||
amdsmi_interface.amdsmi_set_gpu_overdrive_level(args.gpu, 0)
|
||||
reset_clocks_results['overdrive'] = 'Overdrive set to 0'
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.get_error_code() == amdsmi_exception.AmdSmiRetCode.STATUS_NO_PERM:
|
||||
if e.get_error_code() == amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NO_PERM:
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
reset_clocks_results['overdrive'] = "N/A"
|
||||
logging.debug("Failed to reset overdrive on gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to reset overdrive on gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
try:
|
||||
level_auto = amdsmi_interface.AmdSmiDevPerfLevel.AUTO
|
||||
amdsmi_interface.amdsmi_set_gpu_perf_level(args.gpu, level_auto)
|
||||
reset_clocks_results['clocks'] = 'Successfully reset clocks'
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.get_error_code() == amdsmi_exception.AmdSmiRetCode.STATUS_NO_PERM:
|
||||
if e.get_error_code() == amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NO_PERM:
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
reset_clocks_results['clocks'] = "N/A"
|
||||
logging.debug("Failed to reset perf level on gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to reset perf level on gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
try:
|
||||
level_auto = amdsmi_interface.AmdSmiDevPerfLevel.AUTO
|
||||
amdsmi_interface.amdsmi_set_gpu_perf_level(args.gpu, level_auto)
|
||||
reset_clocks_results['performance'] = 'Performance level reset to auto'
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.get_error_code() == amdsmi_exception.AmdSmiRetCode.STATUS_NO_PERM:
|
||||
if e.get_error_code() == amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NO_PERM:
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
reset_clocks_results['performance'] = "N/A"
|
||||
logging.debug("Failed to reset perf level on gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to reset perf level on gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
self.logger.store_output(args.gpu, 'reset_clocks', reset_clocks_results)
|
||||
if args.fans:
|
||||
@@ -1796,10 +1813,10 @@ class AMDSMICommands():
|
||||
amdsmi_interface.amdsmi_reset_gpu_fan(args.gpu, 0)
|
||||
result = 'Successfully reset fan speed to driver control'
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.get_error_code() == amdsmi_exception.AmdSmiRetCode.STATUS_NO_PERM:
|
||||
if e.get_error_code() == amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NO_PERM:
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
result = "N/A"
|
||||
logging.debug("Failed to reset fans on gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to reset fans on gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
self.logger.store_output(args.gpu, 'reset_fans', result)
|
||||
if args.profile:
|
||||
@@ -1810,20 +1827,20 @@ class AMDSMICommands():
|
||||
amdsmi_interface.amdsmi_set_gpu_power_profile(args.gpu, 0, power_profile_mask)
|
||||
reset_profile_results['power_profile'] = 'Successfully reset Power Profile'
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.get_error_code() == amdsmi_exception.AmdSmiRetCode.STATUS_NO_PERM:
|
||||
if e.get_error_code() == amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NO_PERM:
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
reset_profile_results['power_profile'] = "N/A"
|
||||
logging.debug("Failed to reset power profile on gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to reset power profile on gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
try:
|
||||
level_auto = amdsmi_interface.AmdSmiDevPerfLevel.AUTO
|
||||
amdsmi_interface.amdsmi_set_gpu_perf_level(args.gpu, level_auto)
|
||||
reset_profile_results['performance_level'] = 'Successfully reset Performance Level'
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.get_error_code() == amdsmi_exception.AmdSmiRetCode.STATUS_NO_PERM:
|
||||
if e.get_error_code() == amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NO_PERM:
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
reset_profile_results['performance_level'] = "N/A"
|
||||
logging.debug("Failed to reset perf level on gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to reset perf level on gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
self.logger.store_output(args.gpu, 'reset_profile', reset_profile_results)
|
||||
if args.xgmierr:
|
||||
@@ -1831,10 +1848,10 @@ class AMDSMICommands():
|
||||
amdsmi_interface.amdsmi_reset_gpu_xgmi_error(args.gpu)
|
||||
result = 'Successfully reset XGMI Error count'
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.get_error_code() == amdsmi_exception.AmdSmiRetCode.STATUS_NO_PERM:
|
||||
if e.get_error_code() == amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NO_PERM:
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
result = "N/A"
|
||||
logging.debug("Failed to reset xgmi error count on gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to reset xgmi error count on gpu %s | %s", gpu_id, e.get_error_info())
|
||||
self.logger.store_output(args.gpu, 'reset_xgmi_err', result)
|
||||
if args.perfdeterminism:
|
||||
try:
|
||||
@@ -1842,10 +1859,10 @@ class AMDSMICommands():
|
||||
amdsmi_interface.amdsmi_set_gpu_perf_level(args.gpu, level_auto)
|
||||
result = 'Successfully disabled performance determinism'
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.get_error_code() == amdsmi_exception.AmdSmiRetCode.STATUS_NO_PERM:
|
||||
if e.get_error_code() == amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NO_PERM:
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
result = "N/A"
|
||||
logging.debug("Failed to set perf level on gpu %s | %s", args.gpu, e.get_error_info())
|
||||
logging.debug("Failed to set perf level on gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
self.logger.store_output(args.gpu, 'reset_perf_determinism', result)
|
||||
|
||||
@@ -1880,7 +1897,7 @@ class AMDSMICommands():
|
||||
commands.logger.store_output(device, 'values', values_dict)
|
||||
commands.logger.print_output()
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.err_code != amdsmi_exception.AmdSmiRetCode.STATUS_NO_DATA:
|
||||
if e.err_code != amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NO_DATA:
|
||||
print(e)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
@@ -37,6 +37,8 @@ from amdsmi import amdsmi_exception
|
||||
|
||||
# Using basic python logging for user errors and development
|
||||
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.ERROR) # User level logging
|
||||
# This traceback limit only affects this file, once the code hit's the cli portion it get's reset to the user's preference
|
||||
sys.tracebacklimit = -1 # Disable traceback for user errors
|
||||
|
||||
# On initial import set initialized variable
|
||||
AMDSMI_INITIALIZED = False
|
||||
@@ -66,8 +68,7 @@ def init_amdsmi(flag=amdsmi_interface.AmdSmiInitFlags.INIT_AMD_GPUS):
|
||||
amdsmi_interface.amdsmi_init(flag)
|
||||
except (amdsmi_interface.AmdSmiLibraryException, amdsmi_interface.AmdSmiParameterException) as err:
|
||||
raise err
|
||||
|
||||
logging.info('AMDSMI initialized successfully') # without errors really
|
||||
logging.debug('AMDSMI initialized successfully')
|
||||
else:
|
||||
logging.error('Driver not initialized (amdgpu not found in modules)')
|
||||
exit(-1)
|
||||
|
||||
@@ -31,12 +31,10 @@ from amdsmi_helpers import AMDSMIHelpers
|
||||
import amdsmi_cli_exceptions
|
||||
|
||||
class AMDSMILogger():
|
||||
def __init__(self, compatibility='amdsmi', format='human_readable',
|
||||
destination='stdout') -> None:
|
||||
def __init__(self, format='human_readable', destination='stdout') -> None:
|
||||
self.output = {}
|
||||
self.multiple_device_output = []
|
||||
self.watch_output = []
|
||||
self.compatibility = compatibility # amd-smi, gpuv-smi, or rocm-smi
|
||||
self.format = format # csv, json, or human_readable
|
||||
self.destination = destination # stdout, path to a file (append)
|
||||
self.helpers = AMDSMIHelpers()
|
||||
@@ -49,13 +47,6 @@ class AMDSMILogger():
|
||||
human_readable = 'human_readable'
|
||||
|
||||
|
||||
class LoggerCompatibility(Enum):
|
||||
"""Enum for logger compatibility"""
|
||||
amdsmi = 'amdsmi'
|
||||
rocmsmi = 'rocmsmi'
|
||||
gpuvsmi = 'gpuvsmi'
|
||||
|
||||
|
||||
class CsvStdoutBuilder(object):
|
||||
def __init__(self):
|
||||
self.csv_string = []
|
||||
@@ -79,18 +70,6 @@ class AMDSMILogger():
|
||||
return self.format == self.LoggerFormat.human_readable.value
|
||||
|
||||
|
||||
def is_amdsmi_compatibility(self):
|
||||
return self.compatibility == self.LoggerCompatibility.amdsmi.value
|
||||
|
||||
|
||||
def is_rocmsmi_compatibility(self):
|
||||
return self.compatibility == self.LoggerCompatibility.rocmsmi.value
|
||||
|
||||
|
||||
def is_gpuvsmi_compatibility(self):
|
||||
return self.compatibility == self.LoggerCompatibility.gpuvsmi.value
|
||||
|
||||
|
||||
def _capitalize_keys(self, input_dict):
|
||||
output_dict = {}
|
||||
for key in input_dict.keys():
|
||||
@@ -123,10 +102,6 @@ class AMDSMILogger():
|
||||
yaml_data = yaml.safe_load(json_string)
|
||||
yaml_output = yaml.dump(yaml_data, sort_keys=False, allow_unicode=True)
|
||||
|
||||
if self.is_gpuvsmi_compatibility():
|
||||
# Convert from GPU: 0 to GPU 0:
|
||||
yaml_output = re.sub('GPU: ([0-9]+)', 'GPU \\1:', yaml_output)
|
||||
|
||||
# Remove a key line if it is a spacer
|
||||
yaml_output = yaml_output.replace("AMDSMI_SPACING_REMOVAL:\n", "")
|
||||
yaml_output = yaml_output.replace("'", "") # Remove ''
|
||||
@@ -196,13 +171,6 @@ class AMDSMILogger():
|
||||
value_with_parent_key[parent_key] = child_dict
|
||||
value = value_with_parent_key
|
||||
|
||||
if self.is_gpuvsmi_compatibility():
|
||||
if key in ('asic', 'bus', 'pcie', 'vbios','board', 'limit'):
|
||||
value_with_parent_key = {}
|
||||
for child_key, child_value in value.items():
|
||||
value_with_parent_key[key + '_' + child_key] = child_value
|
||||
value = value_with_parent_key
|
||||
|
||||
output_dict.update(self.flatten_dict(value).items())
|
||||
else:
|
||||
output_dict[key] = value
|
||||
@@ -210,9 +178,7 @@ class AMDSMILogger():
|
||||
|
||||
|
||||
def store_output(self, device_handle, argument, data):
|
||||
""" Store the argument and device handle according to the compatibility.
|
||||
Each compatibility function will handle the output format and
|
||||
populate the output
|
||||
""" Convert device handle to gpu id and store output
|
||||
params:
|
||||
device_handle - device handle object to the target device output
|
||||
argument (str) - key to store data
|
||||
@@ -221,12 +187,7 @@ class AMDSMILogger():
|
||||
Nothing
|
||||
"""
|
||||
gpu_id = self.helpers.get_gpu_id_from_device_handle(device_handle)
|
||||
if self.is_amdsmi_compatibility():
|
||||
self._store_output_amdsmi(gpu_id=gpu_id, argument=argument, data=data)
|
||||
elif self.is_rocmsmi_compatibility():
|
||||
self._store_output_rocmsmi(gpu_id=gpu_id, argument=argument, data=data)
|
||||
elif self.is_gpuvsmi_compatibility():
|
||||
self._store_output_gpuvsmi(gpu_id=gpu_id, argument=argument, data=data)
|
||||
self._store_output_amdsmi(gpu_id=gpu_id, argument=argument, data=data)
|
||||
|
||||
|
||||
def _store_output_amdsmi(self, gpu_id, argument, data):
|
||||
@@ -265,42 +226,6 @@ class AMDSMILogger():
|
||||
raise amdsmi_cli_exceptions(self, "Invalid output format given, only json, csv, and human_readable supported")
|
||||
|
||||
|
||||
def _store_output_gpuvsmi(self, gpu_id, argument, data):
|
||||
if argument == 'timestamp': # Make sure timestamp is the first element in the output
|
||||
self.output['timestamp'] = int(time.time())
|
||||
|
||||
if self.is_json_format() or self.is_human_readable_format():
|
||||
self.output['gpu'] = int(gpu_id)
|
||||
self.output[argument] = data
|
||||
elif self.is_csv_format():
|
||||
self.output['gpu'] = int(gpu_id)
|
||||
|
||||
if argument == 'values' or isinstance(data, dict):
|
||||
flat_dict = self.flatten_dict(data)
|
||||
self.output.update(flat_dict)
|
||||
else:
|
||||
self.output[argument] = data
|
||||
|
||||
gpuv_flat_dict = {}
|
||||
for key, value in self.output.items():
|
||||
gpuv_flat_dict[key] = value
|
||||
|
||||
# Change AMDSMI_STATUS strings to N/A for gpuv compatability
|
||||
if isinstance(value, str):
|
||||
if 'AMDSMI_STATUS' in value:
|
||||
gpuv_flat_dict[key] = 'N/A'
|
||||
|
||||
# Change bdf and uuid keys for gpuv compatability
|
||||
if isinstance(key, str):
|
||||
if key in ('bdf','uuid'):
|
||||
gpuv_flat_dict['gpu_' + key] = gpuv_flat_dict.pop(key)
|
||||
|
||||
self.output = gpuv_flat_dict
|
||||
|
||||
else:
|
||||
raise amdsmi_cli_exceptions(self, "Invalid output format given, only json, csv, and human_readable supported")
|
||||
|
||||
|
||||
def store_multiple_device_output(self):
|
||||
""" Store the current output into the multiple_device_output
|
||||
then clear the current output
|
||||
@@ -387,8 +312,20 @@ class AMDSMILogger():
|
||||
if not isinstance(self.output, list):
|
||||
stored_csv_output = [self.output]
|
||||
|
||||
if stored_csv_output:
|
||||
csv_keys = set()
|
||||
for output in stored_csv_output:
|
||||
for key in output:
|
||||
csv_keys.add(key)
|
||||
|
||||
for index, output_dict in enumerate(stored_csv_output):
|
||||
remaining_keys = csv_keys - set(output_dict.keys())
|
||||
for key in remaining_keys:
|
||||
stored_csv_output[index][key] = "N/A"
|
||||
|
||||
if self.destination == 'stdout':
|
||||
if stored_csv_output:
|
||||
# Get the header as a list of the first element to maintain order
|
||||
csv_header = stored_csv_output[0].keys()
|
||||
csv_stdout_output = self.CsvStdoutBuilder()
|
||||
writer = csv.DictWriter(csv_stdout_output, csv_header)
|
||||
@@ -399,12 +336,24 @@ class AMDSMILogger():
|
||||
if watching_output:
|
||||
with self.destination.open('w', newline = '') as output_file:
|
||||
if self.watch_output:
|
||||
csv_keys = set()
|
||||
for output in self.watch_output:
|
||||
for key in output:
|
||||
csv_keys.add(key)
|
||||
|
||||
for index, output_dict in enumerate(self.watch_output):
|
||||
remaining_keys = csv_keys - set(output_dict.keys())
|
||||
for key in remaining_keys:
|
||||
self.watch_output[index][key] = "N/A"
|
||||
|
||||
# Get the header as a list of the first element to maintain order
|
||||
csv_header = self.watch_output[0].keys()
|
||||
writer = csv.DictWriter(output_file, csv_header)
|
||||
writer.writeheader()
|
||||
writer.writerows(self.watch_output)
|
||||
else:
|
||||
with self.destination.open('a', newline = '') as output_file:
|
||||
# Get the header as a list of the first element to maintain order
|
||||
csv_header = stored_csv_output[0].keys()
|
||||
writer = csv.DictWriter(output_file, csv_header)
|
||||
writer.writeheader()
|
||||
|
||||
@@ -53,8 +53,6 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
platform_string = f"Platform: {self.helpers.os_info()}"
|
||||
|
||||
program_name = 'amd-smi'
|
||||
if 'gpuv-smi' in sys.argv[0]:
|
||||
program_name = 'gpuv-smi'
|
||||
|
||||
# Adjust argument parser options
|
||||
super().__init__(
|
||||
@@ -127,14 +125,6 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
path.touch()
|
||||
setattr(args, self.dest, path)
|
||||
elif path.is_file():
|
||||
file_name = str(path)
|
||||
if args.json and str(path).split('.')[-1].lower() != 'json':
|
||||
file_name += ".json"
|
||||
elif args.csv and str(path).split('.')[-1].lower() != 'csv':
|
||||
file_name += ".csv"
|
||||
elif str(path).split('.')[-1].lower() != 'txt':
|
||||
file_name += ".txt"
|
||||
path = Path(file_name)
|
||||
path.touch()
|
||||
setattr(args, self.dest, path)
|
||||
else:
|
||||
@@ -207,11 +197,11 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
return _GPUSelectAction
|
||||
|
||||
|
||||
def _add_command_modifiers(self, subcommand_parser, rocm_smi=True, gpuv_smi=True):
|
||||
def _add_command_modifiers(self, subcommand_parser):
|
||||
json_help = "Displays output in JSON format (human readable by default)."
|
||||
csv_help = "Displays output in CSV format (human readable by default)."
|
||||
file_help = "Saves output into a file on the provided path (stdout by default)."
|
||||
loglevel_help = "Set the logging level for the parser commands"
|
||||
loglevel_help = "Set the logging level for the parser commands (ERROR by default)."
|
||||
|
||||
command_modifier_group = subcommand_parser.add_argument_group('Command Modifiers')
|
||||
|
||||
@@ -571,7 +561,7 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
return
|
||||
|
||||
# Subparser help text
|
||||
topology_help = "Displays topology information of the devices."
|
||||
topology_help = "Displays topology information of the devices"
|
||||
topology_subcommand_help = "If no GPU is specified, returns information for all GPUs on the system.\
|
||||
\nIf no topology argument is provided all topology information will be displayed."
|
||||
topology_optionals_title = "Topology arguments"
|
||||
@@ -607,7 +597,7 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
return
|
||||
|
||||
# Subparser help text
|
||||
set_value_help = "Set options for devices."
|
||||
set_value_help = "Set options for devices"
|
||||
set_value_subcommand_help = "A GPU must be specified to set a configuration.\
|
||||
\nA set argument must be provided; Multiple set arguments are accepted"
|
||||
set_value_optionals_title = "Set Arguments"
|
||||
@@ -734,7 +724,7 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
return
|
||||
|
||||
# Subparser help text
|
||||
reset_help = "Reset options for devices."
|
||||
reset_help = "Reset options for devices"
|
||||
reset_subcommand_help = "A GPU must be specified to reset a configuration.\
|
||||
\nA reset argument must be provided; Multiple reset arguments are accepted"
|
||||
reset_optionals_title = "Reset Arguments"
|
||||
|
||||
@@ -38,7 +38,7 @@ PROJECT_NAME = AMD SMI
|
||||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER = "23.2.1.0"
|
||||
PROJECT_NUMBER = "23.3.1.0"
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewer a
|
||||
|
||||
@@ -99,7 +99,7 @@ typedef enum {
|
||||
#define AMDSMI_LIB_VERSION_YEAR 23
|
||||
|
||||
//! Major version should be changed for every header change (adding/deleting APIs, changing names, fields of structures, etc.)
|
||||
#define AMDSMI_LIB_VERSION_MAJOR 2
|
||||
#define AMDSMI_LIB_VERSION_MAJOR 3
|
||||
|
||||
//! Minor version should be updated for each API change, but without changing headers
|
||||
#define AMDSMI_LIB_VERSION_MINOR 1
|
||||
@@ -290,6 +290,7 @@ typedef enum {
|
||||
FW_ID_SDMA_TH0,
|
||||
FW_ID_SDMA_TH1,
|
||||
FW_ID_CP_MES,
|
||||
FW_ID_MES_KIQ,
|
||||
FW_ID_MES_STACK,
|
||||
FW_ID_MES_THREAD1,
|
||||
FW_ID_MES_THREAD1_STACK,
|
||||
@@ -502,7 +503,7 @@ typedef struct {
|
||||
} amdsmi_proc_info_t;
|
||||
|
||||
//! Guaranteed maximum possible number of supported frequencies
|
||||
#define AMDSMI_MAX_NUM_FREQUENCIES 32
|
||||
#define AMDSMI_MAX_NUM_FREQUENCIES 33
|
||||
|
||||
//! Maximum possible value for fan speed. Should be used as the denominator
|
||||
//! when determining fan speed percentage.
|
||||
@@ -943,6 +944,11 @@ typedef struct {
|
||||
* @brief This structure holds information about clock frequencies.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* Deep Sleep frequency is only supported by some GPUs
|
||||
*/
|
||||
bool has_deep_sleep;
|
||||
|
||||
/**
|
||||
* The number of supported frequencies
|
||||
*/
|
||||
|
||||
@@ -47,9 +47,12 @@ else()
|
||||
find_package(Python3 3.7 COMPONENTS Interpreter Development REQUIRED)
|
||||
# --break-system-packages is needed for python 3.11
|
||||
# see: https://peps.python.org/pep-0668/
|
||||
if (NOT Python3_VERSION VERSION_LESS "3.11")
|
||||
set(Python3_BREAK_SYSTEM_PACKAGES "--break-system-packages")
|
||||
endif()
|
||||
add_custom_target(
|
||||
python_pre_reqs
|
||||
COMMAND ${Python3_EXECUTABLE} -m pip install --break-system-packages clang==${clang_ver} ctypeslib2==${ctypeslib_ver})
|
||||
COMMAND ${Python3_EXECUTABLE} -m pip install ${Python3_BREAK_SYSTEM_PACKAGES} clang==${clang_ver} ctypeslib2==${ctypeslib_ver})
|
||||
# generate new wrapper
|
||||
configure_file(${PROJECT_SOURCE_DIR}/tools/generator.py generator.py @ONLY COPYONLY)
|
||||
add_custom_command(
|
||||
|
||||
@@ -60,7 +60,7 @@ try:
|
||||
print("No GPUs on machine")
|
||||
except AmdSmiException as e:
|
||||
print("Error code: {}".format(e.err_code))
|
||||
if e.err_code == AmdSmiRetCode.STATUS_RETRY:
|
||||
if e.err_code == amdsmi_wrapper.AMDSMI_STATUS_RETRY:
|
||||
print("Error info: {}".format(e.err_info))
|
||||
```
|
||||
|
||||
@@ -1208,7 +1208,7 @@ Example:
|
||||
|
||||
```python
|
||||
try:
|
||||
devices = gpuvsmi_get_devices()
|
||||
devices = amdsmi_get_processor_handles()
|
||||
if len(devices) == 0:
|
||||
print("No GPUs on machine")
|
||||
else:
|
||||
@@ -1253,7 +1253,7 @@ Example:
|
||||
|
||||
```python
|
||||
try:
|
||||
devices = gpuvsmi_get_devices()
|
||||
devices = amdsmi_get_processor_handles()
|
||||
if len(devices) == 0:
|
||||
print("No GPUs on machine")
|
||||
else:
|
||||
@@ -1290,7 +1290,7 @@ Example:
|
||||
|
||||
```python
|
||||
try:
|
||||
devices = gpuvsmi_get_devices()
|
||||
devices = amdsmi_get_processor_handles()
|
||||
if len(devices) == 0:
|
||||
print("No GPUs on machine")
|
||||
else:
|
||||
@@ -1322,7 +1322,7 @@ Example:
|
||||
|
||||
```python
|
||||
try:
|
||||
devices = gpuvsmi_get_devices()
|
||||
devices = amdsmi_get_processor_handles()
|
||||
if len(devices) == 0:
|
||||
print("No GPUs on machine")
|
||||
else:
|
||||
@@ -1353,7 +1353,7 @@ Example:
|
||||
|
||||
```python
|
||||
try:
|
||||
devices = gpuvsmi_get_devices()
|
||||
devices = amdsmi_get_processor_handles()
|
||||
if len(devices) == 0:
|
||||
print("No GPUs on machine")
|
||||
else:
|
||||
@@ -1391,7 +1391,7 @@ Example:
|
||||
|
||||
```python
|
||||
try:
|
||||
devices = gpuvsmi_get_devices()
|
||||
devices = amdsmi_get_processor_handles()
|
||||
if len(devices) == 0:
|
||||
print("No GPUs on machine")
|
||||
else:
|
||||
@@ -1423,7 +1423,7 @@ Example:
|
||||
|
||||
```python
|
||||
try:
|
||||
devices = gpuvsmi_get_devices()
|
||||
devices = amdsmi_get_processor_handles()
|
||||
if len(devices) == 0:
|
||||
print("No GPUs on machine")
|
||||
else:
|
||||
@@ -1495,7 +1495,7 @@ Example:
|
||||
|
||||
```python
|
||||
try:
|
||||
devices = gpuvsmi_get_devices()
|
||||
devices = amdsmi_get_processor_handles()
|
||||
if len(devices) == 0:
|
||||
print("No GPUs on machine")
|
||||
else:
|
||||
@@ -1658,11 +1658,11 @@ Exceptions that can be thrown by `amdsmi_is_gpu_power_management_enabled` functi
|
||||
Example:
|
||||
```python
|
||||
try:
|
||||
processors = amdsmi_get_processor_handles()
|
||||
if len(processors) == 0:
|
||||
devices = amdsmi_get_processor_handles()
|
||||
if len(devices) == 0:
|
||||
print("No GPUs on machine")
|
||||
else:
|
||||
for processor in processors:
|
||||
for processor in devices:
|
||||
is_power_management_enabled = amdsmi_is_gpu_power_management_enabled(processor)
|
||||
print(is_power_management_enabled)
|
||||
except AmdSmiException as e:
|
||||
|
||||
@@ -194,4 +194,3 @@ from .amdsmi_exception import AmdSmiKeyException
|
||||
from .amdsmi_exception import AmdSmiBdfFormatException
|
||||
from .amdsmi_exception import AmdSmiTimeoutException
|
||||
from .amdsmi_exception import AmdSmiException
|
||||
from .amdsmi_exception import AmdSmiRetCode
|
||||
|
||||
@@ -22,40 +22,9 @@
|
||||
from enum import IntEnum
|
||||
from . import amdsmi_wrapper
|
||||
|
||||
class AmdSmiRetCode(IntEnum):
|
||||
SUCCESS = amdsmi_wrapper.AMDSMI_STATUS_SUCCESS
|
||||
STATUS_INVAL = amdsmi_wrapper.AMDSMI_STATUS_INVAL
|
||||
STATUS_NOT_SUPPORTED = amdsmi_wrapper.AMDSMI_STATUS_NOT_SUPPORTED
|
||||
STATUS_FILE_ERROR = amdsmi_wrapper.AMDSMI_STATUS_FILE_ERROR
|
||||
STATUS_NO_PERM = amdsmi_wrapper.AMDSMI_STATUS_NO_PERM
|
||||
STATUS_OUT_OF_RESOURCES = amdsmi_wrapper.AMDSMI_STATUS_OUT_OF_RESOURCES
|
||||
STATUS_INTERNAL_EXCEPTION = amdsmi_wrapper.AMDSMI_STATUS_INTERNAL_EXCEPTION
|
||||
STATUS_INPUT_OUT_OF_BOUNDS = amdsmi_wrapper.AMDSMI_STATUS_INPUT_OUT_OF_BOUNDS
|
||||
STATUS_INIT_ERROR = amdsmi_wrapper.AMDSMI_STATUS_INIT_ERROR
|
||||
STATUS_NOT_YET_IMPLEMENTED = amdsmi_wrapper.AMDSMI_STATUS_NOT_YET_IMPLEMENTED
|
||||
STATUS_NOT_FOUND = amdsmi_wrapper.AMDSMI_STATUS_NOT_FOUND
|
||||
STATUS_INSUFFICIENT_SIZE = amdsmi_wrapper.AMDSMI_STATUS_INSUFFICIENT_SIZE
|
||||
STATUS_INTERRUPT = amdsmi_wrapper.AMDSMI_STATUS_INTERRUPT
|
||||
STATUS_UNEXPECTED_SIZE = amdsmi_wrapper.AMDSMI_STATUS_UNEXPECTED_SIZE
|
||||
STATUS_NO_DATA = amdsmi_wrapper.AMDSMI_STATUS_NO_DATA
|
||||
STATUS_UNEXPECTED_DATA = amdsmi_wrapper.AMDSMI_STATUS_UNEXPECTED_DATA
|
||||
STATUS_BUSY = amdsmi_wrapper.AMDSMI_STATUS_BUSY
|
||||
STATUS_REFCOUNT_OVERFLOW = amdsmi_wrapper.AMDSMI_STATUS_REFCOUNT_OVERFLOW
|
||||
STATUS_FAIL_LOAD_MODULE = amdsmi_wrapper.AMDSMI_STATUS_FAIL_LOAD_MODULE
|
||||
STATUS_FAIL_LOAD_SYMBOL = amdsmi_wrapper.AMDSMI_STATUS_FAIL_LOAD_SYMBOL
|
||||
STATUS_DRM_ERROR = amdsmi_wrapper.AMDSMI_STATUS_DRM_ERROR
|
||||
STATUS_IO = amdsmi_wrapper.AMDSMI_STATUS_IO
|
||||
STATUS_API_FAILED = amdsmi_wrapper.AMDSMI_STATUS_API_FAILED
|
||||
STATUS_TIMEOUT = amdsmi_wrapper.AMDSMI_STATUS_TIMEOUT
|
||||
STATUS_NO_SLOT = amdsmi_wrapper.AMDSMI_STATUS_NO_SLOT
|
||||
STATUS_RETRY = amdsmi_wrapper.AMDSMI_STATUS_RETRY
|
||||
STATUS_NOT_INIT = amdsmi_wrapper.AMDSMI_STATUS_NOT_INIT
|
||||
UNKNOWN_ERROR = amdsmi_wrapper.AMDSMI_STATUS_UNKNOWN_ERROR
|
||||
|
||||
|
||||
class AmdSmiException(Exception):
|
||||
"""Base smi exception class"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
@@ -67,7 +36,7 @@ class AmdSmiLibraryException(AmdSmiException):
|
||||
self.set_err_info()
|
||||
|
||||
def __str__(self):
|
||||
return "An error occured with code: {err_code}({err_info})".format(
|
||||
return "Error code:\n\t{err_code} | {err_info}".format(
|
||||
err_code=self.err_code, err_info=self.err_info
|
||||
)
|
||||
|
||||
@@ -77,34 +46,49 @@ class AmdSmiLibraryException(AmdSmiException):
|
||||
def get_error_code(self):
|
||||
return self.err_code
|
||||
|
||||
# Translate error codes to error strings
|
||||
def set_err_info(self):
|
||||
switch = {
|
||||
AmdSmiRetCode.STATUS_INVAL: "AMDSMI_STATUS_INVAL - Invalid parameters",
|
||||
AmdSmiRetCode.STATUS_NOT_SUPPORTED: "AMDSMI_STATUS_NOT_SUPPORTED - Feature not supported",
|
||||
AmdSmiRetCode.STATUS_FILE_ERROR: "AMDSMI_STATUS_FILE_ERROR - Error opening file",
|
||||
AmdSmiRetCode.STATUS_OUT_OF_RESOURCES: "AMDSMI_STATUS_OUT_OF_RESOURCES - Not enough memory",
|
||||
AmdSmiRetCode.STATUS_INTERNAL_EXCEPTION: "AMDSMI_STATUS_INTERNAL_EXCEPTION - Internal error",
|
||||
AmdSmiRetCode.STATUS_NO_PERM: "AMDSMI_STATUS_NO_PERM - Permission Denied",
|
||||
AmdSmiRetCode.STATUS_INPUT_OUT_OF_BOUNDS: "AMDSMI_STATUS_INPUT_OUT_OF_BOUNDS - Out of bounds",
|
||||
AmdSmiRetCode.STATUS_INIT_ERROR: "AMDSMI_STATUS_INIT_ERROR - Initialization error",
|
||||
AmdSmiRetCode.STATUS_BUSY: "AMDSMI_STATUS_BUSY - Device busy",
|
||||
AmdSmiRetCode.STATUS_NOT_FOUND: "AMDSMI_STATUS_NOT_FOUND - Device Not found",
|
||||
AmdSmiRetCode.STATUS_IO: "AMDSMI_STATUS_IO - I/O Error",
|
||||
AmdSmiRetCode.STATUS_NOT_YET_IMPLEMENTED: "AMDSMI_STATUS_NOT_YET_IMPLEMENTED - Feature not yet implemented",
|
||||
AmdSmiRetCode.STATUS_INSUFFICIENT_SIZE: "AMDSMI_STATUS_INSUFFICIENT_SIZE - Insufficient size for operation",
|
||||
AmdSmiRetCode.STATUS_INTERRUPT: "AMDSMI_STATUS_INTERRUPT - Interrupt ocurred during execution",
|
||||
AmdSmiRetCode.STATUS_UNEXPECTED_SIZE: "AMDSMI_STATUS_UNEXPECTED_SIZE - unexpected size of data was read",
|
||||
AmdSmiRetCode.STATUS_NO_DATA: "AMDSMI_STATUS_NO_DATA - No data was found for given input",
|
||||
AmdSmiRetCode.STATUS_UNEXPECTED_DATA: "AMDSMI_STATUS_UNEXPECTED_DATA - The data read or provided was unexpected",
|
||||
AmdSmiRetCode.STATUS_REFCOUNT_OVERFLOW: "AMDSMI_STATUS_REFCOUNT_OVERFLOW - Internal reference counter exceeded INT32_MAX",
|
||||
AmdSmiRetCode.STATUS_FAIL_LOAD_MODULE: "AMDSMI_STATUS_FAIL_LOAD_MODULE - Fail to load lib",
|
||||
AmdSmiRetCode.STATUS_FAIL_LOAD_SYMBOL: "AMDSMI_STATUS_FAIL_LOAD_SYMBOL - Fail to load symbol",
|
||||
AmdSmiRetCode.STATUS_DRM_ERROR: "AMDSMI_STATUS_DRM_ERROR - Error when called libdrm",
|
||||
AmdSmiRetCode.STATUS_API_FAILED: "AMDSMI_STATUS_API_FAILED - API call failed",
|
||||
AmdSmiRetCode.STATUS_TIMEOUT: "AMDSMI_STATUS_TIMEOUT - Timeout in API call",
|
||||
AmdSmiRetCode.STATUS_NO_SLOT: "AMDSMI_STATUS_NO_SLOT - No more free slot",
|
||||
AmdSmiRetCode.STATUS_RETRY: "AMDSMI_STATUS_RETRY - Retry operation",
|
||||
AmdSmiRetCode.STATUS_NOT_INIT: "AMDSMI_STATUS_NOT_INIT - Device not initialized",
|
||||
amdsmi_wrapper.AMDSMI_STATUS_INVAL : "AMDSMI_STATUS_INVAL - Invalid parameters",
|
||||
amdsmi_wrapper.AMDSMI_STATUS_NOT_SUPPORTED : "AMDSMI_STATUS_NOT_SUPPORTED - Feature not supported",
|
||||
amdsmi_wrapper.AMDSMI_STATUS_NOT_YET_IMPLEMENTED : "AMDSMI_STATUS_NOT_YET_IMPLEMENTED - Feature not yet implemented",
|
||||
amdsmi_wrapper.AMDSMI_STATUS_FAIL_LOAD_MODULE : "AMDSMI_STATUS_FAIL_LOAD_MODULE - Fail to load lib",
|
||||
amdsmi_wrapper.AMDSMI_STATUS_FAIL_LOAD_SYMBOL : "AMDSMI_STATUS_FAIL_LOAD_SYMBOL - Fail to load symbol",
|
||||
amdsmi_wrapper.AMDSMI_STATUS_DRM_ERROR : "AMDSMI_STATUS_DRM_ERROR - Error when called libdrm",
|
||||
amdsmi_wrapper.AMDSMI_STATUS_API_FAILED : "AMDSMI_STATUS_API_FAILED - API call failed",
|
||||
amdsmi_wrapper.AMDSMI_STATUS_TIMEOUT : "AMDSMI_STATUS_TIMEOUT - Timeout in API call",
|
||||
amdsmi_wrapper.AMDSMI_STATUS_RETRY : "AMDSMI_STATUS_RETRY - Retry operation",
|
||||
amdsmi_wrapper.AMDSMI_STATUS_NO_PERM : "AMDSMI_STATUS_NO_PERM - Permission Denied",
|
||||
amdsmi_wrapper.AMDSMI_STATUS_INTERRUPT : "AMDSMI_STATUS_INTERRUPT - Interrupt ocurred during execution",
|
||||
amdsmi_wrapper.AMDSMI_STATUS_IO : "AMDSMI_STATUS_IO - I/O Error",
|
||||
amdsmi_wrapper.AMDSMI_STATUS_ADDRESS_FAULT : "AMDSMI_STATUS_ADDRESS_FAULT - Bad address",
|
||||
amdsmi_wrapper.AMDSMI_STATUS_FILE_ERROR : "AMDSMI_STATUS_FILE_ERROR - Error opening file",
|
||||
amdsmi_wrapper.AMDSMI_STATUS_OUT_OF_RESOURCES : "AMDSMI_STATUS_OUT_OF_RESOURCES - Not enough memory",
|
||||
amdsmi_wrapper.AMDSMI_STATUS_INTERNAL_EXCEPTION : "AMDSMI_STATUS_INTERNAL_EXCEPTION - Internal error",
|
||||
amdsmi_wrapper.AMDSMI_STATUS_INPUT_OUT_OF_BOUNDS : "AMDSMI_STATUS_INPUT_OUT_OF_BOUNDS - Out of bounds",
|
||||
amdsmi_wrapper.AMDSMI_STATUS_INIT_ERROR : "AMDSMI_STATUS_INIT_ERROR - Initialization error",
|
||||
amdsmi_wrapper.AMDSMI_STATUS_REFCOUNT_OVERFLOW : "AMDSMI_STATUS_REFCOUNT_OVERFLOW - Internal reference counter exceeded INT32_MAX",
|
||||
amdsmi_wrapper.AMDSMI_STATUS_BUSY : "AMDSMI_STATUS_BUSY - Device busy",
|
||||
amdsmi_wrapper.AMDSMI_STATUS_NOT_FOUND : "AMDSMI_STATUS_NOT_FOUND - Device Not found",
|
||||
amdsmi_wrapper.AMDSMI_STATUS_NOT_INIT : "AMDSMI_STATUS_NOT_INIT - Device not initialized",
|
||||
amdsmi_wrapper.AMDSMI_STATUS_NO_SLOT : "AMDSMI_STATUS_NO_SLOT - No more free slot",
|
||||
amdsmi_wrapper.AMDSMI_STATUS_DRIVER_NOT_LOADED : "AMDSMI_STATUS_DRIVER_NOT_LOADED - Processor driver not loaded",
|
||||
amdsmi_wrapper.AMDSMI_STATUS_NO_DATA : "AMDSMI_STATUS_NO_DATA - No data was found for given input",
|
||||
amdsmi_wrapper.AMDSMI_STATUS_INSUFFICIENT_SIZE : "AMDSMI_STATUS_INSUFFICIENT_SIZE - Insufficient size for operation",
|
||||
amdsmi_wrapper.AMDSMI_STATUS_UNEXPECTED_SIZE : "AMDSMI_STATUS_UNEXPECTED_SIZE - unexpected size of data was read",
|
||||
amdsmi_wrapper.AMDSMI_STATUS_UNEXPECTED_DATA : "AMDSMI_STATUS_UNEXPECTED_DATA - The data read or provided was unexpected",
|
||||
amdsmi_wrapper.AMDSMI_STATUS_NON_AMD_CPU : "AMDSMI_STATUS_NON_AMD_CPU - System has non-AMD CPU",
|
||||
amdsmi_wrapper.AMDSMI_NO_ENERGY_DRV : "AMD_SMI_NO_ENERGY_DRV - Energy driver not found",
|
||||
amdsmi_wrapper.AMDSMI_NO_MSR_DRV : "AMDSMI_NO_MSR_DRV - MSR driver not found",
|
||||
amdsmi_wrapper.AMDSMI_NO_HSMP_DRV : "AMD_SMI_NO_HSMP_DRV - HSMP driver not found",
|
||||
amdsmi_wrapper.AMDSMI_NO_HSMP_SUP : "AMD_SMI_NO_HSMP_SUP - HSMP not supported",
|
||||
amdsmi_wrapper.AMDSMI_NO_HSMP_MSG_SUP : "AMD_SMI_NO_HSMP_MSG_SUP - HSMP message/feature not supported",
|
||||
amdsmi_wrapper.AMDSMI_HSMP_TIMEOUT : "AMD_SMI_HSMP_TIMEOUT - HSMP message timeout",
|
||||
amdsmi_wrapper.AMDSMI_NO_DRV : "AMDSMI_NO_DRV - No Energy and HSMP driver present",
|
||||
amdsmi_wrapper.AMDSMI_FILE_NOT_FOUND : "AMDSMI_FILE_NOT_FOUND - File or directory not found",
|
||||
amdsmi_wrapper.AMDSMI_ARG_PTR_NULL : "AMDSMI_ARG_PTR_NULL - Parsed argument is invalid",
|
||||
amdsmi_wrapper.AMDSMI_STATUS_MAP_ERROR : "AMDSMI_STATUS_MAP_ERROR - The internal library error did not map to a status code",
|
||||
amdsmi_wrapper.AMDSMI_STATUS_UNKNOWN_ERROR : "AMDSMI_STATUS_UNKNOWN_ERROR - An unknown error occurred"
|
||||
}
|
||||
|
||||
self.err_info = switch.get(self.err_code, "AMDSMI_STATUS_UNKNOWN_ERROR - An unknown error occurred")
|
||||
@@ -112,12 +96,12 @@ class AmdSmiLibraryException(AmdSmiException):
|
||||
|
||||
class AmdSmiRetryException(AmdSmiLibraryException):
|
||||
def __init__(self):
|
||||
super().__init__(AmdSmiRetCode.RETRY)
|
||||
super().__init__(amdsmi_wrapper.AMDSMI_STATUS_RETRY)
|
||||
|
||||
|
||||
class AmdSmiTimeoutException(AmdSmiLibraryException):
|
||||
def __init__(self):
|
||||
super().__init__(AmdSmiRetCode.TIMEOUT)
|
||||
super().__init__(amdsmi_wrapper.AMDSMI_STATUS_TIMEOUT)
|
||||
|
||||
|
||||
class AmdSmiParameterException(AmdSmiException):
|
||||
|
||||
@@ -2393,7 +2393,7 @@ def amdsmi_gpu_xgmi_error_status(
|
||||
processor_handle, ctypes.byref(status))
|
||||
)
|
||||
|
||||
return AmdSmiXgmiStatus(status.value)
|
||||
return AmdSmiXgmiStatus(status.value).value
|
||||
|
||||
|
||||
def amdsmi_reset_gpu_xgmi_error(
|
||||
|
||||
@@ -444,38 +444,39 @@ amdsmi_fw_block_t__enumvalues = {
|
||||
44: 'FW_ID_SDMA_TH0',
|
||||
45: 'FW_ID_SDMA_TH1',
|
||||
46: 'FW_ID_CP_MES',
|
||||
47: 'FW_ID_MES_STACK',
|
||||
48: 'FW_ID_MES_THREAD1',
|
||||
49: 'FW_ID_MES_THREAD1_STACK',
|
||||
50: 'FW_ID_RLX6',
|
||||
51: 'FW_ID_RLX6_DRAM_BOOT',
|
||||
52: 'FW_ID_RS64_ME',
|
||||
53: 'FW_ID_RS64_ME_P0_DATA',
|
||||
54: 'FW_ID_RS64_ME_P1_DATA',
|
||||
55: 'FW_ID_RS64_PFP',
|
||||
56: 'FW_ID_RS64_PFP_P0_DATA',
|
||||
57: 'FW_ID_RS64_PFP_P1_DATA',
|
||||
58: 'FW_ID_RS64_MEC',
|
||||
59: 'FW_ID_RS64_MEC_P0_DATA',
|
||||
60: 'FW_ID_RS64_MEC_P1_DATA',
|
||||
61: 'FW_ID_RS64_MEC_P2_DATA',
|
||||
62: 'FW_ID_RS64_MEC_P3_DATA',
|
||||
63: 'FW_ID_PPTABLE',
|
||||
64: 'FW_ID_PSP_SOC',
|
||||
65: 'FW_ID_PSP_DBG',
|
||||
66: 'FW_ID_PSP_INTF',
|
||||
67: 'FW_ID_RLX6_CORE1',
|
||||
68: 'FW_ID_RLX6_DRAM_BOOT_CORE1',
|
||||
69: 'FW_ID_RLCV_LX7',
|
||||
70: 'FW_ID_RLC_SAVE_RESTORE_LIST',
|
||||
71: 'FW_ID_ASD',
|
||||
72: 'FW_ID_TA_RAS',
|
||||
73: 'FW_ID_XGMI',
|
||||
74: 'FW_ID_RLC_SRLG',
|
||||
75: 'FW_ID_RLC_SRLS',
|
||||
76: 'FW_ID_SMC',
|
||||
77: 'FW_ID_DMCU',
|
||||
78: 'FW_ID__MAX',
|
||||
47: 'FW_ID_MES_KIQ',
|
||||
48: 'FW_ID_MES_STACK',
|
||||
49: 'FW_ID_MES_THREAD1',
|
||||
50: 'FW_ID_MES_THREAD1_STACK',
|
||||
51: 'FW_ID_RLX6',
|
||||
52: 'FW_ID_RLX6_DRAM_BOOT',
|
||||
53: 'FW_ID_RS64_ME',
|
||||
54: 'FW_ID_RS64_ME_P0_DATA',
|
||||
55: 'FW_ID_RS64_ME_P1_DATA',
|
||||
56: 'FW_ID_RS64_PFP',
|
||||
57: 'FW_ID_RS64_PFP_P0_DATA',
|
||||
58: 'FW_ID_RS64_PFP_P1_DATA',
|
||||
59: 'FW_ID_RS64_MEC',
|
||||
60: 'FW_ID_RS64_MEC_P0_DATA',
|
||||
61: 'FW_ID_RS64_MEC_P1_DATA',
|
||||
62: 'FW_ID_RS64_MEC_P2_DATA',
|
||||
63: 'FW_ID_RS64_MEC_P3_DATA',
|
||||
64: 'FW_ID_PPTABLE',
|
||||
65: 'FW_ID_PSP_SOC',
|
||||
66: 'FW_ID_PSP_DBG',
|
||||
67: 'FW_ID_PSP_INTF',
|
||||
68: 'FW_ID_RLX6_CORE1',
|
||||
69: 'FW_ID_RLX6_DRAM_BOOT_CORE1',
|
||||
70: 'FW_ID_RLCV_LX7',
|
||||
71: 'FW_ID_RLC_SAVE_RESTORE_LIST',
|
||||
72: 'FW_ID_ASD',
|
||||
73: 'FW_ID_TA_RAS',
|
||||
74: 'FW_ID_XGMI',
|
||||
75: 'FW_ID_RLC_SRLG',
|
||||
76: 'FW_ID_RLC_SRLS',
|
||||
77: 'FW_ID_SMC',
|
||||
78: 'FW_ID_DMCU',
|
||||
79: 'FW_ID__MAX',
|
||||
}
|
||||
FW_ID_SMU = 1
|
||||
FW_ID_FIRST = 1
|
||||
@@ -524,38 +525,39 @@ FW_ID_IMU_IRAM = 43
|
||||
FW_ID_SDMA_TH0 = 44
|
||||
FW_ID_SDMA_TH1 = 45
|
||||
FW_ID_CP_MES = 46
|
||||
FW_ID_MES_STACK = 47
|
||||
FW_ID_MES_THREAD1 = 48
|
||||
FW_ID_MES_THREAD1_STACK = 49
|
||||
FW_ID_RLX6 = 50
|
||||
FW_ID_RLX6_DRAM_BOOT = 51
|
||||
FW_ID_RS64_ME = 52
|
||||
FW_ID_RS64_ME_P0_DATA = 53
|
||||
FW_ID_RS64_ME_P1_DATA = 54
|
||||
FW_ID_RS64_PFP = 55
|
||||
FW_ID_RS64_PFP_P0_DATA = 56
|
||||
FW_ID_RS64_PFP_P1_DATA = 57
|
||||
FW_ID_RS64_MEC = 58
|
||||
FW_ID_RS64_MEC_P0_DATA = 59
|
||||
FW_ID_RS64_MEC_P1_DATA = 60
|
||||
FW_ID_RS64_MEC_P2_DATA = 61
|
||||
FW_ID_RS64_MEC_P3_DATA = 62
|
||||
FW_ID_PPTABLE = 63
|
||||
FW_ID_PSP_SOC = 64
|
||||
FW_ID_PSP_DBG = 65
|
||||
FW_ID_PSP_INTF = 66
|
||||
FW_ID_RLX6_CORE1 = 67
|
||||
FW_ID_RLX6_DRAM_BOOT_CORE1 = 68
|
||||
FW_ID_RLCV_LX7 = 69
|
||||
FW_ID_RLC_SAVE_RESTORE_LIST = 70
|
||||
FW_ID_ASD = 71
|
||||
FW_ID_TA_RAS = 72
|
||||
FW_ID_XGMI = 73
|
||||
FW_ID_RLC_SRLG = 74
|
||||
FW_ID_RLC_SRLS = 75
|
||||
FW_ID_SMC = 76
|
||||
FW_ID_DMCU = 77
|
||||
FW_ID__MAX = 78
|
||||
FW_ID_MES_KIQ = 47
|
||||
FW_ID_MES_STACK = 48
|
||||
FW_ID_MES_THREAD1 = 49
|
||||
FW_ID_MES_THREAD1_STACK = 50
|
||||
FW_ID_RLX6 = 51
|
||||
FW_ID_RLX6_DRAM_BOOT = 52
|
||||
FW_ID_RS64_ME = 53
|
||||
FW_ID_RS64_ME_P0_DATA = 54
|
||||
FW_ID_RS64_ME_P1_DATA = 55
|
||||
FW_ID_RS64_PFP = 56
|
||||
FW_ID_RS64_PFP_P0_DATA = 57
|
||||
FW_ID_RS64_PFP_P1_DATA = 58
|
||||
FW_ID_RS64_MEC = 59
|
||||
FW_ID_RS64_MEC_P0_DATA = 60
|
||||
FW_ID_RS64_MEC_P1_DATA = 61
|
||||
FW_ID_RS64_MEC_P2_DATA = 62
|
||||
FW_ID_RS64_MEC_P3_DATA = 63
|
||||
FW_ID_PPTABLE = 64
|
||||
FW_ID_PSP_SOC = 65
|
||||
FW_ID_PSP_DBG = 66
|
||||
FW_ID_PSP_INTF = 67
|
||||
FW_ID_RLX6_CORE1 = 68
|
||||
FW_ID_RLX6_DRAM_BOOT_CORE1 = 69
|
||||
FW_ID_RLCV_LX7 = 70
|
||||
FW_ID_RLC_SAVE_RESTORE_LIST = 71
|
||||
FW_ID_ASD = 72
|
||||
FW_ID_TA_RAS = 73
|
||||
FW_ID_XGMI = 74
|
||||
FW_ID_RLC_SRLG = 75
|
||||
FW_ID_RLC_SRLS = 76
|
||||
FW_ID_SMC = 77
|
||||
FW_ID_DMCU = 78
|
||||
FW_ID__MAX = 79
|
||||
amdsmi_fw_block_t = ctypes.c_uint32 # enum
|
||||
|
||||
# values for enumeration 'amdsmi_vram_type_t'
|
||||
@@ -734,7 +736,7 @@ struct_amdsmi_fw_info_t._pack_ = 1 # source:False
|
||||
struct_amdsmi_fw_info_t._fields_ = [
|
||||
('num_fw_info', ctypes.c_ubyte),
|
||||
('PADDING_0', ctypes.c_ubyte * 7),
|
||||
('fw_info_list', struct_fw_info_list_ * 78),
|
||||
('fw_info_list', struct_fw_info_list_ * 79),
|
||||
('reserved', ctypes.c_uint32 * 7),
|
||||
('PADDING_1', ctypes.c_ubyte * 4),
|
||||
]
|
||||
@@ -835,16 +837,6 @@ amdsmi_process_handle_t = ctypes.c_uint32
|
||||
class struct_amdsmi_proc_info_t(Structure):
|
||||
pass
|
||||
|
||||
class struct_engine_usage_(Structure):
|
||||
pass
|
||||
|
||||
struct_engine_usage_._pack_ = 1 # source:False
|
||||
struct_engine_usage_._fields_ = [
|
||||
('gfx', ctypes.c_uint64),
|
||||
('enc', ctypes.c_uint64),
|
||||
('reserved', ctypes.c_uint32 * 12),
|
||||
]
|
||||
|
||||
class struct_memory_usage_(Structure):
|
||||
pass
|
||||
|
||||
@@ -856,6 +848,16 @@ struct_memory_usage_._fields_ = [
|
||||
('reserved', ctypes.c_uint32 * 10),
|
||||
]
|
||||
|
||||
class struct_engine_usage_(Structure):
|
||||
pass
|
||||
|
||||
struct_engine_usage_._pack_ = 1 # source:False
|
||||
struct_engine_usage_._fields_ = [
|
||||
('gfx', ctypes.c_uint64),
|
||||
('enc', ctypes.c_uint64),
|
||||
('reserved', ctypes.c_uint32 * 12),
|
||||
]
|
||||
|
||||
struct_amdsmi_proc_info_t._pack_ = 1 # source:False
|
||||
struct_amdsmi_proc_info_t._fields_ = [
|
||||
('name', ctypes.c_char * 32),
|
||||
@@ -1283,9 +1285,12 @@ class struct_amdsmi_frequencies_t(Structure):
|
||||
|
||||
struct_amdsmi_frequencies_t._pack_ = 1 # source:False
|
||||
struct_amdsmi_frequencies_t._fields_ = [
|
||||
('has_deep_sleep', ctypes.c_bool),
|
||||
('PADDING_0', ctypes.c_ubyte * 3),
|
||||
('num_supported', ctypes.c_uint32),
|
||||
('current', ctypes.c_uint32),
|
||||
('frequency', ctypes.c_uint64 * 32),
|
||||
('PADDING_1', ctypes.c_ubyte * 4),
|
||||
('frequency', ctypes.c_uint64 * 33),
|
||||
]
|
||||
|
||||
amdsmi_frequencies_t = struct_amdsmi_frequencies_t
|
||||
@@ -1295,7 +1300,8 @@ class struct_amdsmi_pcie_bandwidth_t(Structure):
|
||||
struct_amdsmi_pcie_bandwidth_t._pack_ = 1 # source:False
|
||||
struct_amdsmi_pcie_bandwidth_t._fields_ = [
|
||||
('transfer_rate', amdsmi_frequencies_t),
|
||||
('lanes', ctypes.c_uint32 * 32),
|
||||
('lanes', ctypes.c_uint32 * 33),
|
||||
('PADDING_0', ctypes.c_ubyte * 4),
|
||||
]
|
||||
|
||||
amdsmi_pcie_bandwidth_t = struct_amdsmi_pcie_bandwidth_t
|
||||
@@ -1853,13 +1859,13 @@ __all__ = \
|
||||
'FW_ID_CP_PFP', 'FW_ID_CP_PM4', 'FW_ID_DFC', 'FW_ID_DMCU',
|
||||
'FW_ID_DMCU_ERAM', 'FW_ID_DMCU_ISR', 'FW_ID_DRV_CAP',
|
||||
'FW_ID_FIRST', 'FW_ID_IMU_DRAM', 'FW_ID_IMU_IRAM', 'FW_ID_ISP',
|
||||
'FW_ID_MC', 'FW_ID_MES_STACK', 'FW_ID_MES_THREAD1',
|
||||
'FW_ID_MES_THREAD1_STACK', 'FW_ID_MMSCH', 'FW_ID_PPTABLE',
|
||||
'FW_ID_PSP_BL', 'FW_ID_PSP_DBG', 'FW_ID_PSP_INTF',
|
||||
'FW_ID_PSP_KEYDB', 'FW_ID_PSP_SOC', 'FW_ID_PSP_SOSDRV',
|
||||
'FW_ID_PSP_SPL', 'FW_ID_PSP_SYSDRV', 'FW_ID_PSP_TOC',
|
||||
'FW_ID_REG_ACCESS_WHITELIST', 'FW_ID_RLC', 'FW_ID_RLCV_LX7',
|
||||
'FW_ID_RLC_P', 'FW_ID_RLC_RESTORE_LIST_CNTL',
|
||||
'FW_ID_MC', 'FW_ID_MES_KIQ', 'FW_ID_MES_STACK',
|
||||
'FW_ID_MES_THREAD1', 'FW_ID_MES_THREAD1_STACK', 'FW_ID_MMSCH',
|
||||
'FW_ID_PPTABLE', 'FW_ID_PSP_BL', 'FW_ID_PSP_DBG',
|
||||
'FW_ID_PSP_INTF', 'FW_ID_PSP_KEYDB', 'FW_ID_PSP_SOC',
|
||||
'FW_ID_PSP_SOSDRV', 'FW_ID_PSP_SPL', 'FW_ID_PSP_SYSDRV',
|
||||
'FW_ID_PSP_TOC', 'FW_ID_REG_ACCESS_WHITELIST', 'FW_ID_RLC',
|
||||
'FW_ID_RLCV_LX7', 'FW_ID_RLC_P', 'FW_ID_RLC_RESTORE_LIST_CNTL',
|
||||
'FW_ID_RLC_RESTORE_LIST_GPM_MEM',
|
||||
'FW_ID_RLC_RESTORE_LIST_SRM_MEM', 'FW_ID_RLC_SAVE_RESTORE_LIST',
|
||||
'FW_ID_RLC_SRLG', 'FW_ID_RLC_SRLS', 'FW_ID_RLC_V', 'FW_ID_RLX6',
|
||||
|
||||
@@ -10,7 +10,7 @@ name = "amdsmi"
|
||||
authors = [
|
||||
{name = "AMD", email = "amd-smi.support@amd.com"},
|
||||
]
|
||||
version = "23.2.1.0"
|
||||
version = "23.3.1.0"
|
||||
license = {file = "amdsmi/LICENSE"}
|
||||
readme = {file = "amdsmi/README.md", content-type = "text/markdown"}
|
||||
description = "AMDSMI Python LIB - AMD GPU Monitoring Library"
|
||||
|
||||
@@ -70,7 +70,8 @@ extern "C" {
|
||||
*/
|
||||
|
||||
//! Guaranteed maximum possible number of supported frequencies
|
||||
#define RSMI_MAX_NUM_FREQUENCIES 32
|
||||
//! (32 normal + 1 sleep frequency)
|
||||
#define RSMI_MAX_NUM_FREQUENCIES 33
|
||||
|
||||
//! Maximum possible value for fan speed. Should be used as the denominator
|
||||
//! when determining fan speed percentage.
|
||||
@@ -639,6 +640,8 @@ typedef enum {
|
||||
RSMI_FW_BLOCK_ME,
|
||||
RSMI_FW_BLOCK_MEC,
|
||||
RSMI_FW_BLOCK_MEC2,
|
||||
RSMI_FW_BLOCK_MES,
|
||||
RSMI_FW_BLOCK_MES_KIQ,
|
||||
RSMI_FW_BLOCK_PFP,
|
||||
RSMI_FW_BLOCK_RLC,
|
||||
RSMI_FW_BLOCK_RLC_SRLC,
|
||||
@@ -759,6 +762,11 @@ typedef rsmi_power_profile_status_t rsmi_power_profile_status;
|
||||
* @brief This structure holds information about clock frequencies.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* Deep Sleep frequency is only supported by some GPUs
|
||||
*/
|
||||
bool has_deep_sleep;
|
||||
|
||||
/**
|
||||
* The number of supported frequencies
|
||||
*/
|
||||
@@ -1757,6 +1765,30 @@ rsmi_status_t rsmi_dev_pci_bandwidth_set(uint32_t dv_ind, uint64_t bw_bitmask);
|
||||
rsmi_status_t
|
||||
rsmi_dev_power_ave_get(uint32_t dv_ind, uint32_t sensor_ind, uint64_t *power);
|
||||
|
||||
/**
|
||||
* @brief Get the current socket power (also known as instant
|
||||
* power) of the device index provided.
|
||||
*
|
||||
* @details Given a device index @p dv_ind and a pointer to a uint64_t
|
||||
* @p socket_power, this function will write the current socket power
|
||||
* (in microwatts) to the uint64_t pointed to by @p socket_power.
|
||||
*
|
||||
* @param[in] dv_ind a device index
|
||||
*
|
||||
* @param[inout] socket_power a pointer to uint64_t to which the current
|
||||
* socket power will be written to. If this parameter is nullptr,
|
||||
* this function will return ::RSMI_STATUS_INVALID_ARGS if the function is
|
||||
* supported with the provided, arguments and ::RSMI_STATUS_NOT_SUPPORTED
|
||||
* if it is not supported with the provided arguments.
|
||||
*
|
||||
* @retval ::RSMI_STATUS_SUCCESS call was successful
|
||||
* @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not
|
||||
* support this function with the given arguments
|
||||
* @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid
|
||||
*/
|
||||
rsmi_status_t
|
||||
rsmi_dev_current_socket_power_get(uint32_t dv_ind, uint64_t *socket_power);
|
||||
|
||||
/**
|
||||
* @brief Get the energy accumulator counter of the device with provided
|
||||
* device index.
|
||||
|
||||
@@ -146,6 +146,8 @@ enum DevInfoTypes {
|
||||
kDevFwVersionMe,
|
||||
kDevFwVersionMec,
|
||||
kDevFwVersionMec2,
|
||||
kDevFwVersionMes,
|
||||
kDevFwVersionMesKiq,
|
||||
kDevFwVersionPfp,
|
||||
kDevFwVersionRlc,
|
||||
kDevFwVersionRlcSrlc,
|
||||
|
||||
@@ -130,18 +130,18 @@ class Logger {
|
||||
break;
|
||||
}
|
||||
return *getInstance();
|
||||
};
|
||||
}
|
||||
|
||||
Logger &operator<<(const char* s) {
|
||||
return operator<<(std::string(s));
|
||||
};
|
||||
}
|
||||
|
||||
template <class T> Logger &operator<<(const T &v) {
|
||||
std::ostringstream s;
|
||||
s << v;
|
||||
std::string str = s.str();
|
||||
return operator<<(str);
|
||||
};
|
||||
}
|
||||
|
||||
// Interface for Error Log
|
||||
void error(const char* text) throw();
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* The University of Illinois/NCSA
|
||||
* Open Source License (NCSA)
|
||||
*
|
||||
* Copyright (c) 2017, Advanced Micro Devices, Inc.
|
||||
* Copyright (c) 2017-2023, Advanced Micro Devices, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Developed by:
|
||||
@@ -67,6 +67,8 @@ enum MonitorTypes {
|
||||
kMonPowerCapMax,
|
||||
kMonPowerCapMin,
|
||||
kMonPowerAve,
|
||||
kMonPowerInput,
|
||||
kMonPowerLabel,
|
||||
kMonTempMax,
|
||||
kMonTempMin,
|
||||
kMonTempMaxHyst,
|
||||
@@ -94,45 +96,47 @@ enum MonitorTypes {
|
||||
kMonInvalid = 0xFFFFFFFF,
|
||||
};
|
||||
|
||||
const std::map<MonitorTypes,std::string> monitorTypesToString {
|
||||
{MonitorTypes::kMonName, "amd::smi::kMonName"},
|
||||
{MonitorTypes::kMonTemp, "amd::smi::kMonName"},
|
||||
{MonitorTypes::kMonFanSpeed, "amd::smi::kMonName"},
|
||||
{MonitorTypes::kMonMaxFanSpeed, "amd::smi::kMonName"},
|
||||
{MonitorTypes::kMonFanRPMs, "amd::smi::kMonName"},
|
||||
{MonitorTypes::kMonFanCntrlEnable, "amd::smi::kMonName"},
|
||||
{MonitorTypes::kMonPowerCap, "amd::smi::kMonName"},
|
||||
{MonitorTypes::kMonPowerCapDefault, "amd::smi::kMonName"},
|
||||
{MonitorTypes::kMonPowerCapMax, "amd::smi::kMonName"},
|
||||
{MonitorTypes::kMonPowerCapMin, "amd::smi::kMonName"},
|
||||
{MonitorTypes::kMonPowerAve, "amd::smi::kMonName"},
|
||||
{MonitorTypes::kMonTempMax, "amd::smi::kMonName"},
|
||||
{MonitorTypes::kMonTempMin, "amd::smi::kMonName"},
|
||||
{MonitorTypes::kMonTempMaxHyst, "amd::smi::kMonName"},
|
||||
{MonitorTypes::kMonTempMinHyst, "amd::smi::kMonName"},
|
||||
{MonitorTypes::kMonTempCritical, "amd::smi::kMonName"},
|
||||
{MonitorTypes::kMonTempCriticalHyst, "amd::smi::kMonName"},
|
||||
{MonitorTypes::kMonTempEmergency, "amd::smi::kMonName"},
|
||||
{MonitorTypes::kMonTempEmergencyHyst, "amd::smi::kMonName"},
|
||||
{MonitorTypes::kMonTempCritMin, "amd::smi::kMonName"},
|
||||
{MonitorTypes::kMonTempCritMinHyst, "amd::smi::kMonName"},
|
||||
{MonitorTypes::kMonTempOffset, "amd::smi::kMonName"},
|
||||
{MonitorTypes::kMonTempLowest, "amd::smi::kMonName"},
|
||||
{MonitorTypes::kMonTempHighest, "amd::smi::kMonName"},
|
||||
{MonitorTypes::kMonTempLabel, "amd::smi::kMonName"},
|
||||
{MonitorTypes::kMonVolt, "amd::smi::kMonName"},
|
||||
{MonitorTypes::kMonVoltMax, "amd::smi::kMonName"},
|
||||
{MonitorTypes::kMonVoltMinCrit, "amd::smi::kMonName"},
|
||||
{MonitorTypes::kMonVoltMin, "amd::smi::kMonName"},
|
||||
{MonitorTypes::kMonVoltMaxCrit, "amd::smi::kMonName"},
|
||||
{MonitorTypes::kMonVoltAverage, "amd::smi::kMonName"},
|
||||
{MonitorTypes::kMonVoltLowest, "amd::smi::kMonName"},
|
||||
{MonitorTypes::kMonVoltHighest, "amd::smi::kMonName"},
|
||||
{MonitorTypes::kMonVoltLabel, "amd::smi::kMonName"},
|
||||
{MonitorTypes::kMonInvalid, "amd::smi::kMonName"},
|
||||
const std::map<MonitorTypes, std::string> monitorTypesToString{
|
||||
{MonitorTypes::kMonName, "MonitorTypes::kMonName"},
|
||||
{MonitorTypes::kMonTemp, "MonitorTypes::kMonTemp"},
|
||||
{MonitorTypes::kMonFanSpeed, "MonitorTypes::kMonFanSpeed"},
|
||||
{MonitorTypes::kMonMaxFanSpeed, "MonitorTypes::kMonMaxFanSpeed"},
|
||||
{MonitorTypes::kMonFanRPMs, "MonitorTypes::kMonFanRPMs"},
|
||||
{MonitorTypes::kMonFanCntrlEnable, "MonitorTypes::kMonFanCntrlEnable"},
|
||||
{MonitorTypes::kMonPowerCap, "MonitorTypes::kMonPowerCap"},
|
||||
{MonitorTypes::kMonPowerCapDefault, "MonitorTypes::kMonPowerCapDefault"},
|
||||
{MonitorTypes::kMonPowerCapMax, "MonitorTypes::kMonPowerCapMax"},
|
||||
{MonitorTypes::kMonPowerCapMin, "MonitorTypes::kMonPowerCapMin"},
|
||||
{MonitorTypes::kMonPowerAve, "MonitorTypes::kMonPowerAve"},
|
||||
{MonitorTypes::kMonPowerInput, "MonitorTypes::kMonPowerInput"},
|
||||
{MonitorTypes::kMonPowerLabel, "MonitorTypes::kMonPowerLabel"},
|
||||
{MonitorTypes::kMonTempMax, "MonitorTypes::kMonTempMax"},
|
||||
{MonitorTypes::kMonTempMin, "MonitorTypes::kMonTempMin"},
|
||||
{MonitorTypes::kMonTempMaxHyst, "MonitorTypes::kMonTempMaxHyst"},
|
||||
{MonitorTypes::kMonTempMinHyst, "MonitorTypes::kMonTempMinHyst"},
|
||||
{MonitorTypes::kMonTempCritical, "MonitorTypes::kMonTempCritical"},
|
||||
{MonitorTypes::kMonTempCriticalHyst, "MonitorTypes::kMonTempCriticalHyst"},
|
||||
{MonitorTypes::kMonTempEmergency, "MonitorTypes::kMonTempEmergency"},
|
||||
{MonitorTypes::kMonTempEmergencyHyst,
|
||||
"MonitorTypes::kMonTempEmergencyHyst"},
|
||||
{MonitorTypes::kMonTempCritMin, "MonitorTypes::kMonTempCritMin"},
|
||||
{MonitorTypes::kMonTempCritMinHyst, "MonitorTypes::kMonTempCritMinHyst"},
|
||||
{MonitorTypes::kMonTempOffset, "MonitorTypes::kMonTempOffset"},
|
||||
{MonitorTypes::kMonTempLowest, "MonitorTypes::kMonTempLowest"},
|
||||
{MonitorTypes::kMonTempHighest, "MonitorTypes::kMonTempHighest"},
|
||||
{MonitorTypes::kMonTempLabel, "MonitorTypes::kMonTempLabel"},
|
||||
{MonitorTypes::kMonVolt, "MonitorTypes::kMonVolt"},
|
||||
{MonitorTypes::kMonVoltMax, "MonitorTypes::kMonVoltMax"},
|
||||
{MonitorTypes::kMonVoltMinCrit, "MonitorTypes::kMonVoltMinCrit"},
|
||||
{MonitorTypes::kMonVoltMin, "MonitorTypes::kMonVoltMin"},
|
||||
{MonitorTypes::kMonVoltMaxCrit, "MonitorTypes::kMonVoltMaxCrit"},
|
||||
{MonitorTypes::kMonVoltAverage, "MonitorTypes::kMonVoltAverage"},
|
||||
{MonitorTypes::kMonVoltLowest, "MonitorTypes::kMonVoltLowest"},
|
||||
{MonitorTypes::kMonVoltHighest, "MonitorTypes::kMonVoltHighest"},
|
||||
{MonitorTypes::kMonVoltLabel, "MonitorTypes::kMonVoltLabel"},
|
||||
{MonitorTypes::kMonInvalid, "MonitorTypes::kMonInvalid"},
|
||||
};
|
||||
|
||||
|
||||
class Monitor {
|
||||
public:
|
||||
explicit Monitor(std::string path, RocmSMI_env_vars const *e);
|
||||
|
||||
@@ -74,7 +74,7 @@ Display Options:
|
||||
-a, --showallinfo Show Temperature, Fan and Clock values
|
||||
|
||||
Topology:
|
||||
-i, --showid Show GPU ID
|
||||
-i, --showid Show DEVICE ID
|
||||
-v, --showvbios Show VBIOS version
|
||||
--showdriverversion Show kernel driver version
|
||||
--showfwinfo [BLOCK [BLOCK ...]] Show FW information
|
||||
|
||||
@@ -45,9 +45,8 @@ CLOCK_JSON_VERSION = 1
|
||||
|
||||
headerString = ' ROCm System Management Interface '
|
||||
footerString = ' End of ROCm SMI Log '
|
||||
|
||||
# Output formatting
|
||||
appWidth = 100
|
||||
appWidth = 90
|
||||
deviceList = []
|
||||
|
||||
# Enable or disable serialized format
|
||||
@@ -383,8 +382,8 @@ def getPidList():
|
||||
return
|
||||
|
||||
|
||||
def getPower(device, silent=False):
|
||||
""" Return the current power level of a given device
|
||||
def getAvgPower(device, silent=False):
|
||||
""" Return the average power level of a given device
|
||||
|
||||
@param device: DRM device identifier
|
||||
@param silent=Turn on to silence error output
|
||||
@@ -393,7 +392,21 @@ def getPower(device, silent=False):
|
||||
power = c_uint32()
|
||||
ret = rocmsmi.rsmi_dev_power_ave_get(device, 0, byref(power))
|
||||
if rsmi_ret_ok(ret, device, 'get_power_avg', silent):
|
||||
return power.value / 1000000
|
||||
return str(power.value / 1000000)
|
||||
return 'N/A'
|
||||
|
||||
def getCurrentSocketPower(device, silent=False):
|
||||
""" Return the current (also known as instant)
|
||||
socket power of a given device
|
||||
|
||||
@param device: DRM device identifier
|
||||
@param silent=Turn on to silence error output
|
||||
(you plan to handle manually). Default is off.
|
||||
"""
|
||||
power = c_uint32()
|
||||
ret = rocmsmi.rsmi_dev_current_socket_power_get(device, byref(power))
|
||||
if rsmi_ret_ok(ret, device, 'get_socket_power', silent):
|
||||
return str(power.value / 1000000)
|
||||
return 'N/A'
|
||||
|
||||
|
||||
@@ -437,7 +450,7 @@ def findFirstAvailableTemp(device):
|
||||
temp = c_int64(0)
|
||||
metric = rsmi_temperature_metric_t.RSMI_TEMP_CURRENT
|
||||
ret_temp = "N/A"
|
||||
ret_temp_type = "(Unknown)"
|
||||
ret_temp_type = temp_type_lst[0]
|
||||
for i, templist_val in enumerate(temp_type_lst):
|
||||
ret = rocmsmi.rsmi_dev_temp_metric_get(c_uint32(device), i, metric, byref(temp))
|
||||
if rsmi_ret_ok(ret, device, 'get_temp_metric_' + templist_val, silent=True):
|
||||
@@ -448,6 +461,37 @@ def findFirstAvailableTemp(device):
|
||||
continue
|
||||
return (ret_temp_type, ret_temp)
|
||||
|
||||
def getTemperatureLabel(deviceList):
|
||||
""" Discovers the the first identified power label
|
||||
|
||||
Returns a string label value
|
||||
@param device: DRM device identifier
|
||||
"""
|
||||
# Default label is Edge
|
||||
tempLabel = temp_type_lst[0].lower()
|
||||
if len(deviceList) < 1:
|
||||
return tempLabel
|
||||
(temp_type, _) = findFirstAvailableTemp(deviceList[0])
|
||||
tempLabel = temp_type.lower().replace('(', '').replace(')', '')
|
||||
return tempLabel
|
||||
|
||||
def getPowerLabel(deviceList):
|
||||
""" Discovers the the first identified power label
|
||||
|
||||
Returns a string label value
|
||||
@param device: DRM device identifier
|
||||
"""
|
||||
power = c_int64(0)
|
||||
# Default label is AvgPower
|
||||
powerLabel = rsmi_power_label.AVG_POWER
|
||||
if len(deviceList) < 1:
|
||||
return powerLabel
|
||||
device=deviceList[0]
|
||||
power = getCurrentSocketPower(device, True)
|
||||
if power != '0.0' and power != 'N/A':
|
||||
powerLabel = rsmi_power_label.CURRENT_SOCKET_POWER
|
||||
return powerLabel
|
||||
|
||||
def getVbiosVersion(device, silent=False):
|
||||
""" Returns the VBIOS version for a given device
|
||||
|
||||
@@ -679,23 +723,35 @@ def printListLog(metricName, valuesList):
|
||||
print(listStr + line)
|
||||
|
||||
|
||||
def printLogSpacer(displayString=None, fill='='):
|
||||
def printLogSpacer(displayString=None, fill='=', contentSizeToFit=0):
|
||||
""" Prints [name of the option]/[name of the program] in the spacer to explain data below
|
||||
|
||||
If no parameters are given, a default fill of the '=' string is used in the spacer
|
||||
|
||||
@param displayString: name of item to be displayed inside of the log spacer
|
||||
@param fill: padding string which surrounds the given display string
|
||||
@param contentSizeToFit: providing an integer > 0 allows
|
||||
ability to dynamically change output padding/fill based on this value
|
||||
instead of appWidth. Handy for concise info output.
|
||||
"""
|
||||
global appWidth, PRINT_JSON
|
||||
resizeValue = appWidth
|
||||
if contentSizeToFit != 0:
|
||||
resizeValue = contentSizeToFit
|
||||
if resizeValue % 2: # if odd -> make even
|
||||
resizeValue += 1
|
||||
# leaving below to check if resizing works properly
|
||||
# print("resizeVal=" +str(resizeValue) + "; appWidth=" + str(appWidth) +
|
||||
# "; contentSizeToFit=" + str(contentSizeToFit) + "; fill=" + fill)
|
||||
|
||||
if not PRINT_JSON:
|
||||
if displayString:
|
||||
if len(displayString) % 2:
|
||||
displayString += fill
|
||||
logSpacer = fill * int((appWidth - (len(displayString))) / 2) + displayString + fill * int(
|
||||
(appWidth - (len(displayString))) / 2)
|
||||
logSpacer = fill * int((resizeValue - (len(displayString))) / 2) + displayString + fill * int(
|
||||
(resizeValue - (len(displayString))) / 2)
|
||||
else:
|
||||
logSpacer = fill * appWidth
|
||||
logSpacer = fill * resizeValue
|
||||
print(logSpacer)
|
||||
|
||||
|
||||
@@ -1630,22 +1686,15 @@ def showAllConcise(deviceList):
|
||||
print('ERROR: Cannot print JSON/CSV output for concise output')
|
||||
sys.exit(1)
|
||||
|
||||
""" Place holder for the actual max size """
|
||||
MAX_ALL_CONCISE_WIDTH = 100
|
||||
appWidth_temp = appWidth
|
||||
appWidth = MAX_ALL_CONCISE_WIDTH
|
||||
silent = True
|
||||
|
||||
printLogSpacer(' Concise Info ')
|
||||
deviceList.sort()
|
||||
temp_type = '(' + temp_type_lst[0] + ')'
|
||||
if len(deviceList) >= 1:
|
||||
(temp_type, _) = findFirstAvailableTemp(deviceList[0])
|
||||
available_temp_type = temp_type.lower()
|
||||
available_temp_type = available_temp_type.replace('(', '')
|
||||
available_temp_type = available_temp_type.replace(')', '')
|
||||
header = ['GPU', '[Model : Revision]', 'Temp', 'AvgPwr', 'Partitions', 'SCLK', 'MCLK', 'Fan', 'Perf', 'PwrCap', 'VRAM%', 'GPU%']
|
||||
subheader = ['', 'Name (20 chars)', temp_type, '', '(Mem, Compute)', '', '', '', '', '', '', '']
|
||||
available_temp_type = getTemperatureLabel(deviceList)
|
||||
temp_type = "(" + available_temp_type.capitalize() + ")"
|
||||
header=['Device', '[Model : Revision]', 'Temp', 'Power', 'Partitions',
|
||||
'SCLK', 'MCLK', 'Fan', 'Perf', 'PwrCap', 'VRAM%', 'GPU%']
|
||||
subheader = ['', 'Name (20 chars)', temp_type, getPowerLabel(deviceList),
|
||||
'(Mem, Compute)', '', '', '', '', '', '', '']
|
||||
# add additional spaces to match header
|
||||
for idx, item in enumerate(subheader):
|
||||
header_size = len(header[idx])
|
||||
@@ -1667,11 +1716,17 @@ def showAllConcise(deviceList):
|
||||
temp_val = str(getTemp(device, available_temp_type, silent))
|
||||
if temp_val != 'N/A':
|
||||
temp_val += degree_sign + 'C'
|
||||
avgPwr = str(getPower(device))
|
||||
if avgPwr != '0.0' and avgPwr != 'N/A':
|
||||
socketPwr = getCurrentSocketPower(device, True)
|
||||
avgPwr = getAvgPower(device, True)
|
||||
powerVal = 'N/A'
|
||||
if socketPwr != '0.0' and socketPwr != 'N/A':
|
||||
socketPwr += 'W'
|
||||
powerVal=socketPwr
|
||||
elif avgPwr != '0.0' and avgPwr != 'N/A':
|
||||
avgPwr += 'W'
|
||||
powerVal=avgPwr
|
||||
else:
|
||||
avgPwr = 'N/A'
|
||||
powerVal = 'N/A'
|
||||
combined_partition = (getMemoryPartition(device, silent) + ", "
|
||||
+ getComputePartition(device, silent))
|
||||
sclk = showCurrentClocks([device], 'sclk', concise=silent)
|
||||
@@ -1704,10 +1759,10 @@ def showAllConcise(deviceList):
|
||||
'', '', '', '']
|
||||
gpu_dev_product_info_top_name = gpu_dev_product_info_names[1]
|
||||
|
||||
values['card%s' % (str(device))] = [device, gpu_dev_product_info_top_name, temp_val, avgPwr,
|
||||
combined_partition, sclk, mclk,
|
||||
fan, str(perf).lower(), pwrCap,
|
||||
mem_use_pct, gpu_busy]
|
||||
values['card%s' % (str(device))] = [device, gpu_dev_product_info_top_name, temp_val,
|
||||
powerVal, combined_partition, sclk, mclk,
|
||||
fan, str(perf).lower(), pwrCap, mem_use_pct,
|
||||
gpu_busy]
|
||||
|
||||
val_widths = {}
|
||||
for device in deviceList:
|
||||
@@ -1716,10 +1771,17 @@ def showAllConcise(deviceList):
|
||||
for device in deviceList:
|
||||
for col in range(len(val_widths[device])):
|
||||
max_widths[col] = max(max_widths[col], val_widths[device][col])
|
||||
printLog(None, "".join(word.ljust(max_widths[col]) for col, word in zip(range(len(max_widths)), header)), None)
|
||||
printLog(None, "".join(word.ljust(max_widths[col]) for col, word in zip(range(len(max_widths)), subheader)),
|
||||
None, useItalics=True)
|
||||
printLogSpacer(fill='=')
|
||||
|
||||
########################
|
||||
# Display concise info #
|
||||
########################
|
||||
header_output = "".join(word.ljust(max_widths[col]) for col, word in zip(range(len(max_widths)), header))
|
||||
subheader_output = "".join(word.ljust(max_widths[col]) for col, word in zip(range(len(max_widths)), subheader))
|
||||
printLogSpacer(headerString, contentSizeToFit=len(header_output))
|
||||
printLogSpacer(' Concise Info ', contentSizeToFit=len(header_output))
|
||||
printLog(None, header_output, None)
|
||||
printLog(None, subheader_output, None, useItalics=True)
|
||||
printLogSpacer(fill='=', contentSizeToFit=len(header_output))
|
||||
|
||||
for device in deviceList:
|
||||
printLog(None, "".join(str(word).ljust(max_widths[col]) for col, word in
|
||||
@@ -1730,9 +1792,8 @@ def showAllConcise(deviceList):
|
||||
printLog(None, "".join(str(word).ljust(max_widths[col]) for col, word in
|
||||
zip(range(len(max_widths)), values['card%s_Info' % (str(device))])), None)
|
||||
|
||||
printLogSpacer()
|
||||
""" Restore original max size """
|
||||
appWidth = appWidth_temp
|
||||
printLogSpacer(contentSizeToFit=len(header_output))
|
||||
printLogSpacer(footerString, contentSizeToFit=len(header_output))
|
||||
|
||||
|
||||
def showAllConciseHw(deviceList):
|
||||
@@ -1808,12 +1869,21 @@ def showClocks(deviceList):
|
||||
if not rsmi_ret_ok(ret, device, 'get_clk_freq_' + clk_type, True):
|
||||
continue
|
||||
printLog(device, 'Supported %s frequencies on GPU%s' % (clk_type, str(device)), None)
|
||||
for x in range(freq.num_supported):
|
||||
fr = '{:>.0f}Mhz'.format(freq.frequency[x] / 1000000)
|
||||
if x == freq.current:
|
||||
printLog(device, str(x), str(fr) + ' *')
|
||||
else:
|
||||
printLog(device, str(x), str(fr))
|
||||
for i in range(freq.num_supported):
|
||||
freq_string = '{:>.0f}Mhz'.format(freq.frequency[i] / 1000000)
|
||||
if i == freq.current:
|
||||
freq_string += ' *'
|
||||
freq_index = i
|
||||
# Deep Sleep frequency is only supported by some GPUs
|
||||
# It is indicated by letter 'S' instead of the index number
|
||||
if freq.has_deep_sleep:
|
||||
# sleep state
|
||||
if i == 0:
|
||||
freq_index = 'S'
|
||||
# all indices are offset by 1 because Deep Sleep occupies index 0
|
||||
else:
|
||||
freq_index = i - 1
|
||||
printLog(device, str(freq_index), freq_string)
|
||||
printLog(device, '', None)
|
||||
else:
|
||||
logging.debug('{} frequency is unsupported on device[{}]'.format(clk_type, device))
|
||||
@@ -1822,12 +1892,11 @@ def showClocks(deviceList):
|
||||
ret = rocmsmi.rsmi_dev_pci_bandwidth_get(device, byref(bw))
|
||||
if rsmi_ret_ok(ret, device, 'get_PCIe_bandwidth', True):
|
||||
printLog(device, 'Supported %s frequencies on GPU%s' % ('PCIe', str(device)), None)
|
||||
for x in range(bw.transfer_rate.num_supported):
|
||||
fr = '{:>.1f}GT/s x{}'.format(bw.transfer_rate.frequency[x] / 1000000000, bw.lanes[x])
|
||||
if x == bw.transfer_rate.current:
|
||||
printLog(device, str(x), str(fr) + ' *')
|
||||
else:
|
||||
printLog(device, str(x), str(fr))
|
||||
for i in range(bw.transfer_rate.num_supported):
|
||||
freq_string = '{:>.1f}GT/s x{}'.format(bw.transfer_rate.frequency[i] / 1000000000, bw.lanes[i])
|
||||
if i == bw.transfer_rate.current:
|
||||
freq_string += ' *'
|
||||
printLog(device, str(i), str(freq_string))
|
||||
printLog(device, '', None)
|
||||
else:
|
||||
logging.debug('PCIe frequency is unsupported on device [{}]'.format(device))
|
||||
@@ -1857,9 +1926,17 @@ def showCurrentClocks(deviceList, clk_defined=None, concise=False):
|
||||
printLog(device, '%s current clock frequency not found' % (clk_defined), None)
|
||||
continue
|
||||
fr = freq.frequency[levl] / 1000000
|
||||
freq_index = levl
|
||||
if freq.has_deep_sleep:
|
||||
# sleep state
|
||||
if levl == 0:
|
||||
freq_index = 'S'
|
||||
# all indices are offset by 1 because Deep Sleep occupies index 0
|
||||
else:
|
||||
freq_index = levl - 1
|
||||
if concise: # in case function is used for concise output, no need to print.
|
||||
return '{:.0f}Mhz'.format(fr)
|
||||
printLog(device, '{} clock level'.format(clk_defined), '{} ({:.0f}Mhz)'.format(levl, fr))
|
||||
printLog(device, '{} clock level'.format(clk_defined), '{} ({:.0f}Mhz)'.format(freq_index, fr))
|
||||
elif not concise:
|
||||
logging.debug('{} clock is unsupported on device[{}]'.format(clk_defined, device))
|
||||
|
||||
@@ -1872,12 +1949,20 @@ def showCurrentClocks(deviceList, clk_defined=None, concise=False):
|
||||
if levl >= freq.num_supported:
|
||||
printLog(device, '%s current clock frequency not found' % (clk_type), None)
|
||||
continue
|
||||
freq_index = levl
|
||||
if freq.has_deep_sleep:
|
||||
# sleep state
|
||||
if levl == 0:
|
||||
freq_index = 'S'
|
||||
# all indices are offset by 1 because Deep Sleep occupies index 0
|
||||
else:
|
||||
freq_index = levl - 1
|
||||
fr = freq.frequency[levl] / 1000000
|
||||
if PRINT_JSON:
|
||||
printLog(device, '%s clock speed:' % (clk_type), '(%sMhz)' % (str(fr)[:-2]))
|
||||
printLog(device, '%s clock level:' % (clk_type), levl)
|
||||
printLog(device, '%s clock level:' % (clk_type), freq_index)
|
||||
else:
|
||||
printLog(device, '%s clock level: %s' % (clk_type, levl), '(%sMhz)' % (str(fr)[:-2]))
|
||||
printLog(device, '%s clock level: %s' % (clk_type, freq_index), '(%sMhz)' % (str(fr)[:-2]))
|
||||
elif not concise:
|
||||
logging.debug('{} clock is unsupported on device[{}]'.format(clk_type, device))
|
||||
# pcie clocks
|
||||
@@ -2108,8 +2193,8 @@ def showId(deviceList):
|
||||
"""
|
||||
printLogSpacer(' ID ')
|
||||
for device in deviceList:
|
||||
printLog(device, 'GPU ID', getId(device))
|
||||
printLog(device, 'GPU Rev', getRev(device))
|
||||
printLog(device, 'Device ID', getId(device))
|
||||
printLog(device, 'Device Rev', getRev(device))
|
||||
printLogSpacer()
|
||||
|
||||
|
||||
@@ -2336,23 +2421,25 @@ def showPids(verbose):
|
||||
|
||||
|
||||
def showPower(deviceList):
|
||||
""" Display current Average Graphics Package Power Consumption for a list of devices
|
||||
""" Display Current (also known as instant) Socket or Average
|
||||
Graphics Package Power Consumption for a list of devices
|
||||
|
||||
@param deviceList: List of DRM devices (can be a single-item list)
|
||||
"""
|
||||
secondaryPresent=False
|
||||
printLogSpacer(' Power Consumption ')
|
||||
for device in deviceList:
|
||||
if checkIfSecondaryDie(device):
|
||||
if str(getCurrentSocketPower(device, True)) != 'N/A':
|
||||
printLog(device, 'Current Socket Graphics Package Power (W)', getCurrentSocketPower(device))
|
||||
elif checkIfSecondaryDie(device):
|
||||
printLog(device, 'Average Graphics Package Power (W)', "N/A (Secondary die)")
|
||||
secondaryPresent=True
|
||||
elif str(getPower(device)) != '0.0':
|
||||
printLog(device, 'Average Graphics Package Power (W)', getPower(device))
|
||||
elif str(getAvgPower(device)) != '0.0':
|
||||
printLog(device, 'Average Graphics Package Power (W)', getAvgPower(device))
|
||||
else:
|
||||
printErrLog(device, 'Unable to get Average Graphics Package Power Consumption')
|
||||
printErrLog(device, 'Unable to get Average or Current Socket Graphics Package Power Consumption')
|
||||
if secondaryPresent:
|
||||
printLog(None, "\n\t\tPrimary die (usually one above or below the secondary) shows total (primary + secondary) socket power information", None)
|
||||
|
||||
printLogSpacer()
|
||||
|
||||
|
||||
@@ -2848,13 +2935,8 @@ def getGraphColor(percentage):
|
||||
|
||||
def showTempGraph(deviceList):
|
||||
deviceList.sort()
|
||||
temp_type = '(' + temp_type_lst[0] + ')'
|
||||
if len(deviceList) >= 1:
|
||||
(temp_type, _) = findFirstAvailableTemp(deviceList[0])
|
||||
printLogSpacer(' Temperature Graph ' + temp_type + ' ')
|
||||
temp_type = temp_type.lower()
|
||||
temp_type = temp_type.replace('(', '')
|
||||
temp_type = temp_type.replace(')', '')
|
||||
temp_type = getTemperatureLabel(deviceList)
|
||||
printLogSpacer(' Temperature Graph ' + temp_type.capitalize() + ' ')
|
||||
# Start a thread for constantly printing
|
||||
try:
|
||||
# Create a thread (call print function, devices, delay in ms)
|
||||
@@ -3523,9 +3605,14 @@ def save(deviceList, savefilepath):
|
||||
|
||||
|
||||
# The code below is for when this script is run as an executable instead of when imported as a module
|
||||
def isConciseInfoRequested(args):
|
||||
return len(sys.argv) == 1 or \
|
||||
len(sys.argv) == 2 and (args.alldevices or (args.json or args.csv)) or \
|
||||
len(sys.argv) == 3 and (args.alldevices and (args.json or args.csv))
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(
|
||||
description=f'AMD ROCm System Management Interface | ROCM-SMI version: {__version__}',
|
||||
description='AMD ROCm System Management Interface | ROCM-SMI version: %s' % __version__,
|
||||
formatter_class=lambda prog: argparse.HelpFormatter(prog, max_help_position=90, width=120))
|
||||
groupDev = parser.add_argument_group()
|
||||
groupDisplayOpt = parser.add_argument_group('Display Options')
|
||||
@@ -3545,7 +3632,7 @@ if __name__ == '__main__':
|
||||
groupDisplayOpt.add_argument('--showhw', help='Show Hardware details', action='store_true')
|
||||
groupDisplayOpt.add_argument('-a', '--showallinfo', help='Show Temperature, Fan and Clock values',
|
||||
action='store_true')
|
||||
groupDisplayTop.add_argument('-i', '--showid', help='Show GPU ID', action='store_true')
|
||||
groupDisplayTop.add_argument('-i', '--showid', help='Show DEVICE ID', action='store_true')
|
||||
groupDisplayTop.add_argument('-v', '--showvbios', help='Show VBIOS version', action='store_true')
|
||||
groupDisplayTop.add_argument('-e', '--showevents', help='Show event list', metavar='EVENT', type=str, nargs='*')
|
||||
groupDisplayTop.add_argument('--showdriverversion', help='Show kernel driver version', action='store_true')
|
||||
@@ -3731,7 +3818,8 @@ if __name__ == '__main__':
|
||||
|
||||
if not PRINT_JSON:
|
||||
print('\n')
|
||||
printLogSpacer(headerString)
|
||||
if not isConciseInfoRequested(args):
|
||||
printLogSpacer(headerString)
|
||||
|
||||
if args.showallinfo:
|
||||
args.list = True
|
||||
@@ -3785,9 +3873,7 @@ if __name__ == '__main__':
|
||||
if not checkAmdGpus(deviceList):
|
||||
logging.warning('No AMD GPUs specified')
|
||||
|
||||
if len(sys.argv) == 1 or \
|
||||
len(sys.argv) == 2 and (args.alldevices or (args.json or args.csv)) or \
|
||||
len(sys.argv) == 3 and (args.alldevices and (args.json or args.csv)):
|
||||
if isConciseInfoRequested(args):
|
||||
showAllConcise(deviceList)
|
||||
if args.showhw:
|
||||
showAllConciseHw(deviceList)
|
||||
@@ -3994,7 +4080,8 @@ if __name__ == '__main__':
|
||||
devCsv = formatCsv(deviceList)
|
||||
print(devCsv)
|
||||
|
||||
printLogSpacer(footerString)
|
||||
if not isConciseInfoRequested(args):
|
||||
printLogSpacer(footerString)
|
||||
|
||||
rsmi_ret_ok(rocmsmi.rsmi_shut_down())
|
||||
exit(RETCODE)
|
||||
|
||||
@@ -59,7 +59,7 @@ gpu_id = c_uint32(0)
|
||||
|
||||
|
||||
# Policy enums
|
||||
RSMI_MAX_NUM_FREQUENCIES = 32
|
||||
RSMI_MAX_NUM_FREQUENCIES = 33
|
||||
RSMI_MAX_FAN_SPEED = 255
|
||||
RSMI_NUM_VOLTAGE_CURVE_POINTS = 3
|
||||
|
||||
@@ -492,7 +492,8 @@ rsmi_power_profile_status = rsmi_power_profile_status_t
|
||||
|
||||
|
||||
class rsmi_frequencies_t(Structure):
|
||||
_fields_ = [('num_supported', c_int32),
|
||||
_fields_ = [('has_deep_sleep', c_bool),
|
||||
('num_supported', c_int32),
|
||||
('current', c_uint32),
|
||||
('frequency', c_uint64 * RSMI_MAX_NUM_FREQUENCIES)]
|
||||
|
||||
@@ -654,3 +655,8 @@ rsmi_nps_mode_type = rsmi_nps_mode_type_t
|
||||
# nps_mode_type_l[rsmi_nps_mode_type_t.RSMI_MEMORY_PARTITION_NPS2]
|
||||
# will return string 'NPS2'
|
||||
nps_mode_type_l = ['NPS1', 'NPS2', 'NPS4', 'NPS8']
|
||||
|
||||
class rsmi_power_label(str, Enum):
|
||||
AVG_POWER = '(Avg)'
|
||||
CURRENT_SOCKET_POWER = '(Socket)'
|
||||
|
||||
|
||||
@@ -77,7 +77,6 @@
|
||||
#include "rocm_smi/rocm_smi64Config.h"
|
||||
#include "rocm_smi/rocm_smi_logger.h"
|
||||
|
||||
using namespace ROCmLogging;
|
||||
using namespace amd::smi;
|
||||
|
||||
static const uint32_t kMaxOverdriveLevel = 20;
|
||||
@@ -147,14 +146,21 @@ static uint64_t freq_string_to_int(const std::vector<std::string> &freq_lines,
|
||||
|
||||
std::istringstream fs(freq_lines[i]);
|
||||
|
||||
uint32_t ind;
|
||||
char junk_ch;
|
||||
int ind;
|
||||
float freq;
|
||||
std::string junk;
|
||||
std::string junk_str;
|
||||
std::string units_str;
|
||||
std::string star_str;
|
||||
|
||||
fs >> ind;
|
||||
fs >> junk; // colon
|
||||
if (fs.peek() == 'S') {
|
||||
// Deep Sleep frequency is only supported by some GPUs
|
||||
fs >> junk_ch;
|
||||
} else {
|
||||
// All other frequency indices are numbers
|
||||
fs >> ind;
|
||||
}
|
||||
fs >> junk_str; // colon
|
||||
fs >> freq;
|
||||
fs >> units_str;
|
||||
fs >> star_str;
|
||||
@@ -1127,9 +1133,14 @@ static rsmi_status_t get_frequencies(amd::smi::DevInfoTypes type, rsmi_clk_type_
|
||||
}
|
||||
|
||||
f->num_supported = static_cast<uint32_t>(val_vec.size());
|
||||
bool current = false;
|
||||
f->current = RSMI_MAX_NUM_FREQUENCIES + 1; // init to an invalid value
|
||||
|
||||
// Deep Sleep frequency is only supported by some GPUs
|
||||
// It is indicated by letter 'S' instead of the index number
|
||||
f->has_deep_sleep = (val_vec[0][0] == 'S');
|
||||
|
||||
bool current = false;
|
||||
|
||||
for (uint32_t i = 0; i < f->num_supported; ++i) {
|
||||
f->frequency[i] = freq_string_to_int(val_vec, ¤t, lanes, i);
|
||||
|
||||
@@ -1156,9 +1167,9 @@ static rsmi_status_t get_frequencies(amd::smi::DevInfoTypes type, rsmi_clk_type_
|
||||
sysvalue += " Previous Value";
|
||||
sysvalue += ' ' + std::to_string(f->frequency[f->current]);
|
||||
DEBUG_LOG("More than one current clock. ", sysvalue);
|
||||
}
|
||||
else
|
||||
} else {
|
||||
f->current = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1309,6 +1320,11 @@ static rsmi_status_t get_od_clk_volt_info(uint32_t dv_ind,
|
||||
return RSMI_STATUS_UNEXPECTED_DATA;
|
||||
}
|
||||
|
||||
// find last_item but skip empty lines
|
||||
int last_item = val_vec.size()-1;
|
||||
while (val_vec[last_item].empty() || val_vec[last_item][0] == 0)
|
||||
last_item--;
|
||||
|
||||
p->curr_sclk_range.lower_bound = freq_string_to_int(val_vec, nullptr,
|
||||
nullptr, kOD_SCLK_label_array_index + 1);
|
||||
p->curr_sclk_range.upper_bound = freq_string_to_int(val_vec, nullptr,
|
||||
@@ -1322,16 +1338,18 @@ static rsmi_status_t get_od_clk_volt_info(uint32_t dv_ind,
|
||||
} else if (val_vec[kOD_MCLK_label_array_index] == "MCLK:") {
|
||||
p->curr_mclk_range.lower_bound = freq_string_to_int(val_vec, nullptr,
|
||||
nullptr, kOD_MCLK_label_array_index + 1);
|
||||
// the upper memory frequency is the last
|
||||
p->curr_mclk_range.upper_bound = freq_string_to_int(val_vec, nullptr,
|
||||
nullptr, kOD_MCLK_label_array_index + 4);
|
||||
nullptr, last_item);
|
||||
return RSMI_STATUS_SUCCESS;
|
||||
} else if (val_vec[kOD_MCLK_label_array_index + 1] == "MCLK:") {
|
||||
p->curr_sclk_range.upper_bound = freq_string_to_int(val_vec, nullptr,
|
||||
nullptr, kOD_SCLK_label_array_index + 3);
|
||||
p->curr_mclk_range.lower_bound = freq_string_to_int(val_vec, nullptr,
|
||||
nullptr, kOD_MCLK_label_array_index + 2);
|
||||
// the upper memory frequency is the last
|
||||
p->curr_mclk_range.upper_bound = freq_string_to_int(val_vec, nullptr,
|
||||
nullptr, kOD_MCLK_label_array_index + 5);
|
||||
nullptr, last_item);
|
||||
return RSMI_STATUS_SUCCESS;
|
||||
} else {
|
||||
return RSMI_STATUS_NOT_YET_IMPLEMENTED;
|
||||
@@ -1708,6 +1726,8 @@ rsmi_dev_firmware_version_get(uint32_t dv_ind, rsmi_fw_block_t block,
|
||||
{ RSMI_FW_BLOCK_ME, amd::smi::kDevFwVersionMe },
|
||||
{ RSMI_FW_BLOCK_MEC, amd::smi::kDevFwVersionMec },
|
||||
{ RSMI_FW_BLOCK_MEC2, amd::smi::kDevFwVersionMec2 },
|
||||
{ RSMI_FW_BLOCK_MES, amd::smi::kDevFwVersionMes },
|
||||
{ RSMI_FW_BLOCK_MES_KIQ, amd::smi::kDevFwVersionMesKiq },
|
||||
{ RSMI_FW_BLOCK_PFP, amd::smi::kDevFwVersionPfp },
|
||||
{ RSMI_FW_BLOCK_RLC, amd::smi::kDevFwVersionRlc },
|
||||
{ RSMI_FW_BLOCK_RLC_SRLC, amd::smi::kDevFwVersionRlcSrlc },
|
||||
@@ -2485,21 +2505,22 @@ rsmi_dev_temp_metric_get(uint32_t dv_ind, uint32_t sensor_type,
|
||||
amd::smi::MonitorTypes mon_type = amd::smi::kMonInvalid;
|
||||
uint16_t val_ui16;
|
||||
|
||||
static const std::map<rsmi_temperature_metric_t, amd::smi::MonitorTypes> kMetricTypeMap = {
|
||||
{ RSMI_TEMP_CURRENT, amd::smi::kMonTemp },
|
||||
{ RSMI_TEMP_MAX, amd::smi::kMonTempMax },
|
||||
{ RSMI_TEMP_MIN, amd::smi::kMonTempMin },
|
||||
{ RSMI_TEMP_MAX_HYST, amd::smi::kMonTempMaxHyst },
|
||||
{ RSMI_TEMP_MIN_HYST, amd::smi::kMonTempMinHyst },
|
||||
{ RSMI_TEMP_CRITICAL, amd::smi::kMonTempCritical },
|
||||
{ RSMI_TEMP_CRITICAL_HYST, amd::smi::kMonTempCriticalHyst },
|
||||
{ RSMI_TEMP_EMERGENCY, amd::smi::kMonTempEmergency },
|
||||
{ RSMI_TEMP_EMERGENCY_HYST, amd::smi::kMonTempEmergencyHyst },
|
||||
{ RSMI_TEMP_CRIT_MIN, amd::smi::kMonTempCritMin },
|
||||
{ RSMI_TEMP_CRIT_MIN_HYST, amd::smi::kMonTempCritMinHyst },
|
||||
{ RSMI_TEMP_OFFSET, amd::smi::kMonTempOffset },
|
||||
{ RSMI_TEMP_LOWEST, amd::smi::kMonTempLowest },
|
||||
{ RSMI_TEMP_HIGHEST, amd::smi::kMonTempHighest },
|
||||
static const std::map<rsmi_temperature_metric_t, amd::smi::MonitorTypes>
|
||||
kMetricTypeMap = {
|
||||
{ RSMI_TEMP_CURRENT, amd::smi::kMonTemp },
|
||||
{ RSMI_TEMP_MAX, amd::smi::kMonTempMax },
|
||||
{ RSMI_TEMP_MIN, amd::smi::kMonTempMin },
|
||||
{ RSMI_TEMP_MAX_HYST, amd::smi::kMonTempMaxHyst },
|
||||
{ RSMI_TEMP_MIN_HYST, amd::smi::kMonTempMinHyst },
|
||||
{ RSMI_TEMP_CRITICAL, amd::smi::kMonTempCritical },
|
||||
{ RSMI_TEMP_CRITICAL_HYST, amd::smi::kMonTempCriticalHyst },
|
||||
{ RSMI_TEMP_EMERGENCY, amd::smi::kMonTempEmergency },
|
||||
{ RSMI_TEMP_EMERGENCY_HYST, amd::smi::kMonTempEmergencyHyst },
|
||||
{ RSMI_TEMP_CRIT_MIN, amd::smi::kMonTempCritMin },
|
||||
{ RSMI_TEMP_CRIT_MIN_HYST, amd::smi::kMonTempCritMinHyst },
|
||||
{ RSMI_TEMP_OFFSET, amd::smi::kMonTempOffset },
|
||||
{ RSMI_TEMP_LOWEST, amd::smi::kMonTempLowest },
|
||||
{ RSMI_TEMP_HIGHEST, amd::smi::kMonTempHighest },
|
||||
};
|
||||
|
||||
const auto mon_type_it = kMetricTypeMap.find(metric);
|
||||
@@ -2584,7 +2605,8 @@ rsmi_dev_temp_metric_get(uint32_t dv_ind, uint32_t sensor_type,
|
||||
return RSMI_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
*temperature = static_cast<int64_t>(val_ui16) * CENTRIGRADE_TO_MILLI_CENTIGRADE;
|
||||
*temperature =
|
||||
static_cast<int64_t>(val_ui16) * CENTRIGRADE_TO_MILLI_CENTIGRADE;
|
||||
|
||||
ss << __PRETTY_FUNCTION__ << " | ======= end ======= "
|
||||
<< " | Success "
|
||||
@@ -2919,6 +2941,80 @@ rsmi_dev_power_ave_get(uint32_t dv_ind, uint32_t sensor_ind, uint64_t *power) {
|
||||
CATCH
|
||||
}
|
||||
|
||||
rsmi_status_t
|
||||
rsmi_dev_current_socket_power_get(uint32_t dv_ind, uint64_t *socket_power) {
|
||||
TRY
|
||||
std::ostringstream ss;
|
||||
rsmi_status_t rsmiReturn = RSMI_STATUS_NOT_SUPPORTED;
|
||||
std::string val_str;
|
||||
uint32_t sensor_ind = 1; // socket_power sysfs files have 1-based indices
|
||||
MonitorTypes mon_type = amd::smi::kMonPowerInput;
|
||||
ss << __PRETTY_FUNCTION__ << " | ======= start =======, dv_ind="
|
||||
<< std::to_string(dv_ind);
|
||||
LOG_TRACE(ss);
|
||||
if (socket_power == nullptr) {
|
||||
rsmiReturn = RSMI_STATUS_INVALID_ARGS;
|
||||
ss << __PRETTY_FUNCTION__
|
||||
<< " | ======= end ======= "
|
||||
<< " | Fail "
|
||||
<< " | Device #: " << dv_ind
|
||||
<< " | Type: " << monitorTypesToString.at(mon_type)
|
||||
<< " | Cause: socket_power was a null ptr reference"
|
||||
<< " | Returning = "
|
||||
<< getRSMIStatusString(rsmiReturn) << " |";
|
||||
LOG_ERROR(ss);
|
||||
return RSMI_STATUS_INVALID_ARGS;
|
||||
}
|
||||
CHK_SUPPORT_SUBVAR_ONLY(socket_power, sensor_ind)
|
||||
DEVICE_MUTEX
|
||||
|
||||
if (dev->monitor() == nullptr) {
|
||||
ss << __PRETTY_FUNCTION__
|
||||
<< " | ======= end ======= "
|
||||
<< " | Fail "
|
||||
<< " | Device #: " << dv_ind
|
||||
<< " | Type: " << monitorTypesToString.at(mon_type)
|
||||
<< " | Cause: hwmon monitor was a null ptr reference"
|
||||
<< " | Returning = "
|
||||
<< getRSMIStatusString(rsmiReturn) << " |";
|
||||
LOG_ERROR(ss);
|
||||
return rsmiReturn;
|
||||
}
|
||||
|
||||
int ret = dev->monitor()->readMonitor(amd::smi::kMonPowerLabel,
|
||||
sensor_ind, &val_str);
|
||||
if (ret || val_str != "PPT" || val_str.size() != 3) {
|
||||
if (ret != 0) {
|
||||
rsmiReturn = amd::smi::ErrnoToRsmiStatus(ret);
|
||||
}
|
||||
ss << __PRETTY_FUNCTION__
|
||||
<< " | ======= end ======= "
|
||||
<< " | Fail "
|
||||
<< " | Device #: " << dv_ind
|
||||
<< " | Type: " << monitorTypesToString.at(mon_type)
|
||||
<< " | Cause: readMonitor() returned an error status"
|
||||
<< " or Socket Power label did not show PPT or size of label data was"
|
||||
<< " unexpected"
|
||||
<< " | Returning = "
|
||||
<< getRSMIStatusString(rsmiReturn) << " |";
|
||||
LOG_ERROR(ss);
|
||||
return rsmiReturn;
|
||||
}
|
||||
rsmiReturn = get_dev_mon_value(mon_type, dv_ind, sensor_ind,
|
||||
socket_power);
|
||||
ss << __PRETTY_FUNCTION__
|
||||
<< " | ======= end ======= "
|
||||
<< " | Success "
|
||||
<< " | Device #: " << dv_ind
|
||||
<< " | Type: " << monitorTypesToString.at(mon_type)
|
||||
<< " | Data: " << *socket_power
|
||||
<< " | Returning = "
|
||||
<< getRSMIStatusString(rsmiReturn) << " |";
|
||||
LOG_TRACE(ss);
|
||||
return rsmiReturn;
|
||||
CATCH
|
||||
}
|
||||
|
||||
rsmi_status_t
|
||||
rsmi_dev_energy_count_get(uint32_t dv_ind, uint64_t *power,
|
||||
float *counter_resolution, uint64_t *timestamp) {
|
||||
|
||||
@@ -68,8 +68,6 @@
|
||||
#include "rocm_smi/rocm_smi_logger.h"
|
||||
#include "shared_mutex.h" // NOLINT
|
||||
|
||||
using namespace ROCmLogging;
|
||||
|
||||
namespace amd {
|
||||
namespace smi {
|
||||
|
||||
@@ -141,6 +139,8 @@ static const char *kDevFwVersionMcFName = "fw_version/mc_fw_version";
|
||||
static const char *kDevFwVersionMeFName = "fw_version/me_fw_version";
|
||||
static const char *kDevFwVersionMecFName = "fw_version/mec_fw_version";
|
||||
static const char *kDevFwVersionMec2FName = "fw_version/mec2_fw_version";
|
||||
static const char *kDevFwVersionMesFName = "fw_version/mes_fw_version";
|
||||
static const char *kDevFwVersionMesKiqFName = "fw_version/mes_kiq_fw_version";
|
||||
static const char *kDevFwVersionPfpFName = "fw_version/pfp_fw_version";
|
||||
static const char *kDevFwVersionRlcFName = "fw_version/rlc_fw_version";
|
||||
static const char *kDevFwVersionRlcSrlcFName = "fw_version/rlc_srlc_fw_version";
|
||||
@@ -284,6 +284,8 @@ static const std::map<DevInfoTypes, const char *> kDevAttribNameMap = {
|
||||
{kDevFwVersionMe, kDevFwVersionMeFName},
|
||||
{kDevFwVersionMec, kDevFwVersionMecFName},
|
||||
{kDevFwVersionMec2, kDevFwVersionMec2FName},
|
||||
{kDevFwVersionMes, kDevFwVersionMesFName},
|
||||
{kDevFwVersionMesKiq, kDevFwVersionMesKiqFName},
|
||||
{kDevFwVersionPfp, kDevFwVersionPfpFName},
|
||||
{kDevFwVersionRlc, kDevFwVersionRlcFName},
|
||||
{kDevFwVersionRlcSrlc, kDevFwVersionRlcSrlcFName},
|
||||
@@ -347,6 +349,8 @@ static std::map<DevInfoTypes, uint8_t> kDevInfoVarTypeToRSMIVariant = {
|
||||
{kDevFwVersionMe, RSMI_FW_BLOCK_ME},
|
||||
{kDevFwVersionMec, RSMI_FW_BLOCK_MEC},
|
||||
{kDevFwVersionMec2, RSMI_FW_BLOCK_MEC2},
|
||||
{kDevFwVersionMes, RSMI_FW_BLOCK_MES},
|
||||
{kDevFwVersionMesKiq, RSMI_FW_BLOCK_MES_KIQ},
|
||||
{kDevFwVersionPfp, RSMI_FW_BLOCK_PFP},
|
||||
{kDevFwVersionRlc, RSMI_FW_BLOCK_RLC},
|
||||
{kDevFwVersionRlcSrlc, RSMI_FW_BLOCK_RLC_SRLC},
|
||||
@@ -482,6 +486,8 @@ static const std::map<const char *, dev_depends_t> kDevFuncDependsMap = {
|
||||
kDevFwVersionMe,
|
||||
kDevFwVersionMec,
|
||||
kDevFwVersionMec2,
|
||||
kDevFwVersionMes,
|
||||
kDevFwVersionMesKiq,
|
||||
kDevFwVersionPfp,
|
||||
kDevFwVersionRlc,
|
||||
kDevFwVersionRlcSrlc,
|
||||
@@ -962,6 +968,8 @@ int Device::readDevInfo(DevInfoTypes type, uint64_t *val) {
|
||||
case kDevFwVersionMe:
|
||||
case kDevFwVersionMec:
|
||||
case kDevFwVersionMec2:
|
||||
case kDevFwVersionMes:
|
||||
case kDevFwVersionMesKiq:
|
||||
case kDevFwVersionPfp:
|
||||
case kDevFwVersionRlc:
|
||||
case kDevFwVersionRlcSrlc:
|
||||
|
||||
@@ -61,7 +61,6 @@
|
||||
#include "rocm_smi/rocm_smi_exception.h"
|
||||
#include "rocm_smi/rocm_smi_logger.h"
|
||||
|
||||
using namespace ROCmLogging;
|
||||
using namespace amd::smi;
|
||||
|
||||
#define TRY try {
|
||||
|
||||
@@ -71,9 +71,8 @@
|
||||
#include "rocm_smi/rocm_smi_logger.h"
|
||||
#include "rocm_smi/rocm_smi_main.h"
|
||||
|
||||
using namespace ROCmLogging;
|
||||
|
||||
Logger* Logger::m_Instance = nullptr;
|
||||
ROCmLogging::Logger *ROCmLogging::Logger::m_Instance = nullptr;
|
||||
|
||||
// Log file name
|
||||
// WARNING: File name should be changed here and
|
||||
@@ -81,39 +80,39 @@ Logger* Logger::m_Instance = nullptr;
|
||||
// in one place will cause a mismatch in these scripts,
|
||||
// files may not have proper permissions, and logrotate
|
||||
// would not function properly.
|
||||
const std::string logPath = "/var/log/amd_smi_lib/";
|
||||
const std::string logBaseFName = "AMD-SMI-lib";
|
||||
const std::string logExtension = ".log";
|
||||
const std::string logFileName = logPath + logBaseFName + logExtension;
|
||||
#define LOGPATH "/var/log/amd_smi_lib/"
|
||||
#define LOGBASE_FNAME "AMD-SMI-lib"
|
||||
#define LOGEXTENSION ".log"
|
||||
const char *logFileName = LOGPATH LOGBASE_FNAME LOGEXTENSION;
|
||||
|
||||
Logger::Logger() {
|
||||
ROCmLogging::Logger::Logger() {
|
||||
initialize_resources();
|
||||
}
|
||||
|
||||
Logger::~Logger() {
|
||||
ROCmLogging::Logger::~Logger() {
|
||||
if (m_loggingIsOn) {
|
||||
destroy_resources();
|
||||
}
|
||||
}
|
||||
|
||||
Logger* Logger::getInstance() throw() {
|
||||
ROCmLogging::Logger* ROCmLogging::Logger::getInstance() throw() {
|
||||
if (m_Instance == nullptr) {
|
||||
m_Instance = new Logger();
|
||||
m_Instance = new ROCmLogging::Logger();
|
||||
}
|
||||
return m_Instance;
|
||||
}
|
||||
|
||||
void Logger::lock() {
|
||||
void ROCmLogging::Logger::lock() {
|
||||
m_Lock.lock();
|
||||
}
|
||||
|
||||
void Logger::unlock() {
|
||||
void ROCmLogging::Logger::unlock() {
|
||||
m_Lock.unlock();
|
||||
}
|
||||
|
||||
void Logger::logIntoFile(std::string& data) {
|
||||
void ROCmLogging::Logger::logIntoFile(std::string& data) {
|
||||
lock();
|
||||
if(!m_File.is_open()) {
|
||||
if (!m_File.is_open()) {
|
||||
initialize_resources();
|
||||
if (!m_File.is_open()) {
|
||||
std::cout << "WARNING: re-initializing resources was unsuccessful."
|
||||
@@ -127,24 +126,24 @@ void Logger::logIntoFile(std::string& data) {
|
||||
unlock();
|
||||
}
|
||||
|
||||
void Logger::logOnConsole(std::string& data) {
|
||||
void ROCmLogging::Logger::logOnConsole(std::string& data) {
|
||||
std::cout << getCurrentTime() << " " << data << std::endl;
|
||||
}
|
||||
|
||||
// Returns: In string format, YY-MM-DD HH:MM:SS.microseconds
|
||||
std::string Logger::getCurrentTime(void) {
|
||||
using namespace std::chrono;
|
||||
std::string ROCmLogging::Logger::getCurrentTime(void) {
|
||||
std::string currentTime;
|
||||
|
||||
// get current time
|
||||
auto now = system_clock::now();
|
||||
auto now = std::chrono::system_clock::now();
|
||||
|
||||
// get number of milliseconds for the current second
|
||||
// (remainder after division into seconds)
|
||||
auto ms = duration_cast<microseconds>(now.time_since_epoch()) % 1000000;
|
||||
auto ms = std::chrono::duration_cast<std::chrono::microseconds>(
|
||||
now.time_since_epoch()) % 1000000;
|
||||
|
||||
// convert to std::time_t in order to convert to std::tm (broken time)
|
||||
auto timer = system_clock::to_time_t(now);
|
||||
auto timer = std::chrono::system_clock::to_time_t(now);
|
||||
|
||||
// convert to broken time
|
||||
std::tm bt = *std::localtime(&timer);
|
||||
@@ -159,7 +158,7 @@ std::string Logger::getCurrentTime(void) {
|
||||
}
|
||||
|
||||
// Interface for Error Log
|
||||
void Logger::error(const char* text) throw() {
|
||||
void ROCmLogging::Logger::error(const char* text) throw() {
|
||||
// By default, logging is disabled
|
||||
// The check below allows us to toggle logging through RSMI_LOGGING
|
||||
// set or unset
|
||||
@@ -182,18 +181,18 @@ void Logger::error(const char* text) throw() {
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::error(std::string& text) throw() {
|
||||
void ROCmLogging::Logger::error(std::string& text) throw() {
|
||||
error(text.data());
|
||||
}
|
||||
|
||||
void Logger::error(std::ostringstream& stream) throw() {
|
||||
void ROCmLogging::Logger::error(std::ostringstream& stream) throw() {
|
||||
std::string text = stream.str();
|
||||
error(text.data());
|
||||
stream.str("");
|
||||
}
|
||||
|
||||
// Interface for Alarm Log
|
||||
void Logger::alarm(const char* text) throw() {
|
||||
void ROCmLogging::Logger::alarm(const char* text) throw() {
|
||||
// By default, logging is disabled (ie. no RSMI_LOGGING)
|
||||
// The check below allows us to toggle logging through RSMI_LOGGING
|
||||
// set or unset
|
||||
@@ -216,18 +215,18 @@ void Logger::alarm(const char* text) throw() {
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::alarm(std::string& text) throw() {
|
||||
void ROCmLogging::Logger::alarm(std::string& text) throw() {
|
||||
alarm(text.data());
|
||||
}
|
||||
|
||||
void Logger::alarm(std::ostringstream& stream) throw() {
|
||||
void ROCmLogging::Logger::alarm(std::ostringstream& stream) throw() {
|
||||
std::string text = stream.str();
|
||||
alarm(text.data());
|
||||
stream.str("");
|
||||
}
|
||||
|
||||
// Interface for Always Log
|
||||
void Logger::always(const char* text) throw() {
|
||||
void ROCmLogging::Logger::always(const char* text) throw() {
|
||||
// By default, logging is disabled (ie. no RSMI_LOGGING)
|
||||
// The check below allows us to toggle logging through RSMI_LOGGING
|
||||
// set or unset
|
||||
@@ -250,18 +249,18 @@ void Logger::always(const char* text) throw() {
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::always(std::string& text) throw() {
|
||||
void ROCmLogging::Logger::always(std::string& text) throw() {
|
||||
always(text.data());
|
||||
}
|
||||
|
||||
void Logger::always(std::ostringstream& stream) throw() {
|
||||
void ROCmLogging::Logger::always(std::ostringstream& stream) throw() {
|
||||
std::string text = stream.str();
|
||||
always(text.data());
|
||||
stream.str("");
|
||||
}
|
||||
|
||||
// Interface for Buffer Log
|
||||
void Logger::buffer(const char* text) throw() {
|
||||
void ROCmLogging::Logger::buffer(const char* text) throw() {
|
||||
// Buffer is the special case. So don't add log level
|
||||
// and timestamp in the buffer message. Just log the raw bytes.
|
||||
if ((m_LogType == FILE_LOG) && (m_LogLevel >= LOG_LEVEL_BUFFER)) {
|
||||
@@ -284,18 +283,18 @@ void Logger::buffer(const char* text) throw() {
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::buffer(std::string& text) throw() {
|
||||
void ROCmLogging::Logger::buffer(std::string& text) throw() {
|
||||
buffer(text.data());
|
||||
}
|
||||
|
||||
void Logger::buffer(std::ostringstream& stream) throw() {
|
||||
void ROCmLogging::Logger::buffer(std::ostringstream& stream) throw() {
|
||||
std::string text = stream.str();
|
||||
buffer(text.data());
|
||||
stream.str("");
|
||||
}
|
||||
|
||||
// Interface for Info Log
|
||||
void Logger::info(const char* text) throw() {
|
||||
void ROCmLogging::Logger::info(const char* text) throw() {
|
||||
// By default, logging is disabled (ie. no RSMI_LOGGING)
|
||||
// The check below allows us to toggle logging through RSMI_LOGGING
|
||||
// set or unset
|
||||
@@ -318,18 +317,18 @@ void Logger::info(const char* text) throw() {
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::info(std::string& text) throw() {
|
||||
void ROCmLogging::Logger::info(std::string& text) throw() {
|
||||
info(text.data());
|
||||
}
|
||||
|
||||
void Logger::info(std::ostringstream& stream) throw() {
|
||||
void ROCmLogging::Logger::info(std::ostringstream& stream) throw() {
|
||||
std::string text = stream.str();
|
||||
info(text.data());
|
||||
stream.str("");
|
||||
}
|
||||
|
||||
// Interface for Trace Log
|
||||
void Logger::trace(const char* text) throw() {
|
||||
void ROCmLogging::Logger::trace(const char* text) throw() {
|
||||
// By default, logging is disabled (ie. no RSMI_LOGGING)
|
||||
// The check below allows us to toggle logging through RSMI_LOGGING
|
||||
// set or unset
|
||||
@@ -352,18 +351,18 @@ void Logger::trace(const char* text) throw() {
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::trace(std::string& text) throw() {
|
||||
void ROCmLogging::Logger::trace(std::string& text) throw() {
|
||||
trace(text.data());
|
||||
}
|
||||
|
||||
void Logger::trace(std::ostringstream& stream) throw() {
|
||||
void ROCmLogging::Logger::trace(std::ostringstream& stream) throw() {
|
||||
std::string text = stream.str();
|
||||
trace(text.data());
|
||||
stream.str("");
|
||||
}
|
||||
|
||||
// Interface for Debug Log
|
||||
void Logger::debug(const char* text) throw() {
|
||||
void ROCmLogging::Logger::debug(const char* text) throw() {
|
||||
// By default, logging is disabled (ie. no RSMI_LOGGING)
|
||||
// The check below allows us to toggle logging through RSMI_LOGGING
|
||||
// set or unset
|
||||
@@ -386,51 +385,53 @@ void Logger::debug(const char* text) throw() {
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::debug(std::string& text) throw() {
|
||||
void ROCmLogging::Logger::debug(std::string& text) throw() {
|
||||
debug(text.data());
|
||||
}
|
||||
|
||||
void Logger::debug(std::ostringstream& stream) throw() {
|
||||
void ROCmLogging::Logger::debug(std::ostringstream& stream) throw() {
|
||||
std::string text = stream.str();
|
||||
debug(text.data());
|
||||
stream.str("");
|
||||
}
|
||||
|
||||
// Interfaces to control log levels
|
||||
void Logger::updateLogLevel(LogLevel logLevel) {
|
||||
void ROCmLogging::Logger::updateLogLevel(LogLevel logLevel) {
|
||||
m_LogLevel = logLevel;
|
||||
}
|
||||
|
||||
void Logger::enableAllLogLevels() {
|
||||
void ROCmLogging::Logger::enableAllLogLevels() {
|
||||
m_LogLevel = ENABLE_LOG;
|
||||
}
|
||||
|
||||
// Disable all log levels, except error and alarm
|
||||
void Logger::disableLog() {
|
||||
void ROCmLogging::Logger::disableLog() {
|
||||
m_LogLevel = DISABLE_LOG;
|
||||
}
|
||||
|
||||
// Interfaces to control log Types
|
||||
void Logger::updateLogType(LogType logType) {
|
||||
void ROCmLogging::Logger::updateLogType(LogType logType) {
|
||||
m_LogType = logType;
|
||||
}
|
||||
|
||||
void Logger::enableConsoleLogging() {
|
||||
void ROCmLogging::Logger::enableConsoleLogging() {
|
||||
m_LogType = CONSOLE;
|
||||
}
|
||||
|
||||
void Logger::enableFileLogging() {
|
||||
void ROCmLogging::Logger::enableFileLogging() {
|
||||
m_LogType = FILE_LOG;
|
||||
}
|
||||
|
||||
// Returns a string of details on current log settings
|
||||
std::string Logger::getLogSettings() {
|
||||
std::string ROCmLogging::Logger::getLogSettings() {
|
||||
std::string logSettings;
|
||||
|
||||
if (m_File.is_open()) {
|
||||
logSettings += "OpenStatus = File (" + logFileName + ") is open";
|
||||
logSettings += "OpenStatus = File (" + std::string(logFileName)
|
||||
+ ") is open";
|
||||
} else {
|
||||
logSettings += "OpenStatus = File (" + logFileName + ") is not open";
|
||||
logSettings += "OpenStatus = File (" + std::string(logFileName)
|
||||
+ ") is not open";
|
||||
}
|
||||
logSettings += ", ";
|
||||
|
||||
@@ -480,11 +481,11 @@ std::string Logger::getLogSettings() {
|
||||
|
||||
// Returns current reported enabled logging state. State is controlled by
|
||||
// user's environment variable RSMI_LOGGING.
|
||||
bool Logger::isLoggerEnabled() {
|
||||
bool ROCmLogging::Logger::isLoggerEnabled() {
|
||||
return m_loggingIsOn;
|
||||
}
|
||||
|
||||
void Logger::initialize_resources() {
|
||||
void ROCmLogging::Logger::initialize_resources() {
|
||||
// By default, logging is disabled (ie. no RSMI_LOGGING)
|
||||
// The check below allows us to toggle logging through RSMI_LOGGING
|
||||
// set or unset
|
||||
@@ -492,7 +493,7 @@ void Logger::initialize_resources() {
|
||||
if (!m_loggingIsOn) {
|
||||
return;
|
||||
}
|
||||
m_File.open(logFileName.c_str(), std::ios::out | std::ios::app);
|
||||
m_File.open(logFileName, std::ios::out | std::ios::app);
|
||||
m_LogLevel = LOG_LEVEL_TRACE;
|
||||
// RSMI_LOGGING = 1, output to logs only
|
||||
// RSMI_LOGGING = 2, output to console only
|
||||
@@ -521,9 +522,9 @@ void Logger::initialize_resources() {
|
||||
if (m_File.fail()) {
|
||||
std::cout << "WARNING: Failed opening log file." << std::endl;
|
||||
}
|
||||
chmod(logFileName.c_str(), S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR|S_IWGRP|S_IWOTH);
|
||||
chmod(logFileName, S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR|S_IWGRP|S_IWOTH);
|
||||
}
|
||||
|
||||
void Logger::destroy_resources() {
|
||||
void ROCmLogging::Logger::destroy_resources() {
|
||||
m_File.close();
|
||||
}
|
||||
|
||||
@@ -68,7 +68,6 @@
|
||||
#include "rocm_smi/rocm_smi_kfd.h"
|
||||
#include "rocm_smi/rocm_smi_logger.h"
|
||||
|
||||
using namespace ROCmLogging;
|
||||
|
||||
static const char *kPathDRMRoot = "/sys/class/drm";
|
||||
static const char *kPathHWMonRoot = "/sys/class/hwmon";
|
||||
@@ -129,6 +128,8 @@ amd::smi::RocmSMI::devInfoTypesStrings = {
|
||||
{amd::smi::kDevFwVersionMe, amdSMI + "kDevFwVersionMe"},
|
||||
{amd::smi::kDevFwVersionMec, amdSMI + "kDevFwVersionMec"},
|
||||
{amd::smi::kDevFwVersionMec2, amdSMI + "kDevFwVersionMec2"},
|
||||
{amd::smi::kDevFwVersionMes, amdSMI + "kDevFwVersionMes"},
|
||||
{amd::smi::kDevFwVersionMesKiq, amdSMI + "kDevFwVersionMesKiq"},
|
||||
{amd::smi::kDevFwVersionPfp, amdSMI + "kDevFwVersionPfp"},
|
||||
{amd::smi::kDevFwVersionRlc, amdSMI + "kDevFwVersionRlc"},
|
||||
{amd::smi::kDevFwVersionRlcSrlc, amdSMI + "kDevFwVersionRlcSrlc"},
|
||||
@@ -313,12 +314,12 @@ RocmSMI::Initialize(uint64_t flags) {
|
||||
int i_ret;
|
||||
|
||||
LOG_ALWAYS("=============== ROCM SMI initialize ================");
|
||||
Logger::getInstance()->enableAllLogLevels();
|
||||
ROCmLogging::Logger::getInstance()->enableAllLogLevels();
|
||||
// Leaving below to allow developers to check current log settings
|
||||
// std::string logSettings = Logger::getInstance()->getLogSettings();
|
||||
// std::cout << "Current log settings:\n" << logSettings << std::endl;
|
||||
|
||||
if (Logger::getInstance()->isLoggerEnabled()) {
|
||||
if (ROCmLogging::Logger::getInstance()->isLoggerEnabled()) {
|
||||
logSystemDetails();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* The University of Illinois/NCSA
|
||||
* Open Source License (NCSA)
|
||||
*
|
||||
* Copyright (c) 2017, Advanced Micro Devices, Inc.
|
||||
* Copyright (c) 2017-2023, Advanced Micro Devices, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Developed by:
|
||||
@@ -58,8 +58,6 @@
|
||||
#include "rocm_smi/rocm_smi_exception.h"
|
||||
#include "rocm_smi/rocm_smi_logger.h"
|
||||
|
||||
using namespace ROCmLogging;
|
||||
|
||||
namespace amd {
|
||||
namespace smi {
|
||||
|
||||
@@ -80,6 +78,8 @@ static const char *kMonPowerCapName = "power#_cap";
|
||||
static const char *kMonPowerCapMaxName = "power#_cap_max";
|
||||
static const char *kMonPowerCapMinName = "power#_cap_min";
|
||||
static const char *kMonPowerAveName = "power#_average";
|
||||
static const char *kMonPowerInputName = "power#_input";
|
||||
static const char *kMonPowerLabelName = "power#_label";
|
||||
static const char *kMonTempMaxName = "temp#_max";
|
||||
static const char *kMonTempMinName = "temp#_min";
|
||||
static const char *kMonTempMaxHystName = "temp#_max_hyst";
|
||||
@@ -135,6 +135,8 @@ static const std::map<MonitorTypes, const char *> kMonitorNameMap = {
|
||||
{kMonPowerCapMax, kMonPowerCapMaxName},
|
||||
{kMonPowerCapMin, kMonPowerCapMinName},
|
||||
{kMonPowerAve, kMonPowerAveName},
|
||||
{kMonPowerInput, kMonPowerInputName},
|
||||
{kMonPowerLabel, kMonPowerLabelName},
|
||||
{kMonTempMax, kMonTempMaxName},
|
||||
{kMonTempMin, kMonTempMinName},
|
||||
{kMonTempMaxHyst, kMonTempMaxHystName},
|
||||
@@ -202,7 +204,8 @@ static const std::map<const char *, monitor_depends_t> kMonFuncDependsMap = {
|
||||
.variants = {kMonInvalid},
|
||||
}
|
||||
},
|
||||
{"rsmi_dev_power_cap_default_get", { .mandatory_depends = {kMonPowerCapDefaultName},
|
||||
{"rsmi_dev_power_cap_default_get", { .mandatory_depends =
|
||||
{kMonPowerCapDefaultName},
|
||||
.variants = {kMonInvalid},
|
||||
}
|
||||
},
|
||||
@@ -616,7 +619,7 @@ void Monitor::fillSupportedFuncs(SupportedFuncMap *supported_funcs) {
|
||||
supported_monitors = intersect;
|
||||
}
|
||||
if (!supported_monitors.empty()) {
|
||||
for (unsigned long & supported_monitor : supported_monitors) {
|
||||
for (uint64_t &supported_monitor : supported_monitors) {
|
||||
if (m_type == eDefaultMonitor) {
|
||||
assert(supported_monitor > 0);
|
||||
supported_monitor |=
|
||||
|
||||
@@ -70,7 +70,6 @@
|
||||
#include "rocm_smi/rocm_smi_device.h"
|
||||
#include "rocm_smi/rocm_smi_logger.h"
|
||||
|
||||
using namespace ROCmLogging;
|
||||
|
||||
namespace amd {
|
||||
namespace smi {
|
||||
|
||||
@@ -1736,7 +1736,7 @@ amdsmi_status_t
|
||||
amdsmi_get_gpu_device_uuid(amdsmi_processor_handle processor_handle, unsigned int *uuid_length, char *uuid) {
|
||||
AMDSMI_CHECK_INIT();
|
||||
|
||||
if (uuid_length == nullptr || uuid == nullptr) {
|
||||
if (uuid_length == nullptr || uuid == nullptr || uuid_length == nullptr || *uuid_length < AMDSMI_GPU_UUID_SIZE) {
|
||||
return AMDSMI_STATUS_INVAL;
|
||||
}
|
||||
|
||||
@@ -1748,35 +1748,20 @@ amdsmi_get_gpu_device_uuid(amdsmi_processor_handle processor_handle, unsigned in
|
||||
amdsmi_status_t status = AMDSMI_STATUS_SUCCESS;
|
||||
SMIGPUDEVICE_MUTEX(gpu_device->get_mutex())
|
||||
|
||||
FILE *fp;
|
||||
size_t len = AMDSMI_GPU_UUID_SIZE;
|
||||
ssize_t nread;
|
||||
amdsmi_asic_info_t asic_info = {};
|
||||
const uint8_t fcn = 0xff;
|
||||
|
||||
std::string path = "/sys/class/drm/" + gpu_device->get_gpu_path() + "/device/uuid_info";
|
||||
status = amdsmi_get_gpu_asic_info(processor_handle, &asic_info);
|
||||
if (status != AMDSMI_STATUS_SUCCESS) {
|
||||
printf("Getting asic info failed. Return code: %d", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
fp = fopen(path.c_str(), "rb");
|
||||
if (!fp) {
|
||||
/* generate random UUID */
|
||||
status = amdsmi_uuid_gen(uuid, strtoul(asic_info.asic_serial, nullptr, AMDSMI_NORMAL_STRING_LENGTH), (uint16_t)asic_info.device_id, fcn);
|
||||
return status;
|
||||
}
|
||||
|
||||
nread = getline(&uuid, &len, fp);
|
||||
if (nread <= 0) {
|
||||
/* generate random UUID */
|
||||
status = amdsmi_uuid_gen(uuid, strtoul(asic_info.asic_serial, nullptr, AMDSMI_NORMAL_STRING_LENGTH), (uint16_t)asic_info.device_id, fcn);
|
||||
fclose(fp);
|
||||
return status;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
/* generate random UUID */
|
||||
status = amdsmi_uuid_gen(uuid,
|
||||
strtoull(asic_info.asic_serial, nullptr, 16),
|
||||
(uint16_t)asic_info.device_id, fcn);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
@@ -111,6 +111,7 @@ void TestPowerRead::Run(void) {
|
||||
std::cout << "\t**Power Cap Range: " << info.min_power_cap << " to " <<
|
||||
info.max_power_cap << " uW" << std::endl;
|
||||
}
|
||||
// TODO: Add current_socket_power tests
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,6 +56,8 @@ static const std::map<amdsmi_fw_block_t, const char *> kDevFWNameMap = {
|
||||
{FW_ID_CP_ME, "me"},
|
||||
{FW_ID_CP_MEC1, "mec1"},
|
||||
{FW_ID_CP_MEC2, "mec2"},
|
||||
{FW_ID_CP_MES, "mes"},
|
||||
{FW_ID_MES_KIQ, "mes_kiq"}, // TODO: double check
|
||||
{FW_ID_CP_PFP, "pfp"},
|
||||
{FW_ID_RLC, "rlc"},
|
||||
{FW_ID_RLC_SRLG, "rlc_srlg"},
|
||||
|
||||
新增問題並參考
封鎖使用者