Merge amd-dev into amd-master 20231103

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


[ROCm/amdsmi commit: 816752cde9]
This commit is contained in:
Maisam Arif
2023-11-03 05:10:45 -05:00
59 changed files with 2640 additions and 1081 deletions
+34 -25
View File
@@ -28,20 +28,33 @@ find_program(GIT NAMES git)
## Setup the package version based on git tags.
set(PKG_VERSION_GIT_TAG_PREFIX "amdsmi_pkg_ver")
get_package_version_number("23.4.0" ${PKG_VERSION_GIT_TAG_PREFIX} GIT)
get_package_version_number("23.4.2" ${PKG_VERSION_GIT_TAG_PREFIX} GIT)
message("Package version: ${PKG_VERSION_STR}")
set(${AMD_SMI_LIBS_TARGET}_VERSION_MAJOR "${VERSION_MAJOR}")
set(${AMD_SMI_LIBS_TARGET}_VERSION_MINOR "${VERSION_MINOR}")
set(${AMD_SMI_LIBS_TARGET}_VERSION_PATCH "0")
set(${AMD_SMI_LIBS_TARGET}_VERSION_MAJOR "${CPACK_PACKAGE_VERSION_MAJOR}")
set(${AMD_SMI_LIBS_TARGET}_VERSION_MINOR "${CPACK_PACKAGE_VERSION_MINOR}")
set(${AMD_SMI_LIBS_TARGET}_VERSION_PATCH "${CPACK_PACKAGE_VERSION_PATCH}")
set(${AMD_SMI_LIBS_TARGET}_VERSION_BUILD "0")
set(${AMD_SMI_LIBS_TARGET}_VERSION_HASH "${PKG_VERSION_HASH}")
set(${AMD_SMI_LIBS_TARGET}_VERSION_STRING "${${AMD_SMI_LIBS_TARGET}_VERSION_MAJOR}.${${AMD_SMI_LIBS_TARGET}_VERSION_MINOR}.${${AMD_SMI_LIBS_TARGET}_VERSION_PATCH}+${${AMD_SMI_LIBS_TARGET}_VERSION_HASH}")
# Make proper version for appending
# Default Value is 99999
set(ROCM_VERSION_FOR_PACKAGE "99999")
if(DEFINED ENV{ROCM_LIBPATCH_VERSION})
set(ROCM_VERSION_FOR_PACKAGE $ENV{ROCM_LIBPATCH_VERSION})
endif()
#Prepare final version for the CPACK use
set(CPACK_PACKAGE_VERSION
"${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}.${ROCM_VERSION_FOR_PACKAGE}")
# The following default version values should be updated as appropriate for
# ABI breaks (update MAJOR and MINOR), and ABI/API additions (update MINOR).
# Until ABI stabilizes VERSION_MAJOR will be 0. This should be over-ridden
# by git tags (through "git describe") when they are present.
set(PKG_VERSION_MAJOR "${VERSION_MAJOR}")
set(PKG_VERSION_MINOR "${VERSION_MINOR}")
set(PKG_VERSION_PATCH 0)
set(PKG_VERSION_MAJOR "${CPACK_PACKAGE_VERSION_MAJOR}")
set(PKG_VERSION_MINOR "${CPACK_PACKAGE_VERSION_MINOR}")
set(PKG_VERSION_PATCH "${CPACK_PACKAGE_VERSION_PATCH}")
set(PKG_VERSION_NUM_COMMIT 0)
set(AMD_SMI_PACKAGE
@@ -81,7 +94,11 @@ set(CPACK_PACKAGE_DESCRIPTION_SUMMARY
generic_package()
## Compiler flags
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -fno-rtti -m64 -msse -msse2")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -fno-rtti")
if (${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "x86_64")
set(CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} -m64 -msse -msse2")
endif()
# Security options
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wconversion -Wcast-align")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wformat=2 -fno-common -Wstrict-overflow")
@@ -226,21 +243,14 @@ install(
DESTINATION share/doc/${AMD_SMI}
COMPONENT dev)
#Make proper version for appending
#Default Value is 99999, setting it first
set(ROCM_VERSION_FOR_PACKAGE "99999")
if(DEFINED ENV{ROCM_LIBPATCH_VERSION})
set(ROCM_VERSION_FOR_PACKAGE $ENV{ROCM_LIBPATCH_VERSION})
endif()
#Debian package specific variables
set(CPACK_DEBIAN_PACKAGE_PROVIDES "amd-smi")
set(CPACK_DEBIAN_PACKAGE_RECOMMENDS "sudo, libdrm-dev, python3-yaml")
set(CPACK_DEBIAN_PACKAGE_RECOMMENDS "sudo, libdrm-dev, python3-yaml, python3-argcomplete")
set(CPACK_DEBIAN_ASAN_PACKAGE_RECOMMENDS ${CPACK_DEBIAN_PACKAGE_RECOMMENDS})
set(CPACK_DEBIAN_DEV_PACKAGE_RECOMMENDS ${CPACK_DEBIAN_PACKAGE_RECOMMENDS})
set(CPACK_DEBIAN_ASAN_PACKAGE_PROVIDES "${AMD_SMI_PACKAGE}-asan")
set(CPACK_DEBIAN_DEV_PACKAGE_PROVIDES "${AMD_SMI_PACKAGE}")
set(CPACK_DEBIAN_PACKAGE_DEPENDS "python3 (>= 3.7.9)")
set(CPACK_DEBIAN_PACKAGE_DEPENDS "python3 (>= 3.6.8), python3-pip")
set(CPACK_DEBIAN_ASAN_PACKAGE_DEPENDS ${CPACK_DEBIAN_PACKAGE_DEPENDS})
set(CPACK_DEBIAN_DEV_PACKAGE_DEPENDS ${CPACK_DEBIAN_PACKAGE_DEPENDS})
@@ -259,9 +269,13 @@ endif()
set(CPACK_RPM_PACKAGE_PROVIDES "amd-smi")
set(CPACK_RPM_DEV_PACKAGE_PROVIDES "${AMD_SMI_PACKAGE}")
set(CPACK_RPM_ASAN_PACKAGE_PROVIDES "${AMD_SMI_PACKAGE}-asan")
set(CPACK_RPM_PACKAGE_SUGGESTS "python3 >= 3.7.9")
set(CPACK_RPM_PACKAGE_SUGGESTS "python3-argcomplete")
set(CPACK_RPM_DEV_PACKAGE_SUGGESTS ${CPACK_RPM_PACKAGE_SUGGESTS})
set(CPACK_RPM_ASAN_PACKAGE_SUGGESTS ${CPACK_RPM_PACKAGE_SUGGESTS})
# python version gated by rhel8 :(
set(CPACK_RPM_PACKAGE_REQUIRES "python3 >= 3.6.8, python3-pip")
set(CPACK_RPM_DEV_PACKAGE_REQUIRES ${CPACK_RPM_PACKAGE_REQUIRES})
set(CPACK_RPM_ASAN_PACKAGE_REQUIRES ${CPACK_RPM_PACKAGE_REQUIRES})
# don't terminate if bytecompile of python files fails
set(CPACK_RPM_SPEC_MORE_DEFINE "%define _python_bytecompile_errors_terminate_build 0")
@@ -294,17 +308,12 @@ endif()
# https://bugzilla.redhat.com/show_bug.cgi?id=1811358
# set(CPACK_RPM_PACKAGE_SUGGESTS "sudo, libdrm-dev")
#Prepare final version for the CPACK use
set(CPACK_PACKAGE_VERSION
"${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}.${ROCM_VERSION_FOR_PACKAGE}"
)
## Process the Rpm install/remove scripts to update the CPACK variables
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/RPM/post.in" RPM/post @ONLY)
configure_file ( "${CMAKE_CURRENT_SOURCE_DIR}/RPM/preun.in" RPM/preun @ONLY )
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/RPM/preun.in" RPM/preun @ONLY)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/RPM/postun.in" RPM/postun @ONLY)
set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE "${CMAKE_CURRENT_BINARY_DIR}/RPM/post")
set ( CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE "${CMAKE_CURRENT_BINARY_DIR}/RPM/preun" )
set(CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE "${CMAKE_CURRENT_BINARY_DIR}/RPM/preun")
set(CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE "${CMAKE_CURRENT_BINARY_DIR}/RPM/postun")
#Set the names now using CPACK utility
+31
View File
@@ -104,8 +104,39 @@ do_ldconfig() {
fi
}
do_install_amdsmi_python_lib() {
# get python version
local python3_minor_version
python3_minor_version=$(python3 -c 'import sys;print(sys.version_info.minor)')
if [ $? -ne 0 ]; then
echo "[WARNING] Could not determine python version. "\
"AMD-SMI python library will not be installed."
return
fi
# check if python version is supported
if [ "$python3_minor_version" -lt 6 ]; then
echo "[WARNING] AMD-SMI python library is not "\
"supported on python version 3.$python3_minor_version. "\
"AMD-SMI python library will not be installed."
return
fi
# Remove old python library
python3 -m pip uninstall amdsmi --yes --quiet
# install python library at @CPACK_PACKAGING_INSTALL_PREFIX@/@SHARE_INSTALL_PREFIX@/amdsmi
local python_lib_path=@CPACK_PACKAGING_INSTALL_PREFIX@/@SHARE_INSTALL_PREFIX@
python3 -m pip install "$python_lib_path"
python3 -m pip show argcomplete
if [ $? -ne 1 ]; then
activate-global-python-argcomplete
fi
}
case "$1" in
( configure )
do_install_amdsmi_python_lib || return 0
do_ldconfig
do_configureLogrotate || return 0
;;
+26
View File
@@ -33,11 +33,37 @@ return_logrotateToOrigConfig() {
fi
}
rm_python_lib() {
# get python version
local python3_minor_version
python3_minor_version=$(python3 -c 'import sys;print(sys.version_info.minor)')
if [ $? -ne 0 ]; then
echo "[WARNING] Could not determine python version. "\
"AMD-SMI python library will not be uninstalled."
return
fi
# check if python version is supported
if [ "$python3_minor_version" -lt 6 ]; then
echo "[WARNING] AMD-SMI python library is not supported on python version 3.$python3_minor_version. "\
"AMD-SMI python library will not be uninstalled."
return
fi
python3 -m pip uninstall amdsmi --yes
python3 -m pip show amdsmi
if [ $? -ne 1 ]; then
echo "[WARNING] AMD-SMI python library (amdsmi) is still installed. "\
"Check post install to ensure version is correct"
return
fi
}
case "$1" in
( remove | upgrade)
# remove old gpuv-smi symlink
rm -f @CPACK_PACKAGING_INSTALL_PREFIX@/bin/gpuv-smi &> /dev/null
rm_python_lib || return 0
rm_ldconfig
rm_pyc
rm_logFolder
+75 -91
View File
@@ -6,16 +6,83 @@ For additional information refer to [ROCm Documentation](https://rocm.docs.amd.c
Note: This project is a successor to [rocm_smi_lib](https://github.com/RadeonOpenCompute/rocm_smi_lib)
and [esmi_ib_library](https://github.com/amd/esmi_ib_library)
## Supported platforms
At initial release, the AMD SMI library will support Linux bare metal and Linux virtual machine guest for AMD GPUs. In the future release, the library will be extended to support AMD EPYC™ CPUs.
AMD SMI library can run on AMD ROCm supported platforms, please refer to [List of Supported Operating Systems and GPUs](https://rocm.docs.amd.com/en/latest/release/gpu_os_support.html)
To run the AMD SMI library, the amdgpu driver needs to be installed. Optionally, the libdrm can be
To run the AMD SMI library, the amdgpu driver and the hsmp driver needs to be installed. Optionally, the libdrm can be
installed to query firmware information and hardware IPs.
## Usage Basics
## Install CLI Tool and Libraries
### Requirements
* python 3.6.8+ 64-bit
* amdgpu driver must be loaded for amdsmi_init() to pass
### Installation
* Install amdgpu driver
* Install amd-smi-lib package through package manager
* amd-smi --help
### Install Example for Ubuntu 22.04
``` bash
apt install amd-smi-lib
# if installed with rocm ignore the export
export PATH="$PATH:/opt/rocm/bin"
amd-smi --help
```
### Optional autocompletion
`amd-smi` cli application supports autocompletion. The package should attempt to install it, if argcomplete is not installed you can enable it by using the following commands:
```bash
python3 -m pip install argcomplete
activate-global-python-argcomplete
# restart shell to enable
```
### Manual/Multiple Rocm Instance Python Library Install
In the event there are multiple rocm installations and pyenv is not being used, to use the correct amdsmi version you must uninstall previous versions of amd-smi and install the version you want directly from your rocm instance.
#### Python Library Install Example for Ubuntu 22.04
Remove previous amdsmi installation:
```bash
python3 -m pip list | grep amd
python3 -m pip uninstall amdsmi
```
Then install Python library from your target rocm instance:
``` bash
apt install amd-smi-lib
cd /opt/rocm/share/amd_smi
python3 -m pip install --upgrade pip
python3 -m pip install --user .
```
Now you have the amdsmi python library in your python path:
``` 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
>>>
```
## Usage Basics for the C Library
### Device/Socket handles
@@ -25,6 +92,10 @@ GPU device and CPU device on the same socket. Moreover, for MI200, it may have m
To discover the sockets in the system, `amdsmi_get_socket_handles()` is called to get list of sockets
handles, which in turn can be used to query the devices in that socket using `amdsmi_get_processor_handles()`. The device handler is used to distinguish the detected devices from one another. It is important to note that a device may end up with a different device handles after restart application, so a device handle should not be relied upon to be constant over process.
To discover the cpu sockets in the system, `amdsmi_get_cpusocket_handles()` is called to get list of cpu sockets
handles, which in turn can be used to query the cpu cores in that cpu socket using `amdsmi_get_cpucore_handles()`. The cpu core handler is used to distinguish the detected cpu cores from one another.
## Hello AMD SMI
The only required AMD-SMI call for any program that wants to use AMD-SMI is the `amdsmi_init()` call. This call initializes some internal data structures that will be used by subsequent AMD-SMI calls. In the call, a flag can be passed if the application is only interested in a specific device type.
@@ -127,92 +198,7 @@ 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 CLI Tool and Python Library
### Requirements
* python 3.7+ 64-bit
* amdgpu driver must be loaded for amdsmi_init() to pass
### Optional autocompletion
`amd-smi` cli application supports autocompletion. It is enabled by using the
following commands:
```bash
python3 -m pip install argcomplete
activate-global-python-argcomplete
# restart shell to enable
```
### 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 Development 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.
#### Older RPM Packaged OS's
The default python versions in older RPM based OS's are not gauranteed to have the minium version.
For example RHEL 8 and SLES 15 are 3.6.8 and 3.6.15 . You will need to ensure the latest yaml package is installed ( pyyaml >= 5.1) pyyaml is installed to your pip instance:
``` bash
python3 -m pip install pyyaml
amd-smi list
```
While the CLI will work with these older python versions, to install the python development 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 .
```
``` 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
>>>
```
## Building AMD SMI
### Rebuilding Python wrapper
@@ -230,8 +216,6 @@ Note: To be able to re-generate python wrapper you need **docker** installed.
Note: python_wrapper is NOT automatically re-generated. You must run `./update_wrapper.sh`.
## Building AMD SMI
### Additional Required software for building
In order to build the AMD SMI library, the following components are required. Note that the software versions listed are what was used in development. Earlier versions are not guaranteed to work:
@@ -242,7 +226,7 @@ In order to build the AMD SMI library, the following components are required. No
In order to build the AMD SMI python package, the following components are required:
* clang (14.0 or above)
* python (3.7 or above)
* python (3.6.8 or above)
* virtualenv - `python3 -m pip install virtualenv`
In order to build the latest documentation, the following are required:
+31
View File
@@ -104,8 +104,39 @@ do_ldconfig() {
fi
}
do_install_amdsmi_python_lib() {
# get python version
local python3_minor_version
python3_minor_version=$(python3 -c 'import sys;print(sys.version_info.minor)')
if [ $? -ne 0 ]; then
echo "[WARNING] Could not determine python version. "\
"AMD-SMI python library will not be installed."
return
fi
# check if python version is supported
if [ "$python3_minor_version" -lt 6 ]; then
echo "[WARNING] AMD-SMI python library is not "\
"supported on python version 3.$python3_minor_version. "\
"AMD-SMI python library will not be installed."
return
fi
# Remove old python library
python3 -m pip uninstall amdsmi --yes --quiet
# install python library at @CPACK_PACKAGING_INSTALL_PREFIX@/@SHARE_INSTALL_PREFIX@/amdsmi
local python_lib_path=@CPACK_PACKAGING_INSTALL_PREFIX@/@SHARE_INSTALL_PREFIX@
python3 -m pip install "$python_lib_path"
python3 -m pip show argcomplete
if [ $? -ne 1 ]; then
activate-global-python-argcomplete
fi
}
# post install or upgrade, $i is 1 or 2 -> do these actions
if [ "$1" -ge 1 ]; then
do_install_amdsmi_python_lib || return 0
do_ldconfig
do_configureLogrotate || return 0
fi
+27
View File
@@ -25,10 +25,37 @@ return_logrotateToOrigConfig() {
fi
}
rm_python_lib() {
# get python version
local python3_minor_version
python3_minor_version=$(python3 -c 'import sys;print(sys.version_info.minor)')
if [ $? -ne 0 ]; then
echo "[WARNING] Could not determine python version. "\
"AMD-SMI python library will not be uninstalled."
return
fi
# check if python version is supported
if [ "$python3_minor_version" -lt 6 ]; then
echo "[WARNING] AMD-SMI python library is not supported on python version 3.$python3_minor_version. "\
"AMD-SMI python library will not be uninstalled."
return
fi
python3 -m pip uninstall amdsmi --yes
python3 -m pip show amdsmi
if [ $? -ne 1 ]; then
echo "[WARNING] AMD-SMI python library (amdsmi) is still installed. "\
"Check post install to ensure version is correct"
return
fi
}
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_python_lib || return 0
rm_pyc
rm_logFolder
return_logrotateToOrigConfig
+3 -2
View File
@@ -9,10 +9,12 @@ set(PY_CLI_INSTALL_DIR
"${CMAKE_INSTALL_LIBEXECDIR}" CACHE STRING
"CLI tool installation directory")
# populate version string
configure_file(_version.py.in ${PY_PACKAGE_DIR}/_version.py @ONLY)
# hard-linking instead of copying avoids unnecessarry regeneration of packaged files
add_custom_command(
OUTPUT ${PY_PACKAGE_DIR}/__init__.py
${PY_PACKAGE_DIR}/_version.py
${PY_PACKAGE_DIR}/amdsmi_cli.py
${PY_PACKAGE_DIR}/amdsmi_commands.py
${PY_PACKAGE_DIR}/amdsmi_helpers.py
@@ -26,7 +28,6 @@ add_custom_command(
DEPENDS amdsmi_cli
COMMAND mkdir -p ${PY_PACKAGE_DIR}/
COMMAND ln -Pf ${CMAKE_CURRENT_SOURCE_DIR}/__init__.py ${PY_PACKAGE_DIR}/
COMMAND ln -Pf ${CMAKE_CURRENT_SOURCE_DIR}/_version.py ${PY_PACKAGE_DIR}/
COMMAND ln -Pf ${CMAKE_CURRENT_SOURCE_DIR}/amdsmi_cli.py ${PY_PACKAGE_DIR}/
COMMAND ln -Pf ${CMAKE_CURRENT_SOURCE_DIR}/amdsmi_commands.py ${PY_PACKAGE_DIR}/
COMMAND ln -Pf ${CMAKE_CURRENT_SOURCE_DIR}/amdsmi_helpers.py ${PY_PACKAGE_DIR}/
+42 -54
View File
@@ -10,17 +10,10 @@ Recommended: At least one AMD GPU with AMD driver installed
### Requirements
* python 3.7+ 64-bit
* python 3.6.8+ 64-bit
* amdgpu driver must be loaded for amdsmi_init() to pass
### 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
```
### Installation
* Install amdgpu driver
* Install amd-smi-lib package through package manager
@@ -29,42 +22,35 @@ python3 -m pip uninstall amdsmi
### 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 Development Library Installation
### Optional autocompletion
This option is for users who want to develop their own scripts using amd-smi's python library
`amd-smi` cli application supports autocompletion. The package should attempt to install it, if argcomplete is not installed you can enable it by using the following commands:
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.
#### Older RPM Packaged OS's
The default python versions in older RPM based OS's are not gauranteed to have the minium version.
For example RHEL 8 and SLES 15 are 3.6.8 and 3.6.15 . You will need to ensure the latest yaml package is installed ( pyyaml >= 5.1) pyyaml is installed to your pip instance:
``` bash
python3 -m pip install pyyaml
amd-smi list
```bash
python3 -m pip install argcomplete
activate-global-python-argcomplete
# restart shell to enable
```
While the CLI will work with these older python versions, to install the python development library you need to upgrade to python 3.7+
### Manual/Multiple Rocm Instance Python Library Install
In the event there are multiple rocm installations and pyenv is not being used, to use the correct amdsmi version you must uninstall previous versions of amd-smi and install the version you want directly from your rocm instance.
#### Python Library Install Example for Ubuntu 22.04
Remove previous amdsmi installation:
```bash
python3 -m pip list | grep amd
python3 -m pip uninstall amdsmi
```
Then install Python library from your target rocm instance:
``` bash
apt install amd-smi-lib
amd-smi --help
@@ -73,6 +59,8 @@ python3 -m pip install --upgrade pip
python3 -m pip install --user .
```
Now you have the amdsmi python library in your python path:
``` bash
~$ python3
Python 3.8.10 (default, May 26 2023, 14:05:08)
@@ -132,8 +120,8 @@ GPU with some basic information for each VF.
optional arguments:
-h, --help show this help message and exit
-g, --gpu GPU [GPU ...] Select a GPU ID, BDF, or UUID from the possible choices:
ID:0 | BDF:0000:23:00.0 | UUID:ffff73bf-0000-1000-80ff-ffffffffffff
all | Selects all devices
ID: 0 | BDF:0000:23:00.0 | UUID:ffff73bf-0000-1000-80ff-ffffffffffff
all | Selects all devices
Command Modifiers:
--json Displays output in JSON format (human readable by default).
@@ -155,8 +143,8 @@ 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 ...] Select a GPU ID, BDF, or UUID from the possible choices:
ID:0 | BDF:0000:23:00.0 | UUID:ffff73bf-0000-1000-80ff-ffffffffffff
all | Selects all devices
ID: 0 | BDF:0000:23:00.0 | UUID:ffff73bf-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)
@@ -187,8 +175,8 @@ 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 ...] Select a GPU ID, BDF, or UUID from the possible choices:
ID:0 | BDF:0000:23:00.0 | UUID:ffff73bf-0000-1000-80ff-ffffffffffff
all | Selects all devices
ID: 0 | BDF:0000:23:00.0 | UUID:ffff73bf-0000-1000-80ff-ffffffffffff
all | Selects all devices
-f, --ucode-list, --fw-list All FW list information
Command Modifiers:
@@ -209,8 +197,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 ...] Select a GPU ID, BDF, or UUID from the possible choices:
ID:0 | BDF:0000:23:00.0 | UUID:ffff73bf-0000-1000-80ff-ffffffffffff
all | Selects all devices
ID: 0 | BDF:0000:23:00.0 | UUID:ffff73bf-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
@@ -235,8 +223,8 @@ 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 ...] Select a GPU ID, BDF, or UUID from the possible choices:
ID:0 | BDF:0000:23:00.0 | UUID:ffff73bf-0000-1000-80ff-ffffffffffff
all | Selects all devices
ID: 0 | BDF:0000:23:00.0 | UUID:ffff73bf-0000-1000-80ff-ffffffffffff
all | Selects all devices
-w, --watch INTERVAL Reprint the command in a loop of INTERVAL seconds
-W, --watch_time TIME The total TIME to watch the given command
-i, --iterations ITERATIONS Total number of ITERATIONS to loop on the given command
@@ -275,8 +263,8 @@ 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 ...] Select a GPU ID, BDF, or UUID from the possible choices:
ID: 0 | BDF: 0000:23:00.0 | UUID: c4ff73bf-0000-1000-802e-0812b504ed69
all | Selects all devices
ID: 0 | BDF:0000:23:00.0 | UUID:ffff73bf-0000-1000-80ff-ffffffffffff
all | Selects all devices
-w, --watch INTERVAL Reprint the command in a loop of INTERVAL seconds
-W, --watch_time TIME The total TIME to watch the given command
-i, --iterations ITERATIONS Total number of ITERATIONS to loop on the given command
@@ -304,8 +292,8 @@ If no GPU is specified, returns event information for all GPUs on the system.
Event Arguments:
-h, --help show this help message and exit
-g, --gpu GPU [GPU ...] Select a GPU ID, BDF, or UUID from the possible choices:
ID:0 | BDF:0000:23:00.0 | UUID:ffff73bf-0000-1000-80ff-ffffffffffff
all | Selects all devices
ID: 0 | BDF:0000:23:00.0 | UUID:ffff73bf-0000-1000-80ff-ffffffffffff
all | Selects all devices
Command Modifiers:
--json Displays output in JSON format (human readable by default).
@@ -326,8 +314,8 @@ 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 ...] Select a GPU ID, BDF, or UUID from the possible choices:
ID:0 | BDF:0000:23:00.0 | UUID:ffff73bf-0000-1000-80ff-ffffffffffff
all | Selects all devices
ID: 0 | BDF:0000:23:00.0 | UUID:ffff73bf-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
@@ -355,8 +343,8 @@ 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 ...] Select a GPU ID, BDF, or UUID from the possible choices:
ID: 0 | BDF: 0000:23:00.0 | UUID: c4ff73bf-0000-1000-802e-0812b504ed69
all | Selects all devices
ID: 0 | BDF:0000:23:00.0 | UUID:ffff73bf-0000-1000-80ff-ffffffffffff
all | Selects all devices
-f, --fan % Set GPU fan speed (0-255 or 0-100%)
-l, --perf-level LEVEL Set performance level
-P, --profile SETPROFILE Set power profile level (#) or a quoted string of custom profile attributes
@@ -386,8 +374,8 @@ 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 ...] Select a GPU ID, BDF, or UUID from the possible choices:
ID: 0 | BDF: 0000:23:00.0 | UUID: c4ff73bf-0000-1000-802e-0812b504ed69
all | Selects all devices
ID: 0 | BDF:0000:23:00.0 | UUID:ffff73bf-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
+1 -1
View File
@@ -1 +1 @@
__version__ = "23.4.0.0"
from _version import __version__
-1
View File
@@ -1 +0,0 @@
__version__ = "23.4.0.0"
@@ -0,0 +1 @@
__version__ = "@amd_smi_libraries_VERSION_STRING@"
+154 -83
View File
@@ -20,7 +20,6 @@
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
import argparse
import logging
import sys
import threading
@@ -51,8 +50,12 @@ class AMDSMICommands():
sys.exit(-1)
else:
raise e
if len(self.device_handles) == 0:
logging.error('Unable to detect any devices, check if driver is initialized (amdgpu not found in modules)')
sys.exit(-1)
self.stop = ''
self.all_arguments = False
def version(self, args):
@@ -133,7 +136,8 @@ class AMDSMICommands():
def static(self, args, multiple_devices=False, gpu=None, asic=None,
bus=None, vbios=None, limit=None, driver=None, ras=None,
board=None, numa=None, vram=None, cache=None, partition=None):
board=None, numa=None, vram=None, cache=None, partition=None,
dfc_ucode=None, fb_info=None, num_vf=None):
"""Get Static information for target gpu
Args:
@@ -151,6 +155,9 @@ class AMDSMICommands():
vram (bool, optional): Value override for args.vram. Defaults to None.
cache (bool, optional): Value override for args.cache. Defaults to None.
partition (bool, optional): Value override for args.partition. Defaults to None.
dfc_ucode (bool, optional): Value override for args.dfc_ucode. Defaults to None.
fb_info (bool, optional): Value override for args.fb_info. Defaults to None.
num_vf (bool, optional): Value override for args.num_vf. Defaults to None.
Raises:
IndexError: Index error if gpu list is empty
@@ -167,8 +174,6 @@ class AMDSMICommands():
args.bus = bus
if vbios:
args.vbios = vbios
if numa:
args.numa = numa
if board:
args.board = board
if driver:
@@ -177,6 +182,11 @@ class AMDSMICommands():
args.vram = vram
if cache:
args.cache = cache
# Store args that are applicable to the current platform
current_platform_args = ["asic", "bus", "vbios", "driver", "vram", "cache", "board"]
current_platform_values = [args.asic, args.bus, args.vbios, args.driver, args.vram, args.cache, args.board]
if self.helpers.is_linux() and self.helpers.is_baremetal():
if ras:
args.ras = ras
@@ -184,6 +194,24 @@ class AMDSMICommands():
args.partition = partition
if limit:
args.limit = limit
current_platform_args += ["ras", "limit", "partition"]
current_platform_values += [args.ras, args.limit, args.partition]
if self.helpers.is_linux() and not self.helpers.is_virtual_os():
if numa:
args.numa = numa
current_platform_args += ["numa"]
current_platform_values += [args.numa]
if self.helpers.is_hypervisor():
if dfc_ucode:
args.dfc_ucode = dfc_ucode
if fb_info:
args.fb_info = fb_info
if num_vf:
args.num_vf = num_vf
current_platform_args += ["dfc_ucode", "fb_info", "num_vf"]
current_platform_values += [args.dfc_ucode, args.fb_info, args.num_vf]
# Handle No GPU passed
if args.gpu == None:
@@ -195,19 +223,19 @@ class AMDSMICommands():
return # This function is recursive
args.gpu = device_handle
# If all arguments are False, it means that no argument was passed and the entire static should be printed
if self.helpers.is_linux() and self.helpers.is_baremetal():
if not any([args.asic, args.bus, args.vbios, args.limit, args.board, args.ras, args.driver, args.numa, args.vram, args.cache, args.partition]):
args.asic = args.bus = args.vbios = args.limit = args.board = args.ras = args.driver = args.numa = args.vram = args.cache = args.partition = self.all_arguments = True
if self.helpers.is_linux() and self.helpers.is_virtual_os():
if not any([args.asic, args.bus, args.vbios, args.board, args.driver, args.vram, args.cache]):
args.asic = args.bus = args.vbios = args.board = args.driver = args.vram = args.cache = self.all_arguments = True
static_dict = {}
# Get gpu_id for logging
gpu_id = self.helpers.get_gpu_id_from_device_handle(args.gpu)
logging.debug(f"Static Arg information for GPU {gpu_id} on {self.helpers.os_info()}")
logging.debug(f"Applicable Args: {current_platform_args}")
logging.debug(f"Arg Values: {current_platform_values}")
# Set the platform applicable args to True if no args are set
if not any(current_platform_values):
for arg in current_platform_args:
setattr(args, arg, True)
static_dict = {}
if args.asic:
try:
asic_info = amdsmi_interface.amdsmi_get_gpu_asic_info(args.gpu)
@@ -284,8 +312,7 @@ class AMDSMICommands():
static_dict['board'] = board_info
except amdsmi_exception.AmdSmiLibraryException as e:
logging.debug("Failed to get board info for gpu %s | %s", gpu_id, e.get_error_info())
if self.helpers.is_linux() and self.helpers.is_baremetal():
if 'limit' in current_platform_args:
if args.limit:
# Power limits
try:
@@ -398,7 +425,6 @@ class AMDSMICommands():
limit_info['shutdown_hotspot_temperature'] = shutdown_temp_hotspot_limit
limit_info['shutdown_vram_temperature'] = shutdown_temp_vram_limit
static_dict['limit'] = limit_info
if args.driver:
driver_info = {"driver_name" : "N/A",
"driver_version" : "N/A",
@@ -445,16 +471,24 @@ class AMDSMICommands():
if args.cache:
try:
cache_info = amdsmi_interface.amdsmi_get_gpu_cache_info(args.gpu)
for cache_key, cache_dict in cache_info.items():
for key, value in cache_dict.items():
if key == 'cache_size' or key == 'cache_level':
continue
if value:
cache_info[cache_key][key] = "ENABLED"
else:
cache_info[cache_key][key] = "DISABLED"
if self.logger.is_human_readable_format():
for _ , cache_values in cache_info.items():
cache_values['cache_size'] = f"{cache_values['cache_size']} KB"
except amdsmi_exception.AmdSmiLibraryException as e:
cache_info = "N/A"
logging.debug("Failed to get cache info for gpu %s | %s", gpu_id, e.get_error_info())
static_dict['cache'] = cache_info
if self.helpers.is_hypervisor() or self.helpers.is_baremetal():
if 'ras' in current_platform_args:
if args.ras:
ras_dict = {"eeprom_version": "N/A",
"parity_schema" : "N/A",
@@ -467,7 +501,7 @@ class AMDSMICommands():
ras_info = amdsmi_interface.amdsmi_get_gpu_ras_feature_info(args.gpu)
for key, value in ras_info.items():
if isinstance(value, int):
if value >= 65535:
if value == 65535 or value == 0:
logging.debug(f"Failed to get ras {key} for gpu {gpu_id}")
ras_info[key] = "N/A"
continue
@@ -483,6 +517,7 @@ class AMDSMICommands():
logging.debug("Failed to get ras block features for gpu %s | %s", gpu_id, e.get_error_info())
static_dict["ras"] = ras_dict
if 'partition' in current_platform_args:
if args.partition:
try:
compute_partition = amdsmi_interface.amdsmi_dev_compute_partition_get(args.gpu)
@@ -498,8 +533,7 @@ class AMDSMICommands():
static_dict['partition'] = {"compute_partition": compute_partition,
"memory_partition": memory_partition}
if self.helpers.is_linux() and self.helpers.is_baremetal():
if 'numa' in current_platform_args:
if args.numa:
try:
numa_node_number = amdsmi_interface.amdsmi_topo_get_numa_node_number(args.gpu)
@@ -592,12 +626,11 @@ class AMDSMICommands():
for fw_index, fw_entry in enumerate(fw_info['fw_list']):
# Change fw_name to fw_id
fw_entry['fw_id'] = fw_entry.pop('fw_name').name.strip('FW_ID_')
fw_entry['fw_version'] = fw_entry.pop('fw_version')
firmware_identifier = 'FW'
fw_entry['fw_version'] = fw_entry.pop('fw_version') # popping to ensure order
# 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}
fw_info['fw_list'][fw_index] = {f'FW {fw_index}': fw_entry}
else:
fw_info['fw_list'][fw_index] = fw_entry
@@ -750,7 +783,8 @@ class AMDSMICommands():
usage=None, watch=None, watch_time=None, iterations=None, power=None,
clock=None, temperature=None, ecc=None, ecc_block=None, pcie=None,
fan=None, voltage_curve=None, overdrive=None, perf_level=None,
xgmi_err=None, energy=None, mem_usage=None):
xgmi_err=None, energy=None, mem_usage=None, schedule=None,
guard=None, guest_data=None, fb_usage=None, xgmi=None,):
"""Get Metric information for target gpu
Args:
@@ -775,6 +809,11 @@ class AMDSMICommands():
xgmi_err (bool, optional): Value override for args.xgmi_err. Defaults to None.
energy (bool, optional): Value override for args.energy. Defaults to None.
mem_usage (bool, optional): Value override for args.mem_usage. Defaults to None.
schedule (bool, optional): Value override for args.schedule. Defaults to None.
guard (bool, optional): Value override for args.guard. Defaults to None.
guest_data (bool, optional): Value override for args.guest_data. Defaults to None.
fb_usage (bool, optional): Value override for args.fb_usage. Defaults to None.
xgmi (bool, optional): Value override for args.xgmi. Defaults to None.
Raises:
IndexError: Index error if gpu list is empty
@@ -791,11 +830,18 @@ class AMDSMICommands():
args.watch_time = watch_time
if iterations:
args.iterations = iterations
if self.helpers.is_linux():
# Store args that are applicable to the current platform
current_platform_args = []
current_platform_values = []
if not self.helpers.is_hypervisor() and not self.helpers.is_windows():
if mem_usage:
args.mem_usage = mem_usage
current_platform_args += ["mem_usage"]
current_platform_values += [args.mem_usage]
if self.helpers.is_linux() and self.helpers.is_baremetal():
if self.helpers.is_hypervisor() or self.helpers.is_baremetal():
if usage:
args.usage = usage
if power:
@@ -806,10 +852,14 @@ class AMDSMICommands():
args.temperature = temperature
if ecc:
args.ecc = ecc
if ecc_block:
args.ecc_block = ecc_block
if pcie:
args.pcie = pcie
current_platform_args += ["usage", "power", "clock", "temperature", "ecc", "pcie"]
current_platform_values += [args.usage, args.power, args.clock, args.temperature, args.ecc, args.pcie]
if self.helpers.is_baremetal() and self.helpers.is_linux():
if ecc_block:
args.ecc_block = ecc_block
if fan:
args.fan = fan
if voltage_curve:
@@ -822,6 +872,22 @@ class AMDSMICommands():
args.xgmi_err = xgmi_err
if energy:
args.energy = energy
current_platform_args += ["ecc_block", "fan", "voltage_curve", "overdrive", "perf_level", "xgmi_err", "energy"]
current_platform_values += [args.ecc_block, args.fan, args.voltage_curve, args.overdrive, args.perf_level, args.xgmi_err, args.energy]
if self.helpers.is_hypervisor():
if schedule:
args.schedule = schedule
if guard:
args.guard = guard
if guest_data:
args.guest_data = guest_data
if fb_usage:
args.fb_usage = fb_usage
if xgmi:
args.xgmi = xgmi
current_platform_args += ["schedule", "guard", "guest_data", "fb_usage", "xgmi"]
current_platform_values += [args.schedule, args.guard, args.guest_data, args.fb_usage, args.xgmi]
# Handle No GPU passed
if args.gpu == None:
@@ -863,31 +929,27 @@ class AMDSMICommands():
else:
raise IndexError("args.gpu should not be an empty list")
# Check if any of the options have been set, if not then set them all to true
if self.helpers.is_linux() and self.helpers.is_virtual_os():
if not any([args.mem_usage]):
args.mem_usage = self.all_arguments = True
if self.helpers.is_linux() and self.helpers.is_baremetal():
if not any([args.usage, args.mem_usage, args.power, args.clock, args.temperature,
args.ecc, args.ecc_block, args.pcie, args.fan, args.voltage_curve,
args.overdrive, args.perf_level, args.xgmi_err, args.energy]):
args.usage = args.mem_usage = args.power = args.clock = args.temperature = \
args.ecc = args.ecc_block = args.pcie = args.fan = args.voltage_curve = \
args.overdrive = args.perf_level = args.xgmi_err = args.energy = \
self.all_arguments = True
# 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)
# Put the metrics table in the debug logs
try:
logging.debug("GPU Metrics table for %s | %s", gpu_id, amdsmi_interface.amdsmi_get_gpu_metrics_info(args.gpu))
except amdsmi_exception.AmdSmiLibraryException as e:
logging.debug("Unabled to load GPU Metrics table for %s | %s", gpu_id, e.err_info)
if self.helpers.is_linux() and self.helpers.is_baremetal():
logging.debug(f"Metric Arg information for GPU {gpu_id} on {self.helpers.os_info()}")
logging.debug(f"Args: {current_platform_args}")
logging.debug(f"Values: {current_platform_values}")
# Set the platform applicable args to True if no args are set
if not any(current_platform_values):
for arg in current_platform_args:
setattr(args, arg, True)
# Add timestamp and store values for specified arguments
values_dict = {}
if "usage" in current_platform_args:
if args.usage:
try:
engine_usage = amdsmi_interface.amdsmi_get_gpu_activity(args.gpu)
@@ -896,7 +958,7 @@ class AMDSMICommands():
engine_usage['mm_ip_usage'] = engine_usage.pop('mm_activity')
for key, value in engine_usage.items():
if value >= 65535:
if value == 65535:
engine_usage[key] = "N/A"
if self.logger.is_human_readable_format():
@@ -908,6 +970,7 @@ class AMDSMICommands():
except amdsmi_exception.AmdSmiLibraryException as e:
values_dict['usage'] = "N/A"
logging.debug("Failed to get gpu activity for gpu %s | %s", gpu_id, e.get_error_info())
if "power" in current_platform_args:
if args.power:
power_dict = {'current_power': "N/A",
'current_gfx_voltage': "N/A",
@@ -946,6 +1009,7 @@ class AMDSMICommands():
logging.debug("Failed to get power management status for gpu %s | %s", gpu_id, e.get_error_info())
values_dict['power'] = power_dict
if "clock" in current_platform_args:
if args.clock:
clocks = {}
clock_types = [amdsmi_interface.AmdSmiClkType.GFX,
@@ -1005,6 +1069,7 @@ class AMDSMICommands():
clocks['gfx'] = {"is_clk_locked": is_clk_locked}
values_dict['clock'] = clocks
if "temperature" in current_platform_args:
if args.temperature:
try:
temperature_edge_current = amdsmi_interface.amdsmi_get_temp_metric(
@@ -1049,6 +1114,7 @@ class AMDSMICommands():
temperatures[temperature_key] = f"{temperature_value} {unit}"
values_dict['temperature'] = temperatures
if "ecc" in current_platform_args:
if args.ecc:
ecc_count = {}
try:
@@ -1061,29 +1127,7 @@ class AMDSMICommands():
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:
ecc_dict = {}
uncountable_blocks = ["ATHUB", "DF", "SMN", "SEM", "MP0", "MP1", "FUSE"]
try:
ras_states = amdsmi_interface.amdsmi_get_gpu_ras_block_features_enabled(args.gpu)
for state in ras_states:
if state['status'] == amdsmi_interface.AmdSmiRasErrState.ENABLED.name:
gpu_block = amdsmi_interface.AmdSmiGpuBlock[state['block']]
# if the blocks are uncountable do not add them at all.
if gpu_block.name not in uncountable_blocks:
try:
ecc_count = amdsmi_interface.amdsmi_get_gpu_ecc_count(args.gpu, gpu_block)
ecc_dict[state['block']] = {'correctable' : ecc_count['correctable_count'],
'uncorrectable': ecc_count['uncorrectable_count']}
except amdsmi_exception.AmdSmiLibraryException as e:
ecc_dict[state['block']] = {'correctable' : "N/A",
'uncorrectable': "N/A"}
logging.debug("Failed to get ecc count for gpu %s at block %s | %s", gpu_id, gpu_block, e.get_error_info())
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", gpu_id, e.get_error_info())
if "pcie" in current_platform_args:
if args.pcie:
pcie_dict = {"current_lanes": "N/A",
"current_speed": "N/A",
@@ -1092,8 +1136,8 @@ class AMDSMICommands():
"replay_roll_over_count" : "N/A",
"nak_sent_count" : "N/A",
"nak_received_count" : "N/A",
"current_bandwith_sent": "N/A",
"current_bandwith_received": "N/A",
"current_bandwidth_sent": "N/A",
"current_bandwidth_received": "N/A",
"max_packet_size": "N/A"}
try:
@@ -1161,13 +1205,38 @@ class AMDSMICommands():
received = f"{received} MB/s"
pcie_bw['max_pkt_sz'] = f"{pcie_bw['max_pkt_sz']} B"
pcie_dict['current_bandwith_sent'] = sent
pcie_dict['current_bandwith_received'] = received
pcie_dict['current_bandwidth_sent'] = sent
pcie_dict['current_bandwidth_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", gpu_id, e.get_error_info())
values_dict['pcie'] = pcie_dict
if "ecc_block" in current_platform_args:
if args.ecc_block:
ecc_dict = {}
uncountable_blocks = ["ATHUB", "DF", "SMN", "SEM", "MP0", "MP1", "FUSE"]
try:
ras_states = amdsmi_interface.amdsmi_get_gpu_ras_block_features_enabled(args.gpu)
for state in ras_states:
if state['status'] == amdsmi_interface.AmdSmiRasErrState.ENABLED.name:
gpu_block = amdsmi_interface.AmdSmiGpuBlock[state['block']]
# if the blocks are uncountable do not add them at all.
if gpu_block.name not in uncountable_blocks:
try:
ecc_count = amdsmi_interface.amdsmi_get_gpu_ecc_count(args.gpu, gpu_block)
ecc_dict[state['block']] = {'correctable' : ecc_count['correctable_count'],
'uncorrectable': ecc_count['uncorrectable_count']}
except amdsmi_exception.AmdSmiLibraryException as e:
ecc_dict[state['block']] = {'correctable' : "N/A",
'uncorrectable': "N/A"}
logging.debug("Failed to get ecc count for gpu %s at block %s | %s", gpu_id, gpu_block, e.get_error_info())
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", gpu_id, e.get_error_info())
if "fan" in current_platform_args:
if args.fan:
fan_dict = {"speed" : "N/A",
"max" : "N/A",
@@ -1200,6 +1269,7 @@ class AMDSMICommands():
logging.debug("Failed to get fan rpms for gpu %s | %s", args.gpu, e.get_error_info())
values_dict["fan"] = fan_dict
if "voltage_curve" in current_platform_args:
if args.voltage_curve:
try:
od_volt = amdsmi_interface.amdsmi_get_gpu_od_volt_info(args.gpu)
@@ -1219,6 +1289,7 @@ class AMDSMICommands():
except amdsmi_exception.AmdSmiLibraryException as e:
values_dict['voltage_curve'] = "N/A"
logging.debug("Failed to get voltage curve for gpu %s | %s", gpu_id, e.get_error_info())
if "overdrive" in current_platform_args:
if args.overdrive:
try:
overdrive_level = amdsmi_interface.amdsmi_get_gpu_overdrive_level(args.gpu)
@@ -1231,6 +1302,7 @@ class AMDSMICommands():
except amdsmi_exception.AmdSmiLibraryException as e:
values_dict['overdrive'] = "N/A"
logging.debug("Failed to get overdrive level for gpu %s | %s", gpu_id, e.get_error_info())
if "perf_level" in current_platform_args:
if args.perf_level:
try:
perf_level = amdsmi_interface.amdsmi_get_gpu_perf_level(args.gpu)
@@ -1238,8 +1310,7 @@ class AMDSMICommands():
except amdsmi_exception.AmdSmiLibraryException as e:
values_dict['perf_level'] = "N/A"
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 "xgmi_err" in current_platform_args:
if args.xgmi_err:
try:
xgmi_err_status = amdsmi_interface.amdsmi_gpu_xgmi_error_status(args.gpu)
@@ -1247,6 +1318,7 @@ class AMDSMICommands():
except amdsmi_exception.AmdSmiLibraryException as e:
values_dict['xgmi_err'] = "N/A"
logging.debug("Failed to get xgmi error status for gpu %s | %s", gpu_id, e.get_error_info())
if "energy" in current_platform_args:
if args.energy:
try:
energy_dict = amdsmi_interface.amdsmi_get_energy_count(args.gpu)
@@ -1263,8 +1335,7 @@ class AMDSMICommands():
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 "mem_usage" in current_platform_args:
if args.mem_usage:
unit = 'MB'
memory_usage = {'total_vram': "N/A",
@@ -1560,8 +1631,8 @@ class AMDSMICommands():
print('Press q and hit ENTER when you want to stop (listening will stop within 10 seconds)')
threads = []
for gpu in range(len(args.gpu)):
x = threading.Thread(target=self._event_thread, args=(self, gpu))
for device_handle in range(len(args.gpu)):
x = threading.Thread(target=self._event_thread, args=(self, device_handle))
threads.append(x)
x.start()
+6 -2
View File
@@ -154,6 +154,10 @@ class AMDSMIHelpers():
else:
raise e
if len(device_handles) == 0:
logging.error('Unable to find any devices, check if driver is initialized (amdgpu not found in modules)')
sys.exit(-1)
# Handle spacing for the gpu_choices_str
max_padding = int(math.log10(len(device_handles))) + 1
@@ -170,11 +174,11 @@ class AMDSMIHelpers():
id_padding = max_padding
else:
id_padding = max_padding - int(math.log10(gpu_id))
gpu_choices_str += f"\tID: {gpu_id}{' ' * id_padding}| BDF: {bdf} | UUID: {uuid}\n"
gpu_choices_str += f"ID: {gpu_id}{' ' * id_padding}| BDF: {bdf} | UUID: {uuid}\n"
# Add the all option to the gpu_choices
gpu_choices["all"] = "all"
gpu_choices_str += f"\t all{' ' * max_padding}| Selects all devices\n"
gpu_choices_str += f" all{' ' * max_padding}| Selects all devices\n"
return (gpu_choices, gpu_choices_str)
+1 -1
View File
@@ -30,8 +30,8 @@ import sys
from pathlib import Path
sys.path.append(f"{Path(__file__).resolve().parent}/../../share/amd_smi")
sys.path.append("/opt/rocm/share/amd_smi")
# If the python library is installed, it will overwrite the path above
from amdsmi import amdsmi_interface
from amdsmi import amdsmi_exception
+15 -13
View File
@@ -116,6 +116,7 @@ class AMDSMIParser(argparse.ArgumentParser):
outputformat = self.helpers.get_output_format()
raise amdsmi_cli_exceptions.AmdSmiInvalidParameterValueException(int_value, outputformat)
def _positive_int(self, int_value):
# Argument type validator
if int_value.isdigit(): # Is digit doesn't work on negative numbers
@@ -365,9 +366,10 @@ class AMDSMIParser(argparse.ArgumentParser):
if self.helpers.is_hypervisor() or self.helpers.is_baremetal():
static_parser.add_argument('-r', '--ras', action='store_true', required=False, help=ras_help)
static_parser.add_argument('-p', '--partition', action='store_true', required=False, help=partition_help)
if self.helpers.is_linux():
static_parser.add_argument('-l', '--limit', action='store_true', required=False, help=limit_help)
static_parser.add_argument('-u', '--numa', action='store_true', required=False, help=numa_help)
static_parser.add_argument('-l', '--limit', action='store_true', required=False, help=limit_help)
if self.helpers.is_linux() and not self.helpers.is_virtual_os():
static_parser.add_argument('-u', '--numa', action='store_true', required=False, help=numa_help)
# Options to only display on a Hypervisor
if self.helpers.is_hypervisor():
@@ -445,7 +447,7 @@ class AMDSMIParser(argparse.ArgumentParser):
# Optional arguments help text
usage_help = "Displays engine usage information"
# Help text for Arguments only Available on Virtual OS and Baremetal platforms
# Help text for Arguments only Available on Linux Virtual OS and Baremetal platforms
mem_usage_help = "Memory usage per block"
# Help text for Arguments only on Hypervisor and Baremetal platforms
@@ -467,7 +469,9 @@ class AMDSMIParser(argparse.ArgumentParser):
# Help text for Arguments only on Hypervisors
schedule_help = "All scheduling information"
guard_help = "All guard information"
guest_help = "All guest data information"
guest_data_help = "All guest data information"
fb_usage_help = "Displays total and used Frame Buffer usage information"
xgmi_help = "Table of current XGMI metrics information"
# Create metric subparser
metric_parser = subparsers.add_parser('metric', help=metric_help, description=metric_subcommand_help)
@@ -482,8 +486,8 @@ class AMDSMIParser(argparse.ArgumentParser):
# Add Watch args
self._add_watch_arguments(metric_parser)
# Optional Args for Virtual OS and Baremetal systems
if self.helpers.is_virtual_os() or self.helpers.is_baremetal():
# Optional Args for Linux Virtual OS and Baremetal systems
if not self.helpers.is_hypervisor() and not self.helpers.is_windows():
metric_parser.add_argument('-m', '--mem-usage', action='store_true', required=False, help=mem_usage_help)
# Optional Args for Hypervisors and Baremetal systems
@@ -493,11 +497,11 @@ class AMDSMIParser(argparse.ArgumentParser):
metric_parser.add_argument('-c', '--clock', action='store_true', required=False, help=clock_help)
metric_parser.add_argument('-t', '--temperature', action='store_true', required=False, help=temperature_help)
metric_parser.add_argument('-e', '--ecc', action='store_true', required=False, help=ecc_help)
metric_parser.add_argument('-k', '--ecc-block', action='store_true', required=False, help=ecc_block_help)
metric_parser.add_argument('-P', '--pcie', action='store_true', required=False, help=pcie_help)
# Optional Args for Linux Baremetal Systems
if self.helpers.is_baremetal() and self.helpers.is_linux():
metric_parser.add_argument('-k', '--ecc-block', action='store_true', required=False, help=ecc_block_help)
metric_parser.add_argument('-f', '--fan', action='store_true', required=False, help=fan_help)
metric_parser.add_argument('-C', '--voltage-curve', action='store_true', required=False, help=vc_help)
metric_parser.add_argument('-o', '--overdrive', action='store_true', required=False, help=overdrive_help)
@@ -509,7 +513,9 @@ class AMDSMIParser(argparse.ArgumentParser):
if self.helpers.is_hypervisor():
metric_parser.add_argument('-s', '--schedule', action='store_true', required=False, help=schedule_help)
metric_parser.add_argument('-G', '--guard', action='store_true', required=False, help=guard_help)
metric_parser.add_argument('-u', '--guest', action='store_true', required=False, help=guest_help)
metric_parser.add_argument('-u', '--guest-data', action='store_true', required=False, help=guest_data_help)
metric_parser.add_argument('-f', '--fb_usage', action='store_true', required=False, help=fb_usage_help)
metric_parser.add_argument('-m', '--xgmi', action='store_true', required=False, help=xgmi_help)
def _add_process_parser(self, subparsers, func):
@@ -574,10 +580,6 @@ class AMDSMIParser(argparse.ArgumentParser):
def _add_event_parser(self, subparsers, func):
if self.helpers.is_virtual_os():
# This subparser doesn't only apply to guest systems
return
# Subparser help text
event_help = "Displays event information for the given GPU"
event_subcommand_help = "If no GPU is specified, returns event information for all GPUs on the system."
@@ -57,7 +57,7 @@ function(generic_package)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DFORTIFY_SOURCE=2 -fstack-protector-all -Wcast-align" PARENT_SCOPE)
## More security breach mitigation flags
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,-z,noexecstack -Wl,-znoexecheap -Wl,-z,relro" PARENT_SCOPE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wtrampolines -Wl,-z,now -fPIE" PARENT_SCOPE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wtrampolines -Wl,-z,now" PARENT_SCOPE)
endif()
# Clang does not set the build-id
@@ -159,6 +159,7 @@ function(get_package_version_number DEFAULT_VERSION_STRING VERSION_PREFIX GIT)
endif()
set(PKG_VERSION_STR "${PKG_VERSION_STR}-${VERSION_HASH}")
set(PKG_VERSION_STR ${PKG_VERSION_STR} PARENT_SCOPE)
set(PKG_VERSION_HASH ${VERSION_HASH} PARENT_SCOPE)
set(CPACK_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR} PARENT_SCOPE)
set(CPACK_PACKAGE_VERSION_MINOR ${VERSION_MINOR} PARENT_SCOPE)
set(CPACK_PACKAGE_VERSION_PATCH ${VERSION_PATCH} PARENT_SCOPE)
+3
View File
@@ -9,3 +9,6 @@
/latex/
404.md
data/AMD-404.png
# file below is overwritten by sphinx script!
./esmi_lib_readme_link.md
+15
View File
@@ -6,8 +6,20 @@
import subprocess
import urllib
from rocm_docs import ROCmDocs
esmi_readme_link = "https://raw.githubusercontent.com/amd/esmi_ib_library/master/docs/README.md"
try:
# Try to override esmi_lib_readme_link.md with the github esmi readme contents
with urllib.request.urlopen(esmi_readme_link) as f:
esmi_readme = f.read().decode('utf-8')
with open("./esmi_lib_readme_link.md", "w", encoding='utf-8') as f:
f.write(esmi_readme)
except urllib.error.URLError:
# don't care about the error because there is backup link in the file already
pass
get_version_year = r'sed -n -e "s/^#define\ AMDSMI_LIB_VERSION_YEAR\ //p" ../include/amd_smi/amdsmi.h'
get_version_major = r'sed -n -e "s/^#define\ AMDSMI_LIB_VERSION_MAJOR\ //p" ../include/amd_smi/amdsmi.h'
@@ -25,6 +37,9 @@ docs_core = ROCmDocs(f"{name} Documentation")
docs_core.run_doxygen(doxygen_root="doxygen", doxygen_path="doxygen/docBin/xml")
docs_core.enable_api_reference()
docs_core.setup()
docs_core.html_theme_options = {
"repository_url": "https://github.com/RadeonOpenCompute/amdsmi"
}
for sphinx_var in ROCmDocs.SPHINX_VARS:
globals()[sphinx_var] = getattr(docs_core, sphinx_var)
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,3 @@
# ESMI Library README
For more information, see the [ESMI Library README](https://raw.githubusercontent.com/am/esmi_ib_library/master/docs/README.md)
+4
View File
@@ -17,6 +17,10 @@ subtrees:
title: Python CLI Tool
- file: amdsmi_release_notes_link
title: Python CLI Release Notes
- caption: Libraries
entries:
- file: esmi_lib_readme_link
title: ESMI Library
- caption: About
entries:
- file: license
+2 -2
View File
@@ -47,7 +47,7 @@ fastjsonschema==2.17.1
# via rocm-docs-core
gitdb==4.0.10
# via gitpython
gitpython==3.1.31
gitpython==3.1.37
# via rocm-docs-core
idna==3.4
# via requests
@@ -110,7 +110,7 @@ requests==2.30.0
# via
# pygithub
# sphinx
rocm-docs-core[api_reference]>=0.20.0
rocm-docs-core[api_reference]>=0.26.0
# via -r requirements.in
smmap==5.0.0
# via gitdb
@@ -312,9 +312,10 @@ int main() {
CHK_AMDSMI_RET(ret)
printf(" Output of amdsmi_get_gpu_cache_info:\n");
for (unsigned int i = 0 ; i < cache_info.num_cache_types; i++) {
printf("\tCache Level: %d, Cache Size: %d KB\n",
printf("\tCache Level: %d, Cache Size: %d KB, Cache type: 0x%x\n",
cache_info.cache[i].cache_level,
cache_info.cache[i].cache_size_kb);
cache_info.cache[i].cache_size_kb,
cache_info.cache[i].flags);
}
// Get power measure
@@ -619,9 +620,11 @@ int main() {
std::cout << "\tdevice [" << j
<< "]\n\t\tProduct name: " << board_info.product_name
<< "\n"
<< "\t\tProduct number: " << board_info.product_serial
<< "\t\tModel Number: " << board_info.model_number
<< "\n"
<< "\t\tSerial number: " << board_info.serial_number
<< "\t\tBoard Serial: " << board_info.product_serial
<< "\n"
<< "\t\tManufacturer Name: " << board_info.manufacturer_name
<< "\n\n";
// Get temperature
@@ -302,9 +302,11 @@ int main() {
std::cout << "\tdevice [" << j
<< "]\n\t\tProduct name: " << board_info.product_name
<< "\n"
<< "\t\tProduct number: " << board_info.product_serial
<< "\t\tModel Number: " << board_info.model_number
<< "\n"
<< "\t\tSerial number: " << board_info.serial_number
<< "\t\tBoard Serial: " << board_info.product_serial
<< "\n"
<< "\t\tManufacturer Name: " << board_info.manufacturer_name
<< "\n\n";
// Get temperature
+27 -47
View File
@@ -455,11 +455,23 @@ typedef struct {
uint32_t reserved[16];
} amdsmi_vbios_info_t;
/**
* @brief cache flags
*/
typedef enum {
CACHE_FLAGS_ENABLED = 0x00000001,
CACHE_FLAGS_DATA_CACHE = 0x00000002,
CACHE_FLAGS_INST_CACHE = 0x00000004,
CACHE_FLAGS_CPU_CACHE = 0x00000008,
CACHE_FLAGS_SIMD_CACHE = 0x00000010,
} amdsmi_cache_flags_type_t;
typedef struct {
uint32_t num_cache_types;
struct cache_ {
uint32_t cache_size_kb; /* In KB */
uint32_t cache_level;
uint32_t flags; // amdsmi_cache_flags_type_t which is a bitmask
uint32_t reserved[3];
} cache[AMDSMI_MAX_CACHE_TYPES];
uint32_t reserved[15];
@@ -501,13 +513,12 @@ typedef struct {
} amdsmi_driver_info_t;
typedef struct {
uint64_t serial_number;
bool is_master;
char model_number[AMDSMI_NORMAL_STRING_LENGTH];
char product_serial[AMDSMI_NORMAL_STRING_LENGTH];
char fru_id[AMDSMI_NORMAL_STRING_LENGTH];
char product_name[AMDSMI_PRODUCT_NAME_LENGTH];
char manufacturer_name[AMDSMI_NORMAL_STRING_LENGTH];
char product_name[AMDSMI_PRODUCT_NAME_LENGTH];
} amdsmi_board_info_t;
typedef struct {
@@ -1470,6 +1481,20 @@ amdsmi_status_t amdsmi_get_socket_info(
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_get_cpusocket_info(amdsmi_cpusocket_handle socket_handle, uint32_t sockid);
/**
* @brief Get information about the given cpu core
*
* @details This function retrieves cpu core information. The @p core_handle must
* be provided to retrieve the core ID.
*
* @param[in] core_handle a processor handle
*
* @param[out] coreid The id of the core.
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_get_cpucore_info(amdsmi_processor_handle core_handle, uint32_t coreid);
#endif
/**
@@ -4589,51 +4614,6 @@ amdsmi_status_t amdsmi_get_metrics_table(amdsmi_cpusocket_handle socket_handle,
/*---------------------------------------------------------------------------*/
/** @{ */
/**
* @brief Get cpu family.
*
* @param[in,out] family - Input buffer to fill family
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_get_cpu_family(uint32_t family);
/**
* @brief Get cpu model.
*
* @param[in,out] family - Input buffer to fill family
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_get_cpu_model(uint32_t model);
/**
* @brief Get threads per core.
*
* @param[in,out] threads - Input buffer to fill threads count.
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_get_cpu_threads_per_core(uint32_t threads);
/**
* @brief Get number of cpus.
*
* @param[in,out] cpus - Input buffer to fill number of cpus.
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_get_number_of_cpu_cores(uint32_t cpus);
/**
* @brief Get number of sockets
*
* @param[in,out] sockets - Input buffer to fill number of sockets.
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_get_number_of_cpu_sockets(uint32_t sockets);
/**
* @brief Get first online core on socket.
*
@@ -60,14 +60,13 @@ public:
virtual ~AMDSmiCpuCore() {}
const uint32_t& get_core_id() const { return core_idx_; }
void add_processor(AMDSmiProcessor* processor) { processors_.push_back(processor); }
std::vector<AMDSmiProcessor*>& get_processors() { return processors_;}
amdsmi_status_t get_processor_count(uint32_t* processor_count) const;
private:
uint32_t core_idx_;
//uint64_t input;
//uint32_t idx;
std::vector<AMDSmiProcessor*> processors_;
};
+26 -19
View File
@@ -37,15 +37,10 @@ if(NOT GOOD_CLANG_FOUND)
${PY_PACKAGE_DIR}/amdsmi_wrapper.py
DEPENDS ${AMD_SMI}
${CMAKE_CURRENT_SOURCE_DIR}/amdsmi_wrapper.py
COMMAND cp -f ${CMAKE_CURRENT_SOURCE_DIR}/amdsmi_wrapper.py ${CMAKE_CURRENT_BINARY_DIR}/
# hacky alternative to configure_file that will run at MAKE compile instead of CMake configure
COMMAND sed -i
s:"@CPACK_PACKAGING_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@":"${CPACK_PACKAGING_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}":g
${CMAKE_CURRENT_BINARY_DIR}/amdsmi_wrapper.py
COMMAND mkdir -p ${PY_PACKAGE_DIR}
COMMAND ln -Pf ${CMAKE_CURRENT_BINARY_DIR}/amdsmi_wrapper.py ${PY_PACKAGE_DIR}/)
COMMAND ln -Pf ${CMAKE_CURRENT_SOURCE_DIR}/amdsmi_wrapper.py ${PY_PACKAGE_DIR}/)
else()
find_package(Python3 3.7 COMPONENTS Interpreter Development REQUIRED)
find_package(Python3 3.6 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")
@@ -67,46 +62,58 @@ else()
${PROJECT_SOURCE_DIR}/include/amd_smi/amdsmi.h
COMMAND cp ${PROJECT_SOURCE_DIR}/include/amd_smi/amdsmi.h ./
COMMAND ${Python3_EXECUTABLE} generator.py "$<$<BOOL:${ENABLE_ESMI_LIB}>:-e -DENABLE_ESMI_LIB>" -i amdsmi.h -l ${PROJECT_BINARY_DIR}/src/libamd_smi.so -o ${CMAKE_CURRENT_SOURCE_DIR}/amdsmi_wrapper.py
COMMAND cp -f ${CMAKE_CURRENT_SOURCE_DIR}/amdsmi_wrapper.py ${CMAKE_CURRENT_BINARY_DIR}/
# hacky alternative to configure_file that will run at MAKE compile instead of CMake configure
COMMAND sed -i
s:"@CPACK_PACKAGING_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@":"${CPACK_PACKAGING_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}":g
${CMAKE_CURRENT_BINARY_DIR}/amdsmi_wrapper.py
COMMAND mkdir -p ${PY_PACKAGE_DIR}
COMMAND ln -Pf ${CMAKE_CURRENT_BINARY_DIR}/amdsmi_wrapper.py ${PY_PACKAGE_DIR}/)
COMMAND ln -Pf ${CMAKE_CURRENT_SOURCE_DIR}/amdsmi_wrapper.py ${PY_PACKAGE_DIR}/)
endif()
# populate version string
configure_file(pyproject.toml.in ${PY_BUILD_DIR}/pyproject.toml @ONLY)
configure_file(setup.cfg.in ${PY_BUILD_DIR}/setup.cfg @ONLY)
add_custom_target(
python_wrapper
DEPENDS amdsmi_wrapper.py)
# hard-linking instead of copying avoids unnecessarry regeneration of packaged files
add_custom_command(
OUTPUT ${PY_BUILD_DIR}/pyproject.toml
${PY_PACKAGE_DIR}/__init__.py
OUTPUT ${PY_PACKAGE_DIR}/__init__.py
${PY_PACKAGE_DIR}/amdsmi_exception.py
${PY_PACKAGE_DIR}/amdsmi_interface.py
${PY_PACKAGE_DIR}/README.md
${PY_PACKAGE_DIR}/LICENSE
DEPENDS python_wrapper
COMMAND ln -Pf ${CMAKE_CURRENT_SOURCE_DIR}/pyproject.toml ${PY_BUILD_DIR}/
COMMAND ln -Pf ${CMAKE_CURRENT_SOURCE_DIR}/__init__.py ${PY_PACKAGE_DIR}/
COMMAND ln -Pf ${CMAKE_CURRENT_SOURCE_DIR}/amdsmi_exception.py ${PY_PACKAGE_DIR}/
COMMAND ln -Pf ${CMAKE_CURRENT_SOURCE_DIR}/amdsmi_interface.py ${PY_PACKAGE_DIR}/
COMMAND ln -Pf ${CMAKE_CURRENT_SOURCE_DIR}/README.md ${PY_PACKAGE_DIR}/
COMMAND ln -Pf ${PROJECT_SOURCE_DIR}/LICENSE ${PY_PACKAGE_DIR}/)
COMMAND ln -Pf ${PROJECT_SOURCE_DIR}/LICENSE ${PY_PACKAGE_DIR}/
)
# copy libamd_smi.so to allow for a self-contained python package
add_custom_command(
OUTPUT ${PY_PACKAGE_DIR}/libamd_smi.so
DEPENDS ${PROJECT_BINARY_DIR}/src/libamd_smi.so
COMMAND cp
"${PROJECT_BINARY_DIR}/src/libamd_smi.so"
${PY_PACKAGE_DIR}/
)
add_custom_target(
python_package ALL
DEPENDS ${PY_BUILD_DIR}/pyproject.toml
${PY_BUILD_DIR}/setup.cfg
${PY_PACKAGE_DIR}/__init__.py
${PY_PACKAGE_DIR}/amdsmi_exception.py
${PY_PACKAGE_DIR}/amdsmi_interface.py
${PY_PACKAGE_DIR}/README.md
${PY_PACKAGE_DIR}/LICENSE)
${PY_PACKAGE_DIR}/LICENSE
${PY_PACKAGE_DIR}/libamd_smi.so
)
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/${PY_BUILD_DIR}/pyproject.toml
FILES
${CMAKE_CURRENT_BINARY_DIR}/${PY_BUILD_DIR}/pyproject.toml
${CMAKE_CURRENT_BINARY_DIR}/${PY_BUILD_DIR}/setup.cfg
DESTINATION ${PY_WRAPPER_INSTALL_DIR}
COMPONENT dev)
+453 -4
View File
@@ -2,7 +2,7 @@
## Requirements
* python 3.6 64-bit
* python 3.6+ 64-bit
* driver must be loaded for amdsmi_init() to pass
## Overview
@@ -478,6 +478,10 @@ Field | Description
`cache #` | upt 10 caches will be available
`cache_size` | size of cache in KB
`cache_level` | level of cache
`data_cache` | True if data cache is enabled, false otherwise
`instruction_cache` | True if instruction cache is enabled, false otherwise
`cpu_cache` | True if cpu cache is enabled, false otherwise
`simd_cache` | True if simd cache is enabled, false otherwise
Exceptions that can be thrown by `amdsmi_get_gpu_cache_info` function:
@@ -499,6 +503,10 @@ try:
print(cache_index)
print(cache_values['cache_size'])
print(cache_values['cache_level'])
print(cache_values['data_cache'])
print(cache_values['instruction_cache'])
print(cache_values['cpu_cache'])
print(cache_values['simd_cache'])
except AmdSmiException as e:
print(e)
```
@@ -576,6 +584,7 @@ try:
firmware_list = amdsmi_get_fw_info(device)['fw_list']
for firmware_block in firmware_list:
print(firmware_block['fw_name'])
# String formated hex or decimal value ie: 21.00.00.AC or 130
print(firmware_block['fw_version'])
except AmdSmiException as e:
print(e)
@@ -998,8 +1007,10 @@ Output: Dictionary with fields correctable and uncorrectable
Field | Description
---|---
`serial_number` | Board serial number
`model_number` | Board serial number
`product_serial` | Product serial
`fru_id` | FRU ID
`manufacturer_name` | Manufacturer name
`product_name` | Product name
Exceptions that can be thrown by `amdsmi_get_gpu_board_info` function:
@@ -1014,8 +1025,10 @@ Example:
try:
device = amdsmi_get_processor_handle_from_bdf("0000:23.00.0")
board_info = amdsmi_get_gpu_board_info(device)
print(board_info["serial_number"])
print(board_info["model_number"])
print(board_info["product_serial"])
print(board_info["fru_id"])
print(board_info["manufacturer_name"])
print(board_info["product_name"])
except AmdSmiException as e:
print(e)
@@ -1771,19 +1784,23 @@ except AmdSmiException as e:
```
## amdsmi_is_gpu_power_management_enabled
Description: Returns is power management enabled
Input parameters:
* `processor_handle` GPU device which to query
Output: Bool true if power management enabled else false
Exceptions that can be thrown by `amdsmi_is_gpu_power_management_enabled` function:
* `AmdSmiLibraryException`
* `AmdSmiRetryException`
* `AmdSmiParameterException`
Example:
```python
try:
devices = amdsmi_get_processor_handles()
@@ -3268,7 +3285,6 @@ except AmdSmiException as e:
print(e)
```
### amdsmi_dev_compute_partition_get
Description: Get the compute partition from the given GPU
@@ -3495,3 +3511,436 @@ try:
except AmdSmiException as e:
print(e)
```
### amdsmi_get_cpusocket_handles
**Note: CURRENTLY HARDCODED TO RETURN DUMMY DATA**
Description: Returns list of cpusocket handle objects on current machine
Input parameters: `None`
Output: List of cpusocket handle objects
Exceptions that can be thrown by `amdsmi_get_cpusocket_handles` function:
* `AmdSmiLibraryException`
Example:
```python
try:
sockets = amdsmi_get_cpusocket_handles()
print('Socket numbers: {}'.format(len(sockets)))
except AmdSmiException as e:
print(e)
```
### amdsmi_get_cpusocket_info
**Note: CURRENTLY HARDCODED TO RETURN EMPTY VALUES**
Description: Return cpu socket index
Input parameters:
`socket_handle` cpu socket handle
Output: Socket index
Exceptions that can be thrown by `amdsmi_get_cpusocket_info` function:
* `AmdSmiLibraryException`
Example:
```python
try:
socket_handles = amdsmi_get_cpusocket_handles()
if len(socket_handles) == 0:
print("No CPU sockets on machine")
else:
for socket in socket_handles:
print(amdsmi_get_cpusocket_info(socket))
except AmdSmiException as e:
print(e)
```
### amdsmi_get_cpucore_handles
Description: Returns list of CPU core handle objects on current machine
Input parameters: `None`
Output: List of CPU core handle objects
Exceptions that can be thrown by `amdsmi_get_cpucore_handles` function:
* `AmdSmiLibraryException`
Example:
```python
try:
core_handles = amdsmi_get_cpucore_handles()
if len(core_handles) == 0:
print("No CPU cores on machine")
else:
for core in core_handles:
print(amdsmi_get_cpucore_info(core))
except AmdSmiException as e:
print(e)
```
### amdsmi_get_cpu_hsmp_proto_ver
Description: Get the hsmp protocol version.
Output: amdsmi hsmp protocol version
Exceptions that can be thrown by `amdsmi_get_cpu_hsmp_proto_ver` function:
* `AmdSmiLibraryException`
Example:
```python
try:
socket_handles = amdsmi_get_cpusocket_handles()
if len(socket_handles) == 0:
print("No CPU sockets on machine")
else:
for socket in socket_handles:
version = amdsmi_get_cpu_hsmp_proto_ver(socket)
print(version)
except AmdSmiException as e:
print(e)
```
### amdsmi_get_cpu_smu_fw_version
Description: Get the SMU Firmware version.
Output: amdsmi SMU Firmware version
Exceptions that can be thrown by `amdsmi_get_cpu_smu_fw_version` function:
* `AmdSmiLibraryException`
Example:
```python
try:
socket_handles = amdsmi_get_cpusocket_handles()
if len(socket_handles) == 0:
print("No CPU sockets on machine")
else:
for socket in socket_handles:
version = amdsmi_get_cpu_smu_fw_version(socket)
print(version['debug'])
print(version['minor'])
print(version['major'])
except AmdSmiException as e:
print(e)
```
### amdsmi_get_cpu_prochot_status
Description: Get the CPU's prochot status.
Output: amdsmi cpu prochot status
Exceptions that can be thrown by `amdsmi_get_cpu_prochot_status` function:
* `AmdSmiLibraryException`
Example:
```python
try:
socket_handles = amdsmi_get_cpusocket_handles()
if len(socket_handles) == 0:
print("No CPU sockets on machine")
else:
for socket in socket_handles:
prochot = amdsmi_get_cpu_prochot_status(socket)
print(prochot)
except AmdSmiException as e:
print(e)
```
### amdsmi_get_cpu_fclk_mclk
Description: Get the Data fabric clock and Memory clock in MHz.
Output: amdsmi data fabric clock and memory clock
Exceptions that can be thrown by `amdsmi_get_cpu_fclk_mclk` function:
* `AmdSmiLibraryException`
Example:
```python
try:
socket_handles = amdsmi_get_cpusocket_handles()
if len(socket_handles) == 0:
print("No CPU sockets on machine")
else:
for socket in socket_handles:
clk = amdsmi_get_cpu_fclk_mclk(socket)
for fclk, mclk in clk.items():
print(fclk)
print(mclk)
except AmdSmiException as e:
print(e)
```
### amdsmi_get_cpu_cclk_limit
Description: Get the core clock in MHz.
Output: amdsmi core clock
Exceptions that can be thrown by `amdsmi_get_cpu_cclk_limit` function:
* `AmdSmiLibraryException`
Example:
```python
try:
socket_handles = amdsmi_get_cpusocket_handles()
if len(socket_handles) == 0:
print("No CPU sockets on machine")
else:
for socket in socket_handles:
cclk_limit = amdsmi_get_cpu_cclk_limit(socket)
print(cclk_limit)
except AmdSmiException as e:
print(e)
```
### amdsmi_get_cpu_socket_current_active_freq_limit
Description: Get current active frequency limit of the socket.
Output: amdsmi frequency value in MHz and frequency source name
Exceptions that can be thrown by `amdsmi_get_cpu_socket_current_active_freq_limit` function:
* `AmdSmiLibraryException`
Example:
```python
try:
socket_handles = amdsmi_get_cpusocket_handles()
if len(socket_handles) == 0:
print("No CPU sockets on machine")
else:
for socket in socket_handles:
freq_limit = amdsmi_get_cpu_socket_current_active_freq_limit(socket)
for freq, src in freq_limit.items():
print(freq)
print(src)
except AmdSmiException as e:
print(e)
```
### amdsmi_get_cpu_socket_freq_range
Description: Get socket frequency range
Output: amdsmi maximum frequency and minimum frequency
Exceptions that can be thrown by `amdsmi_get_cpu_socket_freq_range` function:
* `AmdSmiLibraryException`
Example:
```python
try:
socket_handles = amdsmi_get_cpusocket_handles()
if len(socket_handles) == 0:
print("No CPU sockets on machine")
else:
for socket in socket_handles:
freq_range = amdsmi_get_cpu_socket_freq_range(socket)
for fmax, fmin in freq_range.items():
print(fmax)
print(fmin)
except AmdSmiException as e:
print(e)
```
### amdsmi_get_cpu_core_current_freq_limit
Description: Get socket frequency limit of the core
Output: amdsmi frequency
Exceptions that can be thrown by `amdsmi_get_cpu_core_current_freq_limit` function:
* `AmdSmiLibraryException`
Example:
```python
try:
core_handles = amdsmi_get_cpucore_handles()
if len(core_handles) == 0:
print("No CPU cores on machine")
else:
for core in core_handles:
freq_limit = amdsmi_get_cpu_core_current_freq_limit(core)
print(freq_limit)
except AmdSmiException as e:
print(e)
```
### amdsmi_get_cpu_socket_power
Description: Get the socket power.
Output: amdsmi socket power
Exceptions that can be thrown by `amdsmi_get_cpu_socket_power` function:
* `AmdSmiLibraryException`
Example:
```python
try:
socket_handles = amdsmi_get_cpusocket_handles()
if len(socket_handles) == 0:
print("No CPU sockets on machine")
else:
for socket in socket_handles:
sock_power = amdsmi_get_cpu_socket_power(socket)
print(sock_power)
except AmdSmiException as e:
print(e)
```
### amdsmi_get_cpu_socket_power_cap
Description: Get the socket power cap.
Output: amdsmi socket power cap
Exceptions that can be thrown by `amdsmi_get_cpu_socket_power_cap` function:
* `AmdSmiLibraryException`
Example:
```python
try:
socket_handles = amdsmi_get_cpusocket_handles()
if len(socket_handles) == 0:
print("No CPU sockets on machine")
else:
for socket in socket_handles:
sock_power = amdsmi_get_cpu_socket_power_cap(socket)
print(sock_power)
except AmdSmiException as e:
print(e)
```
### amdsmi_get_cpu_socket_power_cap_max
Description: Get the socket power cap max.
Output: amdsmi socket power cap max
Exceptions that can be thrown by `amdsmi_get_cpu_socket_power_cap_max` function:
* `AmdSmiLibraryException`
Example:
```python
try:
socket_handles = amdsmi_get_cpusocket_handles()
if len(socket_handles) == 0:
print("No CPU sockets on machine")
else:
for socket in socket_handles:
sock_power = amdsmi_get_cpu_socket_power_cap_max(socket)
print(sock_power)
except AmdSmiException as e:
print(e)
```
### amdsmi_get_cpu_pwr_svi_telemetry_all_rails
Description: Get the SVI based power telemetry for all rails.
Output: amdsmi svi based power value
Exceptions that can be thrown by `amdsmi_get_cpu_pwr_svi_telemetry_all_rails` function:
* `AmdSmiLibraryException`
Example:
```python
try:
socket_handles = amdsmi_get_cpusocket_handles()
if len(socket_handles) == 0:
print("No CPU sockets on machine")
else:
for socket in socket_handles:
power = amdsmi_get_cpu_pwr_svi_telemetry_all_rails(socket)
print(power)
except AmdSmiException as e:
print(e)
```
### amdsmi_set_cpu_socket_power_cap
Description: Set the power cap value for a given socket.
Input: socket index, amdsmi socket power cap value
Exceptions that can be thrown by `amdsmi_set_cpu_socket_power_cap` function:
* `AmdSmiLibraryException`
Example:
```python
try:
socket_handles = amdsmi_get_cpusocket_handles()
if len(socket_handles) == 0:
print("No CPU sockets on machine")
else:
for socket in socket_handles:
power = amdsmi_set_cpu_socket_power_cap(socket, 0, 1000)
except AmdSmiException as e:
print(e)
```
### amdsmi_set_cpu_pwr_efficiency_mode
Description: Set the power efficiency profile policy.
Input: socket index, mode(0, 1, or 2)
Exceptions that can be thrown by `amdsmi_set_cpu_pwr_efficiency_mode` function:
* `AmdSmiLibraryException`
Example:
```python
try:
socket_handles = amdsmi_get_cpusocket_handles()
if len(socket_handles) == 0:
print("No CPU sockets on machine")
else:
for socket in socket_handles:
policy = amdsmi_set_cpu_pwr_efficiency_mode(socket, 0, 0)
except AmdSmiException as e:
print(e)
```
@@ -385,7 +385,7 @@ class AmdSmiEventReader:
)
)
ret = list()
ret = []
for i in range(0, num_elem):
unique_event_values = set(event.value for event in AmdSmiEvtNotificationType)
if self.event_info[i].event in unique_event_values:
@@ -436,7 +436,7 @@ def _format_bad_page_info(bad_page_info, bad_page_count: ctypes.c_uint32) -> Lis
amdsmi_wrapper.amdsmi_retired_page_record_t)
)
table_records = list()
table_records = []
for i in range(bad_page_count.value):
table_records.append(
{
@@ -876,6 +876,101 @@ def amdsmi_get_cpu_socket_power(
return ppower.value
def amdsmi_get_cpu_socket_power_cap(
socket_handle: amdsmi_wrapper.amdsmi_cpusocket_handle, sock_idx: int
) -> int:
if not isinstance(socket_handle, amdsmi_wrapper.amdsmi_cpusocket_handle):
raise AmdSmiParameterException(
socket_handle, amdsmi_wrapper.amdsmi_cpusocket_handle
)
if not isinstance(sock_idx, int):
raise AmdSmiParameterException(sock_idx, int)
pcap = ctypes.c_uint32()
_check_res(
amdsmi_wrapper.amdsmi_get_cpu_socket_power_cap(
socket_handle, sock_idx, ctypes.byref(pcap)
)
)
return pcap.value
def amdsmi_get_cpu_socket_power_cap_max(
socket_handle: amdsmi_wrapper.amdsmi_cpusocket_handle, sock_idx: int
) -> int:
if not isinstance(socket_handle, amdsmi_wrapper.amdsmi_cpusocket_handle):
raise AmdSmiParameterException(
socket_handle, amdsmi_wrapper.amdsmi_cpusocket_handle
)
if not isinstance(sock_idx, int):
raise AmdSmiParameterException(sock_idx, int)
pmax = ctypes.c_uint32()
_check_res(
amdsmi_wrapper.amdsmi_get_cpu_socket_power_cap_max(
socket_handle, sock_idx, ctypes.byref(pmax)
)
)
return pmax.value
def amdsmi_get_cpu_pwr_svi_telemetry_all_rails(
socket_handle: amdsmi_wrapper.amdsmi_cpusocket_handle, sock_idx: int
) -> int:
if not isinstance(socket_handle, amdsmi_wrapper.amdsmi_cpusocket_handle):
raise AmdSmiParameterException(
socket_handle, amdsmi_wrapper.amdsmi_cpusocket_handle
)
if not isinstance(sock_idx, int):
raise AmdSmiParameterException(sock_idx, int)
power = ctypes.c_uint32()
_check_res(
amdsmi_wrapper.amdsmi_get_cpu_pwr_svi_telemetry_all_rails(
socket_handle, sock_idx, ctypes.byref(power)
)
)
return power.value
def amdsmi_set_cpu_socket_power_cap(
socket_handle: amdsmi_wrapper.amdsmi_cpusocket_handle, sock_idx: int, power_cap: int
):
if not isinstance(socket_handle, amdsmi_wrapper.amdsmi_cpusocket_handle):
raise AmdSmiParameterException(
socket_handle, amdsmi_wrapper.amdsmi_cpusocket_handle
)
if not isinstance(sock_idx, int):
raise AmdSmiParameterException(sock_idx, int)
if not isinstance(power_cap, int):
raise AmdSmiParameterException(power_cap, int)
sock_idx = ctypes.c_uint32(sock_idx)
power_cap = ctypes.c_uint32(power_cap)
_check_res(
amdsmi_wrapper.amdsmi_set_cpu_socket_power_cap(
processor_handle, sock_idx, power_cap)
)
def amdsmi_set_cpu_pwr_efficiency_mode(
socket_handle: amdsmi_wrapper.amdsmi_cpusocket_handle, sock_idx: int, mode: int
):
if not isinstance(socket_handle, amdsmi_wrapper.amdsmi_cpusocket_handle):
raise AmdSmiParameterException(
socket_handle, amdsmi_wrapper.amdsmi_cpusocket_handle
)
if not isinstance(sock_idx, int):
raise AmdSmiParameterException(sock_idx, int)
if not isinstance(mode, int):
raise AmdSmiParameterException(mode, int)
sock_idx = ctypes.c_uint8(sock_idx)
mode = ctypes.c_uint8(mode)
_check_res(
amdsmi_wrapper.amdsmi_set_cpu_pwr_efficiency_mode(
socket_handle, sock_idx, mode)
)
def amdsmi_init(flag=AmdSmiInitFlags.INIT_AMD_GPUS):
if not isinstance(flag, AmdSmiInitFlags):
raise AmdSmiParameterException(flag, AmdSmiInitFlags)
@@ -991,7 +1086,7 @@ def amdsmi_get_gpu_vram_info(
def amdsmi_get_gpu_cache_info(
processor_handle: amdsmi_wrapper.amdsmi_processor_handle,
) -> Dict[str, Any]:
) -> Dict[str, Dict[str, Any]]:
if not isinstance(processor_handle, amdsmi_wrapper.amdsmi_processor_handle):
raise AmdSmiParameterException(
processor_handle, amdsmi_wrapper.amdsmi_processor_handle
@@ -1007,8 +1102,17 @@ def amdsmi_get_gpu_cache_info(
for cache_index in range(cache_info.num_cache_types):
cache_size = cache_info.cache[cache_index].cache_size_kb
cache_level = cache_info.cache[cache_index].cache_level
cache_flags = cache_info.cache[cache_index].flags
data_cache = bool(cache_flags & amdsmi_wrapper.CACHE_FLAGS_DATA_CACHE)
inst_cache = bool(cache_flags & amdsmi_wrapper.CACHE_FLAGS_INST_CACHE)
cpu_cache = bool(cache_flags & amdsmi_wrapper.CACHE_FLAGS_CPU_CACHE)
simd_cache = bool(cache_flags & amdsmi_wrapper.CACHE_FLAGS_SIMD_CACHE)
cache_info_dict[f"cache {cache_index}"] = {"cache_size": cache_size,
"cache_level": cache_level}
"cache_level": cache_level,
"data_cache": data_cache,
"instruction_cache": inst_cache,
"cpu_cache": cpu_cache,
"simd_cache": simd_cache}
return cache_info_dict
@@ -1147,7 +1251,7 @@ def amdsmi_get_gpu_board_info(
return {
"model_number": board_info.model_number.decode("utf-8").strip(),
"product_serial": board_info.serial_number,
"product_serial": board_info.product_serial.decode("utf-8").strip(),
"fru_id": board_info.fru_id.decode("utf-8").strip(),
"manufacturer_name" : board_info.manufacturer_name.decode("utf-8").strip(),
"product_name": board_info.product_name.decode("utf-8").strip()
@@ -1171,7 +1275,7 @@ def amdsmi_get_gpu_ras_feature_info(
)
return {
"eeprom_version": ras_feature.ras_eeprom_version,
"eeprom_version": hex(ras_feature.ras_eeprom_version),
"parity_schema" : bool(ras_feature.ecc_correction_schema_flag & 1),
"single_bit_schema" : bool(ras_feature.ecc_correction_schema_flag & 2),
"double_bit_schema" : bool(ras_feature.ecc_correction_schema_flag & 4),
@@ -1365,11 +1469,28 @@ def amdsmi_get_fw_info(
fw_info = amdsmi_wrapper.amdsmi_fw_info_t()
_check_res(amdsmi_wrapper.amdsmi_get_fw_info(
processor_handle, ctypes.byref(fw_info)))
firmwares = list()
hex_format_fw = [AmdSmiFwBlock.FW_ID_SMC,
AmdSmiFwBlock.FW_ID_PSP_SOSDRV,
AmdSmiFwBlock.FW_ID_TA_RAS,
AmdSmiFwBlock.FW_ID_XGMI,
AmdSmiFwBlock.FW_ID_UVD,
AmdSmiFwBlock.FW_ID_VCE,
AmdSmiFwBlock.FW_ID_VCN]
firmwares = []
for i in range(0, fw_info.num_fw_info):
fw_name = AmdSmiFwBlock(fw_info.fw_info_list[i].fw_id)
fw_version = fw_info.fw_info_list[i].fw_version
if fw_name in hex_format_fw:
fw_version_string = ".".join(re.findall('..?', hex(fw_version)[2:]))
else:
fw_version_string = str(fw_version)
firmwares.append({
'fw_name': AmdSmiFwBlock(fw_info.fw_info_list[i].fw_id),
'fw_version': fw_info.fw_info_list[i].fw_version,
'fw_name': fw_name,
'fw_version': fw_version_string.upper(),
})
return {
'fw_list': firmwares
+56 -62
View File
@@ -168,19 +168,11 @@ def char_pointer_cast(string, encoding='utf-8'):
_libraries = {}
from pathlib import Path
libamd_smi_cpack = Path("@CPACK_PACKAGING_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@/libamd_smi.so")
libamd_smi_optrocm = Path("/opt/rocm/lib/libamd_smi.so")
libamd_smi_parent_dir = Path(__file__).resolve().parent / "libamd_smi.so"
libamd_smi_cwd = Path.cwd() / "libamd_smi.so"
try:
if libamd_smi_cpack.is_file():
# try to find library in install directory provided by CMake
_libraries['libamd_smi.so'] = ctypes.CDLL(libamd_smi_cpack)
elif libamd_smi_optrocm.is_file():
# try /opt/rocm/lib as a fallback
_libraries['libamd_smi.so'] = ctypes.CDLL(libamd_smi_optrocm)
elif libamd_smi_parent_dir.is_file():
if libamd_smi_parent_dir.is_file():
# try to fall back to parent directory
_libraries['libamd_smi.so'] = ctypes.CDLL(libamd_smi_parent_dir)
else:
@@ -751,6 +743,21 @@ struct_amdsmi_vbios_info_t._fields_ = [
]
amdsmi_vbios_info_t = struct_amdsmi_vbios_info_t
# values for enumeration 'amdsmi_cache_flags_type_t'
amdsmi_cache_flags_type_t__enumvalues = {
1: 'CACHE_FLAGS_ENABLED',
2: 'CACHE_FLAGS_DATA_CACHE',
4: 'CACHE_FLAGS_INST_CACHE',
8: 'CACHE_FLAGS_CPU_CACHE',
16: 'CACHE_FLAGS_SIMD_CACHE',
}
CACHE_FLAGS_ENABLED = 1
CACHE_FLAGS_DATA_CACHE = 2
CACHE_FLAGS_INST_CACHE = 4
CACHE_FLAGS_CPU_CACHE = 8
CACHE_FLAGS_SIMD_CACHE = 16
amdsmi_cache_flags_type_t = ctypes.c_uint32 # enum
class struct_amdsmi_gpu_cache_info_t(Structure):
pass
@@ -761,6 +768,7 @@ struct_cache_._pack_ = 1 # source:False
struct_cache_._fields_ = [
('cache_size_kb', ctypes.c_uint32),
('cache_level', ctypes.c_uint32),
('flags', ctypes.c_uint32),
('reserved', ctypes.c_uint32 * 3),
]
@@ -840,14 +848,12 @@ class struct_amdsmi_board_info_t(Structure):
struct_amdsmi_board_info_t._pack_ = 1 # source:False
struct_amdsmi_board_info_t._fields_ = [
('serial_number', ctypes.c_uint64),
('is_master', ctypes.c_bool),
('model_number', ctypes.c_char * 32),
('product_serial', ctypes.c_char * 32),
('fru_id', ctypes.c_char * 32),
('product_name', ctypes.c_char * 128),
('manufacturer_name', ctypes.c_char * 32),
('PADDING_0', ctypes.c_ubyte * 7),
('product_name', ctypes.c_char * 128),
]
amdsmi_board_info_t = struct_amdsmi_board_info_t
@@ -1658,6 +1664,9 @@ uint32_t = ctypes.c_uint32
amdsmi_get_cpusocket_info = _libraries['libamd_smi.so'].amdsmi_get_cpusocket_info
amdsmi_get_cpusocket_info.restype = amdsmi_status_t
amdsmi_get_cpusocket_info.argtypes = [amdsmi_cpusocket_handle, uint32_t]
amdsmi_get_cpucore_info = _libraries['libamd_smi.so'].amdsmi_get_cpucore_info
amdsmi_get_cpucore_info.restype = amdsmi_status_t
amdsmi_get_cpucore_info.argtypes = [amdsmi_processor_handle, uint32_t]
amdsmi_get_processor_handles = _libraries['libamd_smi.so'].amdsmi_get_processor_handles
amdsmi_get_processor_handles.restype = amdsmi_status_t
amdsmi_get_processor_handles.argtypes = [amdsmi_socket_handle, ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.POINTER(None))]
@@ -2073,21 +2082,6 @@ class struct_hsmp_metric_table(Structure):
amdsmi_get_metrics_table = _libraries['libamd_smi.so'].amdsmi_get_metrics_table
amdsmi_get_metrics_table.restype = amdsmi_status_t
amdsmi_get_metrics_table.argtypes = [amdsmi_cpusocket_handle, uint8_t, ctypes.POINTER(struct_hsmp_metric_table)]
amdsmi_get_cpu_family = _libraries['libamd_smi.so'].amdsmi_get_cpu_family
amdsmi_get_cpu_family.restype = amdsmi_status_t
amdsmi_get_cpu_family.argtypes = [uint32_t]
amdsmi_get_cpu_model = _libraries['libamd_smi.so'].amdsmi_get_cpu_model
amdsmi_get_cpu_model.restype = amdsmi_status_t
amdsmi_get_cpu_model.argtypes = [uint32_t]
amdsmi_get_cpu_threads_per_core = _libraries['libamd_smi.so'].amdsmi_get_cpu_threads_per_core
amdsmi_get_cpu_threads_per_core.restype = amdsmi_status_t
amdsmi_get_cpu_threads_per_core.argtypes = [uint32_t]
amdsmi_get_number_of_cpu_cores = _libraries['libamd_smi.so'].amdsmi_get_number_of_cpu_cores
amdsmi_get_number_of_cpu_cores.restype = amdsmi_status_t
amdsmi_get_number_of_cpu_cores.argtypes = [uint32_t]
amdsmi_get_number_of_cpu_sockets = _libraries['libamd_smi.so'].amdsmi_get_number_of_cpu_sockets
amdsmi_get_number_of_cpu_sockets.restype = amdsmi_status_t
amdsmi_get_number_of_cpu_sockets.argtypes = [uint32_t]
amdsmi_first_online_core_on_cpu_socket = _libraries['libamd_smi.so'].amdsmi_first_online_core_on_cpu_socket
amdsmi_first_online_core_on_cpu_socket.restype = amdsmi_status_t
amdsmi_first_online_core_on_cpu_socket.argtypes = [amdsmi_cpusocket_handle, uint32_t, ctypes.POINTER(ctypes.c_uint32)]
@@ -2207,22 +2201,24 @@ __all__ = \
'AMDSMI_VRAM_VENDOR__WINBOND', 'AMDSMI_XGMI_STATUS_ERROR',
'AMDSMI_XGMI_STATUS_MULTIPLE_ERRORS',
'AMDSMI_XGMI_STATUS_NO_ERRORS', 'AMD_APU', 'AMD_CPU',
'AMD_CPU_CORE', 'AMD_GPU', 'CLK_TYPE_DCEF', 'CLK_TYPE_DCLK0',
'CLK_TYPE_DCLK1', 'CLK_TYPE_DF', 'CLK_TYPE_FIRST', 'CLK_TYPE_GFX',
'CLK_TYPE_MEM', 'CLK_TYPE_PCIE', 'CLK_TYPE_SOC', 'CLK_TYPE_SYS',
'CLK_TYPE_VCLK0', 'CLK_TYPE_VCLK1', 'CLK_TYPE__MAX',
'COMPUTE_PARTITION_CPX', 'COMPUTE_PARTITION_DPX',
'COMPUTE_PARTITION_INVALID', 'COMPUTE_PARTITION_QPX',
'COMPUTE_PARTITION_SPX', 'COMPUTE_PARTITION_TPX',
'CONTAINER_DOCKER', 'CONTAINER_LXC', 'FW_ID_ASD', 'FW_ID_CP_CE',
'FW_ID_CP_ME', 'FW_ID_CP_MEC1', 'FW_ID_CP_MEC2',
'FW_ID_CP_MEC_JT1', 'FW_ID_CP_MEC_JT2', 'FW_ID_CP_MES',
'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_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',
'AMD_CPU_CORE', 'AMD_GPU', 'CACHE_FLAGS_CPU_CACHE',
'CACHE_FLAGS_DATA_CACHE', 'CACHE_FLAGS_ENABLED',
'CACHE_FLAGS_INST_CACHE', 'CACHE_FLAGS_SIMD_CACHE',
'CLK_TYPE_DCEF', 'CLK_TYPE_DCLK0', 'CLK_TYPE_DCLK1',
'CLK_TYPE_DF', 'CLK_TYPE_FIRST', 'CLK_TYPE_GFX', 'CLK_TYPE_MEM',
'CLK_TYPE_PCIE', 'CLK_TYPE_SOC', 'CLK_TYPE_SYS', 'CLK_TYPE_VCLK0',
'CLK_TYPE_VCLK1', 'CLK_TYPE__MAX', 'COMPUTE_PARTITION_CPX',
'COMPUTE_PARTITION_DPX', 'COMPUTE_PARTITION_INVALID',
'COMPUTE_PARTITION_QPX', 'COMPUTE_PARTITION_SPX',
'COMPUTE_PARTITION_TPX', 'CONTAINER_DOCKER', 'CONTAINER_LXC',
'FW_ID_ASD', 'FW_ID_CP_CE', 'FW_ID_CP_ME', 'FW_ID_CP_MEC1',
'FW_ID_CP_MEC2', 'FW_ID_CP_MEC_JT1', 'FW_ID_CP_MEC_JT2',
'FW_ID_CP_MES', '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_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',
@@ -2256,12 +2252,12 @@ __all__ = \
'VRAM_TYPE_UNKNOWN', 'VRAM_TYPE__MAX', 'WR_BW0',
'amd_metrics_table_header_t', 'amdsmi_asic_info_t',
'amdsmi_bdf_t', 'amdsmi_bit_field_t', 'amdsmi_board_info_t',
'amdsmi_clk_info_t', 'amdsmi_clk_type_t',
'amdsmi_compute_partition_type_t', 'amdsmi_container_types_t',
'amdsmi_counter_command_t', 'amdsmi_counter_value_t',
'amdsmi_cpu_apb_disable', 'amdsmi_cpu_apb_enable',
'amdsmi_cpusocket_handle', 'amdsmi_ddr_bw_metrics_t',
'amdsmi_dev_compute_partition_get',
'amdsmi_cache_flags_type_t', 'amdsmi_clk_info_t',
'amdsmi_clk_type_t', 'amdsmi_compute_partition_type_t',
'amdsmi_container_types_t', 'amdsmi_counter_command_t',
'amdsmi_counter_value_t', 'amdsmi_cpu_apb_disable',
'amdsmi_cpu_apb_enable', 'amdsmi_cpusocket_handle',
'amdsmi_ddr_bw_metrics_t', 'amdsmi_dev_compute_partition_get',
'amdsmi_dev_compute_partition_reset',
'amdsmi_dev_compute_partition_set',
'amdsmi_dev_memory_partition_get',
@@ -2285,9 +2281,8 @@ __all__ = \
'amdsmi_get_cpu_current_xgmi_bw', 'amdsmi_get_cpu_ddr_bw',
'amdsmi_get_cpu_dimm_power_consumption',
'amdsmi_get_cpu_dimm_temp_range_and_refresh_rate',
'amdsmi_get_cpu_dimm_thermal_sensor', 'amdsmi_get_cpu_family',
'amdsmi_get_cpu_fclk_mclk', 'amdsmi_get_cpu_hsmp_proto_ver',
'amdsmi_get_cpu_model', 'amdsmi_get_cpu_prochot_status',
'amdsmi_get_cpu_dimm_thermal_sensor', 'amdsmi_get_cpu_fclk_mclk',
'amdsmi_get_cpu_hsmp_proto_ver', 'amdsmi_get_cpu_prochot_status',
'amdsmi_get_cpu_pwr_svi_telemetry_all_rails',
'amdsmi_get_cpu_smu_fw_version',
'amdsmi_get_cpu_socket_c0_residency',
@@ -2297,12 +2292,12 @@ __all__ = \
'amdsmi_get_cpu_socket_lclk_dpm_level',
'amdsmi_get_cpu_socket_power', 'amdsmi_get_cpu_socket_power_cap',
'amdsmi_get_cpu_socket_power_cap_max',
'amdsmi_get_cpu_socket_temperature',
'amdsmi_get_cpu_threads_per_core', 'amdsmi_get_cpucore_handles',
'amdsmi_get_cpusocket_handles', 'amdsmi_get_cpusocket_info',
'amdsmi_get_energy_count', 'amdsmi_get_esmi_err_msg',
'amdsmi_get_fw_info', 'amdsmi_get_gpu_activity',
'amdsmi_get_gpu_asic_info', 'amdsmi_get_gpu_available_counters',
'amdsmi_get_cpu_socket_temperature', 'amdsmi_get_cpucore_handles',
'amdsmi_get_cpucore_info', 'amdsmi_get_cpusocket_handles',
'amdsmi_get_cpusocket_info', 'amdsmi_get_energy_count',
'amdsmi_get_esmi_err_msg', 'amdsmi_get_fw_info',
'amdsmi_get_gpu_activity', 'amdsmi_get_gpu_asic_info',
'amdsmi_get_gpu_available_counters',
'amdsmi_get_gpu_bad_page_info', 'amdsmi_get_gpu_bdf_id',
'amdsmi_get_gpu_board_info', 'amdsmi_get_gpu_cache_info',
'amdsmi_get_gpu_compute_process_gpus',
@@ -2333,10 +2328,9 @@ __all__ = \
'amdsmi_get_gpu_vram_vendor', 'amdsmi_get_lib_version',
'amdsmi_get_metrics_table', 'amdsmi_get_metrics_table_version',
'amdsmi_get_minmax_bandwidth_between_processors',
'amdsmi_get_number_of_cpu_cores',
'amdsmi_get_number_of_cpu_sockets', 'amdsmi_get_pcie_link_caps',
'amdsmi_get_pcie_link_status', 'amdsmi_get_power_cap_info',
'amdsmi_get_power_info', 'amdsmi_get_processor_handle_from_bdf',
'amdsmi_get_pcie_link_caps', 'amdsmi_get_pcie_link_status',
'amdsmi_get_power_cap_info', 'amdsmi_get_power_info',
'amdsmi_get_processor_handle_from_bdf',
'amdsmi_get_processor_handles', 'amdsmi_get_processor_type',
'amdsmi_get_socket_handles', 'amdsmi_get_socket_info',
'amdsmi_get_temp_metric', 'amdsmi_get_utilization_count',
@@ -2,7 +2,7 @@
# https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html
[build-system]
requires = ["setuptools>=61.0"]
requires = ["setuptools>=59.0"]
build-backend = "setuptools.build_meta"
[project]
@@ -10,11 +10,11 @@ name = "amdsmi"
authors = [
{name = "AMD", email = "amd-smi.support@amd.com"},
]
version = "23.4.0.0"
version = "@amd_smi_libraries_VERSION_STRING@"
license = {file = "amdsmi/LICENSE"}
readme = {file = "amdsmi/README.md", content-type = "text/markdown"}
description = "AMDSMI Python LIB - AMD GPU Monitoring Library"
requires-python = ">=3.7"
requires-python = ">=3.6"
dependencies = [
"PyYAML >= 5.0",
"clang >= 14.0"
@@ -25,3 +25,7 @@ dependencies = [
[tool.setuptools]
packages = ["amdsmi"]
# install libamd_smi.so
[tool.setuptools.package-data]
amdsmi = ["*.so"]
@@ -0,0 +1,9 @@
# this file is only required for setuptools < 61.0
# mostly a rhel8 limitation...
[metadata]
name = amdsmi
version = @amd_smi_libraries_VERSION_STRING@
[options.package_data]
amdsmi = *.so
+1 -1
View File
@@ -32,7 +32,7 @@ message("Package version: ${PKG_VERSION_STR}")
# Debian package specific variables
# Set a default value for the package version
get_version_from_tag("5.0.0.0" ${SO_VERSION_GIT_TAG_PREFIX} GIT)
get_version_from_tag("1.0.0.0" ${SO_VERSION_GIT_TAG_PREFIX} GIT)
# VERSION_* variables should be set by get_version_from_tag
if(${ROCM_PATCH_VERSION})
@@ -156,6 +156,15 @@
} \
}
void print_function_header_with_rsmi_ret(
rsmi_status_t myReturn, std::string header = "") {
std::cout << "\t** ";
if (!header.empty()) {
std::cout << header << ": ";
}
std::cout << amd::smi::getRSMIStatusString(myReturn, false) << "\n";
}
static void print_test_header(const char *str, uint32_t dv_ind) {
std::cout << "********************************" << "\n";
std::cout << "*** " << str << "\n";
@@ -254,14 +263,24 @@ perf_level_string(rsmi_dev_perf_level_t perf_lvl) {
}
}
static bool isUserRunningAsSudo() {
bool isRunningWithSudo = false;
auto myUID = getuid();
auto myPrivledges = geteuid();
if ((myUID == myPrivledges) && (myPrivledges == 0)) {
isRunningWithSudo = true;
static const std::string
clock_type_string(rsmi_clk_type_t clk) {
switch (clk) {
case RSMI_CLK_TYPE_SYS:
return "RSMI_CLK_TYPE_SYS";
case RSMI_CLK_TYPE_DF:
return "RSMI_CLK_TYPE_DF";
case RSMI_CLK_TYPE_DCEF:
return "RSMI_CLK_TYPE_DCEF";
case RSMI_CLK_TYPE_SOC:
return "RSMI_CLK_TYPE_SOC";
case RSMI_CLK_TYPE_MEM:
return "RSMI_CLK_TYPE_MEM";
case RSMI_CLK_TYPE_PCIE:
return "RSMI_CLK_TYPE_PCIE";
default:
return "RSMI_CLK_INVALID";
}
return isRunningWithSudo;
}
static bool isFileWritable(rsmi_status_t response) {
@@ -271,7 +290,7 @@ static bool isFileWritable(rsmi_status_t response) {
// isFileWritable(ret) - intends to capture this
// response situation.
bool fileWritable = true;
if (isUserRunningAsSudo() && (response == RSMI_STATUS_PERMISSION)) {
if (amd::smi::is_sudo_user() && (response == RSMI_STATUS_PERMISSION)) {
std::cout << "[WARN] User is running with sudo "
<< "permissions, file is not writable." << "\n";
fileWritable = false;
@@ -574,9 +593,19 @@ static rsmi_status_t test_set_freq(uint32_t dv_ind) {
}
static void print_frequencies(rsmi_frequencies_t *f) {
assert(f != nullptr);
bool hasDeepSleep = false;
if (f == nullptr) {
std::cout << "Freq was nullptr\n";
return;
}
for (uint32_t j = 0; j < f->num_supported; ++j) {
std::cout << "\t** " << j << ": " << std::to_string(f->frequency[j]);
if (f->has_deep_sleep && j == 0) {
std::cout << "\t** S: " << std::to_string(f->frequency[j]);
hasDeepSleep = true;
} else {
std::cout << "\t** " << (hasDeepSleep ? j-1 : j)
<< ": " << std::to_string(f->frequency[j]);
}
if (j == f->current) {
std::cout << " *";
}
@@ -714,6 +743,7 @@ int main() {
rsmi_frequencies_t f;
uint32_t num_monitor_devs = 0;
rsmi_gpu_metrics_t p;
std::string val_str;
RSMI_POWER_TYPE power_type = RSMI_INVALID_POWER;
rsmi_num_monitor_devices(&num_monitor_devs);
@@ -725,6 +755,8 @@ int main() {
ret = rsmi_dev_revision_get(i, &val_ui16);
CHK_RSMI_RET_I(ret)
std::cout << "\t**Dev.Rev.ID: 0x" << std::hex << val_ui16 << "\n";
ret = amd::smi::rsmi_get_gfx_target_version(i , &val_str);
std::cout << "\t**Target Graphics Version: " << val_str << "\n";
char pcie_vendor_name[256];
ret = rsmi_dev_pcie_vendor_name_get(i, pcie_vendor_name, 256);
@@ -741,7 +773,7 @@ int main() {
? "UNKNOWN" : current_compute_partition);
if (ret != RSMI_STATUS_SUCCESS) {
std::cout << ", RSMI_STATUS = ";
} else {
} else {
std::cout << "\n";
}
CHK_RSMI_NOT_SUPPORTED_OR_UNEXPECTED_DATA_RET(ret)
@@ -778,8 +810,42 @@ int main() {
}
ret = rsmi_dev_gpu_metrics_info_get(i, &p);
CHK_AND_PRINT_RSMI_ERR_RET(ret)
std::cout << "\t**GPU METRICS" << "\n";
print_test_header("GPU METRICS", i);
print_function_header_with_rsmi_ret(ret,
"rsmi_dev_gpu_metrics_info_get(" + std::to_string(i) + ", &p)");
std::cout << "\t**p.common_header.content_revision: " << std::dec
<< p.common_header.content_revision << "\n";
std::cout << "\t**p.common_header.format_revision: " << std::dec
<< p.common_header.format_revision << "\n";
std::cout << "\t**p.average_gfxclk_frequency: " << std::dec
<< p.average_gfxclk_frequency << "\n";
std::cout << "\t**p.average_socclk_frequency: " << std::dec
<< p.average_socclk_frequency << "\n";
std::cout << "\t**p.average_uclk_frequency: " << std::dec
<< p.average_uclk_frequency << "\n";
std::cout << "\t**p.average_vclk0_frequency: " << std::dec
<< p.average_vclk0_frequency << "\n";
std::cout << "\t**p.average_dclk0_frequency: " << std::dec
<< p.average_dclk0_frequency << "\n";
std::cout << "\t**p.average_vclk1_frequency: " << std::dec
<< p.average_vclk1_frequency << "\n";
std::cout << "\t**p.average_dclk1_frequency: " << std::dec
<< p.average_dclk1_frequency << "\n";
std::cout << "\t**p.current_gfxclk: " << std::dec
<< p.current_gfxclk << "\n";
std::cout << "\t**p.current_socclk: " << std::dec
<< p.current_socclk << "\n";
std::cout << "\t**p.current_uclk: " << std::dec
<< p.current_uclk << "\n";
std::cout << "\t**p.current_vclk0: " << std::dec
<< p.current_vclk0 << "\n";
std::cout << "\t**p.current_dclk0: " << std::dec
<< p.current_dclk0 << "\n";
std::cout << "\t**p.current_vclk1: " << std::dec
<< p.current_vclk1 << "\n";
std::cout << "\t**p.current_dclk1: " << std::dec
<< p.current_dclk1 << "\n";
ret = rsmi_dev_perf_level_get(i, &pfl);
CHK_AND_PRINT_RSMI_ERR_RET(ret)
@@ -789,25 +855,25 @@ int main() {
CHK_AND_PRINT_RSMI_ERR_RET(ret)
std::cout << "\t**OverDrive Level:" << val_ui32 << "\n";
ret = rsmi_dev_gpu_clk_freq_get(i, RSMI_CLK_TYPE_MEM, &f);
CHK_AND_PRINT_RSMI_ERR_RET(ret)
std::cout << "\t**Supported GPU Memory clock frequencies: ";
std::cout << f.num_supported << "\n";
print_frequencies(&f);
ret = rsmi_dev_gpu_clk_freq_get(i, RSMI_CLK_TYPE_SYS, &f);
CHK_AND_PRINT_RSMI_ERR_RET(ret)
std::cout << "\t**Supported GPU clock frequencies: ";
std::cout << f.num_supported << "\n";
print_frequencies(&f);
ret = rsmi_dev_gpu_clk_freq_get(i, RSMI_CLK_TYPE_SOC, &f);
CHK_RSMI_NOT_SUPPORTED_OR_UNEXPECTED_DATA_RET(ret)
std::cout << "\t**Supported GPU clock frequencies (SOC clk): ";
std::cout << f.num_supported << "\n";
std::cout << "\t**Current value (SOC clk): ";
std::cout << f.current << "\n";
print_frequencies(&f);
print_test_header("GPU Clocks", i);
for (int clkType = static_cast<int>(RSMI_CLK_TYPE_SYS);
clkType <= static_cast<int>(RSMI_CLK_TYPE_PCIE);
clkType++) {
rsmi_clk_type_t type = static_cast<rsmi_clk_type_t>(clkType);
ret = rsmi_dev_gpu_clk_freq_get(i, type, &f);
print_function_header_with_rsmi_ret(ret,
"rsmi_dev_gpu_clk_freq_get(" + std::to_string(i) +
", " + clock_type_string(type) + ", &f)");
if (ret != RSMI_STATUS_SUCCESS) {
continue;
}
std::cout << "\t** " << clock_type_string(type)
<< " - Supported # of freqs: ";
std::cout << f.num_supported << "\n";
std::cout << "\t** " << clock_type_string(type) << " f.current: "
<< f.current << "\n";
print_frequencies(&f);
}
std::cout << "\t**Monitor name: ";
char name[128];
@@ -897,7 +963,7 @@ int main() {
}
std::cout << "***** Testing write api's" << "\n";
if (isUserRunningAsSudo() == false) {
if (amd::smi::is_sudo_user() == false) {
std::cout << "Write APIs require users to execute with sudo. "
<< "Cannot proceed." << "\n";
return 0;
@@ -377,16 +377,16 @@ typedef rsmi_clk_type_t rsmi_clk_type;
*/
typedef enum {
RSMI_COMPUTE_PARTITION_INVALID = 0,
RSMI_COMPUTE_PARTITION_CPX, //!< Core mode (CPX)- Per-chip XCC with
//!< shared memory
RSMI_COMPUTE_PARTITION_SPX, //!< Single GPU mode (SPX)- All XCCs work
//!< together with shared memory
RSMI_COMPUTE_PARTITION_DPX, //!< Dual GPU mode (DPX)- Half XCCs work
//!< together with shared memory
RSMI_COMPUTE_PARTITION_TPX, //!< Triple GPU mode (TPX)- One-third XCCs
//!< work together with shared memory
RSMI_COMPUTE_PARTITION_QPX //!< Quad GPU mode (QPX)- Quarter XCCs
//!< work together with shared memory
RSMI_COMPUTE_PARTITION_CPX = 1, //!< Core mode (CPX)- Per-chip XCC with
//!< shared memory
RSMI_COMPUTE_PARTITION_SPX = 2, //!< Single GPU mode (SPX)- All XCCs work
//!< together with shared memory
RSMI_COMPUTE_PARTITION_DPX = 3, //!< Dual GPU mode (DPX)- Half XCCs work
//!< together with shared memory
RSMI_COMPUTE_PARTITION_TPX = 4, //!< Triple GPU mode (TPX)- One-third XCCs
//!< work together with shared memory
RSMI_COMPUTE_PARTITION_QPX = 5, //!< Quad GPU mode (QPX)- Quarter XCCs
//!< work together with shared memory
} rsmi_compute_partition_type_t;
/// \cond Ignore in docs.
typedef rsmi_compute_partition_type_t rsmi_compute_partition_type;
@@ -713,6 +713,10 @@ typedef enum _RSMI_IO_LINK_TYPE {
RSMI_IOLINK_TYPE_SIZE = 0xFFFFFFFF //!< Max of IO Link types
} RSMI_IO_LINK_TYPE;
//! The CPU node index which will be used in rsmi_topo_get_link_type
//! to query the link type between GPU and CPU
#define CPU_NODE_INDEX 0xFFFFFFFF
/**
* @brief The utilization counter type
*/
@@ -864,6 +868,14 @@ typedef struct {
struct {
uint32_t cache_size_kb; /* In KB */
uint32_t cache_level;
/*
HSA_CACHE_TYPE_DATA 0x00000001
HSA_CACHE_TYPE_INSTRUCTION 0x00000002
HSA_CACHE_TYPE_CPU 0x00000004
HSA_CACHE_TYPE_HSACU 0x00000008
so HSA_CACHE_TYPE_DATA|HSA_CACHE_TYPE_HSACU == 9
*/
uint32_t flags;
} cache[RSMI_MAX_CACHE_TYPES];
} rsmi_gpu_cache_info_t;
/// \cond Ignore in docs.
@@ -3848,7 +3860,7 @@ rsmi_minmax_bandwidth_get(uint32_t dv_ind_src, uint32_t dv_ind_dst,
uint64_t *min_bandwidth, uint64_t *max_bandwidth);
/**
* @brief Retrieve the hops and the connection type between 2 GPUs
* @brief Retrieve the hops and the connection type between GPU to GPU/CPU
*
* @details Given a source device index @p dv_ind_src and
* a destination device index @p dv_ind_dst, and a pointer to an
@@ -3857,6 +3869,14 @@ rsmi_minmax_bandwidth_get(uint32_t dv_ind_src, uint32_t dv_ind_dst,
* between the device @p dv_ind_src and @p dv_ind_dst to the memory
* pointed to by @p hops and @p type.
*
* To query the link type between GPU and CPU, given a source GPU index
* @p dev_ind_srcc and a destination device index @p dv_ind_dst
* CPU_NODE_INDEX(0xFFFFFFFF), a pointer to an
* uint64_t @p hops and a pointer to an RSMI_IO_LINK_TYPE @p type,
* this function will write the number of hops and the connection type
* between the device @p dv_ind_src and CPU to the memory
* pointed to by @p hops and @p type.
*
* @param[in] dv_ind_src the source device index
*
* @param[in] dv_ind_dst the destination device index
@@ -3960,6 +3980,8 @@ rsmi_dev_compute_partition_get(uint32_t dv_ind, char *compute_partition,
* unavailable for current device
* @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not
* support this function
* @retval ::RSMI_STATUS_BUSY A resource or mutex could not be acquired
* because it is already being used - device is busy
*
*/
rsmi_status_t
@@ -3979,6 +4001,8 @@ rsmi_dev_compute_partition_set(uint32_t dv_ind,
* @retval ::RSMI_STATUS_PERMISSION function requires root access
* @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not
* support this function
* @retval ::RSMI_STATUS_BUSY A resource or mutex could not be acquired
* because it is already being used - device is busy
*
*/
rsmi_status_t rsmi_dev_compute_partition_reset(uint32_t dv_ind);
@@ -4043,6 +4067,8 @@ rsmi_dev_memory_partition_get(uint32_t dv_ind, char *memory_partition,
* support this function
* @retval ::RSMI_STATUS_AMDGPU_RESTART_ERR could not successfully restart
* the amdgpu driver
* @retval ::RSMI_STATUS_BUSY A resource or mutex could not be acquired
* because it is already being used - device is busy
*
*/
rsmi_status_t
@@ -4064,6 +4090,8 @@ rsmi_dev_memory_partition_set(uint32_t dv_ind,
* support this function
* @retval ::RSMI_STATUS_AMDGPU_RESTART_ERR could not successfully restart
* the amdgpu driver
* @retval ::RSMI_STATUS_BUSY A resource or mutex could not be acquired
* because it is already being used - device is busy
*
*/
rsmi_status_t rsmi_dev_memory_partition_reset(uint32_t dv_ind);
@@ -272,7 +272,8 @@ class Device {
std::vector<std::string> *retVec);
int readDevInfoBinary(DevInfoTypes type, std::size_t b_size,
void *p_binary_data);
int writeDevInfoStr(DevInfoTypes type, std::string valStr);
int writeDevInfoStr(DevInfoTypes type, std::string valStr,
bool returnWriteErr = false);
rsmi_status_t run_amdgpu_property_reinforcement_query(const AMDGpuPropertyQuery_t& amdgpu_property_query);
@@ -87,6 +87,9 @@ class KFDNode {
// Get cache info from kfd
int get_cache_info(rsmi_gpu_cache_info_t *info);
// Get gfx target version from kfd
int get_gfx_target_version(uint64_t* gfx_target_version);
private:
uint32_t node_indx_;
uint32_t amdgpu_dev_index_;
@@ -51,6 +51,8 @@
#include <sstream>
#include <iomanip>
#include <type_traits>
#include <tuple>
#include <queue>
#include "rocm_smi/rocm_smi_device.h"
@@ -97,10 +99,10 @@ rsmi_status_t
GetDevBinaryBlob(amd::smi::DevInfoTypes type,
uint32_t dv_ind, std::size_t b_size, void* p_binary_data);
rsmi_status_t ErrnoToRsmiStatus(int err);
std::string getRSMIStatusString(rsmi_status_t ret);
std::string getRSMIStatusString(rsmi_status_t ret, bool fullStatus = true);
std::tuple<bool, std::string, std::string, std::string, std::string,
std::string, std::string, std::string, std::string,
std::string, std::string, std::string>
std::string, std::string, std::string, std::string, std::string>
getSystemDetails(void);
void logSystemDetails(void);
rsmi_status_t getBDFString(uint64_t bdf_id, std::string& bfd_str);
@@ -110,11 +112,20 @@ void logHexDump(const char *desc, const void *addr, const size_t len,
bool isSystemBigEndian();
std::string getBuildType();
std::string getMyLibPath();
std::string getFileCreationDate(std::string path);
int subDirectoryCountInPath(const std::string path);
std::queue<std::string> getAllDeviceGfxVers();
std::string monitor_type_string(amd::smi::MonitorTypes type);
std::string power_type_string(RSMI_POWER_TYPE type);
std::string splitString(std::string str, char delim);
std::string print_rsmi_od_volt_freq_data_t(rsmi_od_volt_freq_data_t *odv);
std::string print_rsmi_od_volt_freq_regions(uint32_t num_regions,
rsmi_freq_volt_region_t *regions);
bool is_sudo_user();
rsmi_status_t rsmi_get_gfx_target_version(uint32_t dv_ind,
std::string *gfx_version);
template <typename T>
std::string print_int_as_hex(T i, bool showHexNotation=true) {
std::string print_int_as_hex(T i, bool showHexNotation = true) {
std::stringstream ss;
if (showHexNotation) {
ss << "0x" << std::setfill('0') << std::setw(sizeof(T) * 2) << std::hex;
@@ -133,7 +144,7 @@ std::string print_int_as_hex(T i, bool showHexNotation=true) {
}
ss << std::dec;
return ss.str();
};
}
template <typename T>
std::string print_unsigned_int(T i) {
@@ -264,7 +275,7 @@ class ScopedAcquire {
LockType* lock_;
bool doRelease;
/// @brief: Disable copiable and assignable ability.
DISALLOW_COPY_AND_ASSIGN(ScopedAcquire);
DISALLOW_COPY_AND_ASSIGN(ScopedAcquire)
};
// The best effort way to decide whether it is in VM guest environment:
@@ -1,4 +1,6 @@
### ROCm System Management Interface
## Synopsis
Radeon Open Compute Platform - System Management Interface - Command Line tool.
This tool acts as a command line interface for manipulating
and monitoring the amdgpu kernel, and is intended to replace
@@ -7,172 +9,195 @@ It uses Ctypes to call the rocm_smi_lib API.
Recommended: At least one AMD GPU with ROCm driver installed
Required: ROCm SMI library installed (librocm_smi64)
#### Installation
## Installation
Follow installation procedure for rocm_smi_lib.
Please refer to [https://github.com/RadeonOpenCompute/rocm_smi_lib](https://github.com/RadeonOpenCompute/rocm_smi_lib) for the installation guide.
LD_LIBRARY_PATH should be set to the folder containing librocm_smi64.
### Version
## Version
The SMI will report a "version" which is the version of the kernel installed:
```shell
AMD ROCm System Management Interface v$(uname)
```
AMD ROCm System Management Interface v$(uname)
For ROCk installations, this will be the AMDGPU module version (e.g. 5.0.71)
For non-ROCk or monolithic ROCk installations, this will be the kernel version,
which will be equivalent to the following bash command:
```shell
$(uname -a) | cut -d ' ' -f 3)
```
$(uname -a) | cut -d ' ' -f 3)
#### Usage
## Usage
For detailed and up to date usage information, we recommend consulting the help:
```shell
/opt/rocm/bin/rocm-smi -h
```
/opt/rocm/bin/rocm-smi -h
For convenience purposes, following is the output from the -h flag:
```shell
usage: rocm-smi [-h] [-V] [-d DEVICE [DEVICE ...]] [--alldevices] [--showhw] [-a] [-i] [-v] [-e [EVENT ...]]
[--showdriverversion] [--showtempgraph] [--showfwinfo [BLOCK ...]] [--showmclkrange] [--showmemvendor]
[--showsclkrange] [--showproductname] [--showserial] [--showuniqueid] [--showvoltagerange] [--showbus]
[--showpagesinfo] [--showpendingpages] [--showretiredpages] [--showunreservablepages] [-f] [-P] [-t]
[-u] [--showmemuse] [--showvoltage] [-b] [-c] [-g] [-l] [-M] [-m] [-o] [-p] [-S] [-s]
[--showmeminfo TYPE [TYPE ...]] [--showpids [VERBOSE]] [--showpidgpus [SHOWPIDGPUS ...]]
[--showreplaycount] [--showrasinfo [SHOWRASINFO ...]] [--showvc] [--showxgmierr] [--showtopo]
[--showtopoaccess] [--showtopoweight] [--showtopohops] [--showtopotype] [--showtoponuma]
[--showenergycounter] [--shownodesbw] [--showcomputepartition] [--showmemorypartition] [-r]
[--resetfans] [--resetprofile] [--resetpoweroverdrive] [--resetxgmierr] [--resetperfdeterminism]
[--resetcomputepartition] [--resetmemorypartition] [--setclock TYPE LEVEL] [--setsclk LEVEL [LEVEL ...]]
[--setmclk LEVEL [LEVEL ...]] [--setpcie LEVEL [LEVEL ...]] [--setslevel SCLKLEVEL SCLK SVOLT]
[--setmlevel MCLKLEVEL MCLK MVOLT] [--setvc POINT SCLK SVOLT] [--setsrange SCLKMIN SCLKMAX]
[--setmrange MCLKMIN MCLKMAX] [--setfan LEVEL] [--setperflevel LEVEL] [--setoverdrive %]
[--setmemoverdrive %] [--setpoweroverdrive WATTS] [--setprofile SETPROFILE] [--setperfdeterminism SCLK]
[--setcomputepartition {CPX,SPX,DPX,TPX,QPX,cpx,spx,dpx,tpx,qpx}]
[--setmemorypartition {NPS1,NPS2,NPS4,NPS8,nps1,nps2,nps4,nps8}] [--rasenable BLOCK ERRTYPE]
[--rasdisable BLOCK ERRTYPE] [--rasinject BLOCK] [--gpureset] [--load FILE | --save FILE]
[--autorespond RESPONSE] [--loglevel LEVEL] [--json] [--csv]
usage: rocmSmiLib_cli.py [-h] [-d DEVICE [DEVICE ...]] [--alldevices] [--showhw] [-a] [-i] [-v] [--showdriverversion]
[--showfwinfo [BLOCK [BLOCK ...]]] [--showmclkrange] [--showmemvendor] [--showsclkrange]
[--showproductname] [--showserial] [--showuniqueid] [--showvoltagerange] [--showbus]
[--showpagesinfo] [--showpendingpages] [--showretiredpages] [--showunreservablepages] [-f] [-P]
[-t] [-u] [--showmemuse] [--showvoltage] [-b] [-c] [-g] [-l] [-M] [-m] [-o] [-p] [-S] [-s]
[--showmeminfo TYPE [TYPE ...]] [--showpids] [--showpidgpus [SHOWPIDGPUS [SHOWPIDGPUS ...]]]
[--showreplaycount] [--showrasinfo [SHOWRASINFO [SHOWRASINFO ...]]] [--showvc] [--showxgmierr]
[--showtopo] [--showtopoweight] [--showtopohops] [--showtopotype] [--showtoponuma] [-r]
[--resetfans] [--resetprofile] [--resetpoweroverdrive] [--resetxgmierr]
[--setsclk LEVEL [LEVEL ...]] [--setmclk LEVEL [LEVEL ...]] [--setpcie LEVEL [LEVEL ...]]
[--setslevel SCLKLEVEL SCLK SVOLT] [--setmlevel MCLKLEVEL MCLK MVOLT]
[--setvc POINT SCLK SVOLT] [--setsrange MINMAX SCLK] [--setmrange MINMAX MCLK] [--setfan LEVEL]
[--setperflevel LEVEL] [--setoverdrive %] [--setmemoverdrive %] [--setpoweroverdrive WATTS]
[--setprofile SETPROFILE] [--rasenable BLOCK ERRTYPE] [--rasdisable BLOCK ERRTYPE]
[--rasinject BLOCK] [--gpureset] [--load FILE | --save FILE] [--autorespond RESPONSE]
[--loglevel LEVEL] [--json] [--csv]
AMD ROCm System Management Interface | ROCM-SMI version: 1.5.0
AMD ROCm System Management Interface | ROCM-SMI version: 1.4.1 | Kernel version: 5.4.8
options:
-h, --help show this help message and exit
--gpureset Reset specified GPU (One GPU must be specified)
--load FILE Load Clock, Fan, Performance and Profile settings
from FILE
--save FILE Save Clock, Fan, Performance and Profile settings to
FILE
optional arguments:
-h, --help show this help message and exit
--gpureset Reset specified GPU (One GPU must be specified)
--load FILE Load Clock, Fan, Performance and Profile settings from FILE
--save FILE Save Clock, Fan, Performance and Profile settings to FILE
-V, --version Show version information
-d DEVICE [DEVICE ...], --device DEVICE [DEVICE ...] Execute command on specified device
-d DEVICE [DEVICE ...], --device DEVICE [DEVICE ...] Execute command on specified device
Display Options:
--alldevices
--showhw Show Hardware details
-a, --showallinfo Show Temperature, Fan and Clock values
Display Options:
--alldevices
--showhw Show Hardware details
-a, --showallinfo Show Temperature, Fan and Clock values
Topology:
-i, --showid Show DEVICE ID
-v, --showvbios Show VBIOS version
--showdriverversion Show kernel driver version
--showfwinfo [BLOCK [BLOCK ...]] Show FW information
--showmclkrange Show mclk range
--showmemvendor Show GPU memory vendor
--showsclkrange Show sclk range
--showproductname Show SKU/Vendor name
--showserial Show GPU's Serial Number
--showuniqueid Show GPU's Unique ID
--showvoltagerange Show voltage range
--showbus Show PCI bus number
Topology:
-i, --showid Show DEVICE ID
-v, --showvbios Show VBIOS version
-e [EVENT ...], --showevents [EVENT ...] Show event list
--showdriverversion Show kernel driver version
--showtempgraph Show Temperature Graph
--showfwinfo [BLOCK ...] Show FW information
--showmclkrange Show mclk range
--showmemvendor Show GPU memory vendor
--showsclkrange Show sclk range
--showproductname Show SKU/Vendor name
--showserial Show GPU's Serial Number
--showuniqueid Show GPU's Unique ID
--showvoltagerange Show voltage range
--showbus Show PCI bus number
Pages information:
--showpagesinfo Show retired, pending and unreservable pages
--showpendingpages Show pending retired pages
--showretiredpages Show retired pages
--showunreservablepages Show unreservable pages
Pages information:
--showpagesinfo Show retired, pending and unreservable pages
--showpendingpages Show pending retired pages
--showretiredpages Show retired pages
--showunreservablepages Show unreservable pages
Hardware-related information:
-f, --showfan Show current fan speed
-P, --showpower Show current Average Graphics Package Power Consumption
-t, --showtemp Show current temperature
-u, --showuse Show current GPU use
--showmemuse Show current GPU memory used
--showvoltage Show current GPU voltage
Hardware-related information:
-f, --showfan Show current fan speed
-P, --showpower Show current Average Graphics Package Power
Consumption
-t, --showtemp Show current temperature
-u, --showuse Show current GPU use
--showmemuse Show current GPU memory used
--showvoltage Show current GPU voltage
Software-related/controlled information:
-b, --showbw Show estimated PCIe use
-c, --showclocks Show current clock frequencies
-g, --showgpuclocks Show current GPU clock frequencies
-l, --showprofile Show Compute Profile attributes
-M, --showmaxpower Show maximum graphics package power this GPU will consume
-m, --showmemoverdrive Show current GPU Memory Clock OverDrive level
-o, --showoverdrive Show current GPU Clock OverDrive level
-p, --showperflevel Show current DPM Performance Level
-S, --showclkvolt Show supported GPU and Memory Clocks and Voltages
-s, --showclkfrq Show supported GPU and Memory Clock
--showmeminfo TYPE [TYPE ...] Show Memory usage information for given block(s) TYPE
--showpids Show current running KFD PIDs
--showpidgpus [SHOWPIDGPUS [SHOWPIDGPUS ...]] Show GPUs used by specified KFD PIDs (all if no arg given)
--showreplaycount Show PCIe Replay Count
--showrasinfo [SHOWRASINFO [SHOWRASINFO ...]] Show RAS enablement information and error counts for the
specified block(s) (all if no arg given)
--showvc Show voltage curve
--showxgmierr Show XGMI error information since last read
--showtopo Show hardware topology information
--showtopoweight Shows the relative weight between GPUs
--showtopohops Shows the number of hops between GPUs
--showtopotype Shows the link type between GPUs
--showtoponuma Shows the numa nodes
Software-related/controlled information:
-b, --showbw Show estimated PCIe use
-c, --showclocks Show current clock frequencies
-g, --showgpuclocks Show current GPU clock frequencies
-l, --showprofile Show Compute Profile attributes
-M, --showmaxpower Show maximum graphics package power this GPU will
consume
-m, --showmemoverdrive Show current GPU Memory Clock OverDrive level
-o, --showoverdrive Show current GPU Clock OverDrive level
-p, --showperflevel Show current DPM Performance Level
-S, --showclkvolt Show supported GPU and Memory Clocks and Voltages
-s, --showclkfrq Show supported GPU and Memory Clock
--showmeminfo TYPE [TYPE ...] Show Memory usage information for given block(s) TYPE
--showpids [VERBOSE] Show current running KFD PIDs (pass details to
VERBOSE for detailed information)
--showpidgpus [SHOWPIDGPUS ...] Show GPUs used by specified KFD PIDs (all if no arg
given)
--showreplaycount Show PCIe Replay Count
--showrasinfo [SHOWRASINFO ...] Show RAS enablement information and error counts for
the specified block(s) (all if no arg given)
--showvc Show voltage curve
--showxgmierr Show XGMI error information since last read
--showtopo Show hardware topology information
--showtopoaccess Shows the link accessibility between GPUs
--showtopoweight Shows the relative weight between GPUs
--showtopohops Shows the number of hops between GPUs
--showtopotype Shows the link type between GPUs
--showtoponuma Shows the numa nodes
--showenergycounter Energy accumulator that stores amount of energy
consumed
--shownodesbw Shows the numa nodes
--showcomputepartition Shows current compute partitioning
--showmemorypartition Shows current memory partition
Set options:
--setsclk LEVEL [LEVEL ...] Set GPU Clock Frequency Level(s) (requires manual Perf level)
--setmclk LEVEL [LEVEL ...] Set GPU Memory Clock Frequency Level(s) (requires manual Perf
level)
--setpcie LEVEL [LEVEL ...] Set PCIE Clock Frequency Level(s) (requires manual Perf level)
--setslevel SCLKLEVEL SCLK SVOLT Change GPU Clock frequency (MHz) and Voltage (mV) for a specific
Level
--setmlevel MCLKLEVEL MCLK MVOLT Change GPU Memory clock frequency (MHz) and Voltage for (mV) a
specific Level
--setvc POINT SCLK SVOLT Change SCLK Voltage Curve (MHz mV) for a specific point
--setsrange MINMAX SCLK Set min(0) or max(1) SCLK speed
--setmrange MINMAX MCLK Set min(0) or max(1) MCLK speed
--setfan LEVEL Set GPU Fan Speed (Level or %)
--setperflevel LEVEL Set Performance Level
--setoverdrive % Set GPU OverDrive level (requires manual|high Perf level)
--setmemoverdrive % Set GPU Memory Overclock OverDrive level (requires manual|high
Perf level)
--setpoweroverdrive WATTS Set the maximum GPU power using Power OverDrive in Watts
--setprofile SETPROFILE Specify Power Profile level (#) or a quoted string of CUSTOM
Profile attributes "# # # #..." (requires manual Perf level)
--rasenable BLOCK ERRTYPE Enable RAS for specified block and error type
--rasdisable BLOCK ERRTYPE Disable RAS for specified block and error type
--rasinject BLOCK Inject RAS poison for specified block (ONLY WORKS ON UNSECURE
BOARDS)
Set options:
--setclock TYPE LEVEL Set Clock Frequency Level(s) for specified clock
(requires manual Perf level)
--setsclk LEVEL [LEVEL ...] Set GPU Clock Frequency Level(s) (requires manual
Perf level)
--setmclk LEVEL [LEVEL ...] Set GPU Memory Clock Frequency Level(s) (requires
manual Perf level)
--setpcie LEVEL [LEVEL ...] Set PCIE Clock Frequency Level(s) (requires manual
Perf level)
--setslevel SCLKLEVEL SCLK SVOLT Change GPU Clock frequency (MHz) and Voltage (mV) for
a specific Level
--setmlevel MCLKLEVEL MCLK MVOLT Change GPU Memory clock frequency (MHz) and Voltage
for (mV) a specific Level
--setvc POINT SCLK SVOLT Change SCLK Voltage Curve (MHz mV) for a specific
point
--setsrange SCLKMIN SCLKMAX Set min and max SCLK speed
--setmrange MCLKMIN MCLKMAX Set min and max MCLK speed
--setfan LEVEL Set GPU Fan Speed (Level or %)
--setperflevel LEVEL Set Performance Level
--setoverdrive % Set GPU OverDrive level (requires manual|high Perf
level)
--setmemoverdrive % Set GPU Memory Overclock OverDrive level (requires
manual|high Perf level)
--setpoweroverdrive WATTS Set the maximum GPU power using Power OverDrive in
Watts
--setprofile SETPROFILE Specify Power Profile level (#) or a quoted string of
CUSTOM Profile attributes "# # # #..." (requires
manual Perf level)
--setperfdeterminism SCLK Set clock frequency limit to get minimal performance
variation
--setcomputepartition {CPX,SPX,DPX,TPX,QPX,cpx,spx,dpx,tpx,qpx} Set compute partition
--setmemorypartition {NPS1,NPS2,NPS4,NPS8,nps1,nps2,nps4,nps8} Set memory partition
--rasenable BLOCK ERRTYPE Enable RAS for specified block and error type
--rasdisable BLOCK ERRTYPE Disable RAS for specified block and error type
--rasinject BLOCK Inject RAS poison for specified block (ONLY WORKS ON
UNSECURE BOARDS)
Reset options:
-r, --resetclocks Reset clocks and OverDrive to default
--resetfans Reset fans to automatic (driver) control
--resetprofile Reset Power Profile back to default
--resetpoweroverdrive Set the maximum GPU power back to the device deafult state
--resetxgmierr Reset XGMI error count
Reset options:
-r, --resetclocks Reset clocks and OverDrive to default
--resetfans Reset fans to automatic (driver) control
--resetprofile Reset Power Profile back to default
--resetpoweroverdrive Set the maximum GPU power back to the device deafult
state
--resetxgmierr Reset XGMI error count
--resetperfdeterminism Disable performance determinism
--resetcomputepartition Resets to boot compute partition state
--resetmemorypartition Resets to boot memory partition state
Auto-response options:
--autorespond RESPONSE Response to automatically provide for all prompts (NOT
RECOMMENDED)
Auto-response options:
--autorespond RESPONSE Response to automatically provide for all prompts
(NOT RECOMMENDED)
Output options:
--loglevel LEVEL How much output will be printed for what program is doing, one
of debug/info/warning/error/critical
--json Print output in JSON format
--csv Print output in CSV format
Output options:
--loglevel LEVEL How much output will be printed for what program is
doing, one of debug/info/warning/error/critical
--json Print output in JSON format
--csv Print output in CSV format
```
#### Detailed Option Descriptions
## Detailed Option Descriptions
--setsclk/--setmclk # [# # ...]:
This allows you to set a mask for the levels. For example, if a GPU has 8 clock levels,
@@ -240,21 +265,28 @@ Output options:
The Compute Profile accepts 1 or n parameters, either the Profile to select (see --showprofile for a list
of preset Power Profiles) or a quoted string of values for the CUSTOM profile.
NOTE: These values can vary based on the ASIC, and may include:
SCLK_PROFILE_ENABLE - Whether or not to apply the 3 following SCLK settings (0=disable,1=enable)
NOTE: This is a hidden field. If set to 0, the following 3 values are displayed as '-'
SCLK_UP_HYST - Delay before sclk is increased (in milliseconds)
SCLK_DOWN_HYST - Delay before sclk is decresed (in milliseconds)
SCLK_ACTIVE_LEVEL - Workload required before sclk levels change (in %)
MCLK_PROFILE_ENABLE - Whether or not to apply the 3 following MCLK settings (0=disable,1=enable)
NOTE: This is a hidden field. If set to 0, the following 3 values are displayed as '-'
MCLK_UP_HYST - Delay before mclk is increased (in milliseconds)
MCLK_DOWN_HYST - Delay before mclk is decresed (in milliseconds)
MCLK_ACTIVE_LEVEL - Workload required before mclk levels change (in %)
BUSY_SET_POINT - Threshold for raw activity level before levels change
FPS - Frames Per Second
USE_RLC_BUSY - When set to 1, DPM is switched up as long as RLC busy message is received
MIN_ACTIVE_LEVEL - Workload required before levels change (in %)
| Setting | Description |
|---------------------|----------------------------------------------------|
| SCLK_PROFILE_ENABLE | Whether or not to apply the 3 following SCLK settings (0=disable,1=enable) |
| | **NOTE: This is a hidden field. If set to 0, the following 3 values are displayed as '-** |
| SCLK_UP_HYST | Delay before sclk is increased (in milliseconds) |
| SCLK_DOWN_HYST | Delay before sclk is decresed (in milliseconds) |
| SCLK_ACTIVE_LEVEL | Workload required before sclk levels change (in %) |
| MCLK_PROFILE_ENABLE | Whether or not to apply the 3 following MCLK settings (0=disable,1=enable) |
| | **NOTE: This is a hidden field. If set to 0, the following 3 values are displayed as '-'** |
| MCLK_UP_HYST | Delay before mclk is increased (in milliseconds) |
| MCLK_DOWN_HYST | Delay before mclk is decresed (in milliseconds) |
| MCLK_ACTIVE_LEVEL | Workload required before mclk levels change (in %) |
Other settings:
| Setting | Description |
|------------------|---------------------------------------------------------------------------|
| BUSY_SET_POINT | Threshold for raw activity level before levels change |
| FPS | Frames Per Second |
| USE_RLC_BUSY | When set to 1, DPM is switched up as long as RLC busy message is received |
| MIN_ACTIVE_LEVEL | Workload required before levels change (in %) |
NOTES:
When a compute queue is detected, the COMPUTE Power Profile values will be automatically
@@ -306,16 +338,19 @@ This shows the RAS information for a given block. This includes enablement of th
ue - Uncorrectable errors
ce - Correctable errors
### Clock Type Descriptions
DCEFCLK - DCE (Display)
FCLK - Data fabric (VG20 and later) - Data flow from XGMI, Memory, PCIe
SCLK - GFXCLK (Graphics core)
Note - SOCCLK split from SCLK as of Vega10. Pre-Vega10 they were both controlled by SCLK
MCLK - GPU Memory (VRAM)
PCLK - PCIe bus
Note - This gives 2 speeds, PCIe Gen1 x1 and the highest available based on the hardware
SOCCLK - System clock (VG10 and later) - Data Fabric (DF), MM HUB, AT HUB, SYSTEM HUB, OSS, DFD
Note - DF split from SOCCLK as of Vega20. Pre-Vega20 they were both controlled by SOCCLK
## Clock Type Descriptions
| Clock type | Description |
| ---------- | --- |
| DCEFCLK | DCE (Display) |
| FCLK | Data fabric (VG20 and later) - Data flow from XGMI, Memory, PCIe |
| SCLK | GFXCLK (Graphics core) |
| | **Note - SOCCLK split from SCLK as of Vega10. Pre-Vega10 they were both controlled by SCLK** |
| MCLK | GPU Memory (VRAM) |
| PCLK | PCIe bus |
| | **Note - This gives 2 speeds, PCIe Gen1 x1 and the highest available based on the hardware** |
| SOCCLK | System clock (VG10 and later) - Data Fabric (DF), MM HUB, AT HUB, SYSTEM HUB, OSS, DFD |
| | **Note - DF split from SOCCLK as of Vega20. Pre-Vega20 they were both controlled by SOCCLK** |
--gpureset:
This flag will attempt to reset the GPU for a specified device. This will invoke the GPU reset through
@@ -355,7 +390,7 @@ is calculated in a generic sense.
as well as the total available for those partitions. The percentage shown there indicates the
amount of used memory in terms of current allocations
### OverDrive settings ####
## OverDrive settings
Enabling OverDrive requires both a card that support OverDrive and a driver parameter that enables its use.
Because OverDrive features can damage your card, most workstation and server GPUs cannot use OverDrive.
@@ -371,22 +406,21 @@ As an example, if the ppfeaturemask is set to 0xffffbfff (1111111111111111101111
then enabling the OverDrive bit would make it 0xffffffff (11111111111111111111111111111111).
These are the flags that require OverDrive functionality to be enabled for the flag to work:
--showclkvolt
--showvoltagerange
--showvc
--showsclkrange
--showmclkrange
--setslevel
--setmlevel
--setoverdrive
--setpoweroverdrive
--resetpoweroverdrive
--setvc
--setsrange
--setmrange
--showclkvolt
--showvoltagerange
--showvc
--showsclkrange
--showmclkrange
--setslevel
--setmlevel
--setoverdrive
--setpoweroverdrive
--resetpoweroverdrive
--setvc
--setsrange
--setmrange
#### Disclaimer
## Disclaimer
The information contained herein is for informational purposes only, and is subject to change without notice. While every precaution has been taken in the preparation of this document, it may contain technical inaccuracies, omissions and typographical errors, and AMD is under no obligation to update or otherwise correct this information. Advanced Micro Devices, Inc. makes no representations or warranties with respect to the accuracy or completeness of the contents of this document, and assumes no liability of any kind, including the implied warranties of noninfringement, merchantability or fitness for particular purposes, with respect to the operation or use of AMD hardware, software or other products described herein.
+16
View File
@@ -0,0 +1,16 @@
#!/usr/bin/env bash
# Build manpages using ronn
set -eu
set -o pipefail
if ! command -v ronn > /dev/null; then
echo "ERROR: no ronn found!" >&2
echo "Please follow installation instructions here:" >&2
echo "https://github.com/apjanke/ronn-ng" >&2
exit 1
fi
set -x
ronn ./README.md
@@ -966,6 +966,9 @@ def resetComputePartition(deviceList):
printLog(device, 'Permission denied', None)
elif ret == rsmi_status_t.RSMI_STATUS_NOT_SUPPORTED:
printLog(device, 'Not supported on the given system', None)
elif ret == rsmi_status_t.RSMI_STATUS_BUSY:
printLog(device, 'Device is currently busy, try again later',
None)
else:
rsmi_ret_ok(ret, device, 'reset_compute_partition')
printErrLog(device, 'Failed to reset the compute partition to boot state')
@@ -1002,6 +1005,9 @@ def resetMemoryPartition(deviceList):
printLog(device, 'Permission denied', None, addExtraLine)
elif ret == rsmi_status_t.RSMI_STATUS_NOT_SUPPORTED:
printLog(device, 'Not supported on the given system', None, addExtraLine)
elif ret == rsmi_status_t.RSMI_STATUS_BUSY:
printLog(device, 'Device is currently busy, try again later',
None)
else:
rsmi_ret_ok(ret, device, 'reset_memory_partition')
printErrLog(device, 'Failed to reset memory partition to boot state')
@@ -1603,6 +1609,9 @@ def setComputePartition(deviceList, computePartitionType):
%computePartitionType, None)
elif ret == rsmi_status_t.RSMI_STATUS_NOT_SUPPORTED:
printLog(device, 'Not supported on the given system', None)
elif ret == rsmi_status_t.RSMI_STATUS_BUSY:
printLog(device, 'Device is currently busy, try again later',
None)
else:
rsmi_ret_ok(ret, device, 'set_compute_partition')
printErrLog(device, 'Failed to retrieve compute partition, even though device supports it.')
@@ -1673,6 +1682,9 @@ def setMemoryPartition(deviceList, memoryPartition):
printLog(device, 'Permission denied', None, addExtraLine)
elif ret == rsmi_status_t.RSMI_STATUS_NOT_SUPPORTED:
printLog(device, 'Not supported on the given system', None, addExtraLine)
elif ret == rsmi_status_t.RSMI_STATUS_BUSY:
printLog(device, 'Device is currently busy, try again later',
None, addExtraLine)
else:
rsmi_ret_ok(ret, device, 'set_memory_partition')
printErrLog(device, 'Failed to retrieve memory partition, even though device supports it.')
+83 -10
View File
@@ -1062,6 +1062,9 @@ rsmi_status_t
rsmi_perf_determinism_mode_set(uint32_t dv_ind, uint64_t clkvalue) {
TRY
DEVICE_MUTEX
std::ostringstream ss;
ss << __PRETTY_FUNCTION__ << " | ======= start =======";
LOG_TRACE(ss);
// Set perf. level to performance determinism so that we can then set the power profile
rsmi_status_t ret = rsmi_dev_perf_level_set_v1(dv_ind,
@@ -1676,6 +1679,9 @@ rsmi_status_t rsmi_dev_od_volt_info_set(uint32_t dv_ind, uint32_t vpoint,
static void get_vc_region(uint32_t start_ind,
std::vector<std::string> *val_vec, rsmi_freq_volt_region_t *p) {
std::ostringstream ss;
ss << __PRETTY_FUNCTION__ << " | ======= start =======";
LOG_TRACE(ss);
assert(p != nullptr);
assert(val_vec != nullptr);
THROW_IF_NULLPTR_DEREF(p)
@@ -1686,6 +1692,9 @@ static void get_vc_region(uint32_t start_ind,
assert((*val_vec)[kOD_OD_RANGE_label_array_index] == "OD_RANGE:");
if ((val_vec->size() < kOD_OD_RANGE_label_array_index + 2) ||
((*val_vec)[kOD_OD_RANGE_label_array_index] != "OD_RANGE:") ) {
ss << __PRETTY_FUNCTION__ << " | ======= end ======= | returning "
<< getRSMIStatusString(RSMI_STATUS_UNEXPECTED_DATA);
LOG_TRACE(ss);
throw amd::smi::rsmi_exception(RSMI_STATUS_UNEXPECTED_DATA, __FUNCTION__);
}
od_value_pair_str_to_range((*val_vec)[start_ind], &p->freq_range);
@@ -1705,6 +1714,7 @@ static rsmi_status_t get_od_clk_volt_curve_regions(uint32_t dv_ind,
TRY
std::vector<std::string> val_vec;
rsmi_status_t ret;
std::ostringstream ss;
assert(num_regions != nullptr);
assert(p != nullptr);
@@ -1713,12 +1723,20 @@ static rsmi_status_t get_od_clk_volt_curve_regions(uint32_t dv_ind,
ret = GetDevValueVec(amd::smi::kDevPowerODVoltage, dv_ind, &val_vec);
if (ret != RSMI_STATUS_SUCCESS) {
ss << __PRETTY_FUNCTION__
<< " | Issue: could not retreive kDevPowerODVoltage" << "; returning "
<< getRSMIStatusString(ret);
LOG_ERROR(ss);
return ret;
}
// This is a work-around to handle systems where kDevPowerODVoltage is not
// fully supported yet.
if (val_vec.size() < 2) {
ss << __PRETTY_FUNCTION__
<< " | Issue: val_vec.size() < 2" << "; returning "
<< getRSMIStatusString(RSMI_STATUS_NOT_YET_IMPLEMENTED);
LOG_ERROR(ss);
return RSMI_STATUS_NOT_YET_IMPLEMENTED;
}
@@ -1726,8 +1744,17 @@ static rsmi_status_t get_od_clk_volt_curve_regions(uint32_t dv_ind,
assert((val_vec_size - kOD_VDDC_CURVE_start_index) > 0);
assert((val_vec_size - kOD_VDDC_CURVE_start_index)%2 == 0);
ss << __PRETTY_FUNCTION__
<< " | val_vec_size = " << std::dec
<< val_vec_size
<< " | kOD_VDDC_CURVE_start_index = " << kOD_VDDC_CURVE_start_index;
LOG_DEBUG(ss);
if (((val_vec_size - kOD_VDDC_CURVE_start_index) <= 0) ||
(((val_vec_size - kOD_VDDC_CURVE_start_index)%2 != 0))) {
ss << __PRETTY_FUNCTION__ << " | Issue: od vdd curve returned unexpected "
<< "data" << "; returning "
<< getRSMIStatusString(RSMI_STATUS_UNEXPECTED_SIZE);
LOG_ERROR(ss);
throw amd::smi::rsmi_exception(RSMI_STATUS_UNEXPECTED_SIZE, __FUNCTION__);
}
@@ -2980,6 +3007,9 @@ rsmi_dev_od_volt_info_get(uint32_t dv_ind, rsmi_od_volt_freq_data_t *odv) {
ss << __PRETTY_FUNCTION__ << "| ======= start =======";
LOG_TRACE(ss);
DEVICE_MUTEX
if (odv == nullptr) {
return RSMI_STATUS_INVALID_ARGS;
}
CHK_SUPPORT_NAME_ONLY(odv)
rsmi_status_t ret = get_od_clk_volt_info(dv_ind, odv);
@@ -3010,7 +3040,7 @@ rsmi_status_t rsmi_dev_od_volt_curve_regions_get(uint32_t dv_ind,
uint32_t *num_regions, rsmi_freq_volt_region_t *buffer) {
TRY
std::ostringstream ss;
ss << __PRETTY_FUNCTION__ << "| ======= start =======";
ss << __PRETTY_FUNCTION__ << " | ======= start =======";
LOG_TRACE(ss);
CHK_SUPPORT_NAME_ONLY((num_regions == nullptr || buffer == nullptr) ?
@@ -3022,6 +3052,12 @@ rsmi_status_t rsmi_dev_od_volt_curve_regions_get(uint32_t dv_ind,
DEVICE_MUTEX
rsmi_status_t ret = get_od_clk_volt_curve_regions(dv_ind, num_regions,
buffer);
if (*num_regions == 0) {
ret = RSMI_STATUS_NOT_SUPPORTED;
}
ss << __PRETTY_FUNCTION__ << " | ======= end ======= | returning "
<< getRSMIStatusString(ret);
LOG_TRACE(ss);
return ret;
CATCH
}
@@ -3969,7 +4005,6 @@ rsmi_status_t rsmi_dev_serial_number_get(uint32_t dv_ind,
if (ret != RSMI_STATUS_SUCCESS) {
return ret;
}
uint32_t ln = static_cast<uint32_t>(val_str.copy(serial_num, len));
serial_num[std::min(len - 1, ln)] = '\0';
@@ -4614,6 +4649,30 @@ rsmi_topo_get_link_type(uint32_t dv_ind_src, uint32_t dv_ind_dst,
rsmi_status_t status;
uint32_t node_ind_dst;
// handle the link type for CPU
if (dv_ind_dst == CPU_NODE_INDEX) {
// No CPU connected
if (kfd_node->numa_node_weight() == 0) {
return RSMI_STATUS_NOT_SUPPORTED;
}
amd::smi::IO_LINK_TYPE io_link_type =
kfd_node->numa_node_type();
switch (io_link_type) {
case amd::smi::IOLINK_TYPE_XGMI:
*type = RSMI_IOLINK_TYPE_XGMI;
*hops = 1;
return RSMI_STATUS_SUCCESS;
case amd::smi::IOLINK_TYPE_PCIEXPRESS:
*type = RSMI_IOLINK_TYPE_PCIEXPRESS;
// always be the same CPU node
*hops = 2;
return RSMI_STATUS_SUCCESS;
default:
return RSMI_STATUS_NOT_SUPPORTED;
}
}
int ret = smi.get_node_index(dv_ind_dst, &node_ind_dst);
if (ret == 0) {
@@ -4731,7 +4790,7 @@ get_compute_partition(uint32_t dv_ind, std::string &compute_partition) {
return ret;
}
switch (mapStringToRSMIComputePartitionTypes[compute_partition_str]) {
switch (mapStringToRSMIComputePartitionTypes.at(compute_partition_str)) {
case RSMI_COMPUTE_PARTITION_CPX:
case RSMI_COMPUTE_PARTITION_SPX:
case RSMI_COMPUTE_PARTITION_DPX:
@@ -4848,9 +4907,12 @@ rsmi_dev_compute_partition_set(uint32_t dv_ind,
ss << __PRETTY_FUNCTION__ << "| ======= start =======";
LOG_TRACE(ss);
REQUIRE_ROOT_ACCESS
if (!amd::smi::is_sudo_user()) {
return RSMI_STATUS_PERMISSION;
}
DEVICE_MUTEX
std::string newComputePartitionStr
= mapRSMIToStringComputePartitionTypes[compute_partition];
= mapRSMIToStringComputePartitionTypes.at(compute_partition);
std::string currentComputePartition;
switch (compute_partition) {
@@ -4868,6 +4930,7 @@ rsmi_dev_compute_partition_set(uint32_t dv_ind,
<< " | Device #: " << dv_ind
<< " | Type: "
<< devInfoTypesStrings.at(amd::smi::kDevComputePartition)
<< " | Data: " << newComputePartitionStr
<< " | Cause: requested setting was invalid"
<< " | Returning = "
<< getRSMIStatusString(RSMI_STATUS_INVALID_ARGS) << " |";
@@ -4886,6 +4949,7 @@ rsmi_dev_compute_partition_set(uint32_t dv_ind,
<< " | Device #: " << dv_ind
<< " | Type: "
<< devInfoTypesStrings.at(amd::smi::kDevComputePartition)
<< " | Data: " << newComputePartitionStr
<< " | Cause: not an available compute partition setting"
<< " | Returning = "
<< getRSMIStatusString(available_ret) << " |";
@@ -4913,7 +4977,7 @@ rsmi_dev_compute_partition_set(uint32_t dv_ind,
return ret_get;
}
rsmi_compute_partition_type_t currRSMIComputePartition
= mapStringToRSMIComputePartitionTypes[currentComputePartition];
= mapStringToRSMIComputePartitionTypes.at(currentComputePartition);
if (currRSMIComputePartition == compute_partition) {
ss << __PRETTY_FUNCTION__
<< " | ======= end ======= "
@@ -4928,6 +4992,15 @@ rsmi_dev_compute_partition_set(uint32_t dv_ind,
return RSMI_STATUS_SUCCESS;
}
ss << __PRETTY_FUNCTION__ << " | about to try writing |"
<< newComputePartitionStr
<< "| size of string = " << newComputePartitionStr.size()
<< "| size of c-string = "<< std::dec
<< sizeof(newComputePartitionStr.c_str())/sizeof(newComputePartitionStr[0])
<< "| sizeof string = " << std::dec
<< sizeof(newComputePartitionStr);
LOG_DEBUG(ss);
GET_DEV_FROM_INDX
int ret = dev->writeDevInfo(amd::smi::kDevComputePartition,
newComputePartitionStr);
@@ -4962,7 +5035,7 @@ static rsmi_status_t get_memory_partition(uint32_t dv_ind,
return ret;
}
switch (mapStringToMemoryPartitionTypes[val_str]) {
switch (mapStringToMemoryPartitionTypes.at(val_str)) {
case RSMI_MEMORY_PARTITION_NPS1:
case RSMI_MEMORY_PARTITION_NPS2:
case RSMI_MEMORY_PARTITION_NPS4:
@@ -5018,7 +5091,7 @@ rsmi_dev_memory_partition_set(uint32_t dv_ind,
}
std::string newMemoryPartition
= mapRSMIToStringMemoryPartitionTypes[memory_partition];
= mapRSMIToStringMemoryPartitionTypes.at(memory_partition);
std::string currentMemoryPartition;
switch (memory_partition) {
@@ -5061,7 +5134,7 @@ rsmi_dev_memory_partition_set(uint32_t dv_ind,
return ret_get;
}
rsmi_memory_partition_type_t currRSMIMemoryPartition
= mapStringToMemoryPartitionTypes[currentMemoryPartition];
= mapStringToMemoryPartitionTypes.at(currentMemoryPartition);
if (currRSMIMemoryPartition == memory_partition) {
ss << __PRETTY_FUNCTION__
<< " | ======= end ======= "
@@ -5205,7 +5278,7 @@ rsmi_status_t rsmi_dev_compute_partition_reset(uint32_t dv_ind) {
// Likely due to device not supporting it
if (bootState != "UNKNOWN") {
rsmi_compute_partition_type_t compute_partition =
mapStringToRSMIComputePartitionTypes[bootState];
mapStringToRSMIComputePartitionTypes.at(bootState);
ret = rsmi_dev_compute_partition_set(dv_ind, compute_partition);
}
ss << __PRETTY_FUNCTION__
@@ -5244,7 +5317,7 @@ rsmi_status_t rsmi_dev_memory_partition_reset(uint32_t dv_ind) {
// Likely due to device not supporting it
if (bootState != "UNKNOWN") {
rsmi_memory_partition_type_t memory_partition =
mapStringToMemoryPartitionTypes[bootState];
mapStringToMemoryPartitionTypes.at(bootState);
ret = rsmi_dev_memory_partition_set(dv_ind, memory_partition);
}
ss << __PRETTY_FUNCTION__
+69 -20
View File
@@ -628,14 +628,17 @@ int Device::openSysfsFileStream(DevInfoTypes type, T *fs, const char *str) {
int ret = isRegularFile(sysfs_path, &reg_file);
if (ret != 0) {
ss << "File did not exist - SYSFS file (" << sysfs_path
ss << __PRETTY_FUNCTION__ << " | Issue: File did not exist - SYSFS file ("
<< sysfs_path
<< ") for DevInfoInfoType (" << RocmSMI::devInfoTypesStrings.at(type)
<< "), returning " << std::to_string(ret);
LOG_ERROR(ss);
return ret;
}
if (!reg_file) {
ss << "File is not a regular file - SYSFS file (" << sysfs_path << ") for "
ss << __PRETTY_FUNCTION__
<< " | Issue: File is not a regular file - SYSFS file ("
<< sysfs_path << ") for "
<< "DevInfoInfoType (" << RocmSMI::devInfoTypesStrings.at(type) << "),"
<< " returning ENOENT (" << std::strerror(ENOENT) << ")";
LOG_ERROR(ss);
@@ -644,8 +647,9 @@ int Device::openSysfsFileStream(DevInfoTypes type, T *fs, const char *str) {
fs->open(sysfs_path);
if (!fs) {
ss << "Could not open - SYSFS file (" << sysfs_path << ") for "
if (!fs->is_open()) {
ss << __PRETTY_FUNCTION__
<< " | Issue: Could not open - SYSFS file (" << sysfs_path << ") for "
<< "DevInfoInfoType (" << RocmSMI::devInfoTypesStrings.at(type) << "), "
<< ", returning " << std::to_string(errno) << " ("
<< std::strerror(errno) << ")";
@@ -653,7 +657,8 @@ int Device::openSysfsFileStream(DevInfoTypes type, T *fs, const char *str) {
return errno;
}
ss << "Successfully opened SYSFS file (" << sysfs_path
ss << __PRETTY_FUNCTION__ << " | Successfully opened SYSFS file ("
<< sysfs_path
<< ") for DevInfoInfoType (" << RocmSMI::devInfoTypesStrings.at(type)
<< ")";
LOG_INFO(ss);
@@ -701,32 +706,51 @@ int Device::readDevInfoStr(DevInfoTypes type, std::string *retStr) {
ret = openSysfsFileStream(type, &fs);
if (ret != 0) {
ss << "Could not read device info string for DevInfoType ("
<< RocmSMI::devInfoTypesStrings.at(type)<< "), returning "
<< RocmSMI::devInfoTypesStrings.at(type) << "), returning "
<< std::to_string(ret);
LOG_ERROR(ss);
return ret;
}
fs >> *retStr;
std::string info = "Successfully read device info string for DevInfoType (" +
RocmSMI::devInfoTypesStrings.at(type) + "): " +
*retStr;
LOG_INFO(info);
fs.close();
ss << __PRETTY_FUNCTION__
<< "Successfully read device info string for DevInfoType (" +
RocmSMI::devInfoTypesStrings.at(type) + "): " + *retStr
<< " | "
<< (fs.is_open() ? " File stream is opened" : " File stream is closed")
<< " | " << (fs.bad() ? "[ERROR] Bad read operation" :
"[GOOD] No bad bit read, successful read operation")
<< " | " << (fs.fail() ? "[ERROR] Failed read - format error" :
"[GOOD] No fail - Successful read operation")
<< " | " << (fs.eof() ? "[ERROR] Failed read - EOF error" :
"[GOOD] No eof error - Successful read operation")
<< " | " << (fs.good() ? "[GOOD] read good - Successful read operation" :
"[ERROR] Failed read - good error");
LOG_INFO(ss);
return 0;
}
int Device::writeDevInfoStr(DevInfoTypes type, std::string valStr) {
auto tempPath = path_;
int Device::writeDevInfoStr(DevInfoTypes type, std::string valStr,
bool returnWriteErr) {
// returnWriteErr = false, backwards compatability (old calls)
// returnWriteErr = true, improvement - allows us to detect errors
// when writing to file
// (such as EBUSY)
auto sysfs_path = path_;
sysfs_path += "/device/";
sysfs_path += kDevAttribNameMap.at(type);
std::ofstream fs;
int ret;
std::ostringstream ss;
fs.rdbuf()->pubsetbuf(nullptr,0);
fs.flush();
fs.rdbuf()->pubsetbuf(0, 0);
ret = openSysfsFileStream(type, &fs, valStr.c_str());
if (ret != 0) {
ss << "Could not write device info string (" << valStr
fs.close();
ss << __PRETTY_FUNCTION__ << " | Issue: Could not open fileStream; "
<< "Could not write device info string (" << valStr
<< ") for DevInfoType (" << RocmSMI::devInfoTypesStrings.at(type)
<< "), returning " << std::to_string(ret);
LOG_ERROR(ss);
@@ -735,19 +759,39 @@ int Device::writeDevInfoStr(DevInfoTypes type, std::string valStr) {
// We'll catch any exceptions in rocm_smi.cc code.
if (fs << valStr) {
fs.flush();
fs.close();
ss << "Successfully wrote device info string (" << valStr
<< ") for DevInfoType (" << RocmSMI::devInfoTypesStrings.at(type)
<< "), returning RSMI_STATUS_SUCCESS";
LOG_INFO(ss);
ret = RSMI_STATUS_SUCCESS;
} else {
ss << "Could not write device info string (" << valStr
if (returnWriteErr) {
ret = errno;
} else {
ret = RSMI_STATUS_NOT_SUPPORTED;
}
fs.flush();
fs.close();
ss << __PRETTY_FUNCTION__ << " | Issue: Could not write to file; "
<< "Could not write device info string (" << valStr
<< ") for DevInfoType (" << RocmSMI::devInfoTypesStrings.at(type)
<< "), returning RSMI_STATUS_NOT_SUPPORTED";
<< "), returning " << getRSMIStatusString(ErrnoToRsmiStatus(ret));
ss << " | "
<< (fs.is_open() ? "[ERROR] File stream open" :
"[GOOD] File stream closed")
<< " | " << (fs.bad() ? "[ERROR] Bad write operation" :
"[GOOD] No bad bit write, successful write operation")
<< " | " << (fs.fail() ? "[ERROR] Failed write - format error" :
"[GOOD] No fail - Successful write operation")
<< " | " << (fs.eof() ? "[ERROR] Failed write - EOF error" :
"[GOOD] No eof error - Successful write operation")
<< " | " << (fs.good() ?
"[GOOD] Write good - Successful write operation" :
"[ERROR] Failed write - good error");
LOG_ERROR(ss);
ret = RSMI_STATUS_NOT_SUPPORTED;
}
fs.close();
return ret;
}
@@ -786,6 +830,9 @@ int Device::writeDevInfo(DevInfoTypes type, uint64_t val) {
}
int Device::writeDevInfo(DevInfoTypes type, std::string val) {
auto sysfs_path = path_;
sysfs_path += "/device/";
sysfs_path += kDevAttribNameMap.at(type);
switch (type) {
case kDevGPUMClk:
case kDevDCEFClk:
@@ -794,9 +841,10 @@ int Device::writeDevInfo(DevInfoTypes type, std::string val) {
case kDevPCIEClk:
case kDevPowerODVoltage:
case kDevSOCClk:
return writeDevInfoStr(type, val);
case kDevComputePartition:
case kDevMemoryPartition:
return writeDevInfoStr(type, val);
return writeDevInfoStr(type, val, true);
default:
return EINVAL;
@@ -929,6 +977,7 @@ int Device::readDevInfo(DevInfoTypes type, uint64_t *val) {
std::string tempStr;
int ret;
int tmp_val;
std::ostringstream ss;
switch (type) {
case kDevDevID:
@@ -496,6 +496,17 @@ rsmi_dev_gpu_metrics_info_get(uint32_t dv_ind, rsmi_gpu_metrics_t *smu) {
// a specific version.
*smu = {};
bool isRevisionExpected = ((dev->gpu_metrics_ver().content_revision == 1) ||
(dev->gpu_metrics_ver().content_revision == 2) ||
(dev->gpu_metrics_ver().content_revision == 3));
if (isRevisionExpected == false) {
ss << __PRETTY_FUNCTION__ << " | content revision was = "
<< print_unsigned_hex_and_int(dev->gpu_metrics_ver().content_revision)
<< ", expected version 1,2, or 3 | returning "
<< getRSMIStatusString(RSMI_STATUS_NOT_SUPPORTED);
LOG_ERROR(ss);
return RSMI_STATUS_NOT_SUPPORTED;
}
if (dev->gpu_metrics_ver().content_revision ==
RSMI_GPU_METRICS_API_CONTENT_VER_1) {
ret = GetDevBinaryBlob(amd::smi::kDevGpuMetrics, dv_ind,
+29 -1
View File
@@ -926,10 +926,15 @@ int KFDNode::get_cache_info(rsmi_gpu_cache_info_t *info) {
int cache_level = std::stoi(level);
if (cache_level < 0 ) continue;
std::string type = get_properties_from_file(prop_file, "type ");
int cache_type = std::stoi(type);
if (cache_type <= 0) continue;
// only count once
bool is_count_already = false;
for (unsigned int i=0; i < info->num_cache_types; i++) {
if (info->cache->cache_level == static_cast<uint32_t>(cache_level)) {
if (info->cache[i].cache_level == static_cast<uint32_t>(cache_level) &&
info->cache[i].flags == static_cast<uint32_t>(cache_type)) {
is_count_already = true;
break;
}
@@ -940,8 +945,10 @@ int KFDNode::get_cache_info(rsmi_gpu_cache_info_t *info) {
std::string size = get_properties_from_file(prop_file, "size ");
int cache_size = std::stoi(size);
if (cache_size <= 0) continue;
info->cache[info->num_cache_types].cache_level = cache_level;
info->cache[info->num_cache_types].cache_size_kb = cache_size;
info->cache[info->num_cache_types].flags = cache_type;
info->num_cache_types++;
} catch (...) {
continue;
@@ -1035,5 +1042,26 @@ int get_gpu_id(uint32_t node, uint64_t *gpu_id) {
return retVal;
}
// /sys/class/kfd/kfd/topology/nodes/*/properties | grep gfx_target_version
int KFDNode::get_gfx_target_version(uint64_t *gfx_target_version) {
std::ostringstream ss;
std::string properties_path = "/sys/class/kfd/kfd/topology/nodes/"
+ std::to_string(this->node_indx_) + "/properties";
uint64_t gfx_version = 0;
int ret = read_node_properties(this->node_indx_, "gfx_target_version",
&gfx_version);
*gfx_target_version = gfx_version;
ss << __PRETTY_FUNCTION__
<< " | File: " << properties_path
<< " | Successfully read node #" << std::to_string(this->node_indx_)
<< " for gfx_target_version"
<< " | Data (gfx_target_version) *gfx_target_version = "
<< std::to_string(*gfx_target_version)
<< " | return = " << std::to_string(ret)
<< " | ";
LOG_DEBUG(ss);
return ret;
}
} // namespace smi
} // namespace amd
@@ -450,6 +450,12 @@ RocmSMI::Initialize(uint64_t flags) {
// store each device boot partition state, if file doesn't exist
dev->storeDevicePartitions(dv_ind);
}
// Assists displaying GPU information after device enumeration
// Otherwise GPU related info will not be discoverable
if (ROCmLogging::Logger::getInstance()->isLoggerEnabled()) {
logSystemDetails();
}
// Leaving below to help debug temp file issues
// displayAppTmpFilesContent();
std::string amdGPUDeviceList = displayAllDevicePaths(devices_);
+201 -7
View File
@@ -618,9 +618,19 @@ std::tuple<bool, std::string> readTmpFile(uint32_t dv_ind,
}
// wrapper to return string expression of a rsmi_status_t return
std::string getRSMIStatusString(rsmi_status_t ret) {
// rsmi_status_t ret - return value of RSMI API function
// bool fullStatus - defaults to true, set to false to chop off description
// Returns:
// string - if fullStatus == true, returns full decription of return value
// ex. 'RSMI_STATUS_SUCCESS: The function has been executed successfully.'
// string - if fullStatus == false, returns a minimalized return value
// ex. 'RSMI_STATUS_SUCCESS'
std::string getRSMIStatusString(rsmi_status_t ret, bool fullStatus) {
const char *err_str;
rsmi_status_string(ret, &err_str);
if (!fullStatus) {
return splitString(std::string(err_str), ':');
}
return std::string(err_str);
}
@@ -639,9 +649,13 @@ std::string getRSMIStatusString(rsmi_status_t ret) {
// Expressed as big endian or little endian.
// Big Endian (BE), multi-bit symbols encoded as big endian (MSB first)
// Little Endian (LE), multi-bit symbols encoded as little endian (LSB first)
// string rocm_lib_path = Path to library
// string rocm_build_type = Release or debug
// string rocm_build_date = Creation date of library
// string dev_gfx_versions = GPU target graphics version
std::tuple<bool, std::string, std::string, std::string, std::string,
std::string, std::string, std::string, std::string,
std::string, std::string, std::string>
std::string, std::string, std::string, std::string, std::string>
getSystemDetails(void) {
struct utsname buf;
bool errorDetected = false;
@@ -656,7 +670,9 @@ std::tuple<bool, std::string, std::string, std::string, std::string,
std::string endianness = "<undefined>";
std::string rocm_lib_path = "<undefined>";
std::string rocm_build_type = "<undefined>";
std::string rocm_build_date = "<undefined>";
std::string rocm_env_variables = "<undefined>";
std::string dev_gfx_versions = "<undefined>";
if (uname(&buf) < 0) {
errorDetected = true;
@@ -693,11 +709,20 @@ std::tuple<bool, std::string, std::string, std::string, std::string,
}
rocm_build_type = getBuildType();
rocm_lib_path = getMyLibPath();
rocm_build_date = getFileCreationDate(rocm_lib_path);
rocm_env_variables = RocmSMI::getInstance().getRSMIEnvVarInfo();
std::queue<std::string> devGraphicsVersions = getAllDeviceGfxVers();
if (devGraphicsVersions.empty() == false) {
dev_gfx_versions = "";
while (devGraphicsVersions.empty() == false) {
dev_gfx_versions += "\n\t" + devGraphicsVersions.front();
devGraphicsVersions.pop();
}
}
return std::make_tuple(errorDetected, sysname, nodename, release,
version, machine, domainName, os_distribution,
endianness, rocm_build_type, rocm_lib_path,
rocm_env_variables);
rocm_build_date, rocm_env_variables, dev_gfx_versions);
}
// If logging is enabled through RSMI_LOGGING environment variable.
@@ -706,10 +731,11 @@ void logSystemDetails(void) {
std::ostringstream ss;
bool errorDetected;
std::string sysname, node, release, version, machine, domain, distName,
endianness, rocm_build_type, lib_path, rocm_env_vars;
endianness, rocm_build_type, lib_path, build_date, rocm_env_vars,
dev_gfx_versions;
std::tie(errorDetected, sysname, node, release, version, machine, domain,
distName, endianness, rocm_build_type, lib_path,
rocm_env_vars) = getSystemDetails();
distName, endianness, rocm_build_type, lib_path, build_date,
rocm_env_vars, dev_gfx_versions) = getSystemDetails();
if (errorDetected == false) {
ss << "====== Gathered system details ============\n"
<< "SYSTEM NAME: " << sysname << "\n"
@@ -722,7 +748,9 @@ void logSystemDetails(void) {
<< "ENDIANNESS: " << endianness << "\n"
<< "ROCM BUILD TYPE: " << rocm_build_type << "\n"
<< "ROCM-SMI-LIB PATH: " << lib_path << "\n"
<< "ROCM ENV VARIABLES: " << rocm_env_vars << "\n";
<< "ROCM-SMI-LIB BUILD DATE: " << build_date << "\n"
<< "ROCM ENV VARIABLES: " << rocm_env_vars
<< "AMD GFX VERSIONS: " << dev_gfx_versions << "\n";
LOG_INFO(ss);
} else {
ss << "====== Gathered system details ============\n"
@@ -873,6 +901,13 @@ std::string getMyLibPath(void) {
return path;
}
std::string getFileCreationDate(std::string path) {
struct stat t_stat;
stat(path.c_str(), &t_stat);
struct tm *timeinfo = localtime(&t_stat.st_ctime); // NOLINT
return removeNewLines(std::string(asctime(timeinfo))); // NOLINT
}
rsmi_status_t getBDFString(uint64_t bdf_id, std::string& bfd_str)
{
auto result = rsmi_status_t::RSMI_STATUS_SUCCESS;
@@ -1016,5 +1051,164 @@ std::string power_type_string(RSMI_POWER_TYPE type) {
return powerTypesToString.at(type);
}
std::string splitString(std::string str, char delim) {
std::vector<std::string> tokens;
std::stringstream ss(str);
std::string token;
if (str.empty()) {
return "";
}
while (std::getline(ss, token, delim)) {
tokens.push_back(token);
return token; // return 1st match
}
}
static std::string pt_rng_Mhz(std::string title, rsmi_range *r) {
std::ostringstream ss;
if (r == nullptr) {
ss << "pt_rng_Mhz | rsmi_range r = nullptr\n";
return ss.str();
}
ss << title;
ss << r->lower_bound/1000000 << " to "
<< r->upper_bound/1000000 << " MHz" << "\n";
return ss.str();
}
static std::string pt_rng_mV(std::string title, rsmi_range *r) {
std::ostringstream ss;
if (r == nullptr) {
ss << "pt_rng_mV | rsmi_range r = nullptr\n";
return ss.str();
}
ss << title;
ss << r->lower_bound << " to " << r->upper_bound
<< " mV" << "\n";
return ss.str();
}
static std::string print_pnt(rsmi_od_vddc_point_t *pt) {
std::ostringstream ss;
ss << "\t\t** Frequency: " << pt->frequency/1000000 << " MHz\n";
ss << "\t\t** Voltage: " << pt->voltage << " mV\n";
return ss.str();
}
static std::string pt_vddc_curve(rsmi_od_volt_curve *c) {
std::ostringstream ss;
if (c == nullptr) {
ss << "pt_vddc_curve | rsmi_od_volt_curve c = nullptr\n";
return ss.str();
}
for (uint32_t i = 0; i < RSMI_NUM_VOLTAGE_CURVE_POINTS; ++i) {
ss << print_pnt(&c->vc_points[i]);
}
return ss.str();
}
std::string print_rsmi_od_volt_freq_data_t(rsmi_od_volt_freq_data_t *odv) {
std::ostringstream ss;
if (odv == nullptr) {
ss << "rsmi_od_volt_freq_data_t odv = nullptr\n";
return ss.str();
}
ss << pt_rng_Mhz("\t**Current SCLK frequency range: ", &odv->curr_sclk_range);
ss << pt_rng_Mhz("\t**Current MCLK frequency range: ", &odv->curr_mclk_range);
ss << pt_rng_Mhz("\t**Min/Max Possible SCLK frequency range: ",
&odv->sclk_freq_limits);
ss << pt_rng_Mhz("\t**Min/Max Possible MCLK frequency range: ",
&odv->mclk_freq_limits);
ss << "\t**Current Freq/Volt. curve: " << "\n";
ss << pt_vddc_curve(&odv->curve);
ss << "\t**Number of Freq./Volt. regions: " << odv->num_regions << "\n\n";
return ss.str();
}
std::string print_odv_region(rsmi_freq_volt_region_t *region) {
std::ostringstream ss;
ss << pt_rng_Mhz("\t\tFrequency range: ", &region->freq_range);
ss << pt_rng_mV("\t\tVoltage range: ", &region->volt_range);
return ss.str();
}
std::string print_rsmi_od_volt_freq_regions(uint32_t num_regions,
rsmi_freq_volt_region_t *regions) {
std::ostringstream ss;
if (regions == nullptr) {
ss << "rsmi_freq_volt_region_t regions = nullptr\n";
return ss.str();
}
for (uint32_t i = 0; i < num_regions; ++i) {
ss << "\tRegion " << i << ": " << "\n";
ss << print_odv_region(&regions[i]);
}
return ss.str();
}
bool is_sudo_user() {
std::ostringstream ss;
bool isRunningWithSudo = false;
auto myUID = getuid();
auto myPrivledges = geteuid();
if ((myUID == myPrivledges) && (myPrivledges == 0)) {
isRunningWithSudo = true;
}
ss << __PRETTY_FUNCTION__ << (isRunningWithSudo ? " | running as sudoer" :
" | NOT running as sudoer");
LOG_DEBUG(ss);
return isRunningWithSudo;
}
rsmi_status_t rsmi_get_gfx_target_version(uint32_t dv_ind,
std::string *gfx_version) {
std::ostringstream ss;
uint64_t kfd_gfx_version = 0;
GET_DEV_AND_KFDNODE_FROM_INDX
int ret = kfd_node->get_gfx_target_version(&kfd_gfx_version);
if (ret == 0) {
ss << "gfx" << kfd_gfx_version;
*gfx_version = ss.str();
return RSMI_STATUS_SUCCESS;
} else {
*gfx_version = "Unknown";
return RSMI_STATUS_NOT_SUPPORTED;
}
}
std::queue<std::string> getAllDeviceGfxVers() {
uint32_t num_monitor_devs = 0;
rsmi_status_t ret;
std::queue<std::string> deviceGfxVersions;
std::string response = "";
std::string dev_gfx_ver = "";
ret = rsmi_num_monitor_devices(&num_monitor_devs);
if (ret != RSMI_STATUS_SUCCESS || num_monitor_devs == 0) {
response = "N/A - No AMD devices detected";
deviceGfxVersions.push(response);
return deviceGfxVersions;
}
for (uint32_t i = 0; i < num_monitor_devs; ++i) {
ret = amd::smi::rsmi_get_gfx_target_version(i , &dev_gfx_ver);
response = "Device[" + std::to_string(i) + "]: ";
if (ret != RSMI_STATUS_SUCCESS) {
deviceGfxVersions.push(response + getRSMIStatusString(ret, false));
} else {
deviceGfxVersions.push(response + std::string(dev_gfx_ver));
}
}
return deviceGfxVersions;
}
} // namespace smi
} // namespace amd
+1 -1
View File
@@ -3,7 +3,7 @@
#
message("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&")
message(" CMake AMD SMI (Library) ")
message(" CMake AMD SMI C/C++ Library ")
message("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&")
message("")
+67 -78
View File
@@ -330,6 +330,25 @@ amdsmi_status_t amdsmi_get_cpusocket_info(
return AMDSMI_STATUS_SUCCESS;
}
amdsmi_status_t amdsmi_get_cpucore_info(
amdsmi_processor_handle core_handle,
uint32_t core_id) {
AMDSMI_CHECK_INIT();
if (core_handle == nullptr) {
return AMDSMI_STATUS_INVAL;
}
amd::smi::AMDSmiProcessor* core = nullptr;
amdsmi_status_t r = amd::smi::AMDSmiSystem::getInstance()
.handle_to_processor(core_handle, &core);
if (r != AMDSMI_STATUS_SUCCESS) return r;
core_id = static_cast<amd::smi::AMDSmiCpuCore*>(core)->get_core_id();
return AMDSMI_STATUS_SUCCESS;
}
#endif
amdsmi_status_t amdsmi_get_processor_handles(amdsmi_socket_handle socket_handle,
@@ -446,7 +465,7 @@ amdsmi_status_t amdsmi_get_gpu_board_info(amdsmi_processor_handle processor_hand
AMDSMI_CHECK_INIT();
if (board_info == NULL) {
if (board_info == nullptr) {
return AMDSMI_STATUS_INVAL;
}
@@ -466,15 +485,10 @@ amdsmi_status_t amdsmi_get_gpu_board_info(amdsmi_processor_handle processor_hand
status = rsmi_wrapper(rsmi_dev_name_get, processor_handle,
board_info->product_name, AMDSMI_PRODUCT_NAME_LENGTH);
if (board_info->product_serial[0] == '\0') {
status = rsmi_wrapper(rsmi_dev_serial_number_get, processor_handle,
status = rsmi_wrapper(rsmi_dev_serial_number_get, processor_handle,
board_info->product_serial, AMDSMI_NORMAL_STRING_LENGTH);
}
}
// Get FRU ID
// Get manufacturer name
return AMDSMI_STATUS_SUCCESS;
}
@@ -496,12 +510,29 @@ amdsmi_status_t amdsmi_get_gpu_cache_info(
processor_handle, &rsmi_info);
if (status != AMDSMI_STATUS_SUCCESS)
return status;
// Sysfs cache type
#define HSA_CACHE_TYPE_DATA 0x00000001
#define HSA_CACHE_TYPE_INSTRUCTION 0x00000002
#define HSA_CACHE_TYPE_CPU 0x00000004
#define HSA_CACHE_TYPE_HSACU 0x00000008
info->num_cache_types = rsmi_info.num_cache_types;
for (unsigned int i =0; i < rsmi_info.num_cache_types; i++) {
info->cache[i].cache_size_kb = rsmi_info.cache[i].cache_size_kb;
info->cache[i].cache_level = rsmi_info.cache[i].cache_level;
// convert from sysfs type to CRAT type(HSA Cache Affinity type)
info->cache[i].flags = 0;
if (rsmi_info.cache[i].flags & HSA_CACHE_TYPE_DATA)
info->cache[i].flags |= CACHE_FLAGS_DATA_CACHE;
if (rsmi_info.cache[i].flags & HSA_CACHE_TYPE_INSTRUCTION)
info->cache[i].flags |= CACHE_FLAGS_INST_CACHE;
if (rsmi_info.cache[i].flags & HSA_CACHE_TYPE_CPU)
info->cache[i].flags |= CACHE_FLAGS_CPU_CACHE;
if (rsmi_info.cache[i].flags & HSA_CACHE_TYPE_HSACU)
info->cache[i].flags |= CACHE_FLAGS_SIMD_CACHE;
}
return AMDSMI_STATUS_SUCCESS;
}
@@ -537,7 +568,7 @@ amdsmi_status_t amdsmi_get_gpu_vram_usage(amdsmi_processor_handle processor_hand
AMDSMI_CHECK_INIT();
if (vram_info == NULL) {
if (vram_info == nullptr) {
return AMDSMI_STATUS_INVAL;
}
@@ -1091,9 +1122,8 @@ amdsmi_get_gpu_compute_process_gpus(uint32_t pid, uint32_t *dv_indices,
amdsmi_status_t amdsmi_get_gpu_ecc_count(amdsmi_processor_handle processor_handle,
amdsmi_gpu_block_t block, amdsmi_error_count_t *ec) {
AMDSMI_CHECK_INIT();
// nullptr api supported
if (ec == nullptr)
return AMDSMI_STATUS_INVAL;
return rsmi_wrapper(rsmi_dev_ecc_count_get, processor_handle,
static_cast<rsmi_gpu_block_t>(block),
reinterpret_cast<rsmi_error_count_t*>(ec));
@@ -1101,9 +1131,8 @@ amdsmi_status_t amdsmi_get_gpu_ecc_count(amdsmi_processor_handle processor_hand
amdsmi_status_t amdsmi_get_gpu_ecc_enabled(amdsmi_processor_handle processor_handle,
uint64_t *enabled_blocks) {
AMDSMI_CHECK_INIT();
// nullptr api supported
if (enabled_blocks == nullptr)
return AMDSMI_STATUS_INVAL;
return rsmi_wrapper(rsmi_dev_ecc_enabled_get, processor_handle,
enabled_blocks);
}
@@ -1111,9 +1140,8 @@ amdsmi_status_t amdsmi_get_gpu_ecc_status(amdsmi_processor_handle processor_han
amdsmi_gpu_block_t block,
amdsmi_ras_err_state_t *state) {
AMDSMI_CHECK_INIT();
// nullptr api supported
if (state == nullptr)
return AMDSMI_STATUS_INVAL;
return rsmi_wrapper(rsmi_dev_ecc_status_get, processor_handle,
static_cast<rsmi_gpu_block_t>(block),
reinterpret_cast<rsmi_ras_err_state_t*>(state));
@@ -1123,9 +1151,8 @@ amdsmi_status_t amdsmi_get_gpu_metrics_info(
amdsmi_processor_handle processor_handle,
amdsmi_gpu_metrics_t *pgpu_metrics) {
AMDSMI_CHECK_INIT();
// nullptr api supported
if (pgpu_metrics == nullptr)
return AMDSMI_STATUS_INVAL;
return rsmi_wrapper(rsmi_dev_gpu_metrics_info_get, processor_handle,
reinterpret_cast<rsmi_gpu_metrics_t*>(pgpu_metrics));
}
@@ -1212,9 +1239,8 @@ amdsmi_status_t
uint32_t sensor_ind,
amdsmi_power_profile_status_t *status) {
AMDSMI_CHECK_INIT();
// nullptr api supported
if (status == nullptr)
return AMDSMI_STATUS_INVAL;
return rsmi_wrapper(rsmi_dev_power_profile_presets_get, processor_handle,
sensor_ind,
reinterpret_cast<rsmi_power_profile_status_t*>(status));
@@ -1233,15 +1259,16 @@ amdsmi_status_t
reserved,
static_cast<rsmi_power_profile_preset_masks_t>(profile));
}
amdsmi_status_t amdsmi_get_gpu_perf_level(amdsmi_processor_handle processor_handle,
amdsmi_dev_perf_level_t *perf) {
AMDSMI_CHECK_INIT();
// nullptr api supported
if (perf == nullptr)
return AMDSMI_STATUS_INVAL;
return rsmi_wrapper(rsmi_dev_perf_level_get, processor_handle,
reinterpret_cast<rsmi_dev_perf_level_t*>(perf));
}
amdsmi_status_t
amdsmi_set_gpu_perf_level(amdsmi_processor_handle processor_handle,
amdsmi_dev_perf_level_t perf_lvl) {
@@ -1265,37 +1292,44 @@ amdsmi_status_t amdsmi_get_gpu_pci_bandwidth(amdsmi_processor_handle processor_h
amdsmi_status_t amdsmi_get_clk_freq(amdsmi_processor_handle processor_handle,
amdsmi_clk_type_t clk_type, amdsmi_frequencies_t *f) {
AMDSMI_CHECK_INIT();
if (f == nullptr)
return AMDSMI_STATUS_INVAL;
// nullptr api supported
// Get from gpu_metrics
if (clk_type == CLK_TYPE_VCLK0 ||
clk_type == CLK_TYPE_VCLK1 ||
clk_type == CLK_TYPE_DCLK0 ||
clk_type == CLK_TYPE_DCLK1 ) {
// when f == nullptr -> check if metrics are supported
amdsmi_gpu_metrics_t metric_info;
amdsmi_gpu_metrics_t * metric_info_p = nullptr;
if (f != nullptr) {
metric_info_p = &metric_info;
}
// when metric_info_p == nullptr - this will not return AMDSMI_STATUS_SUCCESS
auto r_status = amdsmi_get_gpu_metrics_info(
processor_handle, &metric_info);
processor_handle, metric_info_p);
if (r_status != AMDSMI_STATUS_SUCCESS)
return r_status;
f->num_supported = 1;
if (clk_type == CLK_TYPE_VCLK0) {
f->current = metric_info.current_vclk0;
f->frequency[0] = metric_info.average_vclk0_frequency;
f->current = metric_info_p->current_vclk0;
f->frequency[0] = metric_info_p->average_vclk0_frequency;
}
if (clk_type == CLK_TYPE_VCLK1) {
f->current = metric_info.current_vclk1;
f->frequency[0] = metric_info.average_vclk1_frequency;
f->current = metric_info_p->current_vclk1;
f->frequency[0] = metric_info_p->average_vclk1_frequency;
}
if (clk_type == CLK_TYPE_DCLK0) {
f->current = metric_info.current_dclk0;
f->frequency[0] = metric_info.average_dclk0_frequency;
f->current = metric_info_p->current_dclk0;
f->frequency[0] = metric_info_p->average_dclk0_frequency;
}
if (clk_type == CLK_TYPE_DCLK1) {
f->current = metric_info.current_dclk1;
f->frequency[0] = metric_info.average_dclk1_frequency;
f->current = metric_info_p->current_dclk1;
f->frequency[0] = metric_info_p->average_dclk1_frequency;
}
return r_status;
@@ -1310,7 +1344,7 @@ amdsmi_status_t amdsmi_set_clk_freq(amdsmi_processor_handle processor_handle,
amdsmi_clk_type_t clk_type, uint64_t freq_bitmask) {
AMDSMI_CHECK_INIT();
// Not support the clock type read from gpu_metrics
// Not support the clock type write into gpu_metrics
if (clk_type == CLK_TYPE_VCLK0 ||
clk_type == CLK_TYPE_VCLK1 ||
clk_type == CLK_TYPE_DCLK0 ||
@@ -2950,51 +2984,6 @@ amdsmi_status_t amdsmi_get_metrics_table(amdsmi_cpusocket_handle socket_handle,
return AMDSMI_STATUS_SUCCESS;
}
amdsmi_status_t amdsmi_get_number_of_cpu_sockets(uint32_t sockets)
{
amdsmi_status_t status = amd::smi::AMDSmiSystem::getInstance().get_cpu_sockets(sockets);
if (status != AMDSMI_STATUS_SUCCESS)
return status;
return AMDSMI_STATUS_SUCCESS;
}
amdsmi_status_t amdsmi_get_number_of_cpu_cores(uint32_t cpus)
{
amdsmi_status_t status = amd::smi::AMDSmiSystem::getInstance().get_cpu_cores(cpus);
if (status != AMDSMI_STATUS_SUCCESS)
return status;
return AMDSMI_STATUS_SUCCESS;
}
amdsmi_status_t amdsmi_get_cpu_threads_per_core(uint32_t threads)
{
amdsmi_status_t status = amd::smi::AMDSmiSystem::getInstance().get_threads_per_core(threads);
if (status != AMDSMI_STATUS_SUCCESS)
return status;
return AMDSMI_STATUS_SUCCESS;
}
amdsmi_status_t amdsmi_get_cpu_family(uint32_t family)
{
amdsmi_status_t status = amd::smi::AMDSmiSystem::getInstance().get_cpu_family(family);
if (status != AMDSMI_STATUS_SUCCESS)
return status;
return AMDSMI_STATUS_SUCCESS;
}
amdsmi_status_t amdsmi_get_cpu_model(uint32_t model)
{
amdsmi_status_t status = amd::smi::AMDSmiSystem::getInstance().get_cpu_model(model);
if (status != AMDSMI_STATUS_SUCCESS)
return status;
return AMDSMI_STATUS_SUCCESS;
}
amdsmi_status_t amdsmi_first_online_core_on_cpu_socket(amdsmi_cpusocket_handle socket_handle,
uint32_t sock_ind, uint32_t *pcore_ind)
{
+1 -1
View File
@@ -86,7 +86,7 @@ amdsmi_status_t AMDSmiDrm::init() {
int fd = -1;
amdsmi_status_t status = lib_loader_.load("libdrm.so");
amdsmi_status_t status = lib_loader_.load("libdrm.so.2");
if (status != AMDSMI_STATUS_SUCCESS) {
return status;
}
+26 -14
View File
@@ -116,29 +116,41 @@ amdsmi_status_t smi_amdgpu_get_board_info(amd::smi::AMDSmiGPUDevice* device, amd
return AMDSMI_STATUS_NOT_SUPPORTED;
}
SMIGPUDEVICE_MUTEX(device->get_mutex())
std::string product_name_path = "/sys/class/drm/" + device->get_gpu_path() + std::string("/device/product_name");
std::string product_number_path = "/sys/class/drm/" + device->get_gpu_path() + std::string("/device/product_number");
std::string serial_number_path = "/sys/class/drm/" + device->get_gpu_path() + std::string("/device/serial_number");
std::string model_number_path = "/sys/class/drm/" + device->get_gpu_path() + std::string("/device/product_number");
std::string product_serial_path = "/sys/class/drm/" + device->get_gpu_path() + std::string("/device/serial_number");
std::string fru_id_path = "/sys/class/drm/" + device->get_gpu_path() + std::string("/device/fru_id");
std::string manufacturer_name_path = "/sys/class/drm/" + device->get_gpu_path() + std::string("/device/manufacturer");
std::string product_name_path = "/sys/class/drm/" + device->get_gpu_path() + std::string("/device/product_name");
FILE *fp;
fp = fopen(product_name_path.c_str(), "rb");
if (fp) {
fgets(info->product_name, sizeof(info->product_name), fp);
fclose(fp);
}
fp = fopen(product_number_path.c_str(), "rb");
fp = fopen(model_number_path.c_str(), "rb");
if (fp) {
fgets(info->model_number, sizeof(info->model_number), fp);
fclose(fp);
}
fp = fopen(serial_number_path.c_str(), "rb");
fp = fopen(product_serial_path.c_str(), "rb");
if (fp) {
fscanf(fp, "%lx", &info->product_serial);
fgets(info->product_serial, sizeof(info->product_serial), fp);
fclose(fp);
}
fp = fopen(fru_id_path.c_str(), "rb");
if (fp) {
fgets(info->fru_id, sizeof(info->fru_id), fp);
fclose(fp);
}
fp = fopen(manufacturer_name_path.c_str(), "rb");
if (fp) {
fgets(info->manufacturer_name, sizeof(info->manufacturer_name), fp);
fclose(fp);
}
fp = fopen(product_name_path.c_str(), "rb");
if (fp) {
fgets(info->product_name, sizeof(info->product_name), fp);
fclose(fp);
}
@@ -109,7 +109,7 @@ void TestErrCntRead::Run(void) {
}
// Verify api support checking functionality is working
err = amdsmi_get_gpu_ecc_enabled(processor_handles_[i], nullptr);
ASSERT_EQ(err, AMDSMI_STATUS_INVAL);
ASSERT_EQ(err, AMDSMI_STATUS_NOT_SUPPORTED);
continue;
} else {
@@ -150,7 +150,7 @@ void TestErrCntRead::Run(void) {
// Verify api support checking functionality is working
err = amdsmi_get_gpu_ecc_count(processor_handles_[i], static_cast<amdsmi_gpu_block_t>(b),
nullptr);
ASSERT_EQ(err, AMDSMI_STATUS_INVAL);
ASSERT_EQ(err, AMDSMI_STATUS_NOT_SUPPORTED);
} else {
CHK_ERR_ASRT(err)
@@ -107,6 +107,9 @@ void TestFanRead::Run(void) {
std::cout << "\t**" << ": " <<
"Not supported on this machine" << std::endl;
}
// Verify api support checking functionality is working
err = amdsmi_get_gpu_fan_speed(processor_handles_[i], 0, nullptr);
ASSERT_EQ(err, AMDSMI_STATUS_NOT_SUPPORTED);
return;
} else {
CHK_ERR_ASRT(err)
@@ -128,7 +128,7 @@ void TestFrequenciesRead::Run(void) {
": Not supported on this machine" << std::endl;
// Verify api support checking functionality is working
err = amdsmi_get_clk_freq(processor_handles_[i], t, nullptr);
ASSERT_EQ(err, AMDSMI_STATUS_INVAL);
ASSERT_EQ(err, AMDSMI_STATUS_NOT_SUPPORTED);
return;
}
@@ -5,7 +5,7 @@
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 022, Advanced Micro Devices, Inc.
* Copyright (c) 2020-2023, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
@@ -106,20 +106,25 @@ void TestPerfDeterminism::Run(void) {
err = amdsmi_get_gpu_od_volt_info(processor_handles_[i], &odv);
if (err == AMDSMI_STATUS_NOT_SUPPORTED) {
IF_VERB(STANDARD) {
std::cout << "\t** Not supported on this machine" << std::endl;
std::cout << "\t** Not supported on this machine\n";
}
return;
}
else{
} else if (err == AMDSMI_STATUS_SUCCESS) {
clkvalue = (odv.curr_sclk_range.lower_bound/1000000) + 50;
} else {
IF_VERB(STANDARD) {
std::cout << "\t** Unable to retrieve lower bound sclk, continue.. \n";
}
continue;
}
std::cout << "About to rsmi_perf_determinism_mode_set() -->\n";
err = amdsmi_set_gpu_perf_determinism_mode(processor_handles_[i], clkvalue);
if (err == AMDSMI_STATUS_NOT_SUPPORTED) {
IF_VERB(STANDARD) {
std::cout << "\t**Not supported on this machine" << std::endl;
}
return;
continue;
} else {
ret = amdsmi_get_gpu_perf_level(processor_handles_[i], &pfl);
CHK_ERR_ASRT(ret)
@@ -138,7 +143,6 @@ void TestPerfDeterminism::Run(void) {
std::cout << "\t**New Perf Level:" << GetPerfLevelStr(pfl) <<
std::endl;
}
return;
}
}
} // END - SET SUPPORTED
} // END - DEVICE LOOP
}
@@ -160,6 +160,7 @@ void TestVoltCurvRead::Run(void) {
err = amdsmi_get_gpu_od_volt_info(processor_handles_[i], &odv);
if (err == AMDSMI_STATUS_NOT_SUPPORTED
|| err == AMDSMI_STATUS_NOT_YET_IMPLEMENTED) {
//TODO add perf_level tests
IF_VERB(STANDARD) {
std::cout <<
"\t** amdsmi_get_gpu_od_volt_info: Not supported on this machine"
+1 -9
View File
@@ -114,19 +114,11 @@ def main():
library_path = os.path.join(os.path.dirname(__file__), library)
line_to_replace = "_libraries['{}'] = ctypes.CDLL('{}')".format(library_name, library_path)
new_line = f"""from pathlib import Path
libamd_smi_cpack = Path("@CPACK_PACKAGING_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@/{library_name}")
libamd_smi_optrocm = Path("/opt/rocm/lib/{library_name}")
libamd_smi_parent_dir = Path(__file__).resolve().parent / "{library_name}"
libamd_smi_cwd = Path.cwd() / "{library_name}"
try:
if libamd_smi_cpack.is_file():
# try to find library in install directory provided by CMake
_libraries['{library_name}'] = ctypes.CDLL(libamd_smi_cpack)
elif libamd_smi_optrocm.is_file():
# try /opt/rocm/lib as a fallback
_libraries['{library_name}'] = ctypes.CDLL(libamd_smi_optrocm)
elif libamd_smi_parent_dir.is_file():
if libamd_smi_parent_dir.is_file():
# try to fall back to parent directory
_libraries['{library_name}'] = ctypes.CDLL(libamd_smi_parent_dir)
else:
+2 -1
View File
@@ -44,7 +44,8 @@ cp -r /src /tmp/src \
&& rm -rf build .cache \
&& cmake -B build -DBUILD_WRAPPER=ON $ENABLE_ESMI_LIB \
&& make -C build -j $(nproc) \
&& cp /tmp/src/py-interface/amdsmi_wrapper.py /src/py-interface/amdsmi_wrapper.py"
&& cp /tmp/src/py-interface/amdsmi_wrapper.py /src/py-interface/amdsmi_wrapper.py \
&& chown --reference /src/py-interface/CMakeLists.txt /src/py-interface/amdsmi_wrapper.py"
echo -e "Generated new wrapper!
[$DIR/py-interface/amdsmi_wrapper.py]"