Merge amd-dev into amd-master 20230925

Signed-off-by: Maisam Arif <maisarif@amd.com>
Change-Id: Ib60e35c5b8e40229d6da61af2b748f90d8d54417


[ROCm/amdsmi commit: 535f93c1cf]
此提交包含在:
Maisam Arif
2023-09-25 11:32:20 -05:00
當前提交 854d069f1f
共有 39 個檔案被更改,包括 1032 行新增719 行删除
+2
查看文件
@@ -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
+2
查看文件
@@ -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
+1 -6
查看文件
@@ -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
+6 -1
查看文件
@@ -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
查看文件
@@ -1 +1 @@
__version__ = "23.2.1.0"
__version__ = "23.3.1.0"
+1 -1
查看文件
@@ -1 +1 @@
__version__ = "23.2.1.0"
__version__ = "23.3.1.0"
+17 -17
查看文件
@@ -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)
+139 -122
查看文件
@@ -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)
+3 -2
查看文件
@@ -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)
+27 -78
查看文件
@@ -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()
+5 -15
查看文件
@@ -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"
+1 -1
查看文件
@@ -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
+8 -2
查看文件
@@ -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
*/
+4 -1
查看文件
@@ -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(
+12 -12
查看文件
@@ -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:
-1
查看文件
@@ -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
+44 -60
查看文件
@@ -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):
+1 -1
查看文件
@@ -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(
+90 -84
查看文件
@@ -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',
+1 -1
查看文件
@@ -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"
+33 -1
查看文件
@@ -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.
+2
查看文件
@@ -146,6 +146,8 @@ enum DevInfoTypes {
kDevFwVersionMe,
kDevFwVersionMec,
kDevFwVersionMec2,
kDevFwVersionMes,
kDevFwVersionMesKiq,
kDevFwVersionPfp,
kDevFwVersionRlc,
kDevFwVersionRlcSrlc,
+3 -3
查看文件
@@ -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();
+42 -38
查看文件
@@ -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);
+1 -1
查看文件
@@ -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
+161 -74
查看文件
@@ -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)
+8 -2
查看文件
@@ -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)'
+122 -26
查看文件
@@ -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, &current, 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) {
+10 -2
查看文件
@@ -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:
-1
查看文件
@@ -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 {
+56 -55
查看文件
@@ -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();
}
+4 -3
查看文件
@@ -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();
}
+8 -5
查看文件
@@ -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 |=
-1
查看文件
@@ -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 {
+5 -20
查看文件
@@ -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;
}
+1
查看文件
@@ -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
}
}
}
+2
查看文件
@@ -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"},