Merge amd-dev into amd-master 20241213
Signed-off-by: Maisam Arif <Maisam.Arif@amd.com> Change-Id: Ie13efc3ba253965dfe32a93438fe39b0509e305f
Этот коммит содержится в:
@@ -3,6 +3,308 @@
|
||||
Full documentation for amd_smi_lib is available at [https://rocm.docs.amd.com/projects/amdsmi](https://rocm.docs.amd.com/projects/amdsmi/en/latest/).
|
||||
|
||||
***All information listed below is for reference and subject to change.***
|
||||
## amd_smi_lib for ROCm 6.4.0
|
||||
|
||||
### Added
|
||||
|
||||
- **Added fclk and socclk info to `amd-smi metric -c/--clock`**.
|
||||
fclk and socclk information such as min and max clock have been added to the metric command, in line with all the other clocks.
|
||||
|
||||
```shell
|
||||
amd-smi metric -c -g 1
|
||||
...
|
||||
FCLK_0:
|
||||
CLK: 2301 MHz
|
||||
MIN_CLK: 601 MHz
|
||||
MAX_CLK: 2301 MHz
|
||||
CLK_LOCKED: N/A
|
||||
DEEP_SLEEP: DISABLED
|
||||
SOCCLK_0:
|
||||
CLK: 1500 MHz
|
||||
MIN_CLK: 500 MHz
|
||||
MAX_CLK: 1500 MHz
|
||||
CLK_LOCKED: N/A
|
||||
DEEP_SLEEP: DISABLED
|
||||
```
|
||||
|
||||
- **Added new command `amd-smi set -c/--clock-level`**.
|
||||
This new command sets the performance level of the selected clock on the desired GPUs. The command can accept a range of acceptable levels, but will not set the level when a level is beyond the number of frequency levels as show in `amd-smi static -C/--clock`.
|
||||
|
||||
```shell
|
||||
sudo amd-smi set -c sclk 5 6
|
||||
GPU: 0
|
||||
CLK_LEVEL: Successfully changed sclk perf level(s) to 5, 6
|
||||
|
||||
GPU: 1
|
||||
CLK_LEVEL: level(s) 5, 6 is/are greater than performance levels supported for device
|
||||
```
|
||||
|
||||
- **Added new command `amd-smi static -C/--clock`**.
|
||||
This new command displays the clock frequency performance levels for the selected GPUs and clocks.
|
||||
|
||||
```shell
|
||||
amd-smi static --clock all -g 0
|
||||
GPU: 0
|
||||
CLOCK:
|
||||
SYS:
|
||||
CURRENT LEVEL: 2
|
||||
FREQUENCY_LEVELS:
|
||||
0: 300 MHz
|
||||
1: 904 MHz
|
||||
2: 1165 MHz
|
||||
3: 1360 MHz
|
||||
4: 1440 MHz
|
||||
5: 1544 MHz
|
||||
6: 1627 MHz
|
||||
7: 1720 MHz
|
||||
8: 1800 MHz
|
||||
MEM:
|
||||
CURRENT LEVEL: 0
|
||||
FREQUENCY_LEVELS:
|
||||
0: 167 MHz
|
||||
DF:
|
||||
CURRENT LEVEL: 0
|
||||
FREQUENCY_LEVELS:
|
||||
0: 1400 MHz
|
||||
SOC:
|
||||
CURRENT LEVEL: 0
|
||||
FREQUENCY_LEVELS:
|
||||
0: 302 MHz
|
||||
DCEF: N/A
|
||||
VCLK0: N/A
|
||||
VCLK1: N/A
|
||||
DCLK0: N/A
|
||||
DCLK1: N/A
|
||||
```
|
||||
|
||||
## amd_smi_lib for ROCm 6.4.0
|
||||
|
||||
### Added
|
||||
|
||||
### Changed
|
||||
|
||||
### Removed
|
||||
|
||||
- **Removed `GFX_BUSY_ACC` from `amd-smi metric --usage`**.
|
||||
Displaying `GFX_BUSY_ACC` does not provide helpful outputs for users.
|
||||
|
||||
Old output:
|
||||
```shell
|
||||
$ amd-smi metric --usage
|
||||
GPU: 0
|
||||
USAGE:
|
||||
GFX_ACTIVITY: 0 %
|
||||
UMC_ACTIVITY: 0 %
|
||||
MM_ACTIVITY: N/A
|
||||
VCN_ACTIVITY: [0 %, 0 %, 0 %, 0 %]
|
||||
JPEG_ACTIVITY: [0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %]
|
||||
GFX_BUSY_INST:
|
||||
XCP_0: [0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %]
|
||||
JPEG_BUSY:
|
||||
XCP_0: [0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %]
|
||||
VCN_BUSY:
|
||||
XCP_0: [0 %, 0 %, 0 %, 0 %]
|
||||
GFX_BUSY_ACC:
|
||||
XCP_0: [N/A, N/A, N/A, N/A, N/A, N/A, N/A, N/A]
|
||||
...
|
||||
```
|
||||
|
||||
New Output:
|
||||
```shell
|
||||
$ amd-smi metric --usage
|
||||
GPU: 0
|
||||
USAGE:
|
||||
GFX_ACTIVITY: 0 %
|
||||
UMC_ACTIVITY: 0 %
|
||||
MM_ACTIVITY: N/A
|
||||
VCN_ACTIVITY: [0 %, 0 %, 0 %, 0 %]
|
||||
JPEG_ACTIVITY: [0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %]
|
||||
GFX_BUSY_INST:
|
||||
XCP_0: [0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %]
|
||||
JPEG_BUSY:
|
||||
XCP_0: [0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %]
|
||||
VCN_BUSY:
|
||||
XCP_0: [0 %, 0 %, 0 %, 0 %]
|
||||
...
|
||||
```
|
||||
|
||||
|
||||
### Optimized
|
||||
|
||||
- **Modified `amd-smi` CLI to allow case insensitive arguments if the argument does not begin with a single dash**.
|
||||
- With this change `amd-smi version` and `amd-smi VERSION` will now yield the same output.
|
||||
- `amd-smi static --bus` and `amd-smi STATIC --BUS` will produce identical results.
|
||||
- `amd-smi static -b` and `amd-smi static -B` will still return different results (-b for bus and -B for board).
|
||||
|
||||
- **Converted xgmi read and write from KB's to readable units**.
|
||||
- With this change `amd-smi xgmi` will now display the statistics in dynamically selected readable units.
|
||||
- Example output is shown below.
|
||||
|
||||
```shell
|
||||
$ amd-smi xgmi
|
||||
LINK METRIC TABLE:
|
||||
bdf bit_rate max_bandwidth link_type 0000:05:00.0 0000:26:00.0 0000:46:00.0 0000:65:00.0 0000:85:00.0 0000:a6:00.0 0000:c6:00.0 0000:e5:00.0
|
||||
GPU0 0000:05:00.0 32 Gb/s 512 Gb/s XGMI
|
||||
Read N/A 1.123 PB 1.123 PB 1.123 PB 1.123 PB 1.123 PB 1.123 PB 1.123 PB
|
||||
Write N/A 229.1 MB 229.1 MB 229.1 MB 229.1 MB 229.1 MB 229.1 MB 229.1 MB
|
||||
GPU1 0000:26:00.0 32 Gb/s 512 Gb/s XGMI
|
||||
Read 1.123 PB N/A 1.123 PB 1.123 PB 1.123 PB 1.123 PB 1.123 PB 1.123 PB
|
||||
Write 229.1 MB N/A 229.1 MB 229.1 MB 229.1 MB 229.1 MB 229.1 MB 229.1 MB
|
||||
GPU2 0000:46:00.0 32 Gb/s 512 Gb/s XGMI
|
||||
Read 1.123 PB 1.123 PB N/A 1.123 PB 1.123 PB 1.123 PB 1.123 PB 1.123 PB
|
||||
Write 229.1 MB 229.1 MB N/A 229.1 MB 229.1 MB 229.1 MB 229.1 MB 229.1 MB
|
||||
...
|
||||
```
|
||||
|
||||
### Resolved issues
|
||||
|
||||
### Upcoming changes
|
||||
|
||||
### Known issues
|
||||
|
||||
- **AMD SMI only reports 63 GPU devices when setting CPX on all 8 GPUs**
|
||||
When setting CPX as a partition mode, there is a DRM node limitation of 64.
|
||||
|
||||
This is a known limitation of the Linux kernel, not the driver. Other drivers, such as those using PCIe space (e.g., ast), may be occupying the necessary DRM nodes.
|
||||
|
||||
The number of DRM nodes used can be checked via `ls /sys/class/drm`
|
||||
|
||||
Options are as follows:
|
||||
1) ***Workaround - removing other devices using DRM nodes***
|
||||
|
||||
Recommended steps for removing unnecessary drivers:
|
||||
a. Unload amdgpu - `sudo rmmod amdgpu`
|
||||
b. Remove unnecessary driver(s) - ex. `sudo rmmod ast`
|
||||
c. Reload amgpu - `sudo modprobe amdgpu`
|
||||
d. Confirm `amd-smi list` reports all nodes (this can vary per MI ASIC)
|
||||
|
||||
2) ***Update your OS' kernel***
|
||||
Typically you can find examples online by searching "`Update kernel <your OS version> command line`"
|
||||
|
||||
Ex. "Update kernel Ubuntu 22.04 command line" should provide some good examples.
|
||||
https://phoenixnap.com/kb/how-to-update-kernel-ubuntu
|
||||
|
||||
3) ***Building and installing your own kernel***
|
||||
*This option is helpful for users on OS distributions that have not yet merged the necessary changes.*
|
||||
https://phoenixnap.com/kb/build-linux-kernel
|
||||
|
||||
All changes are in the mainline kernel if users need to build their own.
|
||||
|
||||
References to kernel changes:
|
||||
```text
|
||||
for libdrm :
|
||||
Author: James Zhu <James.Zhu@amd.com>
|
||||
|
||||
Date: Mon Aug 7 10:14:18 2023 -0400
|
||||
|
||||
xf86drm: use drm device name to identify drm node type
|
||||
|
||||
Currently drm node's minor range is used to identify node's type.
|
||||
|
||||
Since kernel drm uses node type name and minor to generate drm
|
||||
|
||||
device name, It will be more general to use drm device name to
|
||||
|
||||
identify drm node type.
|
||||
|
||||
Signed-off-by: James Zhu <James.Zhu@amd.com>
|
||||
|
||||
Reviewed-by: Simon Ser <contact@emersion.fr>
|
||||
|
||||
commit 1080273c2b31db6f031a7f889f3104f53ab4502c
|
||||
|
||||
Author: James Zhu <James.Zhu@amd.com>
|
||||
|
||||
Date: Mon Aug 7 10:06:32 2023 -0400
|
||||
|
||||
xf86drm: update DRM_NODE_NAME_MAX supporting more nodes
|
||||
|
||||
Current DRM_NODE_NAME_MAX only can support up to 999 nodes,
|
||||
|
||||
Update to support up to 2^MINORBITS nodes.
|
||||
|
||||
Signed-off-by: James Zhu <James.Zhu@amd.com>
|
||||
|
||||
Reviewed-by: Simon Ser <contact@emersion.fr>
|
||||
```
|
||||
|
||||
## amd_smi_lib for ROCm 6.3.1
|
||||
|
||||
### Added
|
||||
|
||||
### Changed
|
||||
|
||||
- **Changed `amd-smi monitor`: No longer display `ENC_CLOCK`/`DEC_CLOCK` but `VCLOCK` and `DCLOCK`**.
|
||||
Due to fix mentioned in `Resolved Issues`, this change was needed.
|
||||
Reason: Navi products use vclk and dclk for both encode and decode. On MI products, only decode is supported.
|
||||
Before:
|
||||
```shell
|
||||
$ amd-smi monitor -n -d
|
||||
GPU ENC_UTIL ENC_CLOCK DEC_UTIL DEC_CLOCK
|
||||
0 0.0 % 29 MHz N/A 22 MHz
|
||||
1 0.0 % 29 MHz N/A 22 MHz
|
||||
2 0.0 % 29 MHz N/A 22 MHz
|
||||
3 0.0 % 29 MHz N/A 22 MHz
|
||||
4 0.0 % 29 MHz N/A 22 MHz
|
||||
5 0.0 % 29 MHz N/A 22 MHz
|
||||
6 0.0 % 29 MHz N/A 22 MHz
|
||||
7 0.0 % 29 MHz N/A 22 MHz
|
||||
```
|
||||
After:
|
||||
```shell
|
||||
$ amd-smi monitor -n -d
|
||||
GPU ENC_UTIL DEC_UTIL VCLOCK DCLOCK
|
||||
0 N/A 0.0 % 29 MHz 22 MHz
|
||||
1 N/A 0.0 % 29 MHz 22 MHz
|
||||
2 N/A 0.0 % 29 MHz 22 MHz
|
||||
3 N/A 0.0 % 29 MHz 22 MHz
|
||||
4 N/A 0.0 % 29 MHz 22 MHz
|
||||
5 N/A 0.0 % 29 MHz 22 MHz
|
||||
6 N/A 0.0 % 29 MHz 22 MHz
|
||||
7 N/A 0.0 % 29 MHz 22 MHz
|
||||
```
|
||||
|
||||
### Removed
|
||||
|
||||
### Optimized
|
||||
|
||||
### Resolved issues
|
||||
|
||||
- **Fixed `amd-smi monitor`'s encode/decode: `ENC_UTIL`, `DEC_UTIL`, and now associate `VCLOCK`/`DCLOCK` with both**.
|
||||
Navi products use vclk and dclk for both encode and decode. On MI products, only decode is supported.
|
||||
|
||||
Navi products cannot support displaying ENC_UTIL % at this time.
|
||||
|
||||
Before:
|
||||
```shell
|
||||
$ amd-smi monitor -n -d
|
||||
GPU ENC_UTIL ENC_CLOCK DEC_UTIL DEC_CLOCK
|
||||
0 0.0 % 29 MHz N/A 22 MHz
|
||||
1 0.0 % 29 MHz N/A 22 MHz
|
||||
2 0.0 % 29 MHz N/A 22 MHz
|
||||
3 0.0 % 29 MHz N/A 22 MHz
|
||||
4 0.0 % 29 MHz N/A 22 MHz
|
||||
5 0.0 % 29 MHz N/A 22 MHz
|
||||
6 0.0 % 29 MHz N/A 22 MHz
|
||||
7 0.0 % 29 MHz N/A 22 MHz
|
||||
```
|
||||
After:
|
||||
```shell
|
||||
$ amd-smi monitor -n -d
|
||||
GPU ENC_UTIL DEC_UTIL VCLOCK DCLOCK
|
||||
0 N/A 0.0 % 29 MHz 22 MHz
|
||||
1 N/A 0.0 % 29 MHz 22 MHz
|
||||
2 N/A 0.0 % 29 MHz 22 MHz
|
||||
3 N/A 0.0 % 29 MHz 22 MHz
|
||||
4 N/A 0.0 % 29 MHz 22 MHz
|
||||
5 N/A 0.0 % 29 MHz 22 MHz
|
||||
6 N/A 0.0 % 29 MHz 22 MHz
|
||||
7 N/A 0.0 % 29 MHz 22 MHz
|
||||
```
|
||||
|
||||
### Upcoming changes
|
||||
|
||||
### Known issues
|
||||
|
||||
## amd_smi_lib for ROCm 6.3.0
|
||||
|
||||
|
||||
+6
-14
@@ -28,7 +28,7 @@ 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("24.7.1" ${PKG_VERSION_GIT_TAG_PREFIX} GIT)
|
||||
get_package_version_number("24.7.0" ${PKG_VERSION_GIT_TAG_PREFIX} GIT)
|
||||
message("Package version: ${PKG_VERSION_STR}")
|
||||
set(${AMD_SMI_LIBS_TARGET}_VERSION_MAJOR "${CPACK_PACKAGE_VERSION_MAJOR}")
|
||||
set(${AMD_SMI_LIBS_TARGET}_VERSION_MINOR "${CPACK_PACKAGE_VERSION_MINOR}")
|
||||
@@ -107,13 +107,6 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wformat=2 -fno-common -Wstrict-overflow
|
||||
# Intentionally leave out -Wsign-promo. It causes spurious warnings.
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Woverloaded-virtual -Wreorder")
|
||||
|
||||
# Add CMAKE debug flags
|
||||
if ("${CMAKE_BUILD_TYPE}" STREQUAL Release)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2")
|
||||
else ()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ggdb -O0 -DDEBUG")
|
||||
endif ()
|
||||
|
||||
set(COMMON_SRC_DIR "${PROJECT_SOURCE_DIR}/src")
|
||||
set(ROCM_SRC_DIR "${PROJECT_SOURCE_DIR}/rocm_smi/src")
|
||||
set(AMDSMI_SRC_DIR "${PROJECT_SOURCE_DIR}/src/amd_smi")
|
||||
@@ -128,9 +121,8 @@ if(ENABLE_ESMI_LIB)
|
||||
execute_process(COMMAND git clone --depth=1 -b esmi_pkg_ver-3.0.3 https://github.com/amd/esmi_ib_library.git ${PROJECT_SOURCE_DIR}/esmi_ib_library)
|
||||
endif()
|
||||
if(NOT EXISTS ${PROJECT_SOURCE_DIR}/esmi_ib_library/include/asm/amd_hsmp.h)
|
||||
file(DOWNLOAD
|
||||
https://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86.git/plain/arch/x86/include/uapi/asm/amd_hsmp.h?h=review-ilpo
|
||||
${PROJECT_SOURCE_DIR}/esmi_ib_library/include/asm/amd_hsmp.h)
|
||||
file(COPY "${PROJECT_SOURCE_DIR}/include/amd_smi/impl/amd_hsmp.h"
|
||||
DESTINATION "${PROJECT_SOURCE_DIR}/esmi_ib_library/include/asm")
|
||||
endif()
|
||||
add_definitions("-DENABLE_ESMI_LIB=1")
|
||||
set(ESMI_INC_DIR "${PROJECT_SOURCE_DIR}/esmi_ib_library/include")
|
||||
@@ -261,10 +253,10 @@ install(
|
||||
add_subdirectory(goamdsmi_shim)
|
||||
|
||||
#Debian package specific variables
|
||||
set(CPACK_DEBIAN_PACKAGE_RECOMMENDS "python3-argcomplete, libdrm-dev, python3-yaml")
|
||||
set(CPACK_DEBIAN_PACKAGE_RECOMMENDS "python3-argcomplete, libdrm-dev")
|
||||
set(CPACK_DEBIAN_ASAN_PACKAGE_RECOMMENDS ${CPACK_DEBIAN_PACKAGE_RECOMMENDS})
|
||||
set(CPACK_DEBIAN_DEV_PACKAGE_RECOMMENDS ${CPACK_DEBIAN_PACKAGE_RECOMMENDS})
|
||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "sudo, python3 (>= 3.6.8), python3-pip")
|
||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "sudo, python3 (>= 3.6.8), python3-pip, python3-setuptools, python3-wheel")
|
||||
set(CPACK_DEBIAN_ASAN_PACKAGE_DEPENDS ${CPACK_DEBIAN_PACKAGE_DEPENDS})
|
||||
set(CPACK_DEBIAN_DEV_PACKAGE_DEPENDS ${CPACK_DEBIAN_PACKAGE_DEPENDS})
|
||||
|
||||
@@ -285,7 +277,7 @@ 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 "sudo, python3 >= 3.6.8, python3-pip, python3-PyYAML")
|
||||
set(CPACK_RPM_PACKAGE_REQUIRES "sudo, python3 >= 3.6.8, python3-pip, python3-setuptools, python3-wheel")
|
||||
set(CPACK_RPM_DEV_PACKAGE_REQUIRES ${CPACK_RPM_PACKAGE_REQUIRES})
|
||||
set(CPACK_RPM_ASAN_PACKAGE_REQUIRES ${CPACK_RPM_PACKAGE_REQUIRES})
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
# Use ubuntu 20.04 base image
|
||||
FROM compute-artifactory.amd.com:5000/rocm-base-images/ubuntu-20.04-bld:2024112501
|
||||
|
||||
# Set environment variables
|
||||
ENV BUILD_FOLDER=/src/build
|
||||
ENV DEB_BUILD="amd-smi-lib*99999-local_amd64.deb"
|
||||
ENV DEB_BUILD_TEST='amd-smi-lib-tests*99999-local_amd64.deb'
|
||||
|
||||
# Set up the working directory
|
||||
WORKDIR /src
|
||||
|
||||
# Copy the source code into the container
|
||||
COPY . /src
|
||||
|
||||
# Run the build and install commands
|
||||
RUN rm -rf ${BUILD_FOLDER} && \
|
||||
mkdir -p ${BUILD_FOLDER} && \
|
||||
cd ${BUILD_FOLDER} && \
|
||||
cmake .. -DBUILD_TESTS=ON -DENABLE_ESMI_LIB=ON && \
|
||||
make -j $(nproc) VERBOSE=1 && \
|
||||
make package && \
|
||||
sudo apt install -y ${BUILD_FOLDER}/${DEB_BUILD} && \
|
||||
sudo ln -s /opt/rocm/bin/amd-smi /usr/local/bin
|
||||
|
||||
# Verify installation
|
||||
RUN python3 -m pip list | grep amd && \
|
||||
python3 -m pip list | grep pip && \
|
||||
python3 -m pip list | grep setuptools
|
||||
|
||||
# Set the entrypoint
|
||||
ENTRYPOINT ["/bin/bash"]
|
||||
@@ -100,6 +100,8 @@ if __name__ == "__main__":
|
||||
except NameError:
|
||||
logging.debug("argcomplete module not found. Autocomplete will not work.")
|
||||
|
||||
sys.argv = [arg.lower() if arg.startswith('--') or not arg.startswith('-')
|
||||
else arg for arg in sys.argv]
|
||||
args = amd_smi_parser.parse_args(args=None if sys.argv[1:] else ['--help'])
|
||||
|
||||
# Handle command modifiers before subcommand execution
|
||||
|
||||
@@ -31,7 +31,7 @@ import os
|
||||
from _version import __version__
|
||||
from amdsmi_helpers import AMDSMIHelpers
|
||||
from amdsmi_logger import AMDSMILogger
|
||||
from amdsmi_cli_exceptions import AmdSmiRequiredCommandException
|
||||
from amdsmi_cli_exceptions import AmdSmiRequiredCommandException, AmdSmiInvalidParameterException
|
||||
from rocm_version import get_rocm_version
|
||||
from amdsmi import amdsmi_interface
|
||||
from amdsmi import amdsmi_exception
|
||||
@@ -271,7 +271,7 @@ class AMDSMICommands():
|
||||
def static_gpu(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, dfc_ucode=None, fb_info=None, num_vf=None,
|
||||
soc_pstate=None, xgmi_plpd=None, process_isolation=None):
|
||||
soc_pstate=None, xgmi_plpd=None, process_isolation=None, clock=None):
|
||||
"""Get Static information for target gpu
|
||||
|
||||
Args:
|
||||
@@ -321,12 +321,19 @@ class AMDSMICommands():
|
||||
args.cache = cache
|
||||
if process_isolation:
|
||||
args.process_isolation = process_isolation
|
||||
if clock:
|
||||
args.clock = clock
|
||||
# args.clock defaults to False so if it was overwritten to empty list, that indicates that it was given as an arguments but with an empty list
|
||||
if args.clock == []:
|
||||
args.clock = True
|
||||
|
||||
# Store args that are applicable to the current platform
|
||||
current_platform_args = ["asic", "bus", "vbios", "driver", "ras",
|
||||
"vram", "cache", "board", "process_isolation"]
|
||||
"vram", "cache", "board", "process_isolation",
|
||||
"clock"]
|
||||
current_platform_values = [args.asic, args.bus, args.vbios, args.driver, args.ras,
|
||||
args.vram, args.cache, args.board, args.process_isolation]
|
||||
args.vram, args.cache, args.board, args.process_isolation,
|
||||
args.clock]
|
||||
|
||||
if self.helpers.is_linux() and self.helpers.is_baremetal():
|
||||
if partition:
|
||||
@@ -829,6 +836,58 @@ class AMDSMICommands():
|
||||
logging.debug("Failed to get cache info for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
static_dict['cache_info'] = cache_info_list
|
||||
if 'clock' in current_platform_args:
|
||||
if isinstance(args.clock, bool) and args.clock == True:
|
||||
args.clock = ['sys', 'mem', 'df', 'soc', 'dcef', 'vclk0', 'vclk1', 'dclk0', 'dclk1']
|
||||
if isinstance(args.clock, list):
|
||||
# remove potential duplicates from list
|
||||
args.clock = list(set(args.clock))
|
||||
# check that clock is valid option
|
||||
if "all" in args.clock or len(args.clock) == 0:
|
||||
args.clock = ['sys', 'mem', 'df', 'soc', 'dcef', 'vclk0', 'vclk1', 'dclk0', 'dclk1']
|
||||
clk_dict = {}
|
||||
|
||||
for clk in args.clock:
|
||||
clk_type = clk.lower()
|
||||
if clk_type == "sys":
|
||||
clk_type_conversion = amdsmi_interface.AmdSmiClkType.SYS
|
||||
elif clk_type == "mem":
|
||||
clk_type_conversion = amdsmi_interface.AmdSmiClkType.MEM
|
||||
elif clk_type == "df":
|
||||
clk_type_conversion = amdsmi_interface.AmdSmiClkType.DF
|
||||
elif clk_type == "soc":
|
||||
clk_type_conversion = amdsmi_interface.AmdSmiClkType.SOC
|
||||
elif clk_type == "dcef":
|
||||
clk_type_conversion = amdsmi_interface.AmdSmiClkType.DCEF
|
||||
# vclk and dclk currently do not support levels so average clk is given for frequency levels
|
||||
elif clk_type == "vclk0":
|
||||
clk_type_conversion = amdsmi_interface.AmdSmiClkType.VCLK0
|
||||
elif clk_type == "vclk1":
|
||||
clk_type_conversion = amdsmi_interface.AmdSmiClkType.VCLK1
|
||||
elif clk_type == "dclk0":
|
||||
clk_type_conversion = amdsmi_interface.AmdSmiClkType.DCLK0
|
||||
elif clk_type == "dclk1":
|
||||
clk_type_conversion = amdsmi_interface.AmdSmiClkType.DCLK1
|
||||
else:
|
||||
clk_type_conversion = "N/A"
|
||||
output_format = self.helpers.get_output_format()
|
||||
raise AmdSmiInvalidParameterException(clk_type, output_format) # clk type given is bad
|
||||
|
||||
try:
|
||||
frequencies = amdsmi_interface.amdsmi_get_clk_freq(args.gpu, clk_type_conversion)
|
||||
freq_dict = {}
|
||||
freq_dict.update({'current level':frequencies['current']})
|
||||
freq_dict.update({'frequency_levels':{}})
|
||||
for level in range(len(frequencies['frequency'])):
|
||||
freq = str(self.helpers.convert_SI_unit(frequencies['frequency'][level], AMDSMIHelpers.SI_Unit.MICRO)) + " MHz"
|
||||
freq_dict['frequency_levels'].update({level:freq})
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
freq_dict = "N/A"
|
||||
clk_dict.update({clk:freq_dict})
|
||||
|
||||
static_dict['clock'] = clk_dict
|
||||
else:
|
||||
raise amdsmi_exception.AmdSmiParameterException(args.clock, list[str])
|
||||
|
||||
# Convert and store output by pid for csv format
|
||||
multiple_devices_csv_override = False
|
||||
@@ -864,7 +923,8 @@ class AMDSMICommands():
|
||||
bus=None, vbios=None, limit=None, driver=None, ras=None,
|
||||
board=None, numa=None, vram=None, cache=None, partition=None,
|
||||
dfc_ucode=None, fb_info=None, num_vf=None, cpu=None,
|
||||
interface_ver=None, soc_pstate=None, xgmi_plpd = None, process_isolation=None):
|
||||
interface_ver=None, soc_pstate=None, xgmi_plpd = None, process_isolation=None,
|
||||
clock=None):
|
||||
"""Get Static information for target gpu and cpu
|
||||
|
||||
Args:
|
||||
@@ -916,7 +976,7 @@ class AMDSMICommands():
|
||||
gpu_attributes = ["asic", "bus", "vbios", "limit", "driver", "ras",
|
||||
"board", "numa", "vram", "cache", "partition",
|
||||
"dfc_ucode", "fb_info", "num_vf", "soc_pstate", "xgmi_plpd",
|
||||
"process_isolation"]
|
||||
"process_isolation", "clock"]
|
||||
for attr in gpu_attributes:
|
||||
if hasattr(args, attr):
|
||||
if getattr(args, attr):
|
||||
@@ -947,7 +1007,7 @@ class AMDSMICommands():
|
||||
bus, vbios, limit, driver, ras,
|
||||
board, numa, vram, cache, partition,
|
||||
dfc_ucode, fb_info, num_vf, soc_pstate,
|
||||
process_isolation)
|
||||
process_isolation, clock)
|
||||
elif self.helpers.is_amd_hsmp_initialized(): # Only CPU is initialized
|
||||
if args.cpu == None:
|
||||
args.cpu = self.cpu_handles
|
||||
@@ -962,7 +1022,7 @@ class AMDSMICommands():
|
||||
bus, vbios, limit, driver, ras,
|
||||
board, numa, vram, cache, partition,
|
||||
dfc_ucode, fb_info, num_vf, soc_pstate, xgmi_plpd,
|
||||
process_isolation)
|
||||
process_isolation, clock)
|
||||
|
||||
|
||||
def firmware(self, args, multiple_devices=False, gpu=None, fw_list=True):
|
||||
@@ -1471,7 +1531,6 @@ class AMDSMICommands():
|
||||
engine_usage['gfx_busy_inst'] = "N/A"
|
||||
engine_usage['jpeg_busy'] = "N/A"
|
||||
engine_usage['vcn_busy'] = "N/A"
|
||||
engine_usage['gfx_busy_acc'] = "N/A"
|
||||
|
||||
if num_partition != "N/A":
|
||||
# these are one after another, in order to display each in sub-sections
|
||||
@@ -1490,11 +1549,6 @@ class AMDSMICommands():
|
||||
new_xcp_dict[f"xcp_{current_xcp}"] = gpu_metric['xcp_stats.vcn_busy'][current_xcp]
|
||||
engine_usage['vcn_busy'] = new_xcp_dict
|
||||
|
||||
new_xcp_dict = {}
|
||||
for current_xcp in range(num_partition):
|
||||
new_xcp_dict[f"xcp_{current_xcp}"] = gpu_metric['xcp_stats.gfx_busy_acc'][current_xcp]
|
||||
engine_usage['gfx_busy_acc'] = new_xcp_dict
|
||||
|
||||
logging.debug(f"After updates to engine_usage dictionary = {engine_usage}")
|
||||
|
||||
for key, value in engine_usage.items():
|
||||
@@ -1628,6 +1682,18 @@ class AMDSMICommands():
|
||||
"clk_locked" : "N/A",
|
||||
"deep_sleep" : "N/A"}
|
||||
|
||||
clocks["fclk_0"] = {"clk" : "N/A",
|
||||
"min_clk" : "N/A",
|
||||
"max_clk" : "N/A",
|
||||
"clk_locked" : "N/A",
|
||||
"deep_sleep" : "N/A"}
|
||||
|
||||
clocks["socclk_0"] = {"clk" : "N/A",
|
||||
"min_clk" : "N/A",
|
||||
"max_clk" : "N/A",
|
||||
"clk_locked" : "N/A",
|
||||
"deep_sleep" : "N/A"}
|
||||
|
||||
clock_unit = "MHz"
|
||||
# TODO make the deepsleep threshold correspond to the * in sysfs for current deep sleep status
|
||||
deep_sleep_threshold = 140
|
||||
@@ -1705,6 +1771,31 @@ class AMDSMICommands():
|
||||
clocks[dclk_index]["deep_sleep"] = "ENABLED"
|
||||
else:
|
||||
clocks[dclk_index]["deep_sleep"] = "DISABLED"
|
||||
|
||||
# Populate FCLK clock value; fclk not present in gpu_metrics so use amdsmi_get_clk_freq
|
||||
frequency_dict = amdsmi_interface.amdsmi_get_clk_freq(args.gpu, amdsmi_interface.AmdSmiClkType.DF)
|
||||
current_fclk_clock = frequency_dict['frequency'][frequency_dict['current']]
|
||||
current_fclk_clock = self.helpers.convert_SI_unit(current_fclk_clock, self.helpers.SI_Unit.MICRO)
|
||||
clocks["fclk_0"]["clk"] = self.helpers.unit_format(self.logger,
|
||||
current_fclk_clock,
|
||||
clock_unit)
|
||||
|
||||
if int(current_fclk_clock) <= deep_sleep_threshold:
|
||||
clocks["fclk_0"]["deep_sleep"] = "ENABLED"
|
||||
else:
|
||||
clocks["fclk_0"]["deep_sleep"] = "DISABLED"
|
||||
|
||||
# Populate SOCCLK clock value
|
||||
current_socclk_clock = gpu_metric["current_socclk"]
|
||||
clocks["socclk_0"]["clk"] = self.helpers.unit_format(self.logger,
|
||||
current_socclk_clock,
|
||||
clock_unit)
|
||||
|
||||
if int(current_socclk_clock) <= deep_sleep_threshold:
|
||||
clocks["socclk_0"]["deep_sleep"] = "ENABLED"
|
||||
else:
|
||||
clocks["socclk_0"]["deep_sleep"] = "DISABLED"
|
||||
|
||||
except Exception as e:
|
||||
logging.debug("Failed to get gpu_metrics_info for gpu %s | %s", gpu_id, e)
|
||||
|
||||
@@ -1777,6 +1868,36 @@ class AMDSMICommands():
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
logging.debug("Failed to get vclk and/or dclk clock info for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
# FCLK min and max clocks
|
||||
try:
|
||||
fclk_clk_info_dict = amdsmi_interface.amdsmi_get_clock_info(args.gpu,
|
||||
amdsmi_interface.AmdSmiClkType.DF)
|
||||
# if the current clock is N/A then we shouldn't populate the max and min values
|
||||
if clocks["fclk_0"]["clk"] != "N/A":
|
||||
clocks["fclk_0"]["min_clk"] = self.helpers.unit_format(self.logger,
|
||||
fclk_clk_info_dict["min_clk"],
|
||||
clock_unit)
|
||||
clocks["fclk_0"]["max_clk"] = self.helpers.unit_format(self.logger,
|
||||
fclk_clk_info_dict["max_clk"],
|
||||
clock_unit)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
logging.debug("Failed to get fclk info for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
# SOCCLK min and max clocks
|
||||
try:
|
||||
socclk_clk_info_dict = amdsmi_interface.amdsmi_get_clock_info(args.gpu,
|
||||
amdsmi_interface.AmdSmiClkType.SOC)
|
||||
# if the current clock is N/A then we shouldn't populate the max and min values
|
||||
if clocks["socclk_0"]["clk"] != "N/A":
|
||||
clocks["socclk_0"]["min_clk"] = self.helpers.unit_format(self.logger,
|
||||
socclk_clk_info_dict["min_clk"],
|
||||
clock_unit)
|
||||
clocks["socclk_0"]["max_clk"] = self.helpers.unit_format(self.logger,
|
||||
socclk_clk_info_dict["max_clk"],
|
||||
clock_unit)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
logging.debug("Failed to get socclk info for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
values_dict['clock'] = clocks
|
||||
if "temperature" in current_platform_args:
|
||||
if args.temperature:
|
||||
@@ -3843,7 +3964,7 @@ class AMDSMICommands():
|
||||
def set_gpu(self, args, multiple_devices=False, gpu=None, fan=None, perf_level=None,
|
||||
profile=None, perf_determinism=None, compute_partition=None,
|
||||
memory_partition=None, power_cap=None, soc_pstate=None, xgmi_plpd = None,
|
||||
process_isolation=None, clk_limit=None):
|
||||
process_isolation=None, clk_limit=None, clk_level=None):
|
||||
"""Issue reset commands to target gpu(s)
|
||||
|
||||
Args:
|
||||
@@ -3892,6 +4013,8 @@ class AMDSMICommands():
|
||||
args.process_isolation = process_isolation
|
||||
if clk_limit:
|
||||
args.clk_limit = clk_limit
|
||||
if clk_level:
|
||||
args.clk_level = clk_level
|
||||
|
||||
# Handle No GPU passed
|
||||
if args.gpu == None:
|
||||
@@ -3915,6 +4038,7 @@ class AMDSMICommands():
|
||||
args.power_cap is not None,
|
||||
args.soc_pstate is not None,
|
||||
args.xgmi_plpd is not None,
|
||||
args.clk_level is not None,
|
||||
args.clk_limit is not None,
|
||||
args.process_isolation is not None]):
|
||||
command = " ".join(sys.argv[1:])
|
||||
@@ -4166,6 +4290,62 @@ class AMDSMICommands():
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
raise ValueError(f"Unable to set XGMI policy to {args.xgmi_plpd} on {gpu_string}") from e
|
||||
self.logger.store_output(args.gpu, 'xgmiplpd', f"Successfully set per-link power down policy to id {args.xgmi_plpd}")
|
||||
if isinstance(args.clk_level, tuple):
|
||||
clk_type = args.clk_level.clk_type
|
||||
perf_levels = args.clk_level.perf_levels
|
||||
|
||||
# check if perf levels are all valid levels
|
||||
try:
|
||||
if clk_type == "sclk":
|
||||
clk_type_conversion = amdsmi_interface.AmdSmiClkType.SYS
|
||||
elif clk_type == "mclk":
|
||||
clk_type_conversion = amdsmi_interface.AmdSmiClkType.MEM
|
||||
elif clk_type == "pcie":
|
||||
clk_type_conversion = amdsmi_interface.AmdSmiClkType.PCIE
|
||||
elif clk_type == "fclk":
|
||||
clk_type_conversion = amdsmi_interface.AmdSmiClkType.DF
|
||||
elif clk_type == "socclk":
|
||||
clk_type_conversion = amdsmi_interface.AmdSmiClkType.SOC
|
||||
else:
|
||||
clk_type_conversion = "N/A"
|
||||
frequencies = amdsmi_interface.amdsmi_get_clk_freq(args.gpu, clk_type_conversion)
|
||||
num_supported = frequencies['num_supported']
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
pass
|
||||
|
||||
# convert perf_levels given to freq bit mask
|
||||
freq_mask = 0
|
||||
valid_level = True
|
||||
invalid_levels = []
|
||||
for level in perf_levels:
|
||||
if level < num_supported:
|
||||
freq_mask += 2**level
|
||||
else:
|
||||
# cancel this instance since the level should not be possible
|
||||
invalid_levels.append(level)
|
||||
valid_level = False
|
||||
|
||||
if valid_level:
|
||||
perf_levels_str = str(perf_levels).strip('[]')
|
||||
if clk_type.lower() == "pcie":
|
||||
try:
|
||||
amdsmi_interface.amdsmi_set_gpu_pci_bandwidth(args.gpu, freq_mask)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.get_error_code() == amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NO_PERM:
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
raise ValueError(f"Unable to set pcie bandwidth to perf level(s) {perf_levels_str} on {gpu_string}") from e
|
||||
else:
|
||||
try:
|
||||
amdsmi_interface.amdsmi_set_clk_freq(args.gpu, clk_type, freq_mask)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.get_error_code() == amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NO_PERM:
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
raise ValueError(f"Unable to set {clk_type} to perf level(s) {perf_levels_str} on {gpu_string}") from e
|
||||
self.logger.store_output(args.gpu, 'clk_level', f"Successfully changed {clk_type} perf level(s) to {perf_levels_str}")
|
||||
else:
|
||||
invalid_levels_str = str(invalid_levels).strip('[]')
|
||||
self.logger.store_output(args.gpu, 'clk_level', f"level(s) {invalid_levels_str} is/are greater than performance levels supported for device")
|
||||
|
||||
if isinstance(args.clk_limit, tuple):
|
||||
clk_type = args.clk_limit.clk_type
|
||||
lim_type = args.clk_limit.lim_type
|
||||
@@ -4240,7 +4420,7 @@ class AMDSMICommands():
|
||||
cpu_pwr_eff_mode=None, cpu_gmi3_link_width=None, cpu_pcie_link_rate=None,
|
||||
cpu_df_pstate_range=None, cpu_enable_apb=None, cpu_disable_apb=None,
|
||||
soc_boost_limit=None, core=None, core_boost_limit=None, soc_pstate=None, xgmi_plpd=None,
|
||||
process_isolation=None, clk_limit=None):
|
||||
process_isolation=None, clk_limit=None, clk_level=None):
|
||||
"""Issue reset commands to target gpu(s)
|
||||
|
||||
Args:
|
||||
@@ -4292,7 +4472,7 @@ class AMDSMICommands():
|
||||
gpu_args_enabled = False
|
||||
gpu_attributes = ["fan", "perf_level", "profile", "perf_determinism", "compute_partition",
|
||||
"memory_partition", "power_cap", "soc_pstate", "xgmi_plpd",
|
||||
"process_isolation", "clk_limit"]
|
||||
"process_isolation", "clk_limit", "clk_level"]
|
||||
for attr in gpu_attributes:
|
||||
if hasattr(args, attr):
|
||||
if getattr(args, attr) is not None:
|
||||
@@ -4318,6 +4498,18 @@ class AMDSMICommands():
|
||||
core_args_enabled = True
|
||||
break
|
||||
|
||||
# Error if no subcommand args are passed
|
||||
if self.helpers.is_baremetal():
|
||||
if not any([args.gpu, args.fan, args.perf_level, args.profile, args.perf_determinism, \
|
||||
args.compute_partition, args.memory_partition, args.power_cap,\
|
||||
args.soc_pstate, args.xgmi_plpd, args.clk_limit, args.process_isolation]):
|
||||
command = " ".join(sys.argv[1:])
|
||||
raise AmdSmiRequiredCommandException(command, self.logger.format)
|
||||
else:
|
||||
if not any([args.clean_local_data]):
|
||||
command = " ".join(sys.argv[1:])
|
||||
raise AmdSmiRequiredCommandException(command, self.logger.format)
|
||||
|
||||
# Only allow one device's arguments to be set at a time
|
||||
if not any([gpu_args_enabled, cpu_args_enabled, core_args_enabled]):
|
||||
raise ValueError('No GPU, CPU, or CORE arguments provided, specific arguments are needed')
|
||||
@@ -4348,7 +4540,7 @@ class AMDSMICommands():
|
||||
self.set_gpu(args, multiple_devices, gpu, fan, perf_level,
|
||||
profile, perf_determinism, compute_partition,
|
||||
memory_partition, power_cap, soc_pstate, xgmi_plpd,
|
||||
process_isolation, clk_limit)
|
||||
process_isolation, clk_limit, clk_level)
|
||||
elif self.helpers.is_amd_hsmp_initialized(): # Only CPU is initialized
|
||||
if args.cpu == None and args.core == None:
|
||||
raise ValueError('No CPU or CORE provided, specific target(s) are needed')
|
||||
@@ -4368,7 +4560,7 @@ class AMDSMICommands():
|
||||
self.set_gpu(args, multiple_devices, gpu, fan, perf_level,
|
||||
profile, perf_determinism, compute_partition,
|
||||
memory_partition, power_cap, soc_pstate, xgmi_plpd,
|
||||
process_isolation, clk_limit)
|
||||
process_isolation, clk_limit, clk_level)
|
||||
|
||||
|
||||
def reset(self, args, multiple_devices=False, gpu=None, gpureset=None,
|
||||
@@ -4717,6 +4909,23 @@ class AMDSMICommands():
|
||||
self.logger.store_output(args.gpu, 'timestamp', int(time.time()))
|
||||
self.logger.table_header = 'TIMESTAMP'.rjust(10) + ' ' + self.logger.table_header
|
||||
|
||||
if args.loglevel == "DEBUG":
|
||||
try:
|
||||
# Get GPU Metrics table version
|
||||
gpu_metric_version_info = amdsmi_interface.amdsmi_get_gpu_metrics_header_info(args.gpu)
|
||||
gpu_metric_version_str = json.dumps(gpu_metric_version_info, indent=4)
|
||||
logging.debug("GPU Metrics table Version for GPU %s | %s", gpu_id, gpu_metric_version_str)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
logging.debug("Unable to load GPU Metrics table version for %s | %s", gpu_id, e.err_info)
|
||||
|
||||
try:
|
||||
# Get GPU Metrics table
|
||||
gpu_metric_debug_info = amdsmi_interface.amdsmi_get_gpu_metrics_info(args.gpu)
|
||||
gpu_metric_str = json.dumps(gpu_metric_debug_info, indent=4)
|
||||
logging.debug("GPU Metrics table for GPU %s | %s", gpu_id, str(gpu_metric_str))
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
logging.debug("Unable to load GPU Metrics table for %s | %s", gpu_id, e.err_info)
|
||||
|
||||
# Store the pcie_bw values due to possible increase in bandwidth due to repeated gpu_metrics calls
|
||||
if args.pcie:
|
||||
try:
|
||||
@@ -4845,9 +5054,10 @@ class AMDSMICommands():
|
||||
|
||||
self.logger.table_header += 'MEM_CLOCK'.rjust(11)
|
||||
if args.encoder:
|
||||
# TODO: The encoding utilization is in progress for Navi. Note: MI3x ASICs only support decoding.
|
||||
try:
|
||||
# Get List of vcn activity values
|
||||
encoder_util = amdsmi_interface.amdsmi_get_gpu_metrics_info(args.gpu)['vcn_activity']
|
||||
encoder_util = "N/A" # Not yet implemented
|
||||
encoding_activity_avg = []
|
||||
for value in encoder_util:
|
||||
if isinstance(value, int):
|
||||
@@ -4874,49 +5084,72 @@ class AMDSMICommands():
|
||||
|
||||
self.logger.table_header += 'ENC_UTIL'.rjust(10)
|
||||
|
||||
try:
|
||||
encoder_clock = amdsmi_interface.amdsmi_get_gpu_metrics_info(args.gpu)['current_vclk0']
|
||||
monitor_values['encoder_clock'] = encoder_clock
|
||||
freq_unit = 'MHz'
|
||||
if encoder_clock != "N/A":
|
||||
if self.logger.is_human_readable_format():
|
||||
monitor_values['encoder_clock'] = f"{monitor_values['encoder_clock']} {freq_unit}"
|
||||
if self.logger.is_json_format():
|
||||
monitor_values['encoder_clock'] = {"value" : monitor_values['encoder_clock'],
|
||||
"unit" : freq_unit}
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
monitor_values['encoder_clock'] = "N/A"
|
||||
logging.debug("Failed to get encoder clock on gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
self.logger.table_header += 'ENC_CLOCK'.rjust(11)
|
||||
if args.decoder:
|
||||
try:
|
||||
decoder_util = "N/A" # Not yet implemented
|
||||
monitor_values['decoder'] = decoder_util
|
||||
# if self.logger.is_human_readable_format():
|
||||
# monitor_values['decoder'] = f"{monitor_values['decoder']} %"
|
||||
# Get List of vcn activity values
|
||||
# Note: MI3x ASICs only support decoding, so the vcn_activity is used for decoding activity.
|
||||
decoder_util = amdsmi_interface.amdsmi_get_gpu_metrics_info(args.gpu)['vcn_activity']
|
||||
decoding_activity_avg = []
|
||||
for value in decoder_util:
|
||||
if isinstance(value, int):
|
||||
decoding_activity_avg.append(value)
|
||||
|
||||
# Averaging the possible decoding activity values
|
||||
if decoding_activity_avg:
|
||||
decoding_activity_avg = sum(decoding_activity_avg) / len(decoding_activity_avg)
|
||||
else:
|
||||
decoding_activity_avg = "N/A"
|
||||
|
||||
monitor_values['decoder'] = decoding_activity_avg
|
||||
|
||||
activity_unit = '%'
|
||||
if monitor_values['decoder'] != "N/A":
|
||||
if self.logger.is_human_readable_format():
|
||||
monitor_values['decoder'] = f"{monitor_values['decoder']} {activity_unit}"
|
||||
if self.logger.is_json_format():
|
||||
monitor_values['decoder'] = {"value" : monitor_values['decoder'],
|
||||
"unit" : activity_unit}
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
monitor_values['decoder'] = "N/A"
|
||||
logging.debug("Failed to get decoder utilization on gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
self.logger.table_header += 'DEC_UTIL'.rjust(10)
|
||||
|
||||
if args.encoder or args.decoder:
|
||||
try:
|
||||
decoder_clock = amdsmi_interface.amdsmi_get_gpu_metrics_info(args.gpu)['current_dclk0']
|
||||
monitor_values['decoder_clock'] = decoder_clock
|
||||
vclock = amdsmi_interface.amdsmi_get_gpu_metrics_info(args.gpu)['current_vclk0']
|
||||
monitor_values['vclock'] = vclock
|
||||
|
||||
freq_unit = 'MHz'
|
||||
if decoder_clock != "N/A":
|
||||
if vclock != "N/A":
|
||||
if self.logger.is_human_readable_format():
|
||||
monitor_values['decoder_clock'] = f"{monitor_values['decoder_clock']} {freq_unit}"
|
||||
monitor_values['vclock'] = f"{monitor_values['vclock']} {freq_unit}"
|
||||
if self.logger.is_json_format():
|
||||
monitor_values['decoder_clock'] = {"value" : monitor_values['decoder_clock'],
|
||||
monitor_values['vclock'] = {"value" : monitor_values['vclock'],
|
||||
"unit" : freq_unit}
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
monitor_values['decoder_clock'] = "N/A"
|
||||
logging.debug("Failed to get decoder clock on gpu %s | %s", gpu_id, e.get_error_info())
|
||||
monitor_values['vclock'] = "N/A"
|
||||
logging.debug("Failed to get dclock on gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
self.logger.table_header += 'VCLOCK'.rjust(8)
|
||||
|
||||
try:
|
||||
dclock = amdsmi_interface.amdsmi_get_gpu_metrics_info(args.gpu)['current_dclk0']
|
||||
monitor_values['dclock'] = dclock
|
||||
|
||||
freq_unit = 'MHz'
|
||||
if dclock != "N/A":
|
||||
if self.logger.is_human_readable_format():
|
||||
monitor_values['dclock'] = f"{monitor_values['dclock']} {freq_unit}"
|
||||
if self.logger.is_json_format():
|
||||
monitor_values['dclock'] = {"value" : monitor_values['dclock'],
|
||||
"unit" : freq_unit}
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
monitor_values['dclock'] = "N/A"
|
||||
logging.debug("Failed to get vclock on gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
self.logger.table_header += 'DCLOCK'.rjust(8)
|
||||
|
||||
self.logger.table_header += 'DEC_CLOCK'.rjust(11)
|
||||
if args.ecc:
|
||||
try:
|
||||
ecc = amdsmi_interface.amdsmi_get_gpu_total_ecc_count(args.gpu)
|
||||
@@ -5245,8 +5478,8 @@ class AMDSMICommands():
|
||||
|
||||
data_unit = 'KB'
|
||||
if self.logger.is_human_readable_format():
|
||||
dest_link_dict['read'] = f"{read} {data_unit}"
|
||||
dest_link_dict['write'] = f"{write} {data_unit}"
|
||||
dest_link_dict['read'] = self.helpers.convert_bytes_to_readable(read * 1024, True)
|
||||
dest_link_dict['write'] = self.helpers.convert_bytes_to_readable(write * 1024, True)
|
||||
elif self.logger.is_json_format():
|
||||
dest_link_dict['read'] = {"value" : read,
|
||||
"unit" : data_unit}
|
||||
@@ -5297,8 +5530,8 @@ class AMDSMICommands():
|
||||
tabular_output.append(tabular_output_dict)
|
||||
|
||||
# Create Read and Write rows and add to tabular_output
|
||||
read_output_dict = {"RW" : "Read"}
|
||||
write_output_dict = {"RW" : "Write"}
|
||||
read_output_dict = {"RW" : " Read"}
|
||||
write_output_dict = {"RW" : " Write"}
|
||||
for key, value in xgmi_dict.items():
|
||||
if key == "link_metrics":
|
||||
for link_key, link_value in value.items():
|
||||
@@ -5550,7 +5783,14 @@ class AMDSMICommands():
|
||||
events = listener.read(2000)
|
||||
for event in events:
|
||||
values_dict["event"] = event["event"]
|
||||
values_dict["message"] = event["message"]
|
||||
# parse message as it's own dictionary
|
||||
message_list = event["message"].split(" ")
|
||||
message_dict = {}
|
||||
for item in message_list:
|
||||
if not item == "":
|
||||
item_list = item.split(": ")
|
||||
message_dict.update({item_list[0]: item_list[1]})
|
||||
values_dict["message"] = message_dict
|
||||
commands.logger.store_output(device, 'values', values_dict)
|
||||
commands.logger.print_output()
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
|
||||
@@ -779,10 +779,20 @@ class AMDSMIHelpers():
|
||||
return False, profile_presets.values()
|
||||
|
||||
|
||||
def convert_bytes_to_readable(self, bytes_input):
|
||||
def convert_bytes_to_readable(self, bytes_input, format_length=None):
|
||||
for unit in ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB"]:
|
||||
if abs(bytes_input) < 1024:
|
||||
return f"{bytes_input:3.1f} {unit}"
|
||||
if format_length is not None:
|
||||
if bytes_input < 10:
|
||||
return f"{bytes_input:4.3f} {unit}"
|
||||
elif bytes_input < 100:
|
||||
return f"{bytes_input:4.2f} {unit}"
|
||||
elif bytes_input < 1000:
|
||||
return f"{bytes_input:4.1f} {unit}"
|
||||
else:
|
||||
return f"{bytes_input:4.0f} {unit}"
|
||||
else:
|
||||
return f"{bytes_input:3.1f} {unit}"
|
||||
bytes_input /= 1024
|
||||
return f"{bytes_input:.1f} YB"
|
||||
|
||||
|
||||
@@ -25,20 +25,10 @@ import re
|
||||
import time
|
||||
from typing import Dict
|
||||
from enum import Enum
|
||||
import yaml
|
||||
import inspect
|
||||
|
||||
from amdsmi_helpers import AMDSMIHelpers
|
||||
import amdsmi_cli_exceptions
|
||||
|
||||
### Custom YAML Functions
|
||||
# Dumper class to preserve order of yaml.dump
|
||||
class CustomDumper(yaml.Dumper):
|
||||
def represent_dict_preserve_order(self, data):
|
||||
return self.represent_dict(data.items())
|
||||
def has_sort_keys_option(): # to check if sort_keys is available
|
||||
return 'sort_keys' in inspect.signature(yaml.dump).parameters
|
||||
|
||||
class AMDSMILogger():
|
||||
def __init__(self, format='human_readable', destination='stdout') -> None:
|
||||
self.output = {}
|
||||
@@ -127,8 +117,10 @@ class AMDSMILogger():
|
||||
table_values += string_value.rjust(10) + ' '
|
||||
elif key == 'power_usage':
|
||||
table_values += string_value.rjust(7)
|
||||
elif key in ('gfx_clock', 'mem_clock', 'encoder_clock', 'decoder_clock', 'vram_used'):
|
||||
elif key in ('gfx_clock', 'mem_clock', 'vram_used'):
|
||||
table_values += string_value.rjust(11)
|
||||
elif key in ('vclock', 'dclock'):
|
||||
table_values += string_value.rjust(8)
|
||||
elif key == 'vram_total' or 'ecc' in key or key == 'pcie_bw':
|
||||
table_values += string_value.rjust(12)
|
||||
elif key in ['pcie_replay']:
|
||||
@@ -174,7 +166,7 @@ class AMDSMILogger():
|
||||
elif key == "resources_shared":
|
||||
table_values += string_value.ljust(18)
|
||||
elif key == "RW":
|
||||
table_values += string_value.ljust(52)
|
||||
table_values += string_value.ljust(53)
|
||||
elif key == "process_list":
|
||||
#Add an additional padding between the first instance of GPU and NAME
|
||||
table_values += ' '
|
||||
@@ -233,15 +225,8 @@ class AMDSMILogger():
|
||||
|
||||
capitalized_json["AMDSMI_SPACING_REMOVAL"] = tabbed_dictionary
|
||||
|
||||
json_string = json.dumps(capitalized_json, indent=4)
|
||||
|
||||
if has_sort_keys_option():
|
||||
yaml_data = yaml.safe_load(json_string)
|
||||
yaml_output = yaml.dump(yaml_data, sort_keys=False, allow_unicode=True)
|
||||
else:
|
||||
CustomDumper.add_representer(dict, CustomDumper.represent_dict_preserve_order)
|
||||
yaml_data = yaml.safe_load(json_string)
|
||||
yaml_output = yaml.dump(yaml_data, Dumper=CustomDumper, allow_unicode=True, default_flow_style=False)
|
||||
# Convert the capitalized JSON to a YAML-like string
|
||||
yaml_output = self.custom_dump(capitalized_json)
|
||||
|
||||
# Remove a key line if it is a spacer
|
||||
yaml_output = yaml_output.replace("AMDSMI_SPACING_REMOVAL:\n", "")
|
||||
@@ -264,6 +249,22 @@ class AMDSMILogger():
|
||||
|
||||
return clean_yaml_output
|
||||
|
||||
def custom_dump(self, data, indent=0):
|
||||
"""Converts a Python dictionary to a YAML-like string."""
|
||||
yaml_string = ""
|
||||
for key, value in data.items():
|
||||
if isinstance(value, dict):
|
||||
yaml_string += " " * indent + f"{key}:\n" + self.custom_dump(value, indent + 1)
|
||||
elif isinstance(value, list):
|
||||
yaml_string += " " * indent + f"{key}:\n"
|
||||
for item in value:
|
||||
if isinstance(item, dict):
|
||||
yaml_string += self.custom_dump(item, indent + 1)
|
||||
else: # If the list is not a dictionary, print it as a string
|
||||
yaml_string += " " * (indent + 1) + f"- {item}\n"
|
||||
else:
|
||||
yaml_string += " " * indent + f"{key}: {value}\n"
|
||||
return yaml_string
|
||||
|
||||
def flatten_dict(self, target_dict, topology_override=False):
|
||||
"""This will flatten a dictionary out to a single level of key value stores
|
||||
|
||||
@@ -203,6 +203,37 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
return AMDSMILimitArgs
|
||||
|
||||
|
||||
def _level_select(self):
|
||||
"""Custom action for setting clock frequencies to particular performance level"""
|
||||
output_format = self.helpers.get_output_format()
|
||||
|
||||
class AMDSMIFreqArgs(argparse.Action):
|
||||
def __call__(self, parser: AMDSMIParser, namespace: argparse.Namespace,
|
||||
values: list, option_string: Optional[str] = None) -> None:
|
||||
# valid values
|
||||
valid_clk_types = ('sclk', 'mclk', 'pcie', 'fclk', 'socclk')
|
||||
clk_type = values[0]
|
||||
perf_levels_str = values[1:]
|
||||
|
||||
# Check if the sclk and mclk parameters are valid
|
||||
if clk_type not in valid_clk_types:
|
||||
raise amdsmi_cli_exceptions.AmdSmiInvalidParameterException(clk_type, output_format)
|
||||
|
||||
perf_levels = []
|
||||
# Check if every item in perf level is valid
|
||||
for level in perf_levels_str:
|
||||
if not level.isdigit():
|
||||
raise amdsmi_cli_exceptions.AmdSmiInvalidParameterValueException(level, output_format)
|
||||
level = int(level)
|
||||
if level < 0:
|
||||
raise amdsmi_cli_exceptions.AmdSmiInvalidParameterValueException(level, output_format)
|
||||
perf_levels.append(level)
|
||||
|
||||
clk_level_args = collections.namedtuple('clk_level_args', ['clk_type', 'perf_levels'])
|
||||
setattr(namespace, self.dest, clk_level_args(clk_type, perf_levels))
|
||||
return AMDSMIFreqArgs
|
||||
|
||||
|
||||
def _check_output_file_path(self):
|
||||
""" Argument action validator:
|
||||
Returns a path to a file from the output file path provided.
|
||||
@@ -607,6 +638,10 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
soc_pstate_help = "The available soc pstate policy"
|
||||
xgmi_plpd_help = "The available XGMI per-link power down policy"
|
||||
process_isolation_help = "The process isolation status"
|
||||
clk_options = self.helpers.get_clock_types()[0]
|
||||
clk_options.remove('PCIE')
|
||||
clk_option_str = ", ".join(clk_options) + ", ALL"
|
||||
clock_help = f"Show one or more valid clock frequency levels. Available options:\n\t{clk_option_str}"
|
||||
|
||||
# Options arguments help text for Hypervisors and Baremetal
|
||||
ras_help = "Displays RAS features information"
|
||||
@@ -642,6 +677,7 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
static_parser.add_argument('-B', '--board', action='store_true', required=False, help=board_help)
|
||||
static_parser.add_argument('-R', '--process-isolation', action='store_true', required=False, help=process_isolation_help)
|
||||
static_parser.add_argument('-r', '--ras', action='store_true', required=False, help=ras_help)
|
||||
static_parser.add_argument('-C', '--clock', default=False, nargs='*', type=str, required=False, help=clock_help)
|
||||
|
||||
# Options to display on Hypervisors and Baremetal
|
||||
if self.helpers.is_hypervisor() or self.helpers.is_baremetal():
|
||||
@@ -1047,6 +1083,7 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
set_soc_pstate_help = "Set the GPU soc pstate policy using policy id\n"
|
||||
set_xgmi_plpd_help = "Set the GPU XGMI per-link power down policy using policy id\n"
|
||||
set_clk_limit_help = "Sets the sclk (aka gfxclk) or mclk minimum and maximum frequencies:\n\tamd-smi set -L (sclk | mclk) (min | max) value"
|
||||
set_clock_freq_help = "Set the sclk (aka gfxclk), mclk, fclk, pcie, or socclk frequency performance level.\nCan take range of acceptable levels."
|
||||
set_process_isolation_help = "Enable or disable the GPU process isolation on a per partition basis:\n\t0 for disable and 1 for enable.\n"
|
||||
|
||||
# Help text for CPU set options
|
||||
@@ -1086,6 +1123,7 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
set_value_parser.add_argument('-o', '--power-cap', action='store', type=self._positive_int, required=False, help=set_power_cap_help, metavar='WATTS')
|
||||
set_value_parser.add_argument('-p', '--soc-pstate', action='store', required=False, type=self._not_negative_int, help=set_soc_pstate_help, metavar='POLICY_ID')
|
||||
set_value_parser.add_argument('-x', '--xgmi-plpd', action='store', required=False, type=self._not_negative_int, help=set_xgmi_plpd_help, metavar='POLICY_ID')
|
||||
set_value_parser.add_argument('-c', '--clk-level', action=self._level_select(), nargs='+', required=False, help=set_clock_freq_help, metavar=('CLK_TYPE', 'PERF_LEVELS'))
|
||||
|
||||
set_value_parser.add_argument('-L', '--clk-limit', action=self._limit_select(), nargs=3, required=False, help=set_clk_limit_help, metavar=('CLK_TYPE', 'LIM_TYPE', 'VALUE'))
|
||||
set_value_parser.add_argument('-R', '--process-isolation', action='store', choices=[0,1], type=self._not_negative_int, required=False, help=set_process_isolation_help, metavar='STATUS')
|
||||
|
||||
@@ -158,6 +158,8 @@ Static Arguments:
|
||||
-B, --board All board information
|
||||
-R, --process-isolation The process isolation status
|
||||
-r, --ras Displays RAS features information
|
||||
-C, --clock [CLOCK ...] Show one or more valid clock frequency levels. Available options:
|
||||
SYS, DF, DCEF, SOC, MEM, VCLK0, VCLK1, DCLK0, DCLK1, ALL
|
||||
-p, --partition Partition information
|
||||
-l, --limit All limit metric values (i.e. power and thermal limits)
|
||||
-P, --policy The available DPM policy
|
||||
@@ -538,6 +540,8 @@ Set Arguments:
|
||||
-o, --power-cap WATTS Set power capacity limit
|
||||
-p, --soc-pstate POLICY_ID Set the GPU soc pstate policy using policy id
|
||||
-x, --xgmi-plpd POLICY_ID Set the GPU XGMI per-link power down policy using policy id
|
||||
-c, --clk-level CLK_TYPE [PERF_LEVELS ...] Set the sclk (aka gfxclk), mclk, fclk, pcie, or socclk frequency performance level.
|
||||
Can take range of acceptable levels.
|
||||
-L, --clk-limit CLK_TYPE LIM_TYPE VALUE Sets the sclk (aka gfxclk) or mclk minimum and maximum frequencies
|
||||
amd-smi set -L (sclk | mclk) (min | max) value
|
||||
-R, --process-isolation STATUS Enable or disable the GPU process isolation:
|
||||
@@ -855,5 +859,35 @@ GPU: 0
|
||||
CACHE_LEVEL: 3
|
||||
MAX_NUM_CU_SHARED: 228
|
||||
NUM_CACHE_INSTANCE: 1
|
||||
CLOCK:
|
||||
SYS:
|
||||
CURRENT LEVEL: 2
|
||||
FREQUENCY_LEVELS:
|
||||
0: 300 MHz
|
||||
1: 904 MHz
|
||||
2: 1165 MHz
|
||||
3: 1360 MHz
|
||||
4: 1440 MHz
|
||||
5: 1544 MHz
|
||||
6: 1627 MHz
|
||||
7: 1720 MHz
|
||||
8: 1800 MHz
|
||||
DF:
|
||||
CURRENT LEVEL: 0
|
||||
FREQUENCY_LEVELS:
|
||||
0: 1400 MHz
|
||||
DCEF: N/A
|
||||
SOC:
|
||||
CURRENT LEVEL: 0
|
||||
FREQUENCY_LEVELS:
|
||||
0: 302 MHz
|
||||
MEM:
|
||||
CURRENT LEVEL: 0
|
||||
FREQUENCY_LEVELS:
|
||||
0: 167 MHz
|
||||
VCLK0: N/A
|
||||
VCLK1: N/A
|
||||
DCLK1: N/A
|
||||
DCLK0: N/A
|
||||
...
|
||||
```
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <inttypes.h>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
|
||||
@@ -262,11 +263,11 @@ int main() {
|
||||
ret = amdsmi_get_gpu_device_bdf(processor_handles[j], &bdf);
|
||||
CHK_AMDSMI_RET(ret)
|
||||
printf(" Output of amdsmi_get_gpu_device_bdf:\n");
|
||||
printf("\tDevice[%d] BDF %04lx:%02x:%02x.%d\n\n", i,
|
||||
bdf.domain_number,
|
||||
bdf.bus_number,
|
||||
bdf.device_number,
|
||||
bdf.function_number);
|
||||
printf("\tDevice[%d] BDF %04" PRIx64 ":%02" PRIx32 ":%02" PRIx32 ".%" PRIu32 "\n\n", i,
|
||||
static_cast<uint64_t>(bdf.domain_number),
|
||||
static_cast<uint32_t>(bdf.bus_number),
|
||||
static_cast<uint32_t>(bdf.device_number),
|
||||
static_cast<uint32_t>(bdf.function_number));
|
||||
|
||||
// Get handle from BDF
|
||||
amdsmi_processor_handle dev_handle;
|
||||
@@ -408,12 +409,12 @@ int main() {
|
||||
printf("\tPCIe max speed: %d\n", pcie_info.pcie_static.max_pcie_speed);
|
||||
|
||||
// additional pcie related metrics
|
||||
printf("\tPCIe bandwidth: %d\n", pcie_info.pcie_metric.pcie_bandwidth);
|
||||
printf("\tPCIe replay count: %d\n", pcie_info.pcie_metric.pcie_replay_count);
|
||||
printf("\tPCIe L0 recovery count: %d\n", pcie_info.pcie_metric.pcie_l0_to_recovery_count);
|
||||
printf("\tPCIe rollover count: %d\n", pcie_info.pcie_metric.pcie_replay_roll_over_count);
|
||||
printf("\tPCIe nak received count: %d\n", pcie_info.pcie_metric.pcie_nak_received_count);
|
||||
printf("\tPCIe nak sent count: %d\n", pcie_info.pcie_metric.pcie_nak_sent_count);
|
||||
printf("\tPCIe bandwidth: %u\n", pcie_info.pcie_metric.pcie_bandwidth);
|
||||
printf("\tPCIe replay count: %" PRIu64 "\n", pcie_info.pcie_metric.pcie_replay_count);
|
||||
printf("\tPCIe L0 recovery count: %" PRIu64 "\n", pcie_info.pcie_metric.pcie_l0_to_recovery_count);
|
||||
printf("\tPCIe rollover count: %" PRIu64 "\n", pcie_info.pcie_metric.pcie_replay_roll_over_count);
|
||||
printf("\tPCIe nak received count: %" PRIu64 "\n", pcie_info.pcie_metric.pcie_nak_received_count);
|
||||
printf("\tPCIe nak sent count: %" PRIu64 "\n", pcie_info.pcie_metric.pcie_nak_sent_count);
|
||||
|
||||
// Get VRAM temperature limit
|
||||
int64_t temperature = 0;
|
||||
@@ -522,13 +523,6 @@ int main() {
|
||||
printf("\tCorrectable errors: %lu\n", err_cnt_info.correctable_count);
|
||||
printf("\tUncorrectable errors: %lu\n\n",
|
||||
err_cnt_info.uncorrectable_count);
|
||||
// Get process list
|
||||
auto compare = [](const void *a, const void *b) -> int {
|
||||
return (*(amdsmi_proc_info_t *)a).pid >
|
||||
(*(amdsmi_proc_info_t *)b).pid
|
||||
? 1
|
||||
: -1;
|
||||
};
|
||||
|
||||
uint32_t num_process = 0;
|
||||
ret = amdsmi_get_gpu_process_list(processor_handles[j], &num_process, nullptr);
|
||||
@@ -542,18 +536,17 @@ int main() {
|
||||
uint64_t mem = 0, gtt_mem = 0, cpu_mem = 0, vram_mem = 0;
|
||||
uint64_t gfx = 0, enc = 0;
|
||||
char bdf_str[20];
|
||||
sprintf(bdf_str, "%04lx:%02x:%02x.%d",
|
||||
bdf.domain_number,
|
||||
bdf.bus_number,
|
||||
bdf.device_number,
|
||||
bdf.function_number);
|
||||
int num = 0;
|
||||
sprintf(bdf_str, "%04" PRIx64 ":%02" PRIx32 ":%02" PRIx32 ".%" PRIu32,
|
||||
static_cast<uint64_t>(bdf.domain_number),
|
||||
static_cast<uint32_t>(bdf.bus_number),
|
||||
static_cast<uint32_t>(bdf.device_number),
|
||||
static_cast<uint32_t>(bdf.function_number));
|
||||
ret = amdsmi_get_gpu_process_list(processor_handles[j], &num_process, process_info_list);
|
||||
std::cout << "Allocation size for process list: " << num_process << "\n";
|
||||
CHK_AMDSMI_RET(ret);
|
||||
for (auto idx = uint32_t(0); idx < num_process; ++idx) {
|
||||
process = static_cast<amdsmi_proc_info_t>(process_info_list[idx]);
|
||||
printf("\t *Process id: %ld / Name: %s / VRAM: %lld \n", process.pid, process.name, process.memory_usage.vram_mem);
|
||||
printf("\t *Process id: %d / Name: %s / VRAM: %ld \n", process.pid, process.name, process.memory_usage.vram_mem);
|
||||
}
|
||||
|
||||
printf("+=======+==================+============+=============="
|
||||
@@ -569,7 +562,7 @@ int main() {
|
||||
printf("+=======+"
|
||||
"+=============+=============+=============+============"
|
||||
"==+=========================================+\n");
|
||||
for (int it = 0; it < num_process; it++) {
|
||||
for (int it = 0; it < static_cast<int>(num_process); it++) {
|
||||
char command[30];
|
||||
struct passwd *pwd = nullptr;
|
||||
struct stat st;
|
||||
@@ -609,11 +602,13 @@ int main() {
|
||||
"-+-------------+-------------+-------------+----------"
|
||||
"----+-----------------------------------------+\n");
|
||||
}
|
||||
// TODO: To remove compiler warning, the last 3 values in this printf were
|
||||
// set to 0L. Need to find out what these values need to be.
|
||||
printf("| TOTAL:| %s | %7ld "
|
||||
"KiB | %7ld KiB | %7ld KiB | %7ld KiB | %lu %lu "
|
||||
"%lu %lu %lu |\n",
|
||||
bdf_str, mem, gtt_mem, cpu_mem, vram_mem, gfx,
|
||||
enc);
|
||||
enc, 0L, 0L, 0L);
|
||||
printf("+=======+==================+============+=============="
|
||||
"+=============+=============+=============+============"
|
||||
"=+==========================================+\n");
|
||||
@@ -674,11 +669,11 @@ int main() {
|
||||
ret = amdsmi_get_gpu_metrics_info(processor_handles[j], &smu);
|
||||
CHK_AMDSMI_RET(ret)
|
||||
printf(" Output of amdsmi_get_gpu_metrics_info:\n");
|
||||
printf("\tDevice[%d] BDF %04lx:%02x:%02x.%d\n\n", i,
|
||||
bdf.domain_number,
|
||||
bdf.bus_number,
|
||||
bdf.device_number,
|
||||
bdf.function_number);
|
||||
printf("\tDevice[%d] BDF %04" PRIx64 ":%02" PRIx32 ":%02" PRIx32 ".%" PRIu32 "\n\n", i,
|
||||
static_cast<uint64_t>(bdf.domain_number),
|
||||
static_cast<uint32_t>(bdf.bus_number),
|
||||
static_cast<uint32_t>(bdf.device_number),
|
||||
static_cast<uint32_t>(bdf.function_number));
|
||||
|
||||
std::cout << "METRIC TABLE HEADER:\n";
|
||||
std::cout << "structure_size=" << std::dec
|
||||
@@ -706,7 +701,7 @@ int main() {
|
||||
auto idx = 0;
|
||||
for (const auto& temp : smu.temperature_hbm) {
|
||||
std::cout << temp;
|
||||
if ((idx + 1) != std::size(smu.temperature_hbm)) {
|
||||
if ((idx + 1) != static_cast<int>(std::size(smu.temperature_hbm))) {
|
||||
std::cout << ", ";
|
||||
} else {
|
||||
std::cout << "]\n";
|
||||
@@ -723,7 +718,7 @@ int main() {
|
||||
idx = 0;
|
||||
for (const auto& temp : smu.vcn_activity) {
|
||||
std::cout << temp;
|
||||
if ((idx + 1) != std::size(smu.vcn_activity)) {
|
||||
if ((idx + 1) != static_cast<int>(std::size(smu.vcn_activity))) {
|
||||
std::cout << ", ";
|
||||
} else {
|
||||
std::cout << "]\n";
|
||||
@@ -736,7 +731,7 @@ int main() {
|
||||
idx = 0;
|
||||
for (const auto& temp : smu.jpeg_activity) {
|
||||
std::cout << temp;
|
||||
if ((idx + 1) != std::size(smu.jpeg_activity)) {
|
||||
if ((idx + 1) != static_cast<int>(std::size(smu.jpeg_activity))) {
|
||||
std::cout << ", ";
|
||||
} else {
|
||||
std::cout << "]\n";
|
||||
@@ -773,7 +768,7 @@ int main() {
|
||||
idx = 0;
|
||||
for (const auto& temp : smu.current_gfxclks) {
|
||||
std::cout << temp;
|
||||
if ((idx + 1) != std::size(smu.current_gfxclks)) {
|
||||
if ((idx + 1) != static_cast<int>(std::size(smu.current_gfxclks))) {
|
||||
std::cout << ", ";
|
||||
} else {
|
||||
std::cout << "]\n";
|
||||
@@ -786,7 +781,7 @@ int main() {
|
||||
idx = 0;
|
||||
for (const auto& temp : smu.current_socclks) {
|
||||
std::cout << temp;
|
||||
if ((idx + 1) != std::size(smu.current_socclks)) {
|
||||
if ((idx + 1) != static_cast<int>(std::size(smu.current_socclks))) {
|
||||
std::cout << ", ";
|
||||
} else {
|
||||
std::cout << "]\n";
|
||||
@@ -800,7 +795,7 @@ int main() {
|
||||
idx = 0;
|
||||
for (const auto& temp : smu.current_vclk0s) {
|
||||
std::cout << temp;
|
||||
if ((idx + 1) != std::size(smu.current_vclk0s)) {
|
||||
if ((idx + 1) != static_cast<int>(std::size(smu.current_vclk0s))) {
|
||||
std::cout << ", ";
|
||||
} else {
|
||||
std::cout << "]\n";
|
||||
@@ -813,7 +808,7 @@ int main() {
|
||||
idx = 0;
|
||||
for (const auto& temp : smu.current_dclk0s) {
|
||||
std::cout << temp;
|
||||
if ((idx + 1) != std::size(smu.current_dclk0s)) {
|
||||
if ((idx + 1) != static_cast<int>(std::size(smu.current_dclk0s))) {
|
||||
std::cout << ", ";
|
||||
} else {
|
||||
std::cout << "]\n";
|
||||
@@ -850,7 +845,7 @@ int main() {
|
||||
idx = 0;
|
||||
for (const auto& temp : smu.xgmi_read_data_acc) {
|
||||
std::cout << temp;
|
||||
if ((idx + 1) != std::size(smu.xgmi_read_data_acc)) {
|
||||
if ((idx + 1) != static_cast<int>(std::size(smu.xgmi_read_data_acc))) {
|
||||
std::cout << ", ";
|
||||
} else {
|
||||
std::cout << "]\n";
|
||||
@@ -862,7 +857,7 @@ int main() {
|
||||
idx = 0;
|
||||
for (const auto& temp : smu.xgmi_write_data_acc) {
|
||||
std::cout << temp;
|
||||
if ((idx + 1) != std::size(smu.xgmi_write_data_acc)) {
|
||||
if ((idx + 1) != static_cast<int>(std::size(smu.xgmi_write_data_acc))) {
|
||||
std::cout << ", ";
|
||||
} else {
|
||||
std::cout << "]\n";
|
||||
@@ -922,7 +917,7 @@ int main() {
|
||||
for (auto& row : smu.xcp_stats) {
|
||||
std::cout << "\t XCP [" << idx << "] : [";
|
||||
for (auto& col : row.gfx_busy_inst) {
|
||||
if ((idy + 1) != std::size(row.gfx_busy_inst)) {
|
||||
if ((idy + 1) != static_cast<int>(std::size(row.gfx_busy_inst))) {
|
||||
std::cout << col << ", ";
|
||||
} else {
|
||||
std::cout << col;
|
||||
@@ -940,7 +935,7 @@ int main() {
|
||||
for (auto& row : smu.xcp_stats) {
|
||||
std::cout << "\t XCP [" << idx << "] : [";
|
||||
for (auto& col : row.vcn_busy) {
|
||||
if ((idy + 1) != std::size(row.vcn_busy)) {
|
||||
if ((idy + 1) != static_cast<int>(std::size(row.vcn_busy))) {
|
||||
std::cout << col << ", ";
|
||||
} else {
|
||||
std::cout << col;
|
||||
@@ -958,7 +953,7 @@ int main() {
|
||||
for (auto& row : smu.xcp_stats) {
|
||||
std::cout << "\t XCP [" << idx << "] : [";
|
||||
for (auto& col : row.jpeg_busy) {
|
||||
if ((idy + 1) != std::size(row.jpeg_busy)) {
|
||||
if ((idy + 1) != static_cast<int>(std::size(row.jpeg_busy))) {
|
||||
std::cout << col << ", ";
|
||||
} else {
|
||||
std::cout << col;
|
||||
@@ -976,7 +971,7 @@ int main() {
|
||||
for (auto& row : smu.xcp_stats) {
|
||||
std::cout << "\t XCP [" << idx << "] : [";
|
||||
for (auto& col : row.gfx_busy_acc) {
|
||||
if ((idy + 1) != std::size(row.gfx_busy_acc)) {
|
||||
if ((idy + 1) != static_cast<int>(std::size(row.gfx_busy_acc))) {
|
||||
std::cout << col << ", ";
|
||||
} else {
|
||||
std::cout << col;
|
||||
@@ -1040,8 +1035,11 @@ int main() {
|
||||
amdsmi_bdf_t bdf = {};
|
||||
ret = amdsmi_get_gpu_device_bdf(topology_nearest_info.processor_list[k], &bdf);
|
||||
CHK_AMDSMI_RET(ret)
|
||||
printf("\t\tGPU BDF %04lx:%02x:%02x.%d\n", bdf.domain_number,
|
||||
bdf.bus_number, bdf.device_number, bdf.function_number);
|
||||
printf("\t\tGPU BDF %04" PRIx64 ":%02" PRIx32 ":%02" PRIx32 ".%" PRIu32 "\n",
|
||||
static_cast<uint64_t>(bdf.domain_number),
|
||||
static_cast<uint32_t>(bdf.bus_number),
|
||||
static_cast<uint32_t>(bdf.device_number),
|
||||
static_cast<uint32_t>(bdf.function_number));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
*/
|
||||
|
||||
#include <pwd.h>
|
||||
#include <inttypes.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@@ -114,11 +115,11 @@ int main() {
|
||||
ret = amdsmi_get_gpu_device_bdf(processor_handles[j], &bdf);
|
||||
CHK_AMDSMI_RET(ret)
|
||||
printf(" Output of amdsmi_get_gpu_device_bdf:\n");
|
||||
printf("\tDevice[%d] BDF %04lx:%02x:%02x.%d\n\n", i,
|
||||
bdf.domain_number,
|
||||
bdf.bus_number,
|
||||
bdf.device_number,
|
||||
bdf.function_number);
|
||||
printf("\tDevice[%d] BDF %04" PRIx64 ":%02" PRIx32 ":%02" PRIx32 ".%" PRIu32 "\n\n", i,
|
||||
static_cast<uint64_t>(bdf.domain_number),
|
||||
static_cast<uint32_t>(bdf.bus_number),
|
||||
static_cast<uint32_t>(bdf.device_number),
|
||||
static_cast<uint32_t>(bdf.function_number));
|
||||
|
||||
amdsmi_asic_info_t asic_info = {};
|
||||
ret = amdsmi_get_gpu_asic_info(processor_handles[j], &asic_info);
|
||||
@@ -319,7 +320,7 @@ int main() {
|
||||
CHK_AMDSMI_RET(ret)
|
||||
std::cout << "\t amdsmi_get_soc_pstate total:" << policy.num_supported
|
||||
<<" current:" << policy.current << "\n";
|
||||
for (int x=0; x < policy.num_supported; x++) {
|
||||
for (uint32_t x=0; x < policy.num_supported; x++) {
|
||||
std::cout << x <<": (" << policy.policies[x].policy_id
|
||||
<<"," << policy.policies[x].policy_description << ")\n";
|
||||
}
|
||||
@@ -349,8 +350,11 @@ int main() {
|
||||
amdsmi_bdf_t bdf = {};
|
||||
ret = amdsmi_get_gpu_device_bdf(topology_nearest_info.processor_list[k], &bdf);
|
||||
CHK_AMDSMI_RET(ret)
|
||||
printf("\tGPU BDF %04lx:%02x:%02x.%d\n", bdf.domain_number,
|
||||
bdf.bus_number, bdf.device_number, bdf.function_number);
|
||||
printf("\tGPU BDF %04" PRIx64 ":%02" PRIx32 ":%02" PRIx32 ".%" PRIu32 "\n",
|
||||
static_cast<uint64_t>(bdf.domain_number),
|
||||
static_cast<uint32_t>(bdf.bus_number),
|
||||
static_cast<uint32_t>(bdf.device_number),
|
||||
static_cast<uint32_t>(bdf.function_number));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ using std::fixed;
|
||||
using std::setprecision;
|
||||
using std::vector;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int main([[maybe_unused]] int argc, [[maybe_unused]] char **argv) {
|
||||
amdsmi_status_t ret;
|
||||
uint32_t proto_ver;
|
||||
amdsmi_smu_fw_version_t smu_fw = {};
|
||||
@@ -157,7 +157,7 @@ int main(int argc, char **argv) {
|
||||
retVal = snprintf(str, SHOWLINESZ, "\n| mclk (Mhz)\t\t\t |");
|
||||
|
||||
len = strlen(str);
|
||||
uint32_t fclk, mclk, cclk;
|
||||
uint32_t fclk, mclk;
|
||||
err_bits = 0;
|
||||
|
||||
ret = amdsmi_get_cpu_fclk_mclk(plist[index], &fclk, &mclk);
|
||||
@@ -265,7 +265,6 @@ int main(int argc, char **argv) {
|
||||
|
||||
double fraction_q10 = 1/pow(2,10);
|
||||
double fraction_uq10 = fraction_q10;
|
||||
const char* err_str1;
|
||||
|
||||
amdsmi_hsmp_metrics_table_t mtbl = {};
|
||||
ret = amdsmi_get_hsmp_metrics_table(plist[index], &mtbl);
|
||||
|
||||
@@ -961,7 +961,8 @@ typedef enum {
|
||||
#define AMDSMI_EVENT_MASK_FROM_INDEX(i) (1ULL << ((i) - 1))
|
||||
|
||||
//! Maximum number of characters an event notification message will be
|
||||
#define MAX_EVENT_NOTIFICATION_MSG_SIZE 64
|
||||
// matches kfd message max size
|
||||
#define MAX_EVENT_NOTIFICATION_MSG_SIZE 96
|
||||
|
||||
/**
|
||||
* Event notification data returned from event notification API
|
||||
@@ -1415,7 +1416,7 @@ typedef struct {
|
||||
/**
|
||||
* @brief The following structures hold the gpu statistics for a device.
|
||||
*/
|
||||
struct amdsmi_gpu_xcp_metrics_t {
|
||||
typedef struct {
|
||||
/* Utilization Instantaneous (%) */
|
||||
uint32_t gfx_busy_inst[AMDSMI_MAX_NUM_XCC];
|
||||
uint16_t jpeg_busy[AMDSMI_MAX_NUM_JPEG];
|
||||
@@ -1423,7 +1424,7 @@ struct amdsmi_gpu_xcp_metrics_t {
|
||||
|
||||
/* Utilization Accumulated (%) */
|
||||
uint64_t gfx_busy_acc[AMDSMI_MAX_NUM_XCC];
|
||||
};
|
||||
} amdsmi_gpu_xcp_metrics_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
@@ -1622,7 +1623,7 @@ typedef struct {
|
||||
uint16_t num_partition;
|
||||
|
||||
/* XCP (Graphic Cluster Partitions) metrics stats */
|
||||
struct amdsmi_gpu_xcp_metrics_t xcp_stats[AMDSMI_MAX_NUM_XCP];
|
||||
amdsmi_gpu_xcp_metrics_t xcp_stats[AMDSMI_MAX_NUM_XCP];
|
||||
|
||||
/* PCIE other end recovery counter */
|
||||
uint32_t pcie_lc_perf_other_end_recovery;
|
||||
|
||||
@@ -0,0 +1,417 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
|
||||
#ifndef _UAPI_ASM_X86_AMD_HSMP_H_
|
||||
#define _UAPI_ASM_X86_AMD_HSMP_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#pragma pack(4)
|
||||
|
||||
#define HSMP_MAX_MSG_LEN 8
|
||||
|
||||
/*
|
||||
* HSMP Messages supported
|
||||
*/
|
||||
enum hsmp_message_ids {
|
||||
HSMP_TEST = 1, /* 01h Increments input value by 1 */
|
||||
HSMP_GET_SMU_VER, /* 02h SMU FW version */
|
||||
HSMP_GET_PROTO_VER, /* 03h HSMP interface version */
|
||||
HSMP_GET_SOCKET_POWER, /* 04h average package power consumption */
|
||||
HSMP_SET_SOCKET_POWER_LIMIT, /* 05h Set the socket power limit */
|
||||
HSMP_GET_SOCKET_POWER_LIMIT, /* 06h Get current socket power limit */
|
||||
HSMP_GET_SOCKET_POWER_LIMIT_MAX,/* 07h Get maximum socket power value */
|
||||
HSMP_SET_BOOST_LIMIT, /* 08h Set a core maximum frequency limit */
|
||||
HSMP_SET_BOOST_LIMIT_SOCKET, /* 09h Set socket maximum frequency level */
|
||||
HSMP_GET_BOOST_LIMIT, /* 0Ah Get current frequency limit */
|
||||
HSMP_GET_PROC_HOT, /* 0Bh Get PROCHOT status */
|
||||
HSMP_SET_XGMI_LINK_WIDTH, /* 0Ch Set max and min width of xGMI Link */
|
||||
HSMP_SET_DF_PSTATE, /* 0Dh Alter APEnable/Disable messages behavior */
|
||||
HSMP_SET_AUTO_DF_PSTATE, /* 0Eh Enable DF P-State Performance Boost algorithm */
|
||||
HSMP_GET_FCLK_MCLK, /* 0Fh Get FCLK and MEMCLK for current socket */
|
||||
HSMP_GET_CCLK_THROTTLE_LIMIT, /* 10h Get CCLK frequency limit in socket */
|
||||
HSMP_GET_C0_PERCENT, /* 11h Get average C0 residency in socket */
|
||||
HSMP_SET_NBIO_DPM_LEVEL, /* 12h Set max/min LCLK DPM Level for a given NBIO */
|
||||
HSMP_GET_NBIO_DPM_LEVEL, /* 13h Get LCLK DPM level min and max for a given NBIO */
|
||||
HSMP_GET_DDR_BANDWIDTH, /* 14h Get theoretical maximum and current DDR Bandwidth */
|
||||
HSMP_GET_TEMP_MONITOR, /* 15h Get socket temperature */
|
||||
HSMP_GET_DIMM_TEMP_RANGE, /* 16h Get per-DIMM temperature range and refresh rate */
|
||||
HSMP_GET_DIMM_POWER, /* 17h Get per-DIMM power consumption */
|
||||
HSMP_GET_DIMM_THERMAL, /* 18h Get per-DIMM thermal sensors */
|
||||
HSMP_GET_SOCKET_FREQ_LIMIT, /* 19h Get current active frequency per socket */
|
||||
HSMP_GET_CCLK_CORE_LIMIT, /* 1Ah Get CCLK frequency limit per core */
|
||||
HSMP_GET_RAILS_SVI, /* 1Bh Get SVI-based Telemetry for all rails */
|
||||
HSMP_GET_SOCKET_FMAX_FMIN,/* 1Ch Get Fmax and Fmin per socket */
|
||||
HSMP_GET_IOLINK_BANDWITH, /* 1Dh Get current bandwidth on IO Link */
|
||||
HSMP_GET_XGMI_BANDWITH, /* 1Eh Get current bandwidth on xGMI Link */
|
||||
HSMP_SET_GMI3_WIDTH, /* 1Fh Set max and min GMI3 Link width */
|
||||
HSMP_SET_PCI_RATE, /* 20h Control link rate on PCIe devices */
|
||||
HSMP_SET_POWER_MODE, /* 21h Select power efficiency profile policy */
|
||||
HSMP_SET_PSTATE_MAX_MIN, /* 22h Set the max and min DF P-State */
|
||||
HSMP_GET_METRIC_TABLE_VER,/* 23h Get metrics table version */
|
||||
HSMP_GET_METRIC_TABLE, /* 24h Get metrics table */
|
||||
HSMP_GET_METRIC_TABLE_DRAM_ADDR,/* 25h Get metrics table dram address */
|
||||
HSMP_MSG_ID_MAX,
|
||||
};
|
||||
|
||||
struct hsmp_message {
|
||||
__u32 msg_id; /* Message ID */
|
||||
__u16 num_args; /* Number of input argument words in message */
|
||||
__u16 response_sz; /* Number of expected output/response words */
|
||||
__u32 args[HSMP_MAX_MSG_LEN]; /* argument/response buffer */
|
||||
__u16 sock_ind; /* socket number */
|
||||
};
|
||||
|
||||
enum hsmp_msg_type {
|
||||
HSMP_RSVD = -1,
|
||||
HSMP_SET = 0,
|
||||
HSMP_GET = 1,
|
||||
};
|
||||
|
||||
enum hsmp_proto_versions {
|
||||
HSMP_PROTO_VER2 = 2,
|
||||
HSMP_PROTO_VER3,
|
||||
HSMP_PROTO_VER4,
|
||||
HSMP_PROTO_VER5,
|
||||
HSMP_PROTO_VER6
|
||||
};
|
||||
|
||||
struct hsmp_msg_desc {
|
||||
int num_args;
|
||||
int response_sz;
|
||||
enum hsmp_msg_type type;
|
||||
};
|
||||
|
||||
/*
|
||||
* User may use these comments as reference, please find the
|
||||
* supported list of messages and message definition in the
|
||||
* HSMP chapter of respective family/model PPR.
|
||||
*
|
||||
* Not supported messages would return -ENOMSG.
|
||||
*/
|
||||
static const struct hsmp_msg_desc hsmp_msg_desc_table[]
|
||||
__attribute__((unused)) = {
|
||||
/* RESERVED */
|
||||
{0, 0, HSMP_RSVD},
|
||||
|
||||
/*
|
||||
* HSMP_TEST, num_args = 1, response_sz = 1
|
||||
* input: args[0] = xx
|
||||
* output: args[0] = xx + 1
|
||||
*/
|
||||
{1, 1, HSMP_GET},
|
||||
|
||||
/*
|
||||
* HSMP_GET_SMU_VER, num_args = 0, response_sz = 1
|
||||
* output: args[0] = smu fw ver
|
||||
*/
|
||||
{0, 1, HSMP_GET},
|
||||
|
||||
/*
|
||||
* HSMP_GET_PROTO_VER, num_args = 0, response_sz = 1
|
||||
* output: args[0] = proto version
|
||||
*/
|
||||
{0, 1, HSMP_GET},
|
||||
|
||||
/*
|
||||
* HSMP_GET_SOCKET_POWER, num_args = 0, response_sz = 1
|
||||
* output: args[0] = socket power in mWatts
|
||||
*/
|
||||
{0, 1, HSMP_GET},
|
||||
|
||||
/*
|
||||
* HSMP_SET_SOCKET_POWER_LIMIT, num_args = 1, response_sz = 0
|
||||
* input: args[0] = power limit value in mWatts
|
||||
*/
|
||||
{1, 0, HSMP_SET},
|
||||
|
||||
/*
|
||||
* HSMP_GET_SOCKET_POWER_LIMIT, num_args = 0, response_sz = 1
|
||||
* output: args[0] = socket power limit value in mWatts
|
||||
*/
|
||||
{0, 1, HSMP_GET},
|
||||
|
||||
/*
|
||||
* HSMP_GET_SOCKET_POWER_LIMIT_MAX, num_args = 0, response_sz = 1
|
||||
* output: args[0] = maximuam socket power limit in mWatts
|
||||
*/
|
||||
{0, 1, HSMP_GET},
|
||||
|
||||
/*
|
||||
* HSMP_SET_BOOST_LIMIT, num_args = 1, response_sz = 0
|
||||
* input: args[0] = apic id[31:16] + boost limit value in MHz[15:0]
|
||||
*/
|
||||
{1, 0, HSMP_SET},
|
||||
|
||||
/*
|
||||
* HSMP_SET_BOOST_LIMIT_SOCKET, num_args = 1, response_sz = 0
|
||||
* input: args[0] = boost limit value in MHz
|
||||
*/
|
||||
{1, 0, HSMP_SET},
|
||||
|
||||
/*
|
||||
* HSMP_GET_BOOST_LIMIT, num_args = 1, response_sz = 1
|
||||
* input: args[0] = apic id
|
||||
* output: args[0] = boost limit value in MHz
|
||||
*/
|
||||
{1, 1, HSMP_GET},
|
||||
|
||||
/*
|
||||
* HSMP_GET_PROC_HOT, num_args = 0, response_sz = 1
|
||||
* output: args[0] = proc hot status
|
||||
*/
|
||||
{0, 1, HSMP_GET},
|
||||
|
||||
/*
|
||||
* HSMP_SET_XGMI_LINK_WIDTH, num_args = 1, response_sz = 0
|
||||
* input: args[0] = min link width[15:8] + max link width[7:0]
|
||||
*/
|
||||
{1, 0, HSMP_SET},
|
||||
|
||||
/*
|
||||
* HSMP_SET_DF_PSTATE, num_args = 1, response_sz = 0
|
||||
* input: args[0] = df pstate[7:0]
|
||||
*/
|
||||
{1, 0, HSMP_SET},
|
||||
|
||||
/* HSMP_SET_AUTO_DF_PSTATE, num_args = 0, response_sz = 0 */
|
||||
{0, 0, HSMP_SET},
|
||||
|
||||
/*
|
||||
* HSMP_GET_FCLK_MCLK, num_args = 0, response_sz = 2
|
||||
* output: args[0] = fclk in MHz, args[1] = mclk in MHz
|
||||
*/
|
||||
{0, 2, HSMP_GET},
|
||||
|
||||
/*
|
||||
* HSMP_GET_CCLK_THROTTLE_LIMIT, num_args = 0, response_sz = 1
|
||||
* output: args[0] = core clock in MHz
|
||||
*/
|
||||
{0, 1, HSMP_GET},
|
||||
|
||||
/*
|
||||
* HSMP_GET_C0_PERCENT, num_args = 0, response_sz = 1
|
||||
* output: args[0] = average c0 residency
|
||||
*/
|
||||
{0, 1, HSMP_GET},
|
||||
|
||||
/*
|
||||
* HSMP_SET_NBIO_DPM_LEVEL, num_args = 1, response_sz = 0
|
||||
* input: args[0] = nbioid[23:16] + max dpm level[15:8] + min dpm level[7:0]
|
||||
*/
|
||||
{1, 0, HSMP_SET},
|
||||
|
||||
/*
|
||||
* HSMP_GET_NBIO_DPM_LEVEL, num_args = 1, response_sz = 1
|
||||
* input: args[0] = nbioid[23:16]
|
||||
* output: args[0] = max dpm level[15:8] + min dpm level[7:0]
|
||||
*/
|
||||
{1, 1, HSMP_GET},
|
||||
|
||||
/*
|
||||
* HSMP_GET_DDR_BANDWIDTH, num_args = 0, response_sz = 1
|
||||
* output: args[0] = max bw in Gbps[31:20] + utilised bw in Gbps[19:8] +
|
||||
* bw in percentage[7:0]
|
||||
*/
|
||||
{0, 1, HSMP_GET},
|
||||
|
||||
/*
|
||||
* HSMP_GET_TEMP_MONITOR, num_args = 0, response_sz = 1
|
||||
* output: args[0] = temperature in degree celsius. [15:8] integer part +
|
||||
* [7:5] fractional part
|
||||
*/
|
||||
{0, 1, HSMP_GET},
|
||||
|
||||
/*
|
||||
* HSMP_GET_DIMM_TEMP_RANGE, num_args = 1, response_sz = 1
|
||||
* input: args[0] = DIMM address[7:0]
|
||||
* output: args[0] = refresh rate[3] + temperature range[2:0]
|
||||
*/
|
||||
{1, 1, HSMP_GET},
|
||||
|
||||
/*
|
||||
* HSMP_GET_DIMM_POWER, num_args = 1, response_sz = 1
|
||||
* input: args[0] = DIMM address[7:0]
|
||||
* output: args[0] = DIMM power in mW[31:17] + update rate in ms[16:8] +
|
||||
* DIMM address[7:0]
|
||||
*/
|
||||
{1, 1, HSMP_GET},
|
||||
|
||||
/*
|
||||
* HSMP_GET_DIMM_THERMAL, num_args = 1, response_sz = 1
|
||||
* input: args[0] = DIMM address[7:0]
|
||||
* output: args[0] = temperature in degree celsius[31:21] + update rate in ms[16:8] +
|
||||
* DIMM address[7:0]
|
||||
*/
|
||||
{1, 1, HSMP_GET},
|
||||
|
||||
/*
|
||||
* HSMP_GET_SOCKET_FREQ_LIMIT, num_args = 0, response_sz = 1
|
||||
* output: args[0] = frequency in MHz[31:16] + frequency source[15:0]
|
||||
*/
|
||||
{0, 1, HSMP_GET},
|
||||
|
||||
/*
|
||||
* HSMP_GET_CCLK_CORE_LIMIT, num_args = 1, response_sz = 1
|
||||
* input: args[0] = apic id [31:0]
|
||||
* output: args[0] = frequency in MHz[31:0]
|
||||
*/
|
||||
{1, 1, HSMP_GET},
|
||||
|
||||
/*
|
||||
* HSMP_GET_RAILS_SVI, num_args = 0, response_sz = 1
|
||||
* output: args[0] = power in mW[31:0]
|
||||
*/
|
||||
{0, 1, HSMP_GET},
|
||||
|
||||
/*
|
||||
* HSMP_GET_SOCKET_FMAX_FMIN, num_args = 0, response_sz = 1
|
||||
* output: args[0] = fmax in MHz[31:16] + fmin in MHz[15:0]
|
||||
*/
|
||||
{0, 1, HSMP_GET},
|
||||
|
||||
/*
|
||||
* HSMP_GET_IOLINK_BANDWITH, num_args = 1, response_sz = 1
|
||||
* input: args[0] = link id[15:8] + bw type[2:0]
|
||||
* output: args[0] = io bandwidth in Mbps[31:0]
|
||||
*/
|
||||
{1, 1, HSMP_GET},
|
||||
|
||||
/*
|
||||
* HSMP_GET_XGMI_BANDWITH, num_args = 1, response_sz = 1
|
||||
* input: args[0] = link id[15:8] + bw type[2:0]
|
||||
* output: args[0] = xgmi bandwidth in Mbps[31:0]
|
||||
*/
|
||||
{1, 1, HSMP_GET},
|
||||
|
||||
/*
|
||||
* HSMP_SET_GMI3_WIDTH, num_args = 1, response_sz = 0
|
||||
* input: args[0] = min link width[15:8] + max link width[7:0]
|
||||
*/
|
||||
{1, 0, HSMP_SET},
|
||||
|
||||
/*
|
||||
* HSMP_SET_PCI_RATE, num_args = 1, response_sz = 1
|
||||
* input: args[0] = link rate control value
|
||||
* output: args[0] = previous link rate control value
|
||||
*/
|
||||
{1, 1, HSMP_SET},
|
||||
|
||||
/*
|
||||
* HSMP_SET_POWER_MODE, num_args = 1, response_sz = 0
|
||||
* input: args[0] = power efficiency mode[2:0]
|
||||
*/
|
||||
{1, 0, HSMP_SET},
|
||||
|
||||
/*
|
||||
* HSMP_SET_PSTATE_MAX_MIN, num_args = 1, response_sz = 0
|
||||
* input: args[0] = min df pstate[15:8] + max df pstate[7:0]
|
||||
*/
|
||||
{1, 0, HSMP_SET},
|
||||
|
||||
/*
|
||||
* HSMP_GET_METRIC_TABLE_VER, num_args = 0, response_sz = 1
|
||||
* output: args[0] = metrics table version
|
||||
*/
|
||||
{0, 1, HSMP_GET},
|
||||
|
||||
/*
|
||||
* HSMP_GET_METRIC_TABLE, num_args = 0, response_sz = 0
|
||||
*/
|
||||
{0, 0, HSMP_GET},
|
||||
|
||||
/*
|
||||
* HSMP_GET_METRIC_TABLE_DRAM_ADDR, num_args = 0, response_sz = 2
|
||||
* output: args[0] = lower 32 bits of the address
|
||||
* output: args[1] = upper 32 bits of the address
|
||||
*/
|
||||
{0, 2, HSMP_GET},
|
||||
};
|
||||
|
||||
/* Metrics table (supported only with proto version 6) */
|
||||
struct hsmp_metric_table {
|
||||
__u32 accumulation_counter;
|
||||
|
||||
/* TEMPERATURE */
|
||||
__u32 max_socket_temperature;
|
||||
__u32 max_vr_temperature;
|
||||
__u32 max_hbm_temperature;
|
||||
__u64 max_socket_temperature_acc;
|
||||
__u64 max_vr_temperature_acc;
|
||||
__u64 max_hbm_temperature_acc;
|
||||
|
||||
/* POWER */
|
||||
__u32 socket_power_limit;
|
||||
__u32 max_socket_power_limit;
|
||||
__u32 socket_power;
|
||||
|
||||
/* ENERGY */
|
||||
__u64 timestamp;
|
||||
__u64 socket_energy_acc;
|
||||
__u64 ccd_energy_acc;
|
||||
__u64 xcd_energy_acc;
|
||||
__u64 aid_energy_acc;
|
||||
__u64 hbm_energy_acc;
|
||||
|
||||
/* FREQUENCY */
|
||||
__u32 cclk_frequency_limit;
|
||||
__u32 gfxclk_frequency_limit;
|
||||
__u32 fclk_frequency;
|
||||
__u32 uclk_frequency;
|
||||
__u32 socclk_frequency[4];
|
||||
__u32 vclk_frequency[4];
|
||||
__u32 dclk_frequency[4];
|
||||
__u32 lclk_frequency[4];
|
||||
__u64 gfxclk_frequency_acc[8];
|
||||
__u64 cclk_frequency_acc[96];
|
||||
|
||||
/* FREQUENCY RANGE */
|
||||
__u32 max_cclk_frequency;
|
||||
__u32 min_cclk_frequency;
|
||||
__u32 max_gfxclk_frequency;
|
||||
__u32 min_gfxclk_frequency;
|
||||
__u32 fclk_frequency_table[4];
|
||||
__u32 uclk_frequency_table[4];
|
||||
__u32 socclk_frequency_table[4];
|
||||
__u32 vclk_frequency_table[4];
|
||||
__u32 dclk_frequency_table[4];
|
||||
__u32 lclk_frequency_table[4];
|
||||
__u32 max_lclk_dpm_range;
|
||||
__u32 min_lclk_dpm_range;
|
||||
|
||||
/* XGMI */
|
||||
__u32 xgmi_width;
|
||||
__u32 xgmi_bitrate;
|
||||
__u64 xgmi_read_bandwidth_acc[8];
|
||||
__u64 xgmi_write_bandwidth_acc[8];
|
||||
|
||||
/* ACTIVITY */
|
||||
__u32 socket_c0_residency;
|
||||
__u32 socket_gfx_busy;
|
||||
__u32 dram_bandwidth_utilization;
|
||||
__u64 socket_c0_residency_acc;
|
||||
__u64 socket_gfx_busy_acc;
|
||||
__u64 dram_bandwidth_acc;
|
||||
__u32 max_dram_bandwidth;
|
||||
__u64 dram_bandwidth_utilization_acc;
|
||||
__u64 pcie_bandwidth_acc[4];
|
||||
|
||||
/* THROTTLERS */
|
||||
__u32 prochot_residency_acc;
|
||||
__u32 ppt_residency_acc;
|
||||
__u32 socket_thm_residency_acc;
|
||||
__u32 vr_thm_residency_acc;
|
||||
__u32 hbm_thm_residency_acc;
|
||||
__u32 spare;
|
||||
|
||||
/* New items at the end to maintain driver compatibility */
|
||||
__u32 gfxclk_frequency[8];
|
||||
};
|
||||
|
||||
/* Reset to default packing */
|
||||
#pragma pack()
|
||||
|
||||
/* Define unique ioctl command for hsmp msgs using generic _IOWR */
|
||||
#define HSMP_BASE_IOCTL_NR 0xF8
|
||||
#define HSMP_IOCTL_CMD _IOWR(HSMP_BASE_IOCTL_NR, 0, struct hsmp_message)
|
||||
|
||||
#endif /*_ASM_X86_AMD_HSMP_H_*/
|
||||
@@ -69,7 +69,7 @@ AMDSMI_MAX_CACHE_TYPES = 10
|
||||
AMDSMI_MAX_NUM_XGMI_PHYSICAL_LINK = 64
|
||||
AMDSMI_GPU_UUID_SIZE = 38
|
||||
MAX_AMDSMI_NAME_LENGTH = 64
|
||||
MAX_EVENT_NOTIFICATION_MSG_SIZE = 64
|
||||
MAX_EVENT_NOTIFICATION_MSG_SIZE = 96
|
||||
|
||||
|
||||
class AmdSmiInitFlags(IntEnum):
|
||||
@@ -1653,7 +1653,7 @@ def amdsmi_get_gpu_asic_info(
|
||||
|
||||
market_name = _pad_hex_value(asic_info_struct.market_name.decode("utf-8"), 4)
|
||||
target_graphics_version = str(asic_info_struct.target_graphics_version)
|
||||
if len(target_graphics_version) == 4 and ("Instinct MI2" in market_name):
|
||||
if target_graphics_version == "9010":
|
||||
hex_part = str(hex(int(str(asic_info_struct.target_graphics_version)[2:]))).replace("0x", "")
|
||||
target_graphics_version = str(asic_info_struct.target_graphics_version)[:2] + hex_part
|
||||
asic_info = {
|
||||
@@ -2956,21 +2956,31 @@ def amdsmi_reset_gpu_fan(
|
||||
|
||||
def amdsmi_set_clk_freq(
|
||||
processor_handle: amdsmi_wrapper.amdsmi_processor_handle,
|
||||
clk_type: AmdSmiClkType,
|
||||
clk_type: str,
|
||||
freq_bitmask: int,
|
||||
):
|
||||
if not isinstance(processor_handle, amdsmi_wrapper.amdsmi_processor_handle):
|
||||
raise AmdSmiParameterException(
|
||||
processor_handle, amdsmi_wrapper.amdsmi_processor_handle
|
||||
)
|
||||
if not isinstance(clk_type, AmdSmiClkType):
|
||||
raise AmdSmiParameterException(clk_type, AmdSmiParameterException)
|
||||
if clk_type.lower() == "sclk":
|
||||
clk_type_conversion = AmdSmiClkType.SYS
|
||||
elif clk_type.lower() == "mclk":
|
||||
clk_type_conversion = AmdSmiClkType.MEM
|
||||
elif clk_type.lower() == "fclk":
|
||||
clk_type_conversion = AmdSmiClkType.DF
|
||||
elif clk_type.lower() == "socclk":
|
||||
clk_type_conversion = AmdSmiClkType.SOC
|
||||
else:
|
||||
clk_type_conversion = "N/A"
|
||||
if not isinstance(clk_type_conversion, AmdSmiClkType):
|
||||
raise AmdSmiParameterException(clk_type_conversion, AmdSmiClkType)
|
||||
if not isinstance(freq_bitmask, int):
|
||||
raise AmdSmiParameterException(freq_bitmask, int)
|
||||
freq_bitmask = ctypes.c_uint64(freq_bitmask)
|
||||
_check_res(
|
||||
amdsmi_wrapper.amdsmi_set_clk_freq(
|
||||
processor_handle, clk_type, freq_bitmask
|
||||
processor_handle, clk_type_conversion, freq_bitmask
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -1300,7 +1300,7 @@ struct_amdsmi_evt_notification_data_t._pack_ = 1 # source:False
|
||||
struct_amdsmi_evt_notification_data_t._fields_ = [
|
||||
('processor_handle', ctypes.POINTER(None)),
|
||||
('event', amdsmi_evt_notification_type_t),
|
||||
('message', ctypes.c_char * 64),
|
||||
('message', ctypes.c_char * 96),
|
||||
('PADDING_0', ctypes.c_ubyte * 4),
|
||||
]
|
||||
|
||||
@@ -1741,6 +1741,7 @@ struct_amdsmi_gpu_xcp_metrics_t._fields_ = [
|
||||
('gfx_busy_acc', ctypes.c_uint64 * 8),
|
||||
]
|
||||
|
||||
amdsmi_gpu_xcp_metrics_t = struct_amdsmi_gpu_xcp_metrics_t
|
||||
class struct_amdsmi_gpu_metrics_t(Structure):
|
||||
pass
|
||||
|
||||
@@ -2869,11 +2870,12 @@ __all__ = \
|
||||
'amdsmi_gpu_cache_info_t', 'amdsmi_gpu_control_counter',
|
||||
'amdsmi_gpu_counter_group_supported', 'amdsmi_gpu_create_counter',
|
||||
'amdsmi_gpu_destroy_counter', 'amdsmi_gpu_metrics_t',
|
||||
'amdsmi_gpu_read_counter', 'amdsmi_gpu_xgmi_error_status',
|
||||
'amdsmi_hsmp_freqlimit_src_names', 'amdsmi_hsmp_metrics_table_t',
|
||||
'amdsmi_init', 'amdsmi_init_flags_t',
|
||||
'amdsmi_init_gpu_event_notification', 'amdsmi_io_bw_encoding_t',
|
||||
'amdsmi_io_link_type_t', 'amdsmi_is_P2P_accessible',
|
||||
'amdsmi_gpu_read_counter', 'amdsmi_gpu_xcp_metrics_t',
|
||||
'amdsmi_gpu_xgmi_error_status', 'amdsmi_hsmp_freqlimit_src_names',
|
||||
'amdsmi_hsmp_metrics_table_t', 'amdsmi_init',
|
||||
'amdsmi_init_flags_t', 'amdsmi_init_gpu_event_notification',
|
||||
'amdsmi_io_bw_encoding_t', 'amdsmi_io_link_type_t',
|
||||
'amdsmi_is_P2P_accessible',
|
||||
'amdsmi_is_gpu_power_management_enabled', 'amdsmi_kfd_info_t',
|
||||
'amdsmi_link_id_bw_type_t', 'amdsmi_link_metrics_t',
|
||||
'amdsmi_link_type_t', 'amdsmi_memory_page_status_t',
|
||||
|
||||
@@ -15,9 +15,6 @@ license = {file = "amdsmi/LICENSE"}
|
||||
readme = {file = "amdsmi/README.md", content-type = "text/markdown"}
|
||||
description = "AMDSMI Python LIB - AMD GPU Monitoring Library"
|
||||
requires-python = ">=3.6"
|
||||
dependencies = [
|
||||
"PyYAML >= 3.0",
|
||||
]
|
||||
classifiers = [
|
||||
"Programming Language :: Python :: 3"
|
||||
]
|
||||
|
||||
@@ -9,9 +9,6 @@ setup(
|
||||
description="AMDSMI Python LIB - AMD GPU Monitoring Library",
|
||||
url="https://github.com/ROCm/amdsmi",
|
||||
packages=find_packages(),
|
||||
install_requires=[
|
||||
"PyYAML>=3.0",
|
||||
],
|
||||
classifiers=[
|
||||
"Programming Language :: Python :: 3",
|
||||
],
|
||||
|
||||
@@ -695,7 +695,7 @@ static rsmi_status_t test_set_memory_partition(uint32_t dv_ind) {
|
||||
}
|
||||
|
||||
template<typename T> constexpr float convert_mw_to_w(T mw) {
|
||||
return static_cast<float>(mw / 1000.0);
|
||||
return static_cast<float>(static_cast<double>(mw) / 1000.0);
|
||||
}
|
||||
|
||||
|
||||
@@ -1112,7 +1112,7 @@ int main() {
|
||||
if (ret == RSMI_STATUS_SUCCESS) {
|
||||
ret = rsmi_dev_fan_speed_max_get(i, 0, &val_ui64);
|
||||
CHK_AND_PRINT_RSMI_ERR_RET(ret)
|
||||
std::cout << (static_cast<float>(val_i64)/val_ui64) * 100;
|
||||
std::cout << (static_cast<float>(val_i64)/static_cast<float>(val_ui64)) * 100;
|
||||
std::cout << "% (" << std::dec << val_i64 << "/"
|
||||
<< std::dec << val_ui64 << ")" << "\n";
|
||||
}
|
||||
|
||||
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
@@ -344,9 +344,15 @@ typedef enum {
|
||||
RSMI_EVT_NOTIF_THERMAL_THROTTLE = KFD_SMI_EVENT_THERMAL_THROTTLE,
|
||||
RSMI_EVT_NOTIF_GPU_PRE_RESET = KFD_SMI_EVENT_GPU_PRE_RESET,
|
||||
RSMI_EVT_NOTIF_GPU_POST_RESET = KFD_SMI_EVENT_GPU_POST_RESET,
|
||||
RSMI_EVT_NOTIF_RING_HANG = KFD_SMI_EVENT_RING_HANG,
|
||||
|
||||
RSMI_EVT_NOTIF_LAST = RSMI_EVT_NOTIF_RING_HANG
|
||||
RSMI_EVT_NOTIF_EVENT_MIGRATE_START = KFD_SMI_EVENT_MIGRATE_START,
|
||||
RSMI_EVT_NOTIF_EVENT_MIGRATE_END = KFD_SMI_EVENT_MIGRATE_END,
|
||||
RSMI_EVT_NOTIF_EVENT_PAGE_FAULT_START = KFD_SMI_EVENT_PAGE_FAULT_START,
|
||||
RSMI_EVT_NOTIF_EVENT_PAGE_FAULT_END = KFD_SMI_EVENT_PAGE_FAULT_END,
|
||||
RSMI_EVT_NOTIF_EVENT_QUEUE_EVICTION = KFD_SMI_EVENT_QUEUE_EVICTION,
|
||||
RSMI_EVT_NOTIF_EVENT_QUEUE_RESTORE = KFD_SMI_EVENT_QUEUE_RESTORE,
|
||||
RSMI_EVT_NOTIF_EVENT_UNMAP_FROM_GPU = KFD_SMI_EVENT_UNMAP_FROM_GPU,
|
||||
RSMI_EVT_NOTIF_EVENT_ALL_PROCESS = KFD_SMI_EVENT_ALL_PROCESS,
|
||||
RSMI_EVT_NOTIF_LAST = KFD_SMI_EVENT_ALL_PROCESS
|
||||
} rsmi_evt_notification_type_t;
|
||||
|
||||
/**
|
||||
@@ -355,7 +361,8 @@ typedef enum {
|
||||
#define RSMI_EVENT_MASK_FROM_INDEX(i) (1ULL << ((i) - 1))
|
||||
|
||||
//! Maximum number of characters an event notification message will be
|
||||
#define MAX_EVENT_NOTIFICATION_MSG_SIZE 64
|
||||
// matches kfd message max size
|
||||
#define MAX_EVENT_NOTIFICATION_MSG_SIZE 96
|
||||
|
||||
/**
|
||||
* Event notification data returned from event notification API
|
||||
@@ -1264,7 +1271,7 @@ typedef struct {
|
||||
/**
|
||||
* Accumulated throttler residencies
|
||||
*
|
||||
* Socket (thermal) -
|
||||
* Socket (thermal) -
|
||||
* Socket thermal violation % (greater than 0% is a violation);
|
||||
* aka TVIOL
|
||||
*
|
||||
|
||||
@@ -427,7 +427,7 @@ class TagTextContents_t
|
||||
|
||||
decltype(auto) get_structured_data_subkey_last(const PrimaryKeyType& prim_key) {
|
||||
return (get_structured_value_by_keys(prim_key, get_structured_data_subkey_by_position(prim_key,
|
||||
(get_structured_subkeys_size(prim_key) - 1))));
|
||||
static_cast<int>((get_structured_subkeys_size(prim_key) - 1)))));
|
||||
}
|
||||
|
||||
void reset() {
|
||||
|
||||
+226
-59
@@ -186,39 +186,6 @@ static uint64_t freq_string_to_int(const std::vector<std::string> &freq_lines,
|
||||
return static_cast<uint64_t>(freq*multiplier);
|
||||
}
|
||||
|
||||
static void freq_volt_string_to_point(std::string in_line,
|
||||
rsmi_od_vddc_point_t *pt) {
|
||||
std::istringstream fs_vlt(in_line);
|
||||
|
||||
assert(pt != nullptr);
|
||||
THROW_IF_NULLPTR_DEREF(pt)
|
||||
|
||||
uint32_t ind;
|
||||
float freq;
|
||||
float volts;
|
||||
std::string junk;
|
||||
std::string freq_units_str;
|
||||
std::string volts_units_str;
|
||||
|
||||
fs_vlt >> ind;
|
||||
fs_vlt >> junk; // colon
|
||||
fs_vlt >> freq;
|
||||
fs_vlt >> freq_units_str;
|
||||
fs_vlt >> volts;
|
||||
fs_vlt >> volts_units_str;
|
||||
|
||||
if (freq < 0) {
|
||||
throw amd::smi::rsmi_exception(RSMI_STATUS_UNEXPECTED_SIZE, __FUNCTION__);
|
||||
}
|
||||
|
||||
long double multiplier = get_multiplier_from_str(freq_units_str[0]);
|
||||
|
||||
pt->frequency = static_cast<uint64_t>(freq*multiplier);
|
||||
|
||||
multiplier = get_multiplier_from_str(volts_units_str[0]);
|
||||
pt->voltage = static_cast<uint64_t>(volts*multiplier);
|
||||
}
|
||||
|
||||
static void od_value_pair_str_to_range(std::string in_line, rsmi_range_t *rg) {
|
||||
std::istringstream fs_rng(in_line);
|
||||
|
||||
@@ -898,7 +865,7 @@ rsmi_status_t rsmi_ras_feature_info_get(
|
||||
auto eeprom_version = strtoul(
|
||||
feature_line.substr(strlen(version_key)).c_str(), nullptr, 16);
|
||||
if (errno == 0) {
|
||||
ras_feature->ras_eeprom_version = eeprom_version;
|
||||
ras_feature->ras_eeprom_version = static_cast<uint32_t>(eeprom_version);
|
||||
} else {
|
||||
return RSMI_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
@@ -922,7 +889,7 @@ rsmi_status_t rsmi_ras_feature_info_get(
|
||||
auto schema = strtoul(
|
||||
feature_line.substr(strlen(schema_key)).c_str(), nullptr, 16);
|
||||
if (errno == 0) {
|
||||
ras_feature->ecc_correction_schema_flag = schema;
|
||||
ras_feature->ecc_correction_schema_flag = static_cast<uint32_t>(schema);
|
||||
} else {
|
||||
return RSMI_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
@@ -2044,7 +2011,7 @@ rsmi_dev_gpu_clk_freq_set(uint32_t dv_ind,
|
||||
// will have read-only perms, and the OS will deny access, before the request hits the driver level
|
||||
if (status == RSMI_STATUS_PERMISSION){
|
||||
bool read_only = false;
|
||||
int perms = amd::smi::isReadOnlyForAll(dev->path(), &read_only);
|
||||
amd::smi::isReadOnlyForAll(dev->path(), &read_only);
|
||||
if(read_only){
|
||||
return RSMI_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
@@ -2113,8 +2080,6 @@ rsmi_status_t rsmi_dev_process_isolation_get(uint32_t dv_ind,
|
||||
|
||||
rsmi_status_t rsmi_dev_process_isolation_set(uint32_t dv_ind,
|
||||
uint32_t pisolate) {
|
||||
rsmi_status_t ret;
|
||||
|
||||
TRY
|
||||
std::ostringstream ss;
|
||||
ss << __PRETTY_FUNCTION__ << " | ======= start =======";
|
||||
@@ -2178,8 +2143,6 @@ rsmi_status_t rsmi_dev_process_isolation_set(uint32_t dv_ind,
|
||||
}
|
||||
|
||||
rsmi_status_t rsmi_dev_gpu_run_cleaner_shader(uint32_t dv_ind) {
|
||||
rsmi_status_t ret;
|
||||
|
||||
TRY
|
||||
std::ostringstream ss;
|
||||
ss << __PRETTY_FUNCTION__ << " | ======= start =======";
|
||||
@@ -2294,8 +2257,6 @@ rsmi_dev_xgmi_plpd_get(uint32_t dv_ind,
|
||||
rsmi_status_t
|
||||
rsmi_dev_xgmi_plpd_set(uint32_t dv_ind,
|
||||
uint32_t plpd_id) {
|
||||
rsmi_status_t ret;
|
||||
|
||||
TRY
|
||||
std::ostringstream ss;
|
||||
ss << __PRETTY_FUNCTION__ << " | ======= start =======";
|
||||
@@ -2408,8 +2369,6 @@ rsmi_dev_soc_pstate_get(uint32_t dv_ind,
|
||||
rsmi_status_t
|
||||
rsmi_dev_soc_pstate_set(uint32_t dv_ind,
|
||||
uint32_t policy_id) {
|
||||
rsmi_status_t ret;
|
||||
|
||||
TRY
|
||||
std::ostringstream ss;
|
||||
ss << __PRETTY_FUNCTION__ << " | ======= start =======";
|
||||
@@ -2977,25 +2936,25 @@ rsmi_dev_pci_bandwidth_get(uint32_t dv_ind, rsmi_pcie_bandwidth_t *b) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Hardcode based on PCIe specification: Search PCI_Express on wikipedia
|
||||
// Hardcode based on PCIe specification: search PCI_Express on wikipedia
|
||||
const uint32_t link_width[] = {1, 2, 4, 8, 12, 16};
|
||||
const uint32_t link_speed[] = {25, 50, 80, 160}; // 0.1 Ghz
|
||||
const uint32_t WIDTH_DATA_LENGTH = sizeof(link_width)/sizeof(uint32_t);
|
||||
const uint32_t SPEED_DATA_LENGTH = sizeof(link_speed)/sizeof(uint32_t);
|
||||
|
||||
// Calculate the index
|
||||
uint32_t width_index = -1;
|
||||
uint32_t speed_index = -1;
|
||||
int32_t width_index = -1;
|
||||
int32_t speed_index = -1;
|
||||
uint32_t cur_index = 0;
|
||||
for (cur_index = 0; cur_index < WIDTH_DATA_LENGTH; cur_index++) {
|
||||
if (link_width[cur_index] == gpu_metrics.pcie_link_width) {
|
||||
width_index = cur_index;
|
||||
width_index = static_cast<int32_t>(cur_index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (cur_index = 0; cur_index < SPEED_DATA_LENGTH; cur_index++) {
|
||||
if (link_speed[cur_index] == gpu_metrics.pcie_link_speed) {
|
||||
speed_index = cur_index;
|
||||
speed_index = static_cast<int32_t>(cur_index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -3004,7 +2963,7 @@ rsmi_dev_pci_bandwidth_get(uint32_t dv_ind, rsmi_pcie_bandwidth_t *b) {
|
||||
}
|
||||
// Set possible lanes and frequencies
|
||||
b->transfer_rate.num_supported = WIDTH_DATA_LENGTH * SPEED_DATA_LENGTH;
|
||||
b->transfer_rate.current = speed_index*WIDTH_DATA_LENGTH + width_index;
|
||||
b->transfer_rate.current = static_cast<uint32_t>(speed_index)*WIDTH_DATA_LENGTH + static_cast<uint32_t>(width_index);
|
||||
for (cur_index = 0; cur_index < WIDTH_DATA_LENGTH * SPEED_DATA_LENGTH; cur_index++) {
|
||||
b->transfer_rate.frequency[cur_index] =
|
||||
static_cast<long>(link_speed[cur_index/WIDTH_DATA_LENGTH]) * 100 * 1000000L;
|
||||
@@ -3930,7 +3889,6 @@ rsmi_dev_memory_total_get(uint32_t dv_ind, rsmi_memory_type_t mem_type,
|
||||
rsmi_status_t rsmi_dev_cache_info_get(
|
||||
uint32_t dv_ind, rsmi_gpu_cache_info_t *info) {
|
||||
TRY
|
||||
rsmi_status_t ret;
|
||||
std::ostringstream ss;
|
||||
ss << __PRETTY_FUNCTION__ << "| ======= start =======";
|
||||
LOG_TRACE(ss);
|
||||
@@ -4214,7 +4172,6 @@ rsmi_utilization_count_get(uint32_t dv_ind,
|
||||
|
||||
rsmi_status_t ret;
|
||||
rsmi_gpu_metrics_t gpu_metrics;
|
||||
uint32_t val_ui32;
|
||||
uint16_t val_counter(0);
|
||||
|
||||
ret = rsmi_dev_gpu_metrics_info_get(dv_ind, &gpu_metrics);
|
||||
@@ -5704,10 +5661,6 @@ rsmi_dev_memory_partition_set(uint32_t dv_ind,
|
||||
REQUIRE_ROOT_ACCESS
|
||||
DEVICE_MUTEX
|
||||
const int k1000_MS_WAIT = 1000;
|
||||
const uint32_t kMaxBoardLength = 128;
|
||||
bool isCorrectDevice = false;
|
||||
char boardName[kMaxBoardLength];
|
||||
boardName[0] = '\0';
|
||||
|
||||
const uint32_t kMaxMemoryCapabilitiesSize = 30;
|
||||
char available_memory_capabilities[kMaxMemoryCapabilitiesSize];
|
||||
@@ -6618,16 +6571,230 @@ rsmi_event_notification_get(int timeout_ms,
|
||||
reinterpret_cast<rsmi_evt_notification_data_t *>(&data[*num_elem]);
|
||||
|
||||
uint32_t event;
|
||||
while (fscanf(anon_fp, "%x %63s\n", &event,
|
||||
reinterpret_cast<char *>(&data_item->message)) == 2) {
|
||||
/* Output is in format as "event information\n"
|
||||
char event_in[MAX_EVENT_NOTIFICATION_MSG_SIZE];
|
||||
memcpy(reinterpret_cast<char *>(event_in), "\0", MAX_EVENT_NOTIFICATION_MSG_SIZE);
|
||||
while (fgets(event_in, MAX_EVENT_NOTIFICATION_MSG_SIZE, anon_fp)) {
|
||||
/* Output is in format as "event_number message_information\n"
|
||||
* Both event are expressed in hex.
|
||||
* information is a string
|
||||
*/
|
||||
char message[MAX_EVENT_NOTIFICATION_MSG_SIZE];
|
||||
// parse the line here for event_number and rest of message_information
|
||||
sscanf(event_in, "%x %[^\n]\n", &event, message);
|
||||
|
||||
// parse message based on event received
|
||||
switch (event){
|
||||
case RSMI_EVT_NOTIF_NONE:
|
||||
strcpy(reinterpret_cast<char *>(&data_item->message), "Event type None received");
|
||||
break;
|
||||
case RSMI_EVT_NOTIF_VMFAULT:
|
||||
{
|
||||
uint32_t pid;
|
||||
char task_name[MAX_EVENT_NOTIFICATION_MSG_SIZE];
|
||||
memcpy(reinterpret_cast<char *>(task_name), "\0", MAX_EVENT_NOTIFICATION_MSG_SIZE);
|
||||
|
||||
sscanf(message, "%x:%s\n", &pid, task_name);
|
||||
std::stringstream final_message;
|
||||
final_message << "PID: " << std::to_string(pid).c_str()
|
||||
<< " task name: " << task_name;
|
||||
|
||||
strcpy(reinterpret_cast<char *>(&data_item->message), final_message.str().c_str());
|
||||
}
|
||||
break;
|
||||
case RSMI_EVT_NOTIF_THERMAL_THROTTLE:
|
||||
{
|
||||
uint64_t bitmask;
|
||||
uint64_t counter;
|
||||
|
||||
sscanf(message, "%llx:%llx\n", &bitmask, &counter);
|
||||
std::stringstream final_message;
|
||||
final_message << "bitmask: 0x" << std::hex << bitmask
|
||||
<< " counter: 0x" << std::hex << counter;
|
||||
|
||||
strcpy(reinterpret_cast<char *>(&data_item->message), final_message.str().c_str());
|
||||
}
|
||||
break;
|
||||
case RSMI_EVT_NOTIF_GPU_PRE_RESET:
|
||||
{
|
||||
uint32_t reset_seq_num;
|
||||
char reset_cause[MAX_EVENT_NOTIFICATION_MSG_SIZE];
|
||||
memcpy(reinterpret_cast<char *>(reset_cause), "\0", MAX_EVENT_NOTIFICATION_MSG_SIZE);
|
||||
|
||||
sscanf(message, "%x %[^\n]\n", &reset_seq_num, reset_cause);
|
||||
std::stringstream final_message;
|
||||
final_message << "reset sequence number: " << std::to_string(reset_seq_num).c_str()
|
||||
<< " reset cause: " << reset_cause;
|
||||
|
||||
strcpy(reinterpret_cast<char *>(&data_item->message), final_message.str().c_str());
|
||||
}
|
||||
break;
|
||||
case RSMI_EVT_NOTIF_GPU_POST_RESET:
|
||||
{
|
||||
uint32_t reset_seq_num;
|
||||
|
||||
sscanf(message, "%x %[^\n]\n", &reset_seq_num);
|
||||
std::stringstream final_message;
|
||||
final_message << "reset sequence number: " << std::to_string(reset_seq_num).c_str();
|
||||
|
||||
strcpy(reinterpret_cast<char *>(&data_item->message), final_message.str().c_str());
|
||||
}
|
||||
break;
|
||||
case RSMI_EVT_NOTIF_EVENT_MIGRATE_START:
|
||||
{
|
||||
int64_t ns;
|
||||
int32_t pid;
|
||||
uint32_t start;
|
||||
uint32_t size;
|
||||
uint16_t from;
|
||||
uint16_t to;
|
||||
uint16_t prefetch_loc;
|
||||
uint16_t preferred_loc;
|
||||
int32_t migrate_trigger;
|
||||
|
||||
sscanf(message, "%lld -%d @%lx(%lx) %x->%x %x:%x %d\n", &ns, &pid, &start, &size, &from, &to, &prefetch_loc, &preferred_loc, &migrate_trigger);
|
||||
std::stringstream final_message;
|
||||
final_message << "nd: " << std::to_string(ns).c_str()
|
||||
<< " pid: " << std::to_string(pid).c_str()
|
||||
<< " start: 0x" << std::hex << start
|
||||
<< " size: 0x" << std::hex << size
|
||||
<< " from: 0x" << std::hex << from
|
||||
<< " to: 0x" << std::hex << to
|
||||
<< " prefetch_loc: 0x" << std::hex << prefetch_loc
|
||||
<< " preferred_loc: 0x" << std::hex << preferred_loc
|
||||
<< " migrate_trigger: " << std::to_string(migrate_trigger).c_str();
|
||||
|
||||
strcpy(reinterpret_cast<char *>(&data_item->message), final_message.str().c_str());
|
||||
}
|
||||
break;
|
||||
case RSMI_EVT_NOTIF_EVENT_MIGRATE_END:
|
||||
{
|
||||
int64_t ns;
|
||||
int32_t pid;
|
||||
uint32_t start;
|
||||
uint32_t size;
|
||||
uint32_t from;
|
||||
uint32_t to;
|
||||
uint32_t migrate_trigger;
|
||||
uint32_t error_code;
|
||||
|
||||
sscanf(message, "%lld -%d @%lx(%lx) %x->%x %d %d\n", &ns, &pid, &start, &size, &from, &to, &migrate_trigger, &error_code);
|
||||
std::stringstream final_message;
|
||||
final_message << "nd: " << std::to_string(ns).c_str()
|
||||
<< " pid: " << std::to_string(pid).c_str()
|
||||
<< " start: 0x" << std::hex << start
|
||||
<< " size: 0x" << std::hex << size
|
||||
<< " from: 0x" << std::hex << from
|
||||
<< " to: 0x" << std::hex << to
|
||||
<< " migrate_trigger: " << std::to_string(migrate_trigger).c_str()
|
||||
<< " error_code: " << std::to_string(error_code).c_str();
|
||||
|
||||
strcpy(reinterpret_cast<char *>(&data_item->message), final_message.str().c_str());
|
||||
}
|
||||
break;
|
||||
case RSMI_EVT_NOTIF_EVENT_PAGE_FAULT_START:
|
||||
{
|
||||
int64_t ns;
|
||||
int32_t pid;
|
||||
uint32_t addr;
|
||||
uint32_t node;
|
||||
char *rw;
|
||||
|
||||
sscanf(message, "%lld -%d @%lx(%x) %c\n", &ns, &pid, &addr, &node, rw);
|
||||
std::stringstream final_message;
|
||||
final_message << "ns: " << std::to_string(ns).c_str()
|
||||
<< " pid: " << std::to_string(pid).c_str()
|
||||
<< " addr: 0x" << std::hex << addr
|
||||
<< " node: 0x" << std::hex << node
|
||||
<< " rw: " << rw;
|
||||
|
||||
strcpy(reinterpret_cast<char *>(&data_item->message), final_message.str().c_str());
|
||||
}
|
||||
break;
|
||||
case RSMI_EVT_NOTIF_EVENT_PAGE_FAULT_END:
|
||||
{
|
||||
int64_t ns;
|
||||
int32_t pid;
|
||||
uint32_t addr;
|
||||
uint32_t node;
|
||||
char *migrate_update;
|
||||
|
||||
sscanf(message, "%lld -%d @%lx(%x) %c\n", &ns, &pid, &addr, &node, migrate_update);
|
||||
std::stringstream final_message;
|
||||
final_message << "ns: " << std::to_string(ns).c_str()
|
||||
<< " pid: " << std::to_string(pid).c_str()
|
||||
<< " addr: 0x" << std::hex << addr
|
||||
<< " node: 0x" << std::hex << node
|
||||
<< " migrate_udpate: " << migrate_update;
|
||||
|
||||
strcpy(reinterpret_cast<char *>(&data_item->message), final_message.str().c_str());
|
||||
}
|
||||
break;
|
||||
case RSMI_EVT_NOTIF_EVENT_QUEUE_EVICTION:
|
||||
{
|
||||
int64_t ns;
|
||||
int32_t pid;
|
||||
uint32_t node;
|
||||
uint32_t evict_trigger;
|
||||
|
||||
sscanf(message, "%lld -%d %x %d\n", &ns, &pid, &node, &evict_trigger);
|
||||
std::stringstream final_message;
|
||||
final_message << "ns: " << std::to_string(ns).c_str()
|
||||
<< " pid: " << std::to_string(pid).c_str()
|
||||
<< " node: 0x" << std::hex << node
|
||||
<< " evict_trigger: " << std::to_string(evict_trigger).c_str();
|
||||
|
||||
strcpy(reinterpret_cast<char *>(&data_item->message), final_message.str().c_str());
|
||||
}
|
||||
break;
|
||||
case RSMI_EVT_NOTIF_EVENT_QUEUE_RESTORE:
|
||||
{
|
||||
int64_t ns;
|
||||
int32_t pid;
|
||||
uint32_t node;
|
||||
char *rescheduled;
|
||||
|
||||
sscanf(message, "%lld -%d %x %c\n", &ns, &pid, &node, rescheduled);
|
||||
std::stringstream final_message;
|
||||
final_message << "ns: " << std::to_string(ns).c_str()
|
||||
<< " pid: " << std::to_string(pid).c_str()
|
||||
<< " node: 0x" << std::hex << node
|
||||
<< " rescheduled: " << rescheduled;
|
||||
|
||||
strcpy(reinterpret_cast<char *>(&data_item->message), final_message.str().c_str());
|
||||
}
|
||||
break;
|
||||
case RSMI_EVT_NOTIF_EVENT_UNMAP_FROM_GPU:
|
||||
{
|
||||
int64_t ns;
|
||||
int32_t pid;
|
||||
uint32_t addr;
|
||||
uint32_t size;
|
||||
uint32_t node;
|
||||
uint32_t unmap_trigger;
|
||||
|
||||
sscanf(message, "%lld -%d @%lx(%lx) %x %d\n", &ns, &pid, &addr, &size, &node, &unmap_trigger);
|
||||
std::stringstream final_message;
|
||||
final_message << "ns: " << std::to_string(ns).c_str()
|
||||
<< " pid: " << std::to_string(pid).c_str()
|
||||
<< " addr: 0x" <<std::hex << addr
|
||||
<< " size: 0x" <<std::hex << size
|
||||
<< " node: 0x" << std::hex << node
|
||||
<< " unmap_trigger: " << std::to_string(unmap_trigger).c_str();
|
||||
|
||||
strcpy(reinterpret_cast<char *>(&data_item->message), final_message.str().c_str());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
strcpy(reinterpret_cast<char *>(&data_item->message), "Unknown event received");
|
||||
break;
|
||||
}
|
||||
data_item->event = (rsmi_evt_notification_type_t)event;
|
||||
data_item->dv_ind = fd_indx_to_dev_id[i];
|
||||
++(*num_elem);
|
||||
|
||||
// zero out event_in after each use
|
||||
memcpy(reinterpret_cast<char *>(event_in), "\0", MAX_EVENT_NOTIFICATION_MSG_SIZE);
|
||||
|
||||
if (*num_elem >= buffer_size) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "rocm_smi/rocm_smi_logger.h"
|
||||
|
||||
#include <dirent.h>
|
||||
#include <inttypes.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <algorithm>
|
||||
@@ -134,7 +135,7 @@ int present_pmmetrics(const char* fname,
|
||||
}
|
||||
|
||||
table = NULL;
|
||||
len = fread(buf1, 1, 65536, infile);
|
||||
len = static_cast<int32_t>(fread(buf1, 1, 65536, infile));
|
||||
fseek(infile, 0, SEEK_SET);
|
||||
memcpy(&pmmetrics_version, &buf1[12], 4);
|
||||
|
||||
@@ -156,11 +157,11 @@ int present_pmmetrics(const char* fname,
|
||||
static int parse_reg_state_table(uint8_t *buf, int32_t buflen,
|
||||
struct metric_field *table,
|
||||
rsmi_name_value_t **kv, uint32_t *kvnum) {
|
||||
int skip_smn, x, y, cur_instance, cur_smn,
|
||||
num_instance, num_smn, instance_start, smn_start;
|
||||
uint64_t skip_smn, x, y, cur_instance, cur_smn,
|
||||
num_instance, num_smn, instance_start, smn_start;
|
||||
uint64_t v;
|
||||
uint8_t *obuf, *origbuf;
|
||||
int kvsize = 64;
|
||||
uint32_t kvsize = 64;
|
||||
|
||||
*kv = reinterpret_cast<rsmi_name_value_t*>(calloc(kvsize, sizeof **kv));
|
||||
*kvnum = 0;
|
||||
@@ -171,7 +172,7 @@ static int parse_reg_state_table(uint8_t *buf, int32_t buflen,
|
||||
origbuf = buf;
|
||||
top:
|
||||
while (table[x].field_name != NULL) {
|
||||
for (y = 0; y < table[x].field_arr_size; y++) {
|
||||
for (y = 0; y < static_cast<uint64_t>(table[x].field_arr_size); y++) {
|
||||
obuf = buf;
|
||||
v = get_value(&buf, &table[x]);
|
||||
if ((intptr_t)(buf - origbuf) > buflen) {
|
||||
@@ -203,10 +204,10 @@ top:
|
||||
}
|
||||
break;
|
||||
case FIELD_FLAG_NUM_INSTANCE:
|
||||
num_instance = v;
|
||||
num_instance = static_cast<int64_t>(v);
|
||||
break;
|
||||
case FIELD_FLAG_NUM_SMN:
|
||||
num_smn = v;
|
||||
num_smn = static_cast<int64_t>(v);
|
||||
if (v)
|
||||
skip_smn = 0;
|
||||
else
|
||||
@@ -220,12 +221,12 @@ top:
|
||||
}
|
||||
sprintf((*kv)[*kvnum].name, "%s", table[x].field_name);
|
||||
if (table[x].field_arr_size > 1) {
|
||||
sprintf((*kv)[*kvnum].name + strlen((*kv)[*kvnum].name), "[%d]", y);
|
||||
sprintf((*kv)[*kvnum].name + strlen((*kv)[*kvnum].name), "[%" PRId64 "]", y);
|
||||
}
|
||||
if (x >= instance_start)
|
||||
sprintf((*kv)[*kvnum].name + strlen((*kv)[*kvnum].name), ".instance[%d]", cur_instance);
|
||||
sprintf((*kv)[*kvnum].name + strlen((*kv)[*kvnum].name), ".instance[%" PRId64 "]", cur_instance);
|
||||
if (x >= smn_start)
|
||||
sprintf((*kv)[*kvnum].name + strlen((*kv)[*kvnum].name), ".smn[%d]", cur_smn);
|
||||
sprintf((*kv)[*kvnum].name + strlen((*kv)[*kvnum].name), ".smn[%" PRId64 "]", cur_smn);
|
||||
(*kv)[*kvnum].value = v;
|
||||
++(*kvnum);
|
||||
}
|
||||
@@ -290,7 +291,7 @@ int present_reg_state(const char* fname,
|
||||
return -2;
|
||||
}
|
||||
|
||||
len = fread(buf, 1, sizeof buf, infile);
|
||||
len = static_cast<int32_t>(fread(buf, 1, sizeof buf, infile));
|
||||
fclose(infile);
|
||||
return parse_reg_state_table(buf, len, tab, kv, kvnum);
|
||||
}
|
||||
|
||||
@@ -1474,7 +1474,6 @@ rsmi_status_t Device::restartAMDGpuDriver(void) {
|
||||
bool success = false;
|
||||
std::string out;
|
||||
bool wasGdmServiceActive = false;
|
||||
bool restartInProgress = true;
|
||||
bool isRestartInProgress = true;
|
||||
bool isAMDGPUModuleLive = false;
|
||||
bool restartGDM = false;
|
||||
@@ -1560,7 +1559,6 @@ rsmi_status_t Device::isRestartInProgress(bool *isRestartInProgress,
|
||||
bool *isAMDGPUModuleLive) {
|
||||
REQUIRE_ROOT_ACCESS
|
||||
std::ostringstream ss;
|
||||
bool restartSuccessful = true;
|
||||
bool success = false;
|
||||
std::string out;
|
||||
bool deviceRestartInProgress = true; // Assume in progress, we intend to disprove
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace amd::smi
|
||||
|
||||
constexpr uint16_t join_metrics_version(uint8_t format_rev, uint8_t content_rev)
|
||||
{
|
||||
return (format_rev << 8 | content_rev);
|
||||
return static_cast<uint16_t>((format_rev << 8 | content_rev));
|
||||
}
|
||||
|
||||
constexpr uint16_t join_metrics_version(const AMDGpuMetricsHeader_v1_t& metrics_header)
|
||||
@@ -473,8 +473,8 @@ AMDGpuDynamicMetricTblValues_t format_metric_row(const T& metric, const std::str
|
||||
void GpuMetricsBase_v16_t::dump_internal_metrics_table()
|
||||
{
|
||||
std::ostringstream ss;
|
||||
auto idx = uint64_t(0);
|
||||
auto idy = uint64_t(0);
|
||||
auto idx = int64_t(0);
|
||||
auto idy = int64_t(0);
|
||||
std::cout << __PRETTY_FUNCTION__ << " | ======= start ======= \n";
|
||||
ss << __PRETTY_FUNCTION__
|
||||
<< " | ======= DEBUG ======= "
|
||||
@@ -570,9 +570,16 @@ void GpuMetricsBase_v16_t::dump_internal_metrics_table()
|
||||
}
|
||||
for (auto& col : row.gfx_busy_inst) {
|
||||
ss << "\t [" << idx << "] [" << idy << "]: " << col;
|
||||
#if 1 // TODO: Refactor this code using make_ostream_joiner
|
||||
// Do for all occurences in this file
|
||||
if (idy + 1 != (std::end(row.gfx_busy_inst) - std::end(row.gfx_busy_inst) - 1)) {
|
||||
ss << ", ";
|
||||
}
|
||||
#else
|
||||
std::copy(std::begin(row.gfx_busy_inst),
|
||||
std::end(row.gfx_busy_inst),
|
||||
amd::smi::make_ostream_joiner(&ss, ", "));
|
||||
#endif
|
||||
if (idx + 1 !=
|
||||
(std::end(m_gpu_metrics_tbl.m_xcp_stats) - std::end(m_gpu_metrics_tbl.m_xcp_stats) - 1)) {
|
||||
ss << "\n";
|
||||
@@ -4024,7 +4031,7 @@ rsmi_dev_gpu_metrics_info_get(uint32_t dv_ind, rsmi_gpu_metrics_t* smu) {
|
||||
|
||||
dev->set_smi_device_id(dv_ind);
|
||||
uint32_t partition_id = 0;
|
||||
auto ret = rsmi_dev_partition_id_get(dv_ind, &partition_id);
|
||||
rsmi_dev_partition_id_get(dv_ind, &partition_id);
|
||||
dev->set_smi_partition_id(partition_id);
|
||||
dev->dev_log_gpu_metrics(ostrstream);
|
||||
const auto [error_code, external_metrics] = dev->dev_copy_internal_to_external_metrics();
|
||||
|
||||
@@ -879,7 +879,7 @@ int KFDNode::get_used_memory(uint64_t* used) {
|
||||
return 1;
|
||||
}
|
||||
struct kfd_ioctl_get_available_memory_args mem = {0, 0, 0};
|
||||
mem.gpu_id = gpu_id_;
|
||||
mem.gpu_id = static_cast<uint32_t>(gpu_id_);
|
||||
if (ioctl(kfd_fd, AMDKFD_IOC_AVAILABLE_MEMORY , &mem) != 0) {
|
||||
close(kfd_fd);
|
||||
return 1;
|
||||
@@ -925,8 +925,7 @@ int KFDNode::get_cache_info(rsmi_gpu_cache_info_t *info) {
|
||||
// num_cu_shared – this can be fetched by counting the number of 1’s in the sibling_map.
|
||||
std::string sibling_map =
|
||||
get_properties_from_file(prop_file, "sibling_map ");
|
||||
uint32_t num_cu_shared =
|
||||
std::count(sibling_map.begin(), sibling_map.end(), '1');
|
||||
uint32_t num_cu_shared = static_cast<uint32_t>(std::count(sibling_map.begin(), sibling_map.end(), '1'));
|
||||
|
||||
// known cache type
|
||||
bool is_count_already = false;
|
||||
|
||||
@@ -755,10 +755,9 @@ uint32_t RocmSMI::DiscoverAmdgpuDevices(void) {
|
||||
int ret_unique_id = read_node_properties(node_id, "unique_id", &unique_id);
|
||||
int ret_loc_id =
|
||||
read_node_properties(node_id, "location_id", &location_id);
|
||||
int ret_domain =
|
||||
read_node_properties(node_id, "domain", &domain);
|
||||
read_node_properties(node_id, "domain", &domain);
|
||||
if (ret_gpu_id == 0 &&
|
||||
~(ret_unique_id != 0 || ret_loc_id != 0 || ret_unique_id != 0)) {
|
||||
!(ret_unique_id != 0 || ret_loc_id != 0 || ret_unique_id != 0)) {
|
||||
// Do not try to build a node if one of these fields
|
||||
// do not exist in KFD (0 as values okay)
|
||||
systemNode myNode;
|
||||
@@ -804,7 +803,7 @@ uint32_t RocmSMI::DiscoverAmdgpuDevices(void) {
|
||||
|
||||
uint32_t cardAdded = 0;
|
||||
// Discover all root cards & gpu partitions associated with each
|
||||
for (uint32_t cardId = 0; cardId <= max_cardId; cardId++) {
|
||||
for (int32_t cardId = 0; cardId <= max_cardId; cardId++) {
|
||||
std::string path = kPathDRMRoot;
|
||||
path += "/card";
|
||||
path += std::to_string(cardId);
|
||||
@@ -917,7 +916,6 @@ uint32_t RocmSMI::DiscoverAmdgpuDevices(void) {
|
||||
LOG_DEBUG(ss);
|
||||
|
||||
uint64_t temp_primary_unique_id = 0;
|
||||
uint64_t primary_location_id = 0;
|
||||
if (allSystemNodes.empty()) {
|
||||
cardAdded++;
|
||||
ss << __PRETTY_FUNCTION__
|
||||
@@ -966,7 +964,7 @@ uint32_t RocmSMI::DiscoverAmdgpuDevices(void) {
|
||||
} else {
|
||||
cardAdded++;
|
||||
// remove already added nodes associated with current card
|
||||
auto erasedNodes = allSystemNodes.erase(0);
|
||||
allSystemNodes.erase(0);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -988,7 +986,6 @@ uint32_t RocmSMI::DiscoverAmdgpuDevices(void) {
|
||||
auto removalLocId = it->second.s_location_id;
|
||||
auto removaldomain = it->second.s_domain;
|
||||
auto nodesErased = 1;
|
||||
primary_location_id = removalLocId;
|
||||
allSystemNodes.erase(it++);
|
||||
ss << __PRETTY_FUNCTION__
|
||||
<< "\nPRIMARY --> num_nodes == temp_numb_nodes; ERASING "
|
||||
|
||||
@@ -1090,6 +1090,7 @@ std::string splitString(std::string str, char delim) {
|
||||
tokens.push_back(token);
|
||||
return token; // return 1st match
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
static std::string pt_rng_Mhz(std::string title, rsmi_range *r) {
|
||||
@@ -1118,26 +1119,6 @@ static std::string pt_rng_mV(std::string title, rsmi_range *r) {
|
||||
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) {
|
||||
@@ -1242,7 +1223,7 @@ rsmi_status_t rsmi_dev_number_of_computes_get(uint32_t dv_ind, uint32_t* num_com
|
||||
return rsmi_status_t::RSMI_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
*num_computes = (tmp_simd_count / tmp_simd_per_cu);
|
||||
*num_computes = static_cast<uint32_t>((tmp_simd_count / tmp_simd_per_cu));
|
||||
return rsmi_status_t::RSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -1296,7 +1277,7 @@ void system_wait(int milli_seconds) {
|
||||
}
|
||||
|
||||
int countDigit(uint64_t n) {
|
||||
return static_cast<int>(std::floor(log10(n) + 1));
|
||||
return static_cast<int>(std::floor(log10(static_cast<double>(n)) + 1));
|
||||
}
|
||||
|
||||
} // namespace smi
|
||||
|
||||
@@ -1020,8 +1020,9 @@ amdsmi_get_gpu_asic_info(amdsmi_processor_handle processor_handle, amdsmi_asic_i
|
||||
|
||||
// If vendor name is empty and the vendor id is 0x1002, set vendor name to AMD vendor string
|
||||
if ((info->vendor_name != NULL && info->vendor_name[0] == '\0') && info->vendor_id == 0x1002) {
|
||||
memset(info->vendor_name, 0, 38);
|
||||
strncpy(info->vendor_name, "Advanced Micro Devices Inc. [AMD/ATI]", 37);
|
||||
std::string amd_name = "Advanced Micro Devices Inc. [AMD/ATI]";
|
||||
memset(info->vendor_name, 0, amd_name.size()+1);
|
||||
strncpy(info->vendor_name, amd_name.c_str(), amd_name.size()+1);
|
||||
}
|
||||
|
||||
// default to 0xffff as not supported
|
||||
@@ -1506,7 +1507,6 @@ amdsmi_get_gpu_accelerator_partition_profile(amdsmi_processor_handle processor_h
|
||||
|
||||
// TODO(amdsmi_team): add resources here ^
|
||||
auto tmp_partition_id = uint32_t(0);
|
||||
auto tmp_xcd_count = uint16_t(0);
|
||||
amdsmi_status_t status = AMDSMI_STATUS_NOT_SUPPORTED;
|
||||
|
||||
status = rsmi_wrapper(rsmi_dev_partition_id_get, processor_handle, &tmp_partition_id);
|
||||
@@ -2196,7 +2196,7 @@ amdsmi_get_clock_info(amdsmi_processor_handle processor_handle, amdsmi_clk_type_
|
||||
}
|
||||
info->max_clk = max_freq;
|
||||
info->min_clk = min_freq;
|
||||
info->clk_deep_sleep = sleep_state_freq;
|
||||
info->clk_deep_sleep = static_cast<uint8_t>(sleep_state_freq);
|
||||
|
||||
switch (clk_type) {
|
||||
case AMDSMI_CLK_TYPE_GFX:
|
||||
@@ -2217,6 +2217,13 @@ amdsmi_get_clock_info(amdsmi_processor_handle processor_handle, amdsmi_clk_type_
|
||||
case AMDSMI_CLK_TYPE_DCLK1:
|
||||
info->clk = metrics.current_dclk1;
|
||||
break;
|
||||
case AMDSMI_CLK_TYPE_SOC:
|
||||
info->clk = metrics.current_socclk;
|
||||
break;
|
||||
// fclk/df not supported by gpu metrics so providing default value which cannot be contrued to be valid
|
||||
case AMDSMI_CLK_TYPE_DF:
|
||||
info->clk = UINT32_MAX;
|
||||
break;
|
||||
default:
|
||||
return AMDSMI_STATUS_INVAL;
|
||||
}
|
||||
@@ -2486,7 +2493,6 @@ amdsmi_get_gpu_device_uuid(amdsmi_processor_handle processor_handle, unsigned in
|
||||
amdsmi_status_t status = AMDSMI_STATUS_SUCCESS;
|
||||
SMIGPUDEVICE_MUTEX(gpu_device->get_mutex())
|
||||
|
||||
size_t len = AMDSMI_GPU_UUID_SIZE;
|
||||
amdsmi_asic_info_t asic_info = {};
|
||||
const uint8_t fcn = 0xff;
|
||||
|
||||
@@ -2549,7 +2555,7 @@ amdsmi_status_t amdsmi_get_pcie_info(amdsmi_processor_handle processor_handle, a
|
||||
}
|
||||
|
||||
// pcie speed in sysfs returns in GT/s
|
||||
info->pcie_static.max_pcie_speed = pcie_speed * 1000;
|
||||
info->pcie_static.max_pcie_speed = static_cast<uint32_t>(pcie_speed * 1000);
|
||||
|
||||
switch (info->pcie_static.max_pcie_speed) {
|
||||
case 2500:
|
||||
@@ -2715,8 +2721,6 @@ amdsmi_get_link_topology_nearest(amdsmi_processor_handle processor_handle,
|
||||
|
||||
|
||||
auto status(amdsmi_status_t::AMDSMI_STATUS_SUCCESS);
|
||||
constexpr auto kKFD_CRAT_INTRA_SOCKET_WEIGHT = uint32_t(13);
|
||||
constexpr auto kKFD_CRAT_XGMI_WEIGHT = uint32_t(15);
|
||||
|
||||
/*
|
||||
* Note: This will need to be eventually consolidated within a unique link type.
|
||||
@@ -2759,7 +2763,6 @@ amdsmi_get_link_topology_nearest(amdsmi_processor_handle processor_handle,
|
||||
uint64_t link_weight;
|
||||
};
|
||||
|
||||
using LinkTopogyOrderPair_t = std::pair<uint64_t, uint64_t>;
|
||||
/*
|
||||
* Note: The link topology table is sorted by the number of hops and link weight.
|
||||
*/
|
||||
@@ -2815,7 +2818,6 @@ amdsmi_get_link_topology_nearest(amdsmi_processor_handle processor_handle,
|
||||
|
||||
// Link type matches what we are searching for?
|
||||
auto io_link_type = translated_link_type(link_type);
|
||||
auto io_link_type_bck(io_link_type);
|
||||
auto num_hops = uint64_t(0);
|
||||
if (auto api_status = amdsmi_topo_get_link_type(processor_handle, device_list[device_idx], &num_hops, &io_link_type);
|
||||
(api_status != amdsmi_status_t::AMDSMI_STATUS_SUCCESS) || (translated_io_link_type(io_link_type) != link_type)) {
|
||||
@@ -2846,7 +2848,7 @@ amdsmi_get_link_topology_nearest(amdsmi_processor_handle processor_handle,
|
||||
* Note: The link topology table is sorted by the number of hops and link weight.
|
||||
*/
|
||||
topology_nearest_info->processor_list[AMDSMI_MAX_DEVICES] = {nullptr};
|
||||
topology_nearest_info->count = link_topology_order.size();
|
||||
topology_nearest_info->count = static_cast<uint32_t>(link_topology_order.size());
|
||||
auto topology_nearest_counter = uint32_t(0);
|
||||
while (!link_topology_order.empty()) {
|
||||
auto link_info = link_topology_order.top();
|
||||
@@ -3952,13 +3954,15 @@ amdsmi_status_t amdsmi_get_cpu_handles(uint32_t *cpu_count,
|
||||
}
|
||||
|
||||
// Get the cpu count
|
||||
*cpu_count = cpu_handles.size();
|
||||
if (processor_handles == nullptr)
|
||||
*cpu_count = static_cast<uint32_t>(cpu_handles.size());
|
||||
if (processor_handles == nullptr) {
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Copy the cpu socket handles
|
||||
for (uint32_t i = 0; i < *cpu_count; i++)
|
||||
for (uint32_t i = 0; i < *cpu_count; i++) {
|
||||
processor_handles[i] = reinterpret_cast<amdsmi_processor_handle>(cpu_handles[i]);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -4001,28 +4005,32 @@ amdsmi_status_t amdsmi_get_cpucore_handles(uint32_t *cores_count,
|
||||
// Get the coress for each socket
|
||||
status = amdsmi_get_processor_handles_by_type(sockets[index], processor_type,
|
||||
&plist[0], &cores_per_soc);
|
||||
if (status != AMDSMI_STATUS_SUCCESS)
|
||||
if (status != AMDSMI_STATUS_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
core_handles.insert(core_handles.end(), plist.begin(), plist.end());
|
||||
}
|
||||
|
||||
// Get the cores count
|
||||
*cores_count = core_handles.size();
|
||||
if (processor_handles == nullptr)
|
||||
*cores_count = static_cast<uint32_t>(core_handles.size());
|
||||
if (processor_handles == nullptr) {
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Copy the core handles
|
||||
for (uint32_t i = 0; i < *cores_count; i++)
|
||||
for (uint32_t i = 0; i < *cores_count; i++) {
|
||||
processor_handles[i] = reinterpret_cast<amdsmi_processor_handle>(core_handles[i]);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
amdsmi_status_t amdsmi_get_esmi_err_msg(amdsmi_status_t status, const char **status_string)
|
||||
{
|
||||
for (auto& iter : amd::smi::esmi_status_map) {
|
||||
if (iter.first == status) {
|
||||
for (const auto& iter : amd::smi::esmi_status_map) {
|
||||
const amdsmi_status_t _status = status;
|
||||
if (static_cast<int>(iter.first) == static_cast<int>(_status)) {
|
||||
*status_string = esmi_get_err_msg(static_cast<esmi_status_t>(iter.first));
|
||||
return iter.second;
|
||||
}
|
||||
|
||||
@@ -41,6 +41,8 @@ namespace smi {
|
||||
std::string AMDSmiDrm::find_file_in_folder(const std::string& folder,
|
||||
const std::string& regex) {
|
||||
std::string file_name;
|
||||
// TODO: The closedir function has some non-standard attributes that are being ignored here
|
||||
// which is causing a warning to be thrown
|
||||
using dir_ptr = std::unique_ptr<DIR, decltype(&closedir)>;
|
||||
|
||||
struct dirent *dir = nullptr;
|
||||
@@ -64,7 +66,6 @@ amdsmi_status_t AMDSmiDrm::init() {
|
||||
// using drm_device_ptr = std::unique_ptr(drmDevicePtr,
|
||||
// decltype(&drmFreeDevice));
|
||||
|
||||
struct dirent *dir = nullptr;
|
||||
int fd = -1;
|
||||
|
||||
|
||||
@@ -162,7 +163,7 @@ amdsmi_status_t AMDSmiDrm::init() {
|
||||
<< "bdf_rocm | Received bdf: "
|
||||
<< "\nWhole BDF: " << amd::smi::print_unsigned_hex_and_int(bdf_rocm)
|
||||
<< "\nDomain = "
|
||||
<< amd::smi::print_unsigned_hex_and_int((bdf_rocm & 0xFFFFFFFF00000000) >> 32)
|
||||
<< amd::smi::print_unsigned_hex_and_int((bdf_rocm & static_cast<uint64_t>(0xFFFFFFFF00000000)) >> 32)
|
||||
<< "; \nBus# = " << amd::smi::print_unsigned_hex_and_int((bdf_rocm & 0xFF00) >> 8)
|
||||
<< "; \nDevice# = "<< amd::smi::print_unsigned_hex_and_int((bdf_rocm & 0xF8) >> 3)
|
||||
<< "; \nFunction# = " << amd::smi::print_unsigned_hex_and_int((bdf_rocm & 0x7));
|
||||
@@ -170,6 +171,8 @@ amdsmi_status_t AMDSmiDrm::init() {
|
||||
bdf.function_number = ((bdf_rocm & 0x7));
|
||||
bdf.device_number = ((bdf_rocm & 0xF8) >> 3);
|
||||
bdf.bus_number = ((bdf_rocm & 0xFF00) >> 8);
|
||||
// TODO: This is throwing a compiler warning since bdf.domain_number is part of a struct
|
||||
// and is 48 bits long and throws a conversion warning
|
||||
bdf.domain_number = ((bdf_rocm & 0xFFFFFFFF00000000) >> 32);
|
||||
ss << __PRETTY_FUNCTION__ << " | " << "Received bdf: Domain = " << bdf.domain_number
|
||||
<< "; Bus# = " << bdf.bus_number << "; Device# = "<< bdf.device_number
|
||||
|
||||
@@ -229,11 +229,15 @@ amdsmi_status_t AMDSmiSystem::get_gpu_socket_id(uint32_t index,
|
||||
*/
|
||||
|
||||
uint64_t domain = (bdfid >> 32) & 0xffffffff;
|
||||
/* May need later
|
||||
// may need to identify with partition_id in the future as well... TBD
|
||||
uint64_t partition_id = (bdfid >> 28) & 0xf;
|
||||
*/
|
||||
uint64_t bus = (bdfid >> 8) & 0xff;
|
||||
uint64_t device_id = (bdfid >> 3) & 0x1f;
|
||||
/* May need later
|
||||
uint64_t function = bdfid & 0x7;
|
||||
*/
|
||||
|
||||
// The BD part of the BDF is used as the socket id as it
|
||||
// represents a physical device.
|
||||
|
||||
@@ -190,12 +190,11 @@ amdsmi_status_t smi_amdgpu_get_board_info(amd::smi::AMDSmiGPUDevice* device, amd
|
||||
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");
|
||||
|
||||
openFileAndModifyBuffer(model_number_path, info->model_number, AMDSMI_256_LENGTH);
|
||||
openFileAndModifyBuffer(product_serial_path, info->product_serial, AMDSMI_NORMAL_STRING_LENGTH);
|
||||
openFileAndModifyBuffer(fru_id_path, info->fru_id, AMDSMI_NORMAL_STRING_LENGTH);
|
||||
openFileAndModifyBuffer(manufacturer_name_path, info->manufacturer_name,
|
||||
AMDSMI_MAX_STRING_LENGTH);
|
||||
openFileAndModifyBuffer(product_name_path, info->product_name, AMDSMI_256_LENGTH);
|
||||
openFileAndModifyBuffer(model_number_path, info->model_number, AMDSMI_MAX_STRING_LENGTH);
|
||||
openFileAndModifyBuffer(product_serial_path, info->product_serial, AMDSMI_MAX_STRING_LENGTH);
|
||||
openFileAndModifyBuffer(fru_id_path, info->fru_id, AMDSMI_MAX_STRING_LENGTH);
|
||||
openFileAndModifyBuffer(manufacturer_name_path, info->manufacturer_name, AMDSMI_MAX_STRING_LENGTH);
|
||||
openFileAndModifyBuffer(product_name_path, info->product_name, AMDSMI_MAX_STRING_LENGTH);
|
||||
|
||||
std::ostringstream ss;
|
||||
ss << __PRETTY_FUNCTION__ << "[Before correction] "
|
||||
@@ -276,6 +275,12 @@ amdsmi_status_t smi_amdgpu_get_ranges(amd::smi::AMDSmiGPUDevice* device, amdsmi_
|
||||
case AMDSMI_CLK_TYPE_DCLK1:
|
||||
fullpath += "/pp_dpm_dclk1";
|
||||
break;
|
||||
case AMDSMI_CLK_TYPE_SOC:
|
||||
fullpath += "/pp_dpm_socclk";
|
||||
break;
|
||||
case AMDSMI_CLK_TYPE_DF:
|
||||
fullpath += "/pp_dpm_fclk";
|
||||
break;
|
||||
default:
|
||||
return AMDSMI_STATUS_INVAL;
|
||||
}
|
||||
@@ -522,7 +527,7 @@ amdsmi_status_t smi_amdgpu_get_driver_version(amd::smi::AMDSmiGPUDevice* device,
|
||||
|
||||
fclose(fp);
|
||||
if (length) {
|
||||
*length = version[len-1] == '\n' ? len - 1 : len;
|
||||
*length = version[len-1] == '\n' ? static_cast<int>(len - 1) : static_cast<int>(len);
|
||||
}
|
||||
version[len-1] = version[len-1] == '\n' ? '\0' : version[len-1];
|
||||
}
|
||||
@@ -584,6 +589,9 @@ amdsmi_status_t smi_amdgpu_get_market_name_from_dev_id(uint32_t device_id, char
|
||||
case 0x74b6:
|
||||
strcpy(market_name, "MI308X");
|
||||
break;
|
||||
case 0x74a5:
|
||||
strcpy(market_name, "AMD Instinct MI325X");
|
||||
break;
|
||||
case 0x74a9:
|
||||
case 0x74bd:
|
||||
strcpy(market_name, "AMD Instinct MI300X HF");
|
||||
@@ -639,6 +647,7 @@ std::string smi_amdgpu_split_string(std::string str, char delim) {
|
||||
tokens.push_back(token);
|
||||
return token; // return 1st match
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// wrapper to return string expression of a rsmi_status_t return
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <inttypes.h>
|
||||
#include <unistd.h>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
@@ -75,11 +76,11 @@ amdsmi_status_t gpuvsmi_get_pids(const amdsmi_bdf_t &bdf, std::vector<long int>
|
||||
struct dirent *dir;
|
||||
|
||||
/* 0000:00:00.0 */
|
||||
snprintf(bdf_str, 13, "%04x:%02x:%02x.%d",
|
||||
bdf.domain_number & 0xffff,
|
||||
bdf.bus_number & 0xff,
|
||||
bdf.device_number & 0x1f,
|
||||
bdf.function_number & 0x7);
|
||||
snprintf(bdf_str, 13, "%04" PRIx32 ":%02" PRIx32 ":%02" PRIx32 ".%" PRIu32,
|
||||
static_cast<uint32_t>(bdf.domain_number & 0xffff),
|
||||
static_cast<uint32_t>(bdf.bus_number & 0xff),
|
||||
static_cast<uint32_t>(bdf.device_number & 0x1f),
|
||||
static_cast<uint32_t>(bdf.function_number & 0x7));
|
||||
|
||||
d = opendir("/proc");
|
||||
if (!d)
|
||||
@@ -124,12 +125,11 @@ amdsmi_status_t gpuvsmi_get_pid_info(const amdsmi_bdf_t &bdf, long int pid,
|
||||
struct dirent *dir;
|
||||
|
||||
/* 0000:00:00.0 */
|
||||
snprintf(bdf_str, 13, "%04x:%02x:%02x.%d",
|
||||
bdf.domain_number & 0xffff,
|
||||
bdf.bus_number & 0xff,
|
||||
bdf.device_number & 0x1f,
|
||||
bdf.function_number & 0x7);
|
||||
|
||||
snprintf(bdf_str, 13, "%04" PRIx32 ":%02" PRIx32 ":%02" PRIx32 ".%" PRIu32,
|
||||
static_cast<uint32_t>(bdf.domain_number & 0xffff),
|
||||
static_cast<uint32_t>(bdf.bus_number & 0xff),
|
||||
static_cast<uint32_t>(bdf.device_number & 0x1f),
|
||||
static_cast<uint32_t>(bdf.function_number & 0x7));
|
||||
|
||||
std::string path = "/proc/" + std::to_string(pid) + "/fdinfo/";
|
||||
std::string name_path = "/proc/" + std::to_string(pid) + "/comm";
|
||||
@@ -158,7 +158,7 @@ amdsmi_status_t gpuvsmi_get_pid_info(const amdsmi_bdf_t &bdf, long int pid,
|
||||
char fd_bdf_str[13];
|
||||
|
||||
/* Only check against fdinfo files that contain a bdf */
|
||||
if (sscanf(bdfline.c_str(), "drm-pdev: %s", &fd_bdf_str) != 1)
|
||||
if (sscanf(bdfline.c_str(), "drm-pdev: %s", &fd_bdf_str[0]) != 1)
|
||||
continue;
|
||||
|
||||
/* Populate amdsmi_proc_info_t struct only if the bdf in
|
||||
|
||||
@@ -63,8 +63,6 @@ void TestAPISupportRead::Close() {
|
||||
}
|
||||
|
||||
void TestAPISupportRead::Run(void) {
|
||||
amdsmi_status_t err;
|
||||
|
||||
TestBase::Run();
|
||||
if (setup_failed_) {
|
||||
IF_VERB(STANDARD) {
|
||||
|
||||
@@ -100,7 +100,7 @@ void TestFanRead::Run(void) {
|
||||
err = amdsmi_get_gpu_fan_speed_max(processor_handles_[i], 0, &val_ui64);
|
||||
CHK_ERR_ASRT(err)
|
||||
IF_VERB(STANDARD) {
|
||||
std::cout << val_i64/static_cast<float>(val_ui64)*100;
|
||||
std::cout << static_cast<float>(val_i64)/static_cast<float>(val_ui64)*100;
|
||||
std::cout << "% ("<< val_i64 << "/" << val_ui64 << ")" << std::endl;
|
||||
}
|
||||
// Verify api support checking functionality is working
|
||||
|
||||
@@ -100,7 +100,7 @@ void TestFanReadWrite::Run(void) {
|
||||
ret = amdsmi_get_gpu_fan_speed_max(processor_handles_[dv_ind], 0, &max_speed);
|
||||
CHK_ERR_ASRT(ret)
|
||||
|
||||
new_speed = 1.1 * orig_speed;
|
||||
new_speed = static_cast<int64_t>(1.1F * static_cast<float>(orig_speed));
|
||||
|
||||
if (new_speed > static_cast<int64_t>(max_speed)) {
|
||||
std::cout <<
|
||||
@@ -135,8 +135,9 @@ void TestFanReadWrite::Run(void) {
|
||||
// cur_speed < 1.1 * new_speed) ||
|
||||
// cur_speed > 0.95 * AMDSMI_MAX_FAN_SPEED);
|
||||
IF_VERB(STANDARD) {
|
||||
if (!((cur_speed > 0.95 * new_speed && cur_speed < 1.1 * new_speed) ||
|
||||
(cur_speed > 0.95 * AMDSMI_MAX_FAN_SPEED))) {
|
||||
if (!((cur_speed > static_cast<int64_t>(0.95 * static_cast<double>(new_speed)) &&
|
||||
cur_speed < static_cast<int64_t>(1.10 * static_cast<double>(new_speed))) ||
|
||||
(cur_speed > static_cast<int64_t>(0.95 * AMDSMI_MAX_FAN_SPEED)))) {
|
||||
std::cout << "WARNING: Fan speed is not within the expected range!" <<
|
||||
std::endl;
|
||||
}
|
||||
|
||||
@@ -63,9 +63,6 @@ void TestGPUBusyRead::Close() {
|
||||
|
||||
|
||||
void TestGPUBusyRead::Run(void) {
|
||||
amdsmi_status_t err;
|
||||
uint32_t val_ui32;
|
||||
|
||||
TestBase::Run();
|
||||
if (setup_failed_) {
|
||||
std::cout << "** SetUp Failed for this test. Skipping.**" << std::endl;
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
@@ -477,8 +478,11 @@ void TestHWTopologyRead::Run(void) {
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("\tGPU BDF %04lx:%02x:%02x.%d\n", bdf.domain_number,
|
||||
bdf.bus_number, bdf.device_number, bdf.function_number);
|
||||
printf("\tGPU BDF %04" PRIx64 ":%02" PRIx32 ":%02" PRIx32 ".%" PRIu32 "\n",
|
||||
static_cast<uint64_t>(bdf.domain_number),
|
||||
static_cast<uint32_t>(bdf.bus_number),
|
||||
static_cast<uint32_t>(bdf.device_number),
|
||||
static_cast<uint32_t>(bdf.function_number));
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -67,7 +67,6 @@ void TestIdInfoRead::Run(void) {
|
||||
amdsmi_status_t err;
|
||||
uint16_t id;
|
||||
uint64_t val_ui64;
|
||||
uint32_t drm_render_minor;
|
||||
|
||||
char buffer[kBufferLen];
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ rsmi_test_refcount(uint64_t refcnt_type);
|
||||
|
||||
static void rand_sleep_mod(int msec) {
|
||||
assert(msec > 10);
|
||||
unsigned int seed = time(NULL);
|
||||
uint64_t seed = static_cast<uint64_t>(time(NULL));
|
||||
std::mt19937_64 eng{seed};
|
||||
std::uniform_int_distribution<> dist{10, msec};
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds{dist(eng)});
|
||||
|
||||
@@ -117,7 +117,7 @@ void TestMemUtilRead::Run(void) {
|
||||
std::cout << "\t**" <<
|
||||
kDevMemoryTypeNameMap.at(static_cast<amdsmi_memory_type_t>(mem_type))
|
||||
<< " Calculated Utilization: " <<
|
||||
(static_cast<float>(usage)*100)/total << "% ("<< usage <<
|
||||
(static_cast<float>(usage)*100)/static_cast<float>(total) << "% ("<< usage <<
|
||||
"/" << total << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ void TestMetricsCounterRead::Run(void) {
|
||||
std::cout << std::dec << "energy_accumulator counter="
|
||||
<< energy_accumulator << '\n';
|
||||
std::cout << "energy_accumulator in uJ="
|
||||
<< (double)(energy_accumulator * counter_resolution) << '\n';
|
||||
<< static_cast<double>((static_cast<double>(energy_accumulator) * counter_resolution)) << '\n';
|
||||
std::cout << std::dec << "timestamp="
|
||||
<< timestamp << '\n';
|
||||
}
|
||||
|
||||
@@ -155,7 +155,6 @@ void TestMutualExclusion::Run(void) {
|
||||
// Set dummy values should to working, deterministic values.
|
||||
uint16_t dmy_ui16 = 0;
|
||||
uint32_t dmy_ui32 = 1;
|
||||
uint32_t dmy_i32 = 0;
|
||||
uint64_t dmy_ui64 = 0;
|
||||
int64_t dmy_i64 = 0;
|
||||
char dmy_str[10];
|
||||
|
||||
@@ -121,7 +121,7 @@ void TestPerfCntrReadWrite::CountEvents(amdsmi_processor_handle dv_ind,
|
||||
std::cout << "\t\t\tTime Enabled (nS): " << val->time_enabled << std::endl;
|
||||
std::cout << "\t\t\tTime Running (nS): " << val->time_running << std::endl;
|
||||
std::cout << "\t\t\tEvents/Second Running: " <<
|
||||
val->value/static_cast<float>(val->time_running) << std::endl;
|
||||
static_cast<float>(val->value)/static_cast<float>(val->time_running) << std::endl;
|
||||
}
|
||||
ret = amdsmi_gpu_destroy_counter(evt_handle);
|
||||
CHK_ERR_ASRT(ret)
|
||||
@@ -158,14 +158,14 @@ TestPerfCntrReadWrite::testEventsIndividually(amdsmi_processor_handle dv_ind) {
|
||||
|
||||
CountEvents(dv_ind, evt, &val, 1);
|
||||
double coll_time_sec = static_cast<double>(val.time_running)/kGig;
|
||||
throughput = (val.value * 32)/coll_time_sec;
|
||||
throughput = static_cast<uint64_t>(static_cast<double>((val.value * 32L))/coll_time_sec);
|
||||
std::cout << "\t\t\tCollected events for " << coll_time_sec <<
|
||||
" seconds" << std::endl;
|
||||
std::cout << "\t\t\tEvents collected: " << val.value << std::endl;
|
||||
std::cout << "\t\t\tXGMI throughput: " << throughput <<
|
||||
" bytes/second" << std::endl;
|
||||
std::cout << "\t\t\tXGMI Channel Utilization: " <<
|
||||
100*throughput/static_cast<double>(kVg20Level1Bandwidth*kGigByte) <<
|
||||
static_cast<double>(100*throughput)/static_cast<double>(kVg20Level1Bandwidth*kGigByte) <<
|
||||
"%" << std::endl;
|
||||
std::cout << "\t\t\t****" << std::endl;
|
||||
}
|
||||
|
||||
@@ -64,8 +64,6 @@ void TestPowerRead::Close() {
|
||||
|
||||
void TestPowerRead::Run(void) {
|
||||
amdsmi_status_t err;
|
||||
uint64_t val_ui64, val2_ui64;
|
||||
amdsmi_power_type_t type = AMDSMI_INVALID_POWER;
|
||||
|
||||
TestBase::Run();
|
||||
if (setup_failed_) {
|
||||
|
||||
@@ -69,9 +69,7 @@ void TestSysInfoRead::Close() {
|
||||
void TestSysInfoRead::Run(void) {
|
||||
amdsmi_status_t err;
|
||||
uint64_t val_ui64;
|
||||
uint32_t val_ui32;
|
||||
int32_t val_i32;
|
||||
char buffer[80];
|
||||
amdsmi_version_t ver = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, nullptr};
|
||||
|
||||
TestBase::Run();
|
||||
|
||||
@@ -65,7 +65,6 @@ void TestXGMIReadWrite::Run(void) {
|
||||
GTEST_SKIP_("Temporarily disabled");
|
||||
amdsmi_status_t err;
|
||||
amdsmi_xgmi_status_t err_stat;
|
||||
uint64_t hive_id;
|
||||
|
||||
TestBase::Run();
|
||||
if (setup_failed_) {
|
||||
|
||||
Ссылка в новой задаче
Block a user