Merge amd-staging into amd-master 20230728

Signed-off-by: Hao Zhou <Hao.Zhou@amd.com>
Change-Id: I8d5505cb14009eed9d52a73f73a8317e58f4b8c3
This commit is contained in:
Hao Zhou
2023-07-28 16:00:59 +08:00
126 changed files with 5190 additions and 10427 deletions
+17
View File
@@ -0,0 +1,17 @@
# EditorConfig standardizes spacing in all editors: https://EditorConfig.org
# Please get a plugin for your editor to match the formatting
# top-most EditorConfig file
root = true
# Unix-style newlines with a newline ending every file and no stray whitespaces
[*]
end_of_line = lf
trim_trailing_whitespace = true
# Matches multiple files with brace expansion notation
# Set default charset
[*.{c,cc,cpp,h,hh,hpp}]
charset = utf-8
indent_style = space
indent_size = 2
+9 -4
View File
@@ -1,16 +1,21 @@
# NOTE! Please use 'git ls-files -i --exclude-standard'
# command after changing this file, to see if there are
# any tracked files which get ignored after the change.
# VisualStudioCode
.vscode/
# build directories generated by cmake
build/
cmake/build/
.cache/
# build artifacts
include/rocm_smi/rocm_smi64Config.h
oam/include/oam/oamConfig.h
python_smi_tools/rsmiBindings.py
include/amd_smi/amd_smi64Config.h
include/amd_smi/amd_smiConfig.h
rocm_smi/include/rocm_smi/rocm_smi64Config.h
DEBIAN/postinst
DEBIAN/prerm
RPM/
docs/*.pdf
# Byte-compiled / optimized / DLL files
+22
View File
@@ -0,0 +1,22 @@
# Change Log for ROCm SMI Library
Full documentation for rocm_smi_lib is available at [https://docs.amd.com/](https://docs.amd.com/category/SMI%20API%20Guides).
## rocm_smi_lib for ROCm 5.5.0
### Optimizations
- Add new test to measure api execution time.
- Remove the shared mutex if no process is using it.
### Added
- ROCm SMI CLI: Add --showtempgraph Feature.
### Changed
- Relying on vendor ID to detect AMDGPU.
- Change pragma message to warning for backward compatibility.
### Fixed
- Fix --showproductname when device's SKU cannot be parsed out of the VBIOS string.
- Fix compile error: memcpy was not declared.
- Fix order of CE and UE reporting in ROCm SMI CLI.
- Handle error return value from ReadSysfsStr function.
+7 -1
View File
@@ -95,6 +95,7 @@ set(SHR_MUTEX_DIR "${PROJECT_SOURCE_DIR}/third_party/shared_mutex")
if(ENABLE_ESMI_LIB)
if((EXISTS ${PROJECT_SOURCE_DIR}/e_smi_library/src) AND (EXISTS ${PROJECT_SOURCE_DIR}/e_smi_library/src/e_smi_plat.c))
set(ESMI_AVAILABLE TRUE)
add_definitions("-DENABLE_ESMI_LIB=1")
else()
message("E-smi source not found. Errors will be encountered during compilation!!!")
endif()
@@ -121,6 +122,7 @@ set(CMN_SRC_LIST
"${ROCM_SRC_DIR}/rocm_smi_monitor.cc"
"${ROCM_SRC_DIR}/rocm_smi_power_mon.cc"
"${ROCM_SRC_DIR}/rocm_smi_utils.cc"
"${ROCM_SRC_DIR}/rocm_smi_logger.cc"
"${SHR_MUTEX_DIR}/shared_mutex.cc")
if(ESMI_AVAILABLE)
@@ -142,6 +144,7 @@ set(CMN_INC_LIST
"${ROCM_INC_DIR}/rocm_smi_monitor.h"
"${ROCM_INC_DIR}/rocm_smi_power_mon.h"
"${ROCM_INC_DIR}/rocm_smi_utils.h"
"${ROCM_INC_DIR}/rocm_smi_logger.h"
"${SHR_MUTEX_DIR}/shared_mutex.h")
add_subdirectory("rocm_smi")
@@ -149,7 +152,8 @@ add_subdirectory("src")
add_subdirectory("example")
if(BUILD_TESTS)
add_subdirectory("tests/rocm_smi_test")
set(TESTS_COMPONENT "tests")
#add_subdirectory("tests/rocm_smi_test")
add_subdirectory("tests/amd_smi_test")
endif()
@@ -288,8 +292,10 @@ set(CPACK_PACKAGE_VERSION
## Process the Rpm install/remove scripts to update the CPACK variables
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/RPM/post.in" RPM/post @ONLY)
configure_file ( "${CMAKE_CURRENT_SOURCE_DIR}/RPM/preun.in" RPM/preun @ONLY )
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/RPM/postun.in" RPM/postun @ONLY)
set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE "${CMAKE_CURRENT_BINARY_DIR}/RPM/post")
set ( CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE "${CMAKE_CURRENT_BINARY_DIR}/RPM/preun" )
set(CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE "${CMAKE_CURRENT_BINARY_DIR}/RPM/postun")
#Set the names now using CPACK utility
+3 -3
View File
@@ -1,9 +1,9 @@
Package: rocm_smi_lib
Package: amd_smi_lib
Architecture: any
Maintainer: Advanced Micro Devices Inc.
Priority: optional
Version: MODULE_VERSION
Depends:
Homepage: https://github.com/RadeonOpenCompute/rocm_smi_lib
Description: System Management Interface Library for ROCm
Homepage: https://github.com/RadeonOpenCompute/amdsmi
Description: AMD System Management Interface Library for ROCm
+107 -2
View File
@@ -1,11 +1,114 @@
#!/bin/bash
#set -x
set -e
packageName="amd-smi-lib"
logPath=/var/log/amd_smi_lib
logName=AMD-SMI-lib.log
logFile="${logPath}/${logName}"
logrotateConfFile=/etc/logrotate.d/amd_smi.conf
do_addLogFolder() {
sudo mkdir -p "${logPath}"
sudo touch "${logFile}"
sudo chmod -R a+rw "${logPath}"
sudo chmod a+rw "${logFile}"
}
do_configureLogrotate() {
logrotate --version &>/dev/null
if [ $? -ne 0 ]; then
echo "[WARNING] Detected logrotate is not installed."\
"$packageName logs (when turned on) will not rotate properly."
return
fi
if [ ! -f $logrotateConfFile ]; then
sudo touch "${logrotateConfFile}"
sudo chmod 644 "${logrotateConfFile}" # root r/w, all others read
# ROCm SMI logging rotation, rotates files using root user/group
# Hourly logrotation check
# Only rotates if size grew larger than 1MB
# Max of 4 rotation files, oldest will be removed
# Rotated files use date extention of ex. ROCm-SMI-lib.log.2023-05-09_16:51:42
cat << EOF | sudo tee "${logrotateConfFile}" >/dev/null
${logFile} {
su root root
hourly
missingok
notifempty
rotate 4
size 1M
copytruncate
dateext
dateformat .%%Y-%%m-%%d_%H:%%M:%%S
}
EOF
# Fix for % S argument not found (now we escape with %%)
# issue was RPM build thought we were using macros
# https://gitlab.kitware.com/cmake/cmake/-/issues/22965
# https://rpm-software-management.github.io/rpm/manual/spec.html
sudo sed -i s/%%/%/g "${logrotateConfFile}"
# workaround: remove extra 'OURCE' text
# from rocm_smi.conf. Unsure if CMAKE,
# bash, or here document
# issue (only seen on RHEL 8.7)
sudo sed -i s/OURCE//g "${logrotateConfFile}"
fi
# check if logrotate uses system timers, Ubuntu/modern OS's do
# Several older OS's like RHEL 8.7, do not. Instead defaults
# to use daily cron jobs - see https://stackoverflow.com/a/69465677
sudo systemctl list-timers|grep -iq logrotate
if [ $? -ne 0 ]; then
# confirm logrotate file exists in daily
if [ -f /etc/cron.daily/logrotate ]; then
# move logrotate daily to hourly
if [ -f /etc/cron.hourly/logrotate ]; then
sudo mv /etc/cron.daily/logrotate /etc/cron.hourly/logrotate
else
echo "[WARNING] Could find and configure hourly cron for $packageName's"\
" logrotate. $packageName logs (when turned on) will not rotate properly."
return
fi
else
# confirm that it's already been moved to hourly
sudo find /etc/cron.* -iname logrotate -print -quit |grep -iq hourly
if [ $? -ne 0 ]; then
echo "[WARNING] Could not configure an hourly cron for $packageName's logrotate."\
"$packageName logs (when turned on) may not rotate properly."
fi
fi
else
# Configure systemd timers - the typical setup for modern Linux logrotation setups
if [ -f /lib/systemd/system/logrotate.timer ]; then
if [ ! -f /lib/systemd/system/logrotate.timer.backup ]; then
sudo cp /lib/systemd/system/logrotate.timer /lib/systemd/system/logrotate.timer.backup
fi
cat <<'EOF' | sudo tee /lib/systemd/system/logrotate.timer >/dev/null
[Unit]
Description=Hourly rotation of log files
Documentation=man:logrotate(8) man:logrotate.conf(5)
[Timer]
OnCalendar=
OnCalendar=hourly
AccuracySec=1m
Persistent=true
[Install]
WantedBy=timers.target
EOF
sudo systemctl reenable --now logrotate.timer
else
echo "[WARNING] Could not configure systemd timer for $packageName's logrotate."\
"$packageName logs (when turned on) will not rotate properly."
fi
fi
}
do_ldconfig() {
# left-hand term originates from ENABLE_LDCONFIG = ON/OFF at package build
if [ "@ENABLE_LDCONFIG@" == "ON" ]; then
echo @CPACK_PACKAGING_INSTALL_PREFIX@/lib > /etc/ld.so.conf.d/x86_64-librocm_smi_lib.conf
echo @CPACK_PACKAGING_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@ > /etc/ld.so.conf.d/x86_64-librocm_smi_lib.conf
ldconfig
fi
}
@@ -13,6 +116,8 @@ do_ldconfig() {
case "$1" in
( configure )
do_ldconfig
do_addLogFolder
do_configureLogrotate
;;
( abort-upgrade | abort-remove | abort-deconfigure )
echo "$1"
+27 -2
View File
@@ -1,7 +1,30 @@
#!/bin/bash
set -e
packageName="amd-smi-lib"
logPath=/var/log/amd_smi_lib
logName=AMD-SMI-lib.log
logFile="${logPath}/${logName}"
logrotateConfFile=/etc/logrotate.d/amd_smi.conf
rm_logFolder() {
sudo rm -rf "$logPath"
}
return_logrotateToOrigConfig() {
if [ -f $logrotateConfFile ]; then
sudo rm -rf "${logrotateConfFile}"
fi
if [ -f /etc/cron.hourly/logrotate ]; then
sudo mv /etc/cron.hourly/logrotate /etc/cron.daily/logrotate
fi
if [ -f /lib/systemd/system/logrotate.timer.backup ]; then
sudo cp /lib/systemd/system/logrotate.timer.backup /lib/systemd/system/logrotate.timer
sudo rm -rf /lib/systemd/system/logrotate.timer.backup
sudo systemctl reenable --now logrotate.timer
fi
}
rm_ldconfig() {
# left-hand term originates from ENABLE_LDCONFIG = ON/OFF at package build
if [ "@ENABLE_LDCONFIG@" == "ON" ]; then
@@ -12,13 +35,15 @@ rm_ldconfig() {
rm_pyc() {
# remove pyc file generated by python
rm -rf @CPACK_PACKAGING_INSTALL_PREFIX@/libexec/rocm_smi/__pycache__
rm -rf @CPACK_PACKAGING_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBEXECDIR@/rocm_smi/__pycache__
}
case "$1" in
( remove | upgrade)
rm_ldconfig
rm_pyc
rm_logFolder
return_logrotateToOrigConfig
;;
( purge )
;;
+122 -1
View File
@@ -1,5 +1,126 @@
#!/bin/bash
#set -x
packageName="amd-smi-lib"
logPath=/var/log/amd_smi_lib
logName=AMD-SMI-lib.log
logFile="${logPath}/${logName}"
logrotateConfFile=/etc/logrotate.d/amd_smi.conf
do_addLogFolder() {
sudo mkdir -p "${logPath}"
sudo touch "${logFile}"
sudo chmod -R a+rw "${logPath}"
sudo chmod a+rw "${logFile}"
}
do_configureLogrotate() {
logrotate --version &>/dev/null
if [ $? -ne 0 ]; then
echo "[WARNING] Detected logrotate is not installed."\
"$packageName logs (when turned on) will not rotate properly."
return
fi
if [ ! -f $logrotateConfFile ]; then
sudo touch "${logrotateConfFile}"
sudo chmod 644 "${logrotateConfFile}" # root r/w, all others read
# ROCm SMI logging rotation, rotates files using root user/group
# Hourly logrotation check
# Only rotates if size grew larger than 1MB
# Max of 4 rotation files, oldest will be removed
# Rotated files use date extention of ex. ROCm-SMI-lib.log.2023-05-09_16:51:42
cat << EOF | sudo tee "${logrotateConfFile}" >/dev/null
${logFile} {
su root root
hourly
missingok
notifempty
rotate 4
size 1M
copytruncate
dateext
dateformat .%%Y-%%m-%%d_%H:%%M:%%S
}
EOF
# Fix for % S argument not found (now we escape with %%)
# issue was RPM build thought we were using macros
# https://gitlab.kitware.com/cmake/cmake/-/issues/22965
# https://rpm-software-management.github.io/rpm/manual/spec.html
sudo sed -i s/%%/%/g "${logrotateConfFile}"
# workaround: remove extra 'OURCE' text
# from rocm_smi.conf. Unsure if CMAKE,
# bash, or here document
# issue (only seen on RHEL 8.7)
sudo sed -i s/OURCE//g "${logrotateConfFile}"
fi
# check if logrotate uses system timers, Ubuntu/modern OS's do
# Several older OS's like RHEL 8.7, do not. Instead defaults
# to use daily cron jobs - see https://stackoverflow.com/a/69465677
sudo systemctl list-timers|grep -iq logrotate
if [ $? -ne 0 ]; then
# confirm logrotate file exists in daily
if [ -f /etc/cron.daily/logrotate ]; then
# move logrotate daily to hourly
if [ -f /etc/cron.hourly/logrotate ]; then
sudo mv /etc/cron.daily/logrotate /etc/cron.hourly/logrotate
else
echo "[WARNING] Could find and configure hourly cron for $packageName's"\
" logrotate. $packageName logs (when turned on) will not rotate properly."
return
fi
else
# confirm that it's already been moved to hourly
sudo find /etc/cron.* -iname logrotate -print -quit |grep -iq hourly
if [ $? -ne 0 ]; then
echo "[WARNING] Could not configure an hourly cron for $packageName's logrotate."\
"$packageName logs (when turned on) may not rotate properly."
fi
fi
else
# Configure systemd timers - the typical setup for modern Linux logrotation setups
if [ -f /lib/systemd/system/logrotate.timer ]; then
if [ ! -f /lib/systemd/system/logrotate.timer.backup ]; then
sudo cp /lib/systemd/system/logrotate.timer /lib/systemd/system/logrotate.timer.backup
fi
cat <<'EOF' | sudo tee /lib/systemd/system/logrotate.timer >/dev/null
[Unit]
Description=Hourly rotation of log files
Documentation=man:logrotate(8) man:logrotate.conf(5)
[Timer]
OnCalendar=
OnCalendar=hourly
AccuracySec=1m
Persistent=true
[Install]
WantedBy=timers.target
EOF
sudo systemctl reenable --now logrotate.timer
else
echo "[WARNING] Could not configure systemd timer for $packageName's logrotate."\
"$packageName logs (when turned on) will not rotate properly."
fi
fi
}
do_ldconfig() {
# left-hand term originates from ENABLE_LDCONFIG = ON/OFF at package build
if [ "@ENABLE_LDCONFIG@" == "ON" ]; then
echo @CPACK_PACKAGING_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@ > /etc/ld.so.conf.d/x86_64-librocm_smi_lib.conf
ldconfig
fi
}
# left-hand term originates from ENABLE_LDCONFIG = ON/OFF at package build
if [ "@ENABLE_LDCONFIG@" == "ON" ]; then
echo -e "@CPACK_PACKAGING_INSTALL_PREFIX@/lib\n@CPACK_PACKAGING_INSTALL_PREFIX@/lib64" > /etc/ld.so.conf.d/x86_64-librocm_smi_lib.conf
echo -e "@CPACK_PACKAGING_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@" > /etc/ld.so.conf.d/x86_64-librocm_smi_lib.conf
ldconfig
fi
# post install or upgrade, $i is 1 or 2 -> do these actions
if [ $1 -ge 1 ]; then
do_addLogFolder
do_configureLogrotate
fi
+2
View File
@@ -1,3 +1,5 @@
#!/bin/bash
# second term originates from ENABLE_LDCONFIG = ON/OFF at package build
if [ $1 -le 1 ] && [ "@ENABLE_LDCONFIG@" == "ON" ]; then
# perform the below actions for rpm remove($1=0) or upgrade($1=1) operations
Executable
+36
View File
@@ -0,0 +1,36 @@
#!/bin/bash
#set -x
set -e
packageName="amd-smi-lib"
logPath=/var/log/amd_smi_lib
logName=AMD-SMI-lib.log
logFile="${logPath}/${logName}"
logrotateConfFile=/etc/logrotate.d/amd_smi.conf
rm_logFolder() {
sudo rm -rf "$logPath"
}
return_logrotateToOrigConfig() {
if [ -f $logrotateConfFile ]; then
sudo rm -rf "${logrotateConfFile}"
fi
if [ -f /etc/cron.hourly/logrotate ]; then
sudo mv /etc/cron.hourly/logrotate /etc/cron.daily/logrotate
fi
if [ -f /lib/systemd/system/logrotate.timer.backup ]; then
sudo cp /lib/systemd/system/logrotate.timer.backup /lib/systemd/system/logrotate.timer
sudo rm -rf /lib/systemd/system/logrotate.timer.backup
sudo systemctl reenable --now logrotate.timer
fi
}
if [ $1 -le 1 ]; then
# perform the below actions for rpm remove($1=0) or upgrade($1=1) operations
# remove pyc file generated by python
rm -rf @CPACK_PACKAGING_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBEXECDIR@/rocm_smi/__pycache__
rm_logFolder
return_logrotateToOrigConfig
fi
-1
View File
@@ -146,7 +146,6 @@ Static Arguments:
-V, --vbios All video bios information (if available)
-l, --limit All limit metric values (i.e. power and thermal limits)
-d, --driver Displays driver version
-c, --caps All caps information
-r, --ras Displays RAS features information
-B, --board All board information
-u, --numa All numa node information
+6 -11
View File
@@ -138,7 +138,7 @@ class AMDSMICommands():
def static(self, args, multiple_devices=False, gpu=None, asic=None,
bus=None, vbios=None, limit=None, driver=None, caps=None,
bus=None, vbios=None, limit=None, driver=None,
ras=None, board=None, numa=None):
"""Get Static information for target gpu
@@ -151,7 +151,6 @@ class AMDSMICommands():
vbios (bool, optional): Value override for args.vbios. Defaults to None.
limit (bool, optional): Value override for args.limit. Defaults to None.
driver (bool, optional): Value override for args.driver. Defaults to None.
caps (bool, optional): Value override for args.caps. Defaults to None.
ras (bool, optional): Value override for args.ras. Defaults to None.
board (bool, optional): Value override for args.board. Defaults to None.
numa (bool, optional): Value override for args.numa. Defaults to None.
@@ -173,8 +172,6 @@ class AMDSMICommands():
args.vbios = vbios
if driver:
args.driver = driver
if caps:
args.caps = caps
if numa:
args.numa = numa
if self.helpers.is_linux() and self.helpers.is_baremetal():
@@ -197,11 +194,11 @@ class AMDSMICommands():
# If all arguments are False, it means that no argument was passed and the entire static should be printed
if self.helpers.is_linux() and self.helpers.is_baremetal():
if not any([args.asic, args.bus, args.vbios, args.limit, args.driver, args.caps, args.ras, args.board]):
args.asic = args.bus = args.vbios = args.limit = args.driver = args.caps = args.ras = args.board = args.numa = self.all_arguments = True
if not any([args.asic, args.bus, args.vbios, args.limit, args.driver, args.ras, args.board]):
args.asic = args.bus = args.vbios = args.limit = args.driver = args.ras = args.board = args.numa = self.all_arguments = True
if self.helpers.is_linux() and self.helpers.is_virtual_os():
if not any([args.asic, args.bus, args.vbios, args.driver, args.caps]):
args.asic = args.bus = args.vbios = args.driver = args.caps = self.all_arguments = True
if not any([args.asic, args.bus, args.vbios, args.driver]):
args.asic = args.bus = args.vbios = args.driver = self.all_arguments = True
static_dict = {}
@@ -322,7 +319,7 @@ class AMDSMICommands():
if args.driver:
try:
driver_info = {}
driver_info['driver_version'] = amdsmi_interface.amdsmi_get_gpu_driver_version(args.gpu)
driver_info = amdsmi_interface.amdsmi_get_gpu_driver_info(args.gpu)
static_dict['driver'] = driver_info
except amdsmi_exception.AmdSmiLibraryException as e:
@@ -340,8 +337,6 @@ class AMDSMICommands():
static_dict['ras'] = e.get_error_info()
if not self.all_arguments:
raise e
if args.caps:
pass
if (self.helpers.is_linux() and self.helpers.is_baremetal()):
if args.numa:
try:
-12
View File
@@ -387,18 +387,6 @@ class AMDSMIHelpers():
return False, profile_presets.values()
def has_ras_support(self, device_handle):
try:
caps_info = amdsmi_interface.amdsmi_get_caps_info(device_handle)
if caps_info['ras_supported']:
return True
else:
return False
except amdsmi_exception.AmdSmiLibraryException:
return False
def convert_bytes_to_readable(self, bytes_input):
for unit in ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB"]:
if abs(bytes_input) < 1024:
-2
View File
@@ -294,7 +294,6 @@ class AMDSMIParser(argparse.ArgumentParser):
vbios_help = "All video bios information (if available)"
limit_help = "All limit metric values (i.e. power and thermal limits)"
driver_help = "Displays driver version"
caps_help = "All caps information"
# Options arguments help text for Hypervisors and Baremetal
ras_help = "Displays RAS features information"
@@ -321,7 +320,6 @@ class AMDSMIParser(argparse.ArgumentParser):
static_parser.add_argument('-b', '--bus', action='store_true', required=False, help=bus_help)
static_parser.add_argument('-V', '--vbios', action='store_true', required=False, help=vbios_help)
static_parser.add_argument('-d', '--driver', action='store_true', required=False, help=driver_help)
static_parser.add_argument('-c', '--caps', action='store_true', required=False, help=caps_help)
# Options to display on Hypervisors and Baremetal
if self.helpers.is_hypervisor() or self.helpers.is_baremetal():
+9
View File
@@ -0,0 +1,9 @@
!.sphinx/
!.doxygen/
/_build/
/_doxygen/
/_images/
/_static/
/_templates/
/html/
/latex/
+3 -3
View File
@@ -44,7 +44,7 @@ PROJECT_NUMBER = "23.1.1.0"
# for a project that appears at the top of each page and should give viewer a
# quick idea about the purpose of the project. Keep the description short.
PROJECT_BRIEF = "AMD SMI Reference Manual"
PROJECT_BRIEF = "AMD SMI Tool Guide"
# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
# in the documentation. The maximum height of the logo should not exceed 55
@@ -2170,14 +2170,14 @@ DOT_NUM_THREADS = 0
# The default value is: Helvetica.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_FONTNAME = Helvetica
DOT_FONTNAME = Calibri
# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
# dot graphs.
# Minimum value: 4, maximum value: 24, default value: 10.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_FONTSIZE = 10
DOT_FONTSIZE = 11
# By default doxygen will tell dot to use the default font as specified with
# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
+5 -5
View File
@@ -314,12 +314,12 @@ int main() {
printf("\tGPU Power limit: %d\n\n", power_measure.power_limit);
// Get driver version
char version[AMDSMI_MAX_DRIVER_VERSION_LENGTH];
int version_length = AMDSMI_MAX_DRIVER_VERSION_LENGTH;
ret = amdsmi_get_gpu_driver_version(processor_handles[j], &version_length, version);
amdsmi_driver_info_t driver_info;
ret = amdsmi_get_gpu_driver_info(processor_handles[j], &driver_info);
CHK_AMDSMI_RET(ret)
printf(" Output of amdsmi_get_gpu_driver_version:\n");
printf("\tDriver version: %s\n\n", version);
printf(" Output of amdsmi_get_gpu_driver_info:\n");
printf("\tDriver version: %s\n", driver_info.driver_version);
printf("\tDriver date: %s\n\n", driver_info.driver_date);
// Get device uuid
unsigned int uuid_length = AMDSMI_GPU_UUID_SIZE;
+764 -10
View File
@@ -53,6 +53,10 @@
#ifdef __cplusplus
extern "C" {
#include <cstdint>
#ifdef ENABLE_ESMI_LIB
#include <e_smi/e_smi.h>
#endif
#else
#include <stdint.h>
#endif // __cplusplus
@@ -122,16 +126,24 @@ typedef enum {
//! opaque handler point to underlying implementation
typedef void *amdsmi_processor_handle;
typedef void *amdsmi_socket_handle;
#ifdef ENABLE_ESMI_LIB
typedef void *amdsmi_cpusocket_handle;
#endif
/**
* @brief Device types detectable by AMD SMI
* @brief Processor types detectable by AMD SMI
* AMD_CPU - CPU Socket is a physical component that holds the CPU.
* AMD_CPU_CORE - CPU Cores are number of individual processing units within the CPU.
* AMD_APU - Combination of AMD_CPU and integrated GPU on single die
*/
typedef enum {
UNKNOWN = 0,
AMD_GPU,
AMD_CPU,
NON_AMD_GPU,
NON_AMD_CPU
NON_AMD_CPU,
AMD_CPU_CORE,
AMD_APU
} processor_type_t;
/**
@@ -171,6 +183,17 @@ typedef enum {
AMDSMI_STATUS_INSUFFICIENT_SIZE = 41, //!< Not enough resources were available for the operation
AMDSMI_STATUS_UNEXPECTED_SIZE = 42, //!< An unexpected amount of data was read
AMDSMI_STATUS_UNEXPECTED_DATA = 43, //!< The data read or provided to function is not what was expected
//esmi errors
AMDSMI_STATUS_NON_AMD_CPU = 44, //!< System has different cpu than AMD
AMDSMI_NO_ENERGY_DRV = 45, //!< Energy driver not found
AMDSMI_NO_MSR_DRV = 46, //!< MSR driver not found
AMDSMI_NO_HSMP_DRV = 47, //!< HSMP driver not found
AMDSMI_NO_HSMP_SUP = 48, //!< HSMP not supported
AMDSMI_NO_HSMP_MSG_SUP = 49, //!< HSMP message/feature not supported
AMDSMI_HSMP_TIMEOUT = 50, //!< HSMP message is timedout
AMDSMI_NO_DRV = 51, //!< No Energy and HSMP driver present
AMDSMI_FILE_NOT_FOUND = 52, //!< file or directory not found
AMDSMI_ARG_PTR_NULL = 53, //!< Parsed argument is invalid
// General errors
AMDSMI_STATUS_MAP_ERROR = 0xFFFFFFFE, //!< The internal library error did not map to a status code
AMDSMI_STATUS_UNKNOWN_ERROR = 0xFFFFFFFF, //!< An unknown error occurred
@@ -375,6 +398,11 @@ typedef struct {
uint32_t reserved[3];
} amdsmi_asic_info_t;
typedef struct {
char driver_version[AMDSMI_MAX_STRING_LENGTH];
char driver_date[AMDSMI_MAX_STRING_LENGTH];
} amdsmi_driver_info_t;
typedef struct {
uint64_t serial_number;
bool is_master;
@@ -1094,6 +1122,76 @@ typedef struct {
//! but do have monitors or sensors.
#define AMDSMI_DEFAULT_VARIANT 0xFFFFFFFFFFFFFFFF
#ifdef ENABLE_ESMI_LIB
/**
* @brief This structure holds SMU Firmware version information.
*/
typedef struct {
uint8_t debug; //!< SMU fw Debug version number
uint8_t minor; //!< SMU fw Minor version number
uint8_t major; //!< SMU fw Major version number
uint8_t unused; //!< reserved fields
} amdsmi_smu_fw_version_t;
/**
* @brief DDR bandwidth metrics.
*/
typedef struct {
uint32_t max_bw; //!< DDR Maximum theoritical bandwidth in GB/s
uint32_t utilized_bw; //!< DDR bandwidth utilization in GB/s
uint32_t utilized_pct; //!< DDR bandwidth utilization in % of theoritical max
} amdsmi_ddr_bw_metrics_t;
/**
* @brief temperature range and refresh rate metrics of a DIMM
*/
typedef struct {
uint8_t range : 3; //!< temp range[2:0](3 bit data)
uint8_t ref_rate : 1; //!< DDR refresh rate mode[3](1 bit data)
} amdsmi_temp_range_refresh_rate_t;
/**
* @brief DIMM Power(mW), power update rate(ms) and dimm address
*/
typedef struct {
uint16_t power : 15; //!< Dimm power consumption[31:17](15 bits data)
uint16_t update_rate : 9; //!< Time since last update[16:8](9 bit data)
uint8_t dimm_addr; //!< Dimm address[7:0](8 bit data)
} amdsmi_dimm_power_t;
/**
* @brief DIMM temperature(°C) and update rate(ms) and dimm address
*/
typedef struct {
uint16_t sensor : 11; //!< Dimm thermal sensor[31:21](11 bit data)
uint16_t update_rate : 9; //!< Time since last update[16:8](9 bit data)
uint8_t dimm_addr; //!< Dimm address[7:0](8 bit data)
float temp; //!< temperature in degree celcius
} amdsmi_dimm_thermal_t;
/**
* @brief LINK name and Bandwidth type Information.It contains
* link names i.e valid link names are
* "P0", "P1", "P2", "P3", "P4", "G0", "G1", "G2", "G3", "G4"
* "G5", "G6", "G7"
* Valid bandwidth types 1(Aggregate_BW), 2 (Read BW), 4 (Write BW).
*/
typedef struct {
io_bw_encoding bw_type; //!< Bandwidth Type Information [1, 2, 4]
char *link_name; //!< Link name [P0, P1, G0, G1 etc]
} amdsmi_link_id_bw_type_t;
/**
* @brief max and min LCLK DPM level on a given NBIO ID.
* Valid max and min DPM level values are 0 - 1.
*/
typedef struct {
uint8_t max_dpm_level; //!< Max LCLK DPM level[15:8](8 bit data)
uint8_t min_dpm_level; //!< Min LCLK DPM level[7:0](8 bit data)
} amdsmi_dpm_level_t;
#endif
/*****************************************************************************/
/** @defgroup InitShutAdmin Initialization and Shutdown
* These functions are used for initialization of AMD SMI and clean up when done.
@@ -1103,7 +1201,7 @@ typedef struct {
/**
* @brief Initialize the AMD SMI library
*
* @details This function initializes the library and the internal data structures,
* @details This function initializes the library and the internal data structures,
* including those corresponding to sources of information that SMI provides.
*
* The @p init_flags decides which type of processor
@@ -1123,7 +1221,7 @@ amdsmi_status_t amdsmi_init(uint64_t init_flags);
/**
* @brief Shutdown the AMD SMI library
*
* @details This function shuts down the library and internal data structures and
* @details This function shuts down the library and internal data structures and
* performs any necessary clean ups.
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
@@ -1167,10 +1265,39 @@ amdsmi_status_t amdsmi_shut_down(void);
amdsmi_status_t amdsmi_get_socket_handles(uint32_t *socket_count,
amdsmi_socket_handle* socket_handles);
#ifdef ENABLE_ESMI_LIB
/**
* @brief Get the list of cpu socket handles in the system.
*
* @details Depends on AMDSMI_INIT_AMD_CPUS flag passed to ::amdsmi_init.
* The socket handles can be used to query the processor handles in that socket, which
* will be used in other APIs to get processor detail information.
*
* @param[in,out] socket_count As input, the value passed
* through this parameter is the number of ::amdsmi_cpusocket_handle that
* may be safely written to the memory pointed to by @p socket_handles. This is the
* limit on how many socket handles will be written to @p socket_handles. On return, @p
* socket_count will contain the number of socket handles written to @p socket_handles,
* or the number of socket handles that could have been written if enough memory had been
* provided.
* If @p socket_handles is NULL, as output, @p socket_count will contain
* how many sockets are available to read in the system.
*
* @param[in,out] socket_handles A pointer to a block of memory to which the
* ::amdsmi_cpusocket_handle values will be written. This value may be NULL.
* In this case, this function can be used to query how many sockets are
* available to read in the system.
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_get_cpusocket_handles(uint32_t *socket_count,
amdsmi_cpusocket_handle* socket_handles);
#endif
/**
* @brief Get information about the given socket
*
* @details This function retrieves socket information. The @p socket_handle must
* @details This function retrieves socket information. The @p socket_handle must
* be provided to retrieve the Socket ID.
*
* @param[in] socket_handle a socket handle
@@ -1185,6 +1312,22 @@ amdsmi_status_t amdsmi_get_socket_info(
amdsmi_socket_handle socket_handle,
size_t len, char *name);
#ifdef ENABLE_ESMI_LIB
/**
* @brief Get information about the given cpu socket
*
* @details This function retrieves cpu socket information. The @p socket_handle must
* be provided to retrieve the Socket ID.
*
* @param[in] socket_handle a socket handle
*
* @param[out] sockid The id of the socket.
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_get_cpusocket_info(amdsmi_cpusocket_handle socket_handle, uint32_t sockid);
#endif
/**
* @brief Get the list of the processor handles associated to a socket.
*
@@ -1220,6 +1363,34 @@ amdsmi_status_t amdsmi_get_processor_handles(amdsmi_socket_handle socket_handle,
uint32_t *processor_count,
amdsmi_processor_handle* processor_handles);
#ifdef ENABLE_ESMI_LIB
/**
* @brief Get the list of the cpu core handles associated to a cpu socket.
*
* @details This function retrieves the cpu core handles of a cpu socket.
* @param[in] socket_handle The cpu socket to query
* @param[in,out] processor_count As input, the value passed
* through this parameter is the number of ::amdsmi_processor_handle's that
* may be safely written to the memory pointed to by @p processor_handles. This is the
* limit on how many processor handles will be written to @p processor_handles. On return, @p
* processor_count will contain the number of processor handles written to @p processor_handles,
* or the number of processor handles that could have been written if enough memory had been
* provided.
* If @p processor_handles is NULL, as output, @p processor_count will contain
* how many cpu cores are available to read for the cpu socket.
*
* @param[in,out] processor_handles A pointer to a block of memory to which the
* ::amdsmi_processor_handle values will be written. This value may be NULL.
* In this case, this function can be used to query how many processors are
* available to read.
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_get_cpucore_handles(amdsmi_cpusocket_handle socket_handle,
uint32_t *processor_count,
amdsmi_processor_handle* processor_handles);
#endif
/**
* @brief Get the processor type of the processor_handle
*
@@ -1724,7 +1895,7 @@ amdsmi_get_gpu_memory_usage(amdsmi_processor_handle processor_handle, amdsmi_mem
* records.
* @param[in] processor_handle a processor handle
* @param[out] num_pages Number of bad page records.
* @param[out] info The results will be written to the
* @param[out] info The results will be written to the
* amdsmi_retired_page_record_t pointer.
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
@@ -2058,7 +2229,7 @@ amdsmi_status_t amdsmi_get_pcie_link_caps(amdsmi_processor_handle processor_hand
*
* @details This function will write the ::amdsmi_dev_perf_level_t to the uint32_t
* pointed to by @p perf, for a given processor handle @p processor_handle and a pointer
* to a uint32_t @p perf.
* to a uint32_t @p perf.
*
* @param[in] processor_handle a processor handle
*
@@ -3205,13 +3376,13 @@ amdsmi_get_gpu_device_uuid(amdsmi_processor_handle processor_handle, unsigned in
* string buffer. As output parameter length of the returned
* string buffer.
*
* @param[out] version Version information in string format. Must be
* @param[out] info Reference to driver information structure. Must be
* allocated by user.
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t
amdsmi_get_gpu_driver_version(amdsmi_processor_handle processor_handle, int *length, char *version);
amdsmi_get_gpu_driver_info(amdsmi_processor_handle processor_handle, amdsmi_driver_info_t *info);
/** @} End swversion */
@@ -3222,7 +3393,7 @@ amdsmi_get_gpu_driver_version(amdsmi_processor_handle processor_handle, int *len
/**
* @brief Returns the ASIC information for the device
*
*
* @details This function returns ASIC information such as the product name,
* the vendor ID, the subvendor ID, the device ID,
* the revision ID and the serial number.
@@ -3456,6 +3627,589 @@ amdsmi_get_gpu_total_ecc_count(amdsmi_processor_handle processor_handle, amdsmi_
/** @} End eccinfo */
#ifdef ENABLE_ESMI_LIB
/*---------------------------------------------------------------------------*/
/** @defgroup energyinfo Energy information (RAPL MSR) */
/*---------------------------------------------------------------------------*/
/** @{ */
/**
* @brief Get the core energy for a given core.
*
* @param[in] processor_handle Cpu core which to query
* @param[in] core_ind - cpu core index
*
* @param[in,out] penergy - Input buffer to return the core energy
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_get_cpu_core_energy(amdsmi_processor_handle processor_handle,
uint32_t core_ind, uint64_t *penergy);
/**
* @brief Get the socket energy for a given socket.
*
* @param[in] socket_handle Cpu socket which to query
* @param[in] sock_ind - socket index
*
* @param[in,out] penergy - Input buffer to return the socket energy
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_get_cpu_socket_energy(amdsmi_cpusocket_handle socket_handle,
uint32_t sock_ind, uint64_t *penergy);
/** @} */
/*---------------------------------------------------------------------------*/
/** @defgroup systemstatistics HSMP system statistics */
/*---------------------------------------------------------------------------*/
/** @{ */
/**
* @brief Get SMU Firmware Version.
*
* @param[in,out] amdsmi_smu_fw - Input buffer to return the firmware version
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_get_smu_fw_version(amdsmi_smu_fw_version_t *amdsmi_smu_fw);
/**
* @brief Get HSMP protocol Version.
*
* @param[in,out] proto_ver - Input buffer to return the protocol version
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_get_hsmp_proto_ver(uint32_t *proto_ver);
/**
* @brief Get normalized status of the processor's PROCHOT status.
*
* @param[in] socket_handle Cpu socket which to query
* @param[in] sock_ind - socket index
*
* @param[in,out] prochot - Input buffer to return the procohot status.
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_get_cpu_prochot_status(amdsmi_cpusocket_handle socket_handle,
uint32_t sock_ind, uint32_t *prochot);
/**
* @brief Get Data fabric clock and Memory clock in MHz.
*
* @param[in] socket_handle Cpu socket which to query
* @param[in] sock_ind - socket index
*
* @param[in,out] fclk - Input buffer to return fclk
*
* @param[in,out] mclk - Input buffer to return mclk
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_get_cpu_fclk_mclk(amdsmi_cpusocket_handle socket_handle,
uint32_t sock_ind, uint32_t *fclk, uint32_t *mclk);
/**
* @brief Get core clock in MHz.
*
* @param[in] socket_handle Cpu socket which to query
* @param[in] sock_ind - socket index
*
* @param[in,out] cclk - Input buffer to return core clock
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_get_cpu_cclk_limit(amdsmi_cpusocket_handle socket_handle,
uint32_t sock_ind, uint32_t *cclk);
/**
* @brief Get current active frequency limit of the socket.
*
* @param[in] socket_handle Cpu socket which to query
* @param[in] sock_ind - socket index
*
* @param[in,out] freq - Input buffer to return frequency value in MHz
*
* @param[in,out] src_type - Input buffer to return frequency source name
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_get_cpu_socket_current_active_freq_limit(amdsmi_cpusocket_handle socket_handle,
uint32_t sock_ind, uint16_t *freq, char **src_type);
/**
* @brief Get socket frequency range.
*
* @param[in] socket_handle Cpu socket which to query
* @param[in] sock_ind - socket index
*
* @param[in,out] fmax - Input buffer to return maximum frequency
*
* @param[in,out] fmin - Input buffer to return minimum frequency
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_get_cpu_socket_freq_range(amdsmi_cpusocket_handle socket_handle,
uint32_t sock_ind, uint16_t *fmax, uint16_t *fmin);
/**
* @brief Get socket frequency limit of the core.
*
* @param[in] processor_handle Cpu core which to query
* @param[in] core_ind - core index
*
* @param[in,out] freq - Input buffer to return frequency.
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_get_cpu_core_current_freq_limit(amdsmi_processor_handle processor_handle,
uint32_t core_ind, uint32_t *freq);
/** @} */
/*---------------------------------------------------------------------------*/
/** @defgroup powercont Power Control */
/*---------------------------------------------------------------------------*/
/** @{ */
/**
* @brief Get the socket power.
*
* @param[in] socket_handle Cpu socket which to query
* @param[in] sock_ind - socket index
*
* @param[in,out] ppower - Input buffer to return socket power
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_get_cpu_socket_power(amdsmi_cpusocket_handle socket_handle,
uint32_t sock_ind, uint32_t *ppower);
/**
* @brief Get the socket power cap.
*
* @param[in] socket_handle Cpu socket which to query
* @param[in] sock_ind - socket index
*
* @param[in,out] pcap - Input buffer to return power cap.
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_get_cpu_socket_power_cap(amdsmi_cpusocket_handle socket_handle,
uint32_t sock_ind, uint32_t *pcap);
/**
* @brief Get the maximum power cap value for a given socket.
*
* @param[in] socket_handle Cpu socket which to query
* @param[in] sock_ind - socket index
*
* @param[in,out] pmax - Input buffer to return maximum power limit value
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_get_cpu_socket_power_cap_max(amdsmi_cpusocket_handle socket_handle,
uint32_t sock_ind, uint32_t *pmax);
/**
* @brief Get the SVI based power telemetry for all rails.
*
* @param[in] socket_handle Cpu socket which to query
* @param[in] sock_ind - socket index
*
* @param[in,out] power - Input buffer to return svi based power value
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_get_cpu_pwr_svi_telemetry_all_rails(amdsmi_cpusocket_handle socket_handle,
uint32_t sock_ind, uint32_t *power);
/**
* @brief Set the power cap value for a given socket.
*
* @param[in] socket_handle Cpu socket which to query
* @param[in] sock_ind - socket index
*
* @param[in] power - Input power limit value
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_set_cpu_socket_power_cap(amdsmi_cpusocket_handle socket_handle,
uint32_t sock_ind, uint32_t pcap);
/**
* @brief Set the power efficiency profile policy.
*
* @param[in] socket_handle Cpu socket which to query
* @param[in] sock_ind - socket index
*
* @param[in] mode - mode to be set
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_set_cpu_pwr_efficiency_mode(amdsmi_cpusocket_handle socket_handle,
uint8_t sock_ind, uint8_t mode);
/** @} */
/*---------------------------------------------------------------------------*/
/** @defgroup perfcont Performance (Boost limit) Control */
/*---------------------------------------------------------------------------*/
/** @{ */
/**
* @brief Get the core boost limit.
*
* @param[in] processor_handle Cpu core which to query
* @param[in] core_ind - core index
*
* @param[in,out] pboostlimit - Input buffer to fill the boostlimit value
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_get_cpu_core_boostlimit(amdsmi_processor_handle processor_handle,
uint32_t core_ind, uint32_t *pboostlimit);
/**
* @brief Get the socket c0 residency.
*
* @param[in] socket_handle Cpu socket which to query
* @param[in] sock_ind - socket index
*
* @param[in,out] pc0_residency - Input buffer to fill the c0 residency value
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_get_cpu_socket_c0_residency(amdsmi_cpusocket_handle socket_handle,
uint32_t sock_ind, uint32_t *pc0_residency);
/**
* @brief Set the core boostlimit value.
*
* @param[in] processor_handle Cpu core which to query
* @param[in] core_ind - core index
*
* @param[in] boostlimit - boostlimit value to be set
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_set_cpu_core_boostlimit(amdsmi_processor_handle processor_handle,
uint32_t core_ind, uint32_t boostlimit);
/**
* @brief Set the socket boostlimit value.
*
* @param[in] socket_handle Cpu socket which to query
* @param[in] sock_ind - socket index
*
* @param[in] boostlimit - boostlimit value to be set
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_set_cpu_socket_boostlimit(amdsmi_cpusocket_handle socket_handle,
uint32_t sock_ind, uint32_t boostlimit);
/** @} */
/*---------------------------------------------------------------------------*/
/** @defgroup ddrquer DDR bandwidth monitor */
/*---------------------------------------------------------------------------*/
/** @{ */
/**
* @brief Get the DDR bandwidth data.
*
* @param[in,out] ddr_bw - Input buffer to fill ddr bandwidth data
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_get_cpu_ddr_bw(amdsmi_ddr_bw_metrics_t *ddr_bw);
/** @} */
/*---------------------------------------------------------------------------*/
/** @defgroup tempquer Temperature Query */
/*---------------------------------------------------------------------------*/
/** @{ */
/**
* @brief Get socket temperature.
*
* @param[in] socket_handle Cpu socket which to query
* @param[in] sock_ind - socket index
*
* @param[in,out] ptmon - Input buffer to fill temperature value
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_get_cpu_socket_temperature(amdsmi_cpusocket_handle socket_handle,
uint32_t sock_ind, uint32_t *ptmon);
/** @} */
/*---------------------------------------------------------------------------*/
/** @defgroup dimmstatistics Dimm statistics */
/*---------------------------------------------------------------------------*/
/** @{ */
/**
* @brief Get DIMM temperature range and refresh rate.
*
* @param[in] socket_handle Cpu socket which to query
* @param[in] sock_ind - socket index
* @param[in] dimm_addr - DIMM address
* @param[in,out] rate - Input buffer to fill temperature range and refresh rate value
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_get_cpu_dimm_temp_range_and_refresh_rate(amdsmi_cpusocket_handle socket_handle,
uint8_t sock_ind, uint8_t dimm_addr, amdsmi_temp_range_refresh_rate_t *rate);
/**
* @brief Get DIMM power consumption.
*
* @param[in] socket_handle Cpu socket which to query
* @param[in] sock_ind - socket index
* @param[in] dimm_addr - DIMM address
* @param[in,out] rate - Input buffer to fill power consumption value
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_get_cpu_dimm_power_consumption(amdsmi_cpusocket_handle socket_handle,
uint8_t sock_ind, uint8_t dimm_addr, amdsmi_dimm_power_t *dimm_pow);
/**
* @brief Get DIMM thermal sensor value.
*
* @param[in] socket_handle Cpu socket which to query
* @param[in] sock_ind - socket index
* @param[in] dimm_addr - DIMM address
* @param[in,out] dimm_temp - Input buffer to fill temperature value
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_get_cpu_dimm_thermal_sensor(amdsmi_cpusocket_handle socket_handle,
uint8_t sock_ind, uint8_t dimm_addr, amdsmi_dimm_thermal_t *dimm_temp);
/** @} */
/*---------------------------------------------------------------------------*/
/** @defgroup xgmibwcont xGMI bandwidth control */
/*---------------------------------------------------------------------------*/
/** @{ */
/**
* @brief Set xgmi width.
*
* @param[in] socket_handle Cpu socket which to query
* @param[in] min - Minimum xgmi width to be set
* @param[in] max - maximum xgmi width to be set
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_set_cpu_xgmi_width(amdsmi_cpusocket_handle socket_handle,
uint8_t min, uint8_t max);
/** @} */
/*---------------------------------------------------------------------------*/
/** @defgroup gmi3widthcont GMI3 width control */
/*---------------------------------------------------------------------------*/
/** @{ */
/**
* @brief Set gmi3 link width range.
*
* @param[in] socket_handle Cpu socket which to query
* @param[in] sock_ind - socket index
* @param[in] min_link_width - minimum link width to be set.
* @param[in] max_link_width - maximum link width to be set.
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_set_cpu_gmi3_link_width_range(amdsmi_cpusocket_handle socket_handle,
uint8_t sock_ind, uint8_t min_link_width, uint8_t max_link_width);
/** @} */
/*---------------------------------------------------------------------------*/
/** @defgroup pstatecnt Pstate selection */
/*---------------------------------------------------------------------------*/
/** @{ */
/**
* @brief Enable APB.
*
* @param[in] socket_handle Cpu socket which to query
* @param[in] sock_ind - socket index
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_cpu_apb_enable(amdsmi_cpusocket_handle socket_handle, uint32_t sock_ind);
/**
* @brief Disable APB.
*
* @param[in] socket_handle Cpu socket which to query
* @param[in] sock_ind - socket index
*
* @param[in] pstate - pstate value to be set
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_cpu_apb_disable(amdsmi_cpusocket_handle socket_handle,
uint32_t sock_ind, uint8_t pstate);
/**
* @brief Set NBIO lclk dpm level value.
*
* @param[in] socket_handle Cpu socket which to query
* @param[in] sock_ind - socket index
* @param[in] nbio_id - nbio index
* @param[in] min - minimum value to be set
* @param[in] max - maximum value to be set
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_set_cpu_socket_lclk_dpm_level(amdsmi_cpusocket_handle socket_handle,
uint32_t sock_ind, uint8_t nbio_id, uint8_t min, uint8_t max);
/**
* @brief Get NBIO LCLK dpm level.
*
* @param[in] socket_handle Cpu socket which to query
* @param[in] sock_ind - socket index
* @param[in] nbio_id - nbio index
* @param[in,out] nbio - Input buffer to fill lclk dpm level
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_get_cpu_socket_lclk_dpm_level(amdsmi_cpusocket_handle socket_handle,
uint8_t sock_ind, uint8_t nbio_id, amdsmi_dpm_level_t *nbio);
/**
* @brief Set pcie link rate.
*
* @param[in] socket_handle Cpu socket which to query
* @param[in] sock_ind - socket index
* @param[in] rate_ctrl - rate control value to be set.
* @param[in,out] prev_mode - Input buffer to fill previous rate control value.
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_set_cpu_pcie_link_rate(amdsmi_cpusocket_handle socket_handle,
uint8_t sock_ind, uint8_t rate_ctrl, uint8_t *prev_mode);
/**
* @brief Set df pstate range.
*
* @param[in] socket_handle Cpu socket which to query
* @param[in] sock_ind - socket index
* @param[in] max_pstate - maximum pstate value to be set
* @param[in] min_pstate - minimum pstate value to be set
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_set_cpu_df_pstate_range(amdsmi_cpusocket_handle socket_handle,
uint8_t sock_ind, uint8_t max_pstate, uint8_t min_pstate);
/** @} */
/*---------------------------------------------------------------------------*/
/** @defgroup bwquer Bandwidth monitor */
/*---------------------------------------------------------------------------*/
/** @{ */
/**
* @brief Get current input output bandwidth.
*
* @param[in] socket_handle Cpu socket which to query
* @param[in] sock_ind - socket index
* @param[in] link - link id and bw type to which io bandwidth to be obtained
* @param[in,out] io_bw - Input buffer to fill bandwidth data
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_get_cpu_current_io_bandwidth(amdsmi_cpusocket_handle socket_handle,
uint8_t sock_ind, amdsmi_link_id_bw_type_t link, uint32_t *io_bw);
/**
* @brief Get current input output bandwidth.
*
* @param[in] link - link id and bw type to which xgmi bandwidth to be obtained
* @param[in,out] xgmi_bw - Input buffer to fill bandwidth data
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_get_cpu_current_xgmi_bw(amdsmi_link_id_bw_type_t link, uint32_t *xgmi_bw);
/** @} */
/*---------------------------------------------------------------------------*/
/** @defgroup auxiquer Auxillary functions */
/*---------------------------------------------------------------------------*/
/** @{ */
/**
* @brief Get cpu family.
*
* @param[in,out] family - Input buffer to fill family
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_get_cpu_family(uint32_t family);
/**
* @brief Get cpu model.
*
* @param[in,out] family - Input buffer to fill family
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_get_cpu_model(uint32_t model);
/**
* @brief Get threads per core.
*
* @param[in,out] threads - Input buffer to fill threads count.
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_get_cpu_threads_per_core(uint32_t threads);
/**
* @brief Get number of cpus.
*
* @param[in,out] cpus - Input buffer to fill number of cpus.
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_get_number_of_cpu_cores(uint32_t cpus);
/**
* @brief Get number of sockets
*
* @param[in,out] sockets - Input buffer to fill number of sockets.
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_get_number_of_cpu_sockets(uint32_t sockets);
/**
* @brief Get first online core on socket.
*
* @param[in] sock_ind - socket index.
*
* @param[in,out] sockets - Input buffer to fill first online core on socket data
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_first_online_core_on_cpu_socket(uint32_t sock_ind, uint32_t *pcore_ind);
#endif
/** @} */
#ifdef __cplusplus
}
#endif // __cplusplus
+7
View File
@@ -45,6 +45,7 @@
#define AMD_SMI_INCLUDE_IMPL_AMD_SMI_DRM_H_
#include <unistd.h>
#include <xf86drm.h>
#include <vector>
#include <memory>
#include <mutex> // NOLINT
@@ -74,6 +75,7 @@ class AMDSmiDrm {
amdsmi_status_t amdgpu_query_hw_ip(int fd, unsigned info_id,
unsigned hw_ip_type, unsigned size, void *value);
amdsmi_status_t amdgpu_query_vbios(int fd, void *info);
amdsmi_status_t amdgpu_query_driver_date(int fd, std::string& driver_date);
private:
// when file is not found, the empty string will be returned
@@ -87,6 +89,11 @@ class AMDSmiDrm {
AMDSmiLibraryLoader lib_loader_; // lazy load libdrm
DrmCmdWriteFunc drm_cmd_write_; // drmCommandWrite
using drmGetVersionFunc = drmVersionPtr (*)(int); // drmGetVersion
using drmFreeVersionFunc = void (*)(drmVersionPtr); // drmFreeVersion
drmGetVersionFunc drm_get_version_;
drmFreeVersionFunc drm_free_version_;
std::mutex drm_mutex_;
};
@@ -81,6 +81,7 @@ class AMDSmiGPUDevice: public AMDSmiProcessor {
amdsmi_status_t amdgpu_query_fw(unsigned info_id, unsigned fw_type,
unsigned size, void *value) const;
amdsmi_status_t amdgpu_query_vbios(void *info) const;
amdsmi_status_t amdgpu_query_driver_date(std::string& date) const;
private:
uint32_t gpu_id_;
uint32_t fd_;
+5 -5
View File
@@ -302,17 +302,17 @@ except AmdSmiException as e:
print(e)
```
### amdsmi_get_gpu_driver_version
### amdsmi_get_gpu_driver_info
Description: Returns the version string of the driver
Description: Returns the info of the driver
Input parameters:
* `processor_handle` dev for which to query
Output: Driver version string that is handling the device
Output: Driver info that is handling the device
Exceptions that can be thrown by `amdsmi_get_gpu_driver_version` function:
Exceptions that can be thrown by `amdsmi_get_gpu_driver_info` function:
* `AmdSmiParameterException`
* `AmdSmiLibraryException`
@@ -322,7 +322,7 @@ Example:
```python
try:
device = amdsmi_get_processor_handles()[0]
print("Driver version: ", amdsmi_get_gpu_driver_version(device))
print("Driver info: ", amdsmi_get_gpu_driver_info(device))
except AmdSmiException as e:
print(e)
```
+1 -1
View File
@@ -34,7 +34,7 @@ from .amdsmi_interface import amdsmi_get_gpu_device_uuid
from .amdsmi_interface import amdsmi_get_processor_handle_from_bdf
# # SW Version Information
from .amdsmi_interface import amdsmi_get_gpu_driver_version
from .amdsmi_interface import amdsmi_get_gpu_driver_info
# # ASIC and Bus Static Information
from .amdsmi_interface import amdsmi_get_gpu_asic_info
+9 -5
View File
@@ -917,9 +917,9 @@ def amdsmi_get_gpu_device_uuid(processor_handle: amdsmi_wrapper.amdsmi_processor
return uuid.value.decode("utf-8")
def amdsmi_get_gpu_driver_version(
def amdsmi_get_gpu_driver_info(
processor_handle: amdsmi_wrapper.amdsmi_processor_handle,
) -> str:
) -> Dict[str, Any]:
if not isinstance(processor_handle, amdsmi_wrapper.amdsmi_processor_handle):
raise AmdSmiParameterException(
processor_handle, amdsmi_wrapper.amdsmi_processor_handle
@@ -930,13 +930,17 @@ def amdsmi_get_gpu_driver_version(
version = ctypes.create_string_buffer(_AMDSMI_MAX_DRIVER_VERSION_LENGTH)
info = amdsmi_wrapper.amdsmi_driver_info_t()
_check_res(
amdsmi_wrapper.amdsmi_get_gpu_driver_version(
processor_handle, ctypes.byref(length), version
amdsmi_wrapper.amdsmi_get_gpu_driver_info(
processor_handle, ctypes.byref(info)
)
)
return version.value.decode("utf-8")
return {
"driver_version": info.driver_version.decode("utf-8"),
"driver_date": info.driver_date.decode("utf-8")
}
def amdsmi_get_power_info(
+19 -8
View File
@@ -675,6 +675,16 @@ struct_c__SA_amdsmi_asic_info_t._fields_ = [
]
amdsmi_asic_info_t = struct_c__SA_amdsmi_asic_info_t
class struct_c__SA_amdsmi_driver_info_t(Structure):
pass
struct_c__SA_amdsmi_driver_info_t._pack_ = 1 # source:False
struct_c__SA_amdsmi_driver_info_t._fields_ = [
('driver_version', ctypes.c_char * 64),
('driver_date', ctypes.c_char * 64),
]
amdsmi_driver_info_t = struct_c__SA_amdsmi_driver_info_t
class struct_c__SA_amdsmi_board_info_t(Structure):
pass
@@ -1613,9 +1623,9 @@ amdsmi_get_gpu_device_bdf.argtypes = [amdsmi_processor_handle, ctypes.POINTER(un
amdsmi_get_gpu_device_uuid = _libraries['libamd_smi.so'].amdsmi_get_gpu_device_uuid
amdsmi_get_gpu_device_uuid.restype = amdsmi_status_t
amdsmi_get_gpu_device_uuid.argtypes = [amdsmi_processor_handle, ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.c_char)]
amdsmi_get_gpu_driver_version = _libraries['libamd_smi.so'].amdsmi_get_gpu_driver_version
amdsmi_get_gpu_driver_version.restype = amdsmi_status_t
amdsmi_get_gpu_driver_version.argtypes = [amdsmi_processor_handle, ctypes.POINTER(ctypes.c_int32), ctypes.POINTER(ctypes.c_char)]
amdsmi_get_gpu_driver_info = _libraries['libamd_smi.so'].amdsmi_get_gpu_driver_info
amdsmi_get_gpu_driver_info.restype = amdsmi_status_t
amdsmi_get_gpu_driver_info.argtypes = [amdsmi_processor_handle, ctypes.POINTER(struct_c__SA_amdsmi_driver_info_t)]
amdsmi_get_gpu_asic_info = _libraries['libamd_smi.so'].amdsmi_get_gpu_asic_info
amdsmi_get_gpu_asic_info.restype = amdsmi_status_t
amdsmi_get_gpu_asic_info.argtypes = [amdsmi_processor_handle, ctypes.POINTER(struct_c__SA_amdsmi_asic_info_t)]
@@ -1796,10 +1806,10 @@ __all__ = \
'amdsmi_counter_command_t',
'amdsmi_counter_command_t__enumvalues', 'amdsmi_counter_value_t',
'amdsmi_dev_perf_level_t', 'amdsmi_dev_perf_level_t__enumvalues',
'amdsmi_engine_usage_t', 'amdsmi_error_count_t',
'amdsmi_event_group_t', 'amdsmi_event_group_t__enumvalues',
'amdsmi_event_handle_t', 'amdsmi_event_type_t',
'amdsmi_event_type_t__enumvalues',
'amdsmi_driver_info_t', 'amdsmi_engine_usage_t',
'amdsmi_error_count_t', 'amdsmi_event_group_t',
'amdsmi_event_group_t__enumvalues', 'amdsmi_event_handle_t',
'amdsmi_event_type_t', 'amdsmi_event_type_t__enumvalues',
'amdsmi_evt_notification_data_t',
'amdsmi_evt_notification_type_t',
'amdsmi_evt_notification_type_t__enumvalues', 'amdsmi_freq_ind_t',
@@ -1816,7 +1826,7 @@ __all__ = \
'amdsmi_get_gpu_compute_process_info',
'amdsmi_get_gpu_compute_process_info_by_pid',
'amdsmi_get_gpu_device_bdf', 'amdsmi_get_gpu_device_uuid',
'amdsmi_get_gpu_driver_version', 'amdsmi_get_gpu_ecc_count',
'amdsmi_get_gpu_driver_info', 'amdsmi_get_gpu_ecc_count',
'amdsmi_get_gpu_ecc_enabled', 'amdsmi_get_gpu_ecc_status',
'amdsmi_get_gpu_event_notification', 'amdsmi_get_gpu_fan_rpms',
'amdsmi_get_gpu_fan_speed', 'amdsmi_get_gpu_fan_speed_max',
@@ -1910,6 +1920,7 @@ __all__ = \
'struct_c__SA_amdsmi_board_info_t',
'struct_c__SA_amdsmi_clk_info_t',
'struct_c__SA_amdsmi_counter_value_t',
'struct_c__SA_amdsmi_driver_info_t',
'struct_c__SA_amdsmi_engine_usage_t',
'struct_c__SA_amdsmi_error_count_t',
'struct_c__SA_amdsmi_evt_notification_data_t',
+1 -1
View File
@@ -32,7 +32,7 @@ message("Package version: ${PKG_VERSION_STR}")
# Debian package specific variables
# Set a default value for the package version
get_version_from_tag("1.0.0.0" ${SO_VERSION_GIT_TAG_PREFIX} GIT)
get_version_from_tag("5.0.0.0" ${SO_VERSION_GIT_TAG_PREFIX} GIT)
# VERSION_* variables should be set by get_version_from_tag
if(${ROCM_PATCH_VERSION})
Binary file not shown.
+408 -56
View File
@@ -5,7 +5,7 @@
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2017, Advanced Micro Devices, Inc.
* Copyright (c) 2017-2023, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
@@ -50,13 +50,14 @@
#include <vector>
#include <iostream>
#include <bitset>
#include <map>
#include "rocm_smi/rocm_smi.h"
#define PRINT_RSMI_ERR(RET) { \
if (RET != RSMI_STATUS_SUCCESS) { \
const char *err_str; \
std::cout << "RSMI call returned " << (RET) \
std::cout << "[ERROR] RSMI call returned " << (RET) \
<< " at line " << __LINE__ << std::endl; \
rsmi_status_string((RET), &err_str); \
std::cout << err_str << std::endl; \
@@ -70,6 +71,11 @@
} \
}
#define CHK_AND_PRINT_RSMI_ERR_RET(RET) { \
PRINT_RSMI_ERR(RET) \
CHK_RSMI_RET(RET) \
}
#define CHK_RSMI_RET_I(RET) { \
PRINT_RSMI_ERR(RET) \
if (RET != RSMI_STATUS_SUCCESS) { \
@@ -77,11 +83,77 @@
} \
}
#define CHK_RSMI_PERM_RET(RET) { \
#define CHK_FILE_PERMISSIONS(RET) { \
if ((RET) == RSMI_STATUS_PERMISSION) { \
std::cout << "This command requires root access." << std::endl; \
if (isFileWritable(RET)) { \
CHK_RSMI_RET(RET) \
} \
} else { \
CHK_RSMI_RET_I(RET) \
CHK_RSMI_RET(RET) \
} \
}
#define CHK_FILE_PERMISSIONS_AND_NOT_SUPPORTED_OR_UNIMPLEMENTED(RET) { \
if ((RET) == RSMI_STATUS_PERMISSION) { \
if (isFileWritable(RET)) { \
CHK_RSMI_RET(RET) \
} \
} else if ((RET) == RSMI_STATUS_NOT_SUPPORTED) { \
std::cout << "Not Supported." \
<< std::endl; \
} else if ((RET) == RSMI_STATUS_NOT_YET_IMPLEMENTED) { \
std::cout << "Not Yet Implemented." \
<< std::endl; \
} else { \
CHK_RSMI_RET(RET) \
} \
}
#define CHK_RSMI_NOT_SUPPORTED_RET(RET) { \
if ((RET) == RSMI_STATUS_NOT_SUPPORTED) { \
std::cout << "Not Supported." \
<< std::endl; \
} else { \
CHK_RSMI_RET(RET) \
} \
}
#define CHK_RSMI_NOT_SUPPORTED_OR_UNEXPECTED_DATA_RET(RET) { \
if ((RET) == RSMI_STATUS_NOT_SUPPORTED) { \
std::cout << "Not Supported." \
<< std::endl; \
} else if ((RET) == RSMI_STATUS_UNEXPECTED_DATA) { \
std::cout << "[ERROR] RSMI_STATUS_UNEXPECTED_DATA retrieved." \
<< std::endl; \
} else { \
CHK_RSMI_RET(RET) \
} \
}
#define CHK_RSMI_NOT_SUPPORTED_OR_SETTING_UNAVAILABLE_RET(RET) {\
if ((RET) == RSMI_STATUS_NOT_SUPPORTED) { \
std::cout << "Not Supported."\
<< std::endl; \
} else if ((RET) == RSMI_STATUS_SETTING_UNAVAILABLE) { \
std::cout << "[WARN] RSMI_STATUS_SETTING_UNAVAILABLE retrieved." \
<< std::endl; \
} else { \
CHK_RSMI_RET(RET) \
} \
}
#define CHK_NOT_SUPPORTED_OR_UNEXPECTED_DATA_OR_INSUFFICIENT_SIZE_RET(RET) { \
if ((RET) == RSMI_STATUS_NOT_SUPPORTED) { \
std::cout << "Not Supported." \
<< std::endl; \
} else if ((RET) == RSMI_STATUS_UNEXPECTED_DATA) { \
std::cout << "[WARN] RSMI_STATUS_UNEXPECTED_DATA retrieved." \
<< std::endl; \
} else if ((RET) == RSMI_STATUS_INSUFFICIENT_SIZE) { \
std::cout << "[WARN] RSMI_STATUS_INSUFFICIENT_SIZE retrieved." \
<< std::endl; \
} else { \
CHK_RSMI_RET(RET) \
} \
}
@@ -92,6 +164,10 @@ static void print_test_header(const char *str, uint32_t dv_ind) {
std::cout << "Device index: " << dv_ind << std::endl;
}
static void print_mini_header(const char *str) {
std::cout << "\n>> " << str << " <<" << std::endl;
}
static const char *
power_profile_string(rsmi_power_profile_preset_masks_t profile) {
switch (profile) {
@@ -112,6 +188,57 @@ power_profile_string(rsmi_power_profile_preset_masks_t profile) {
}
}
static const std::string
compute_partition_string(rsmi_compute_partition_type partition) {
switch (partition) {
case RSMI_COMPUTE_PARTITION_CPX:
return "CPX";
case RSMI_COMPUTE_PARTITION_SPX:
return "SPX";
case RSMI_COMPUTE_PARTITION_DPX:
return "DPX";
case RSMI_COMPUTE_PARTITION_TPX:
return "TPX";
case RSMI_COMPUTE_PARTITION_QPX:
return "QPX";
default:
return "UNKNOWN";
}
}
static std::map<std::string, rsmi_compute_partition_type_t>
mapStringToRSMIComputePartitionTypes {
{"CPX", RSMI_COMPUTE_PARTITION_CPX},
{"SPX", RSMI_COMPUTE_PARTITION_SPX},
{"DPX", RSMI_COMPUTE_PARTITION_DPX},
{"TPX", RSMI_COMPUTE_PARTITION_TPX},
{"QPX", RSMI_COMPUTE_PARTITION_QPX}
};
static const std::string
nps_mode_string(rsmi_nps_mode_type_t partition) {
switch (partition) {
case RSMI_MEMORY_PARTITION_NPS1:
return "NPS1";
case RSMI_MEMORY_PARTITION_NPS2:
return "NPS2";
case RSMI_MEMORY_PARTITION_NPS4:
return "NPS4";
case RSMI_MEMORY_PARTITION_NPS8:
return "NPS8";
default:
return "UNKNOWN";
}
}
static std::map<std::string, rsmi_nps_mode_type_t>
mapStringToRSMINpsModeTypes {
{"NPS1", RSMI_MEMORY_PARTITION_NPS1},
{"NPS2", RSMI_MEMORY_PARTITION_NPS2},
{"NPS4", RSMI_MEMORY_PARTITION_NPS4},
{"NPS8", RSMI_MEMORY_PARTITION_NPS8}
};
static const char *
perf_level_string(rsmi_dev_perf_level_t perf_lvl) {
switch (perf_lvl) {
@@ -128,13 +255,46 @@ perf_level_string(rsmi_dev_perf_level_t perf_lvl) {
}
}
static bool isUserRunningAsSudo() {
bool isRunningWithSudo = false;
auto myUID = getuid();
auto myPrivledges = geteuid();
if ((myUID == myPrivledges) && (myPrivledges == 0)) {
isRunningWithSudo = true;
}
return isRunningWithSudo;
}
static bool isFileWritable(rsmi_status_t response) {
// Clock files may not be writable, causing sets to
// return RSMI_STATUS_PERMISSION. If running as sudo,
// this means file is not writable.
// isFileWritable(ret) - intends to capture this
// response situation.
bool fileWritable = true;
if (isUserRunningAsSudo() && (response == RSMI_STATUS_PERMISSION)) {
std::cout << "[WARN] User is running with sudo "
<< "permissions, file is not writable." << std::endl;
fileWritable = false;
} else {
CHK_AND_PRINT_RSMI_ERR_RET(response)
}
return fileWritable;
}
static rsmi_status_t test_power_profile(uint32_t dv_ind) {
rsmi_status_t ret;
rsmi_power_profile_status_t status;
print_test_header("Power Profile", dv_ind);
std::cout << "The available power profiles are: ";
ret = rsmi_dev_power_profile_presets_get(dv_ind, 0, &status);
CHK_RSMI_NOT_SUPPORTED_RET(ret)
if (ret != RSMI_STATUS_SUCCESS) {
std::cout << "***Skipping Power Profile test." << std::endl;
return RSMI_STATUS_SUCCESS;
}
CHK_RSMI_RET(ret)
std::cout << "The available power profiles are:" << std::endl;
@@ -255,13 +415,13 @@ static rsmi_status_t test_set_overdrive(uint32_t dv_ind) {
CHK_RSMI_RET(ret)
ret = rsmi_dev_overdrive_level_get(dv_ind, &val);
CHK_RSMI_RET(ret)
std::cout << "\t**New OverDrive Level:" << val << std::endl;
std::cout << "\t**New OverDrive Level:" << std::dec << val << std::endl;
std::cout << "Reset Overdrive level to 0%..." << std::endl;
ret = rsmi_dev_overdrive_level_set_v1(dv_ind, 0);
CHK_RSMI_RET(ret)
ret = rsmi_dev_overdrive_level_get(dv_ind, &val);
CHK_RSMI_RET(ret)
std::cout << "\t**New OverDrive Level:" << val << std::endl;
std::cout << "\t**New OverDrive Level:" << std::dec << val << std::endl;
return ret;
}
@@ -274,9 +434,15 @@ static rsmi_status_t test_set_fan_speed(uint32_t dv_ind) {
print_test_header("Fan Speed Control", dv_ind);
std::cout << "Original fan speed: ";
ret = rsmi_dev_fan_speed_get(dv_ind, 0, &orig_speed);
CHK_RSMI_RET(ret)
std::cout << "Original fan speed: " << orig_speed << std::endl;
if (ret == RSMI_STATUS_SUCCESS) {
std::cout << orig_speed << std::endl;
} else {
CHK_RSMI_NOT_SUPPORTED_RET(ret)
std::cout << "***Skipping Fan Speed Control test." << std::endl;
return RSMI_STATUS_SUCCESS;
}
if (orig_speed == 0) {
std::cout << "***System fan speed value is 0. Skip fan test." << std::endl;
@@ -336,6 +502,11 @@ static rsmi_status_t test_set_perf_level(uint32_t dv_ind) {
std::cout << "Set Performance Level to " << (uint32_t)pfl << " ..." <<
std::endl;
ret = rsmi_dev_perf_level_set_v1(dv_ind, pfl);
if (ret != RSMI_STATUS_SUCCESS) {
CHK_RSMI_NOT_SUPPORTED_RET(ret)
std::cout << "***Skipping Performance Level Control test." << std::endl;
return RSMI_STATUS_SUCCESS;
}
CHK_RSMI_RET(ret)
ret = rsmi_dev_perf_level_get(dv_ind, &pfl);
CHK_RSMI_RET(ret)
@@ -355,13 +526,19 @@ static rsmi_status_t test_set_freq(uint32_t dv_ind) {
uint32_t freq_bitmask;
rsmi_clk_type rsmi_clk;
// Clock files may not be writable, causing sets to
// return RSMI_STATUS_PERMISSION even if running with
// sudo. See isFileWritable() for more info.
print_test_header("Clock Frequency Control", dv_ind);
for (uint32_t clk = (uint32_t)RSMI_CLK_TYPE_FIRST;
clk <= RSMI_CLK_TYPE_LAST; ++clk) {
std::string miniHeader = "Testing clock" + std::to_string(clk);
print_mini_header(miniHeader.c_str());
rsmi_clk = (rsmi_clk_type)clk;
ret = rsmi_dev_gpu_clk_freq_get(dv_ind, rsmi_clk, &f);
CHK_RSMI_RET(ret)
CHK_FILE_PERMISSIONS_AND_NOT_SUPPORTED_OR_UNIMPLEMENTED(ret)
std::cout << "Initial frequency for clock" << rsmi_clk << " is " <<
f.current << std::endl;
@@ -380,19 +557,20 @@ static rsmi_status_t test_set_freq(uint32_t dv_ind) {
" to 0b" << freq_bm_str << " ..." << std::endl;
ret = rsmi_dev_gpu_clk_freq_set(dv_ind, rsmi_clk, freq_bitmask);
CHK_RSMI_RET(ret)
CHK_FILE_PERMISSIONS_AND_NOT_SUPPORTED_OR_UNIMPLEMENTED(ret)
ret = rsmi_dev_gpu_clk_freq_get(dv_ind, rsmi_clk, &f);
CHK_RSMI_RET(ret)
CHK_FILE_PERMISSIONS_AND_NOT_SUPPORTED_OR_UNIMPLEMENTED(ret)
std::cout << "Frequency is now index " << f.current << std::endl;
std::cout << "Resetting mask to all frequencies." << std::endl;
ret = rsmi_dev_gpu_clk_freq_set(dv_ind, rsmi_clk, 0xFFFFFFFF);
CHK_RSMI_RET(ret)
CHK_FILE_PERMISSIONS_AND_NOT_SUPPORTED_OR_UNIMPLEMENTED(ret)
ret = rsmi_dev_perf_level_set_v1(dv_ind, RSMI_DEV_PERF_LEVEL_AUTO);
CHK_RSMI_RET(ret)
CHK_FILE_PERMISSIONS(ret)
}
std::cout << std::endl;
return RSMI_STATUS_SUCCESS;
}
@@ -406,13 +584,125 @@ static void print_frequencies(rsmi_frequencies_t *f) {
std::cout << std::endl;
}
}
static rsmi_status_t test_set_compute_partitioning(uint32_t dv_ind) {
rsmi_status_t ret;
uint32_t buffer_len = 10;
char originalComputePartition[buffer_len];
originalComputePartition[0] = '\0';
print_test_header("Compute Partitioning Control", dv_ind);
ret = rsmi_dev_compute_partition_get(dv_ind, originalComputePartition,
buffer_len);
CHK_RSMI_NOT_SUPPORTED_OR_UNEXPECTED_DATA_RET(ret)
if (ret == RSMI_STATUS_NOT_SUPPORTED) {
return RSMI_STATUS_SUCCESS;
}
std::cout << "Original Compute Partition: "
<< (((originalComputePartition == nullptr)
|| ((originalComputePartition != nullptr)
&& (originalComputePartition[0] == '\0')))
? "UNKNOWN" : originalComputePartition)
<< std::endl << std::endl;
for (int newComputePartition = RSMI_COMPUTE_PARTITION_CPX;
newComputePartition <= RSMI_COMPUTE_PARTITION_QPX;
newComputePartition++) {
rsmi_compute_partition_type newPartition
= static_cast<rsmi_compute_partition_type>(newComputePartition);
std::cout << "Attempting to set compute partition to "
<< compute_partition_string(newPartition) << "..."
<< std::endl;
ret = rsmi_dev_compute_partition_set(dv_ind, newPartition);
CHK_RSMI_NOT_SUPPORTED_OR_SETTING_UNAVAILABLE_RET(ret)
std::cout << "Done setting compute partition to "
<< compute_partition_string(newPartition) << "." << std::endl;
std::cout << std::endl << std::endl;
}
std::cout << "About to initate compute partition reset..." << std::endl;
ret = rsmi_dev_compute_partition_reset(dv_ind);
CHK_RSMI_NOT_SUPPORTED_RET(ret)
std::cout << "Done resetting compute partition." << std::endl;
std::string myComputePartition = originalComputePartition;
if (myComputePartition.empty() == false) {
std::cout << "Resetting back to original compute partition to "
<< originalComputePartition << "... " << std::endl;
rsmi_compute_partition_type origComputePartitionType
= mapStringToRSMIComputePartitionTypes[originalComputePartition];
ret = rsmi_dev_compute_partition_set(dv_ind, origComputePartitionType);
CHK_RSMI_NOT_SUPPORTED_OR_SETTING_UNAVAILABLE_RET(ret)
std::cout << "Done" << std::endl;
}
return RSMI_STATUS_SUCCESS;
}
static rsmi_status_t test_set_nps_mode(uint32_t dv_ind) {
rsmi_status_t ret;
uint32_t buffer_len = 10;
char originalNpsMode[buffer_len];
originalNpsMode[0] = '\0';
print_test_header("NPS Mode Control", dv_ind);
ret = rsmi_dev_nps_mode_get(dv_ind, originalNpsMode, buffer_len);
CHK_RSMI_NOT_SUPPORTED_OR_UNEXPECTED_DATA_RET(ret)
if (ret == RSMI_STATUS_NOT_SUPPORTED) {
return RSMI_STATUS_SUCCESS;
}
std::cout << "Original NPS Mode: "
<< (((originalNpsMode == nullptr)
|| ((originalNpsMode != nullptr)
&& (originalNpsMode[0] == '\0')))
? "UNKNOWN" : originalNpsMode)
<< std::endl << std::endl;
for (int newNpsMode = RSMI_MEMORY_PARTITION_NPS1;
newNpsMode <= RSMI_MEMORY_PARTITION_NPS8;
newNpsMode++) {
rsmi_nps_mode_type_t newMemoryPartition
= static_cast<rsmi_nps_mode_type_t>(newNpsMode);
std::cout << "Attempting to set NPS mode to "
<< nps_mode_string(newMemoryPartition) << "..."
<< std::endl;
ret = rsmi_dev_nps_mode_set(dv_ind, newMemoryPartition);
CHK_RSMI_NOT_SUPPORTED_RET(ret)
if (ret == RSMI_STATUS_NOT_SUPPORTED) {
// do not continue attempting to set, device does not support setting
return RSMI_STATUS_SUCCESS;
}
std::cout << "Done setting NPS mode to "
<< nps_mode_string(newMemoryPartition)
<< "." << std::endl;
std::cout << std::endl << std::endl;
}
std::cout << "About to initate nps mode reset..." << std::endl;
ret = rsmi_dev_nps_mode_reset(dv_ind);
CHK_RSMI_NOT_SUPPORTED_RET(ret)
std::cout << "Done resetting nps mode." << std::endl;
std::string myNpsMode = originalNpsMode;
if (myNpsMode.empty() == false) {
std::cout << "Resetting compute partition to " << originalNpsMode
<< "... " << std::endl;
rsmi_nps_mode_type_t origNpsModeType
= mapStringToRSMINpsModeTypes[originalNpsMode];
ret = rsmi_dev_nps_mode_set(dv_ind, origNpsModeType);
CHK_RSMI_NOT_SUPPORTED_RET(ret)
std::cout << "Done" << std::endl;
}
return RSMI_STATUS_SUCCESS;
}
int main() {
rsmi_status_t ret;
ret = rsmi_init(0);
CHK_RSMI_RET_I(ret)
std::string val_str;
std::vector<std::string> val_vec;
uint64_t val_ui64, val2_ui64;
int64_t val_i64;
@@ -424,98 +714,160 @@ int main() {
rsmi_gpu_metrics_t p;
rsmi_num_monitor_devices(&num_monitor_devs);
for (uint32_t i = 0; i< num_monitor_devs; ++i) {
for (uint32_t i = 0; i < num_monitor_devs; ++i) {
ret = rsmi_dev_id_get(i, &val_ui16);
CHK_RSMI_RET_I(ret)
std::cout << "\t**Device ID: 0x" << std::hex << val_ui64 << std::endl;
std::cout << "\t**Device ID: 0x" << std::hex << val_ui16 << std::endl;
char current_compute_partition[256];
current_compute_partition[0] = '\0';
ret = rsmi_dev_compute_partition_get(i, current_compute_partition, 256);
std::cout << "\t**Current Compute Partition: "
<< (((current_compute_partition == nullptr)
|| ((current_compute_partition != nullptr)
&& (current_compute_partition[0] == '\0')))
? "UNKNOWN" : current_compute_partition);
if (ret != RSMI_STATUS_SUCCESS) {
std::cout << ", RSMI_STATUS = ";
} else {
std::cout << std::endl;
}
CHK_RSMI_NOT_SUPPORTED_OR_UNEXPECTED_DATA_RET(ret)
uint32_t len = 5;
char nps_mode[len];
nps_mode[0] = '\0';
ret = rsmi_dev_nps_mode_get(i, nps_mode, len);
std::cout << "\t**NPS Mode: "
<< (((nps_mode == nullptr)
|| ((nps_mode != nullptr)
&& (nps_mode[0] == '\0')))
? "UNKNOWN" : nps_mode);
if (ret != RSMI_STATUS_SUCCESS) {
std::cout << ", RSMI_STATUS = ";
} else {
std::cout << std::endl;
}
CHK_NOT_SUPPORTED_OR_UNEXPECTED_DATA_OR_INSUFFICIENT_SIZE_RET(ret)
ret = rsmi_dev_gpu_metrics_info_get(i, &p);
CHK_RSMI_RET(ret)
CHK_AND_PRINT_RSMI_ERR_RET(ret)
std::cout << "\t**GPU METRICS" << std::endl;
ret = rsmi_dev_perf_level_get(i, &pfl);
CHK_RSMI_RET_I(ret)
CHK_AND_PRINT_RSMI_ERR_RET(ret)
std::cout << "\t**Performance Level:" <<
perf_level_string(pfl) << std::endl;
ret = rsmi_dev_overdrive_level_get(i, &val_ui32);
CHK_RSMI_RET_I(ret)
CHK_AND_PRINT_RSMI_ERR_RET(ret)
std::cout << "\t**OverDrive Level:" << val_ui32 << std::endl;
ret = rsmi_dev_gpu_clk_freq_get(i, RSMI_CLK_TYPE_MEM, &f);
CHK_RSMI_RET_I(ret)
CHK_AND_PRINT_RSMI_ERR_RET(ret)
std::cout << "\t**Supported GPU Memory clock frequencies: ";
std::cout << f.num_supported << std::endl;
print_frequencies(&f);
ret = rsmi_dev_gpu_clk_freq_get(i, RSMI_CLK_TYPE_SYS, &f);
CHK_RSMI_RET_I(ret)
CHK_AND_PRINT_RSMI_ERR_RET(ret)
std::cout << "\t**Supported GPU clock frequencies: ";
std::cout << f.num_supported << std::endl;
print_frequencies(&f);
char name[20];
ret = rsmi_dev_name_get(i, name, 20);
CHK_RSMI_RET_I(ret)
std::cout << "\t**Monitor name: " << name << std::endl;
std::cout << "\t**Monitor name: ";
char name[128];
ret = rsmi_dev_name_get(i, name, 128);
CHK_AND_PRINT_RSMI_ERR_RET(ret)
std::cout << name << std::endl;
std::cout << "\t**Temperature: ";
ret = rsmi_dev_temp_metric_get(i, 0, RSMI_TEMP_CURRENT, &val_i64);
CHK_RSMI_RET_I(ret)
std::cout << "\t**Temperature: " << val_i64/1000 << "C" << std::endl;
if (ret == RSMI_STATUS_SUCCESS) {
std::cout << val_i64/1000 << "C" << std::endl;
}
CHK_RSMI_NOT_SUPPORTED_RET(ret)
std::cout << "\t**Voltage: ";
ret = rsmi_dev_volt_metric_get(i, RSMI_VOLT_TYPE_VDDGFX,
RSMI_VOLT_CURRENT, &val_i64);
CHK_RSMI_RET_I(ret)
std::cout << "\t**Voltage: " << val_i64 << "mV" << std::endl;
if (ret == RSMI_STATUS_SUCCESS) {
std::cout << val_i64 << "mV" << std::endl;
}
CHK_RSMI_NOT_SUPPORTED_RET(ret)
ret = rsmi_dev_fan_speed_get(i, 0, &val_i64);
CHK_RSMI_RET_I(ret)
ret = rsmi_dev_fan_speed_max_get(i, 0, &val_ui64);
CHK_RSMI_RET_I(ret)
std::cout << "\t**Current Fan Speed: ";
std::cout << val_i64/static_cast<int64_t>(val_ui64)*100;
std::cout << "% ("<< val_i64 << "/" << val_ui64 << ")" << std::endl;
ret = rsmi_dev_fan_speed_get(i, 0, &val_i64);
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 << "% (" << std::dec << val_i64 << "/"
<< std::dec << val_ui64 << ")" << std::endl;
}
CHK_RSMI_NOT_SUPPORTED_RET(ret)
std::cout << "\t**Current fan RPMs: ";
ret = rsmi_dev_fan_rpms_get(i, 0, &val_i64);
CHK_RSMI_RET_I(ret)
std::cout << "\t**Current fan RPMs: " << val_i64 << std::endl;
if (ret == RSMI_STATUS_SUCCESS) {
std::cout << std::dec << val_i64 << std::endl;
}
CHK_RSMI_NOT_SUPPORTED_RET(ret)
std::cout << "\t**Current Power Cap: ";
ret = rsmi_dev_power_cap_get(i, 0, &val_ui64);
CHK_RSMI_PERM_RET(ret)
std::cout << "\t**Current Power Cap: " << val_ui64 << "uW" <<std::endl;
if (ret == RSMI_STATUS_SUCCESS) {
std::cout << std::dec << val_ui64 << "uW" <<std::endl;
}
CHK_RSMI_NOT_SUPPORTED_RET(ret)
std::cout << "\t**Power Cap Range: ";
ret = rsmi_dev_power_cap_range_get(i, 0, &val_ui64, &val2_ui64);
CHK_RSMI_PERM_RET(ret)
std::cout << "\t**Power Cap Range: " << val2_ui64 << " to " <<
val_ui64 << " uW" << std::endl;
if (ret == RSMI_STATUS_SUCCESS) {
std::cout << std::dec << val2_ui64 << " to "
<< std::dec << val_ui64 << " uW" << std::endl;
}
CHK_RSMI_NOT_SUPPORTED_RET(ret)
ret = rsmi_dev_power_ave_get(i, 0, &val_ui64);
CHK_RSMI_PERM_RET(ret)
std::cout << "\t**Averge Power Usage: ";
std::cout << static_cast<float>(val_ui64)/1000 << " W" <<
std::endl;
ret = rsmi_dev_power_ave_get(i, 0, &val_ui64);
if (ret == RSMI_STATUS_SUCCESS) {
std::cout << static_cast<float>(val_ui64)/1000 << " W" << std::endl;
}
CHK_RSMI_NOT_SUPPORTED_RET(ret)
std::cout << "\t=======" << std::endl;
}
std::cout << "***** Testing write api's" << std::endl;
if (isUserRunningAsSudo() == false) {
std::cout << "Write APIs require users to execute with sudo. "
<< "Cannot proceed." << std::endl;
return 0;
}
for (uint32_t i = 0; i< num_monitor_devs; ++i) {
ret = test_set_overdrive(i);
CHK_RSMI_RET_I(ret)
CHK_AND_PRINT_RSMI_ERR_RET(ret)
ret = test_set_perf_level(i);
CHK_RSMI_RET_I(ret)
ret = test_set_freq(i);
CHK_RSMI_RET_I(ret)
CHK_AND_PRINT_RSMI_ERR_RET(ret)
ret = test_set_fan_speed(i);
CHK_RSMI_RET_I(ret)
CHK_AND_PRINT_RSMI_ERR_RET(ret)
ret = test_power_cap(i);
CHK_RSMI_RET_I(ret)
CHK_AND_PRINT_RSMI_ERR_RET(ret)
ret = test_power_profile(i);
CHK_RSMI_RET_I(ret)
CHK_AND_PRINT_RSMI_ERR_RET(ret)
ret = test_set_compute_partitioning(i);
CHK_AND_PRINT_RSMI_ERR_RET(ret)
ret = test_set_freq(i);
CHK_AND_PRINT_RSMI_ERR_RET(ret)
ret = test_set_nps_mode(i);
CHK_AND_PRINT_RSMI_ERR_RET(ret)
}
return 0;
+268 -6
View File
@@ -3,7 +3,7 @@
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2017, Advanced Micro Devices, Inc.
* Copyright (c) 2017-2023, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
@@ -124,8 +124,12 @@ typedef enum {
RSMI_STATUS_BUSY, //!< A resource or mutex could not be
//!< acquired because it is already
//!< being used
RSMI_STATUS_REFCOUNT_OVERFLOW, //!< An internal reference counter
RSMI_STATUS_REFCOUNT_OVERFLOW, //!< An internal reference counter
//!< exceeded INT32_MAX
RSMI_STATUS_SETTING_UNAVAILABLE, //!< Requested setting is unavailable
//!< for the current device
RSMI_STATUS_AMDGPU_RESTART_ERR, //!< Could not successfully restart
//!< the amdgpu driver
RSMI_STATUS_UNKNOWN_ERROR = 0xFFFFFFFF, //!< An unknown error occurred
} rsmi_status_t;
@@ -352,6 +356,51 @@ typedef enum {
typedef rsmi_clk_type_t rsmi_clk_type;
/// \endcond
/**
* @brief Compute Partition. This enum is used to identify
* various compute partitioning settings.
*/
typedef enum {
RSMI_COMPUTE_PARTITION_INVALID = 0,
RSMI_COMPUTE_PARTITION_CPX, //!< Core mode (CPX)- Per-chip XCC with
//!< shared memory
RSMI_COMPUTE_PARTITION_SPX, //!< Single GPU mode (SPX)- All XCCs work
//!< together with shared memory
RSMI_COMPUTE_PARTITION_DPX, //!< Dual GPU mode (DPX)- Half XCCs work
//!< together with shared memory
RSMI_COMPUTE_PARTITION_TPX, //!< Triple GPU mode (TPX)- One-third XCCs
//!< work together with shared memory
RSMI_COMPUTE_PARTITION_QPX //!< Quad GPU mode (QPX)- Quarter XCCs
//!< work together with shared memory
} rsmi_compute_partition_type_t;
/// \cond Ignore in docs.
typedef rsmi_compute_partition_type_t rsmi_compute_partition_type;
/// \endcond
/**
* @brief NPS Modes. This enum is used to identify various
* NPS mode types.
*/
typedef enum {
RSMI_MEMORY_PARTITION_UNKNOWN = 0,
RSMI_MEMORY_PARTITION_NPS1, //!< NPS1 - All CCD & XCD data is interleaved
//!< accross all 8 HBM stacks (all stacks/1).
RSMI_MEMORY_PARTITION_NPS2, //!< NPS2 - 2 sets of CCDs or 4 XCD interleaved
//!< accross the 4 HBM stacks per AID pair
//!< (8 stacks/2).
RSMI_MEMORY_PARTITION_NPS4, //!< NPS4 - Each XCD data is interleaved accross
//!< accross 2 (or single) HBM stacks
//!< (8 stacks/8 or 8 stacks/4).
RSMI_MEMORY_PARTITION_NPS8, //!< NPS8 - Each XCD uses a single HBM stack
//!< (8 stacks/8). Or each XCD uses a single
//!< HBM stack & CCDs share 2 non-interleaved
//!< HBM stacks on its AID
//!< (AID[1,2,3] = 6 stacks/6).
} rsmi_nps_mode_type_t;
/// \cond Ignore in docs.
typedef rsmi_nps_mode_type_t rsmi_nps_mode_type;
/// \endcond
/**
* @brief Temperature Metrics. This enum is used to identify various
* temperature metrics. Corresponding values will be in millidegress
@@ -2226,8 +2275,8 @@ rsmi_status_t rsmi_dev_perf_level_get(uint32_t dv_ind,
* @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid
*
*/
rsmi_status_t rsmi_perf_determinism_mode_set(uint32_t dv_ind, uint64_t clkvalue);
/**
* @brief Get the overdrive percent associated with the device with provided
* device index.
@@ -2251,9 +2300,33 @@ rsmi_status_t rsmi_perf_determinism_mode_set(uint32_t dv_ind, uint64_t clkvalue)
* @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid
*
*/
rsmi_status_t rsmi_dev_overdrive_level_get(uint32_t dv_ind, uint32_t *od);
/**
* @brief Get the memory clock overdrive percent associated with the device
* with provided device index.
*
* @details Given a device index @p dv_ind and a pointer to a uint32_t @p od,
* this function will write the memory overdrive percentage to the uint32_t
* pointed to by @p od
*
* @param[in] dv_ind a device index
*
* @param[inout] od a pointer to uint32_t to which the overdrive percentage
* will be written
* If this parameter is nullptr, this function will return
* ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,
* arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the
* provided arguments.
*
* @retval ::RSMI_STATUS_SUCCESS call was successful
* @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not
* support this function with the given arguments
* @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid
*
*/
rsmi_status_t rsmi_dev_mem_overdrive_level_get(uint32_t dv_ind, uint32_t *od);
/**
* @brief Get the list of possible system clock speeds of device for a
* specified clock type.
@@ -2269,7 +2342,7 @@ rsmi_status_t rsmi_dev_overdrive_level_get(uint32_t dv_ind, uint32_t *od);
*
* @param[inout] f a pointer to a caller provided ::rsmi_frequencies_t structure
* to which the frequency information will be written. Frequency values are in
* Hz.
* Hz.
* If this parameter is nullptr, this function will return
* ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,
* arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the
@@ -3242,7 +3315,30 @@ rsmi_compute_process_info_by_pid_get(uint32_t pid, rsmi_process_info_t *proc);
*/
rsmi_status_t
rsmi_compute_process_gpus_get(uint32_t pid, uint32_t *dv_indices,
uint32_t *num_devices);
uint32_t *num_devices);
/**
* @brief Get the info of a process on a specific device.
*
* @details Given a process id @p pid, a @p dv_ind, this function will
* write the process information for @p pid on the device, if available, to
* the memory pointed to by @p proc.
*
* @param[in] pid The process id of the process for which the gpu
* currently being used is requested.
*
* @param[in] dv_ind a device index where the process running on.
*
* @param[inout] procs a pointer to memory provided by the caller to which
* process information will be written.
*
* @retval ::RSMI_STATUS_SUCCESS is returned upon successful call
* @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid
*
*/
rsmi_status_t
rsmi_compute_process_info_by_device_get(uint32_t pid, uint32_t dv_ind,
rsmi_process_info_t *proc);
/** @} */ // end of SysInfo
@@ -3446,6 +3542,172 @@ rsmi_is_P2P_accessible(uint32_t dv_ind_src, uint32_t dv_ind_dst,
/** @} */ // end of HWTopo
/*****************************************************************************/
/** @defgroup ComputePartition Compute Partition Functions
* These functions are used to configure and query the device's
* compute parition setting.
* @{
*/
/**
* @brief Retrieves the current compute partitioning for a desired device
*
* @details
* Given a device index @p dv_ind and a string @p compute_partition ,
* and uint32 @p len , this function will attempt to obtain the device's
* current compute partition setting string. Upon successful retreival,
* the obtained device's compute partition settings string shall be stored in
* the passed @p compute_partition char string variable.
*
* @param[in] dv_ind a device index
*
* @param[inout] compute_partition a pointer to a char string variable,
* which the device's current compute partition will be written to.
*
* @param[in] len the length of the caller provided buffer @p compute_partition
* , suggested length is 4 or greater.
*
* @retval ::RSMI_STATUS_SUCCESS call was successful
* @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid
* @retval ::RSMI_STATUS_UNEXPECTED_DATA data provided to function is not valid
* @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not
* support this function
* @retval ::RSMI_STATUS_INSUFFICIENT_SIZE is returned if @p len bytes is not
* large enough to hold the entire compute partition value. In this case,
* only @p len bytes will be written.
*
*/
rsmi_status_t
rsmi_dev_compute_partition_get(uint32_t dv_ind, char *compute_partition,
uint32_t len);
/**
* @brief Modifies a selected device's compute partition setting.
*
* @details Given a device index @p dv_ind, a type of compute partition
* @p compute_partition, this function will attempt to update the selected
* device's compute partition setting.
*
* @param[in] dv_ind a device index
*
* @param[in] compute_partition using enum ::rsmi_compute_partition_type_t,
* define what the selected device's compute partition setting should be
* updated to.
*
* @retval ::RSMI_STATUS_SUCCESS call was successful
* @retval ::RSMI_STATUS_PERMISSION function requires root access
* @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid
* @retval ::RSMI_STATUS_SETTING_UNAVAILABLE the provided setting is
* unavailable for current device
* @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not
* support this function
*
*/
rsmi_status_t
rsmi_dev_compute_partition_set(uint32_t dv_ind,
rsmi_compute_partition_type_t compute_partition);
/**
* @brief Reverts a selected device's compute partition setting back to its
* boot state.
*
* @details Given a device index @p dv_ind , this function will attempt to
* revert its compute partition setting back to its boot state.
*
* @param[in] dv_ind a device index
*
* @retval ::RSMI_STATUS_SUCCESS call was successful
* @retval ::RSMI_STATUS_PERMISSION function requires root access
* @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not
* support this function
*
*/
rsmi_status_t rsmi_dev_compute_partition_reset(uint32_t dv_ind);
/** @} */ // end of ComputePartition
/*****************************************************************************/
/** @defgroup NPSMode NPS Mode Functions
* These functions are used to query the device's NPS mode (memory partition).
* @{
*/
/**
* @brief Retrieves the NPS mode (memory partition) for a desired device
*
* @details
* Given a device index @p dv_ind and a string @p nps_mode ,
* and uint32 @p len , this function will attempt to obtain the device's
* nps mode string. Upon successful retreival, the obtained device's
* nps mode string shall be stored in the passed @p nps_mode char string
* variable.
*
* @param[in] dv_ind a device index
*
* @param[inout] nps_mode a pointer to a char string variable,
* which the device's nps mode will be written to.
*
* @param[in] len the length of the caller provided buffer @p nps_mode ,
* suggested length is 5 or greater.
*
* @retval ::RSMI_STATUS_SUCCESS call was successful
* @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid
* @retval ::RSMI_STATUS_UNEXPECTED_DATA data provided to function is not valid
* @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not
* support this function
* @retval ::RSMI_STATUS_INSUFFICIENT_SIZE is returned if @p len bytes is not
* large enough to hold the entire nps mode value. In this case,
* only @p len bytes will be written.
*
*/
rsmi_status_t
rsmi_dev_nps_mode_get(uint32_t dv_ind, char *nps_mode, uint32_t len);
/**
* @brief Modifies a selected device's NPS mode (memory partition) setting.
*
* @details Given a device index @p dv_ind and a type of nps mode
* @p nps_mode, this function will attempt to update the selected
* device's nps mode setting.
*
* @param[in] dv_ind a device index
*
* @param[in] nps_mode using enum ::rsmi_nps_mode_type_t,
* define what the selected device's NPS mode setting should be updated to.
*
* @retval ::RSMI_STATUS_SUCCESS call was successful
* @retval ::RSMI_STATUS_PERMISSION function requires root access
* @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid
* @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not
* support this function
* @retval ::RSMI_STATUS_AMDGPU_RESTART_ERR could not successfully restart
* the amdgpu driver
*
*/
rsmi_status_t
rsmi_dev_nps_mode_set(uint32_t dv_ind, rsmi_nps_mode_type_t nps_mode);
/**
* @brief Reverts a selected device's NPS mode setting back to its
* boot state.
*
* @details Given a device index @p dv_ind , this function will attempt to
* revert its NPS mode setting back to its boot state.
*
* @param[in] dv_ind a device index
*
* @retval ::RSMI_STATUS_SUCCESS call was successful
* @retval ::RSMI_STATUS_PERMISSION function requires root access
* @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not
* support this function
* @retval ::RSMI_STATUS_AMDGPU_RESTART_ERR could not successfully restart
* the amdgpu driver
*
*/
rsmi_status_t rsmi_dev_nps_mode_reset(uint32_t dv_ind);
/** @} */ // end of NPSMode
/*****************************************************************************/
/** @defgroup APISupport Supported Functions
* API function support varies by both GPU type and the version of the
+9 -2
View File
@@ -5,7 +5,7 @@
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2018, Advanced Micro Devices, Inc.
* Copyright (c) 2018-2023, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
@@ -49,6 +49,7 @@
#include <map>
#include <vector>
#include <string>
#include <unordered_set>
#define CHECK_DV_IND_RANGE \
amd::smi::RocmSMI& smi = amd::smi::RocmSMI::getInstance(); \
@@ -165,7 +166,13 @@ struct RocmSMI_env_vars {
// The integer value of sysfs field enum that is to be over-ridden.
// Env. variable RSMI_DEBUG_ENUM_OVERRIDE is used to specify this.
uint32_t enum_override;
// A set of enum overrides, RSMI_DEBUG_ENUM_OVERRIDE now supports
// comma delimited values.
std::unordered_set<uint32_t> enum_overrides;
// If RSMI_LOGGING is set, enables logging.
// Otherwise unset values, signify logging is turned off.
uint32_t logging_on;
// Sysfs path overrides
+9 -2
View File
@@ -3,7 +3,7 @@
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2017, Advanced Micro Devices, Inc.
* Copyright (c) 2017-2023, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
@@ -98,6 +98,7 @@ enum DevKFDNodePropTypes {
enum DevInfoTypes {
kDevPerfLevel,
kDevOverDriveLevel,
kDevMemOverDriveLevel,
kDevDevID,
kDevDevProdName,
kDevDevProdNum,
@@ -160,7 +161,10 @@ enum DevInfoTypes {
kDevMemPageBad,
kDevNumaNode,
kDevGpuMetrics,
kDevGpuReset
kDevGpuReset,
kDevAvailableComputePartition,
kDevComputePartition,
kDevMemoryPartition
};
typedef struct {
@@ -213,6 +217,9 @@ class Device {
void DumpSupportedFunctions(void);
bool DeviceAPISupported(std::string name, uint64_t variant,
uint64_t sub_variant);
rsmi_status_t restartAMDGpuDriver(void);
rsmi_status_t storeDevicePartitions(uint32_t dv_ind);
template <typename T> std::string readBootPartitionState(uint32_t dv_ind);
private:
std::shared_ptr<Monitor> monitor_;
+224
View File
@@ -0,0 +1,224 @@
/*
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2023, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
* Detail Description:
* Implemented complete logging mechanism, supporting multiple logging type
* like as file based logging, console base logging etc. It also supported
* for different log types.
*
* Thread Safe logging mechanism. Compatible with G++ (Linux platform)
*
* Supported Log Type: ERROR, ALARM, ALWAYS, INFO, BUFFER, TRACE, DEBUG
* No control for ERROR, ALRAM and ALWAYS messages. These type of messages
* should be always captured -- IF logging is enabled.
*
* WARNING: Logging is controlled by users environment variable - RSMI_LOGGING.
* Enabling RSMI_LOGGING, by export RSMI_LOGGING=<any value>. No logs will
* be printed, unless RSMI_LOGGING is enabled.
*
* BUFFER log type should be use while logging raw buffer or raw messages
* Having direct interface as well as C++ Singleton inface. Can use
* whatever interface fits your needs.
*/
#ifndef _ROCM_SMI_LOGGER_H_
#define _ROCM_SMI_LOGGER_H_
// C++ Header File(s)
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <mutex>
// POSIX Socket Header File(s)
#include <errno.h>
// Code Specific Header Files(s)
namespace ROCmLogging {
// Direct Interface for logging into log file or console using MACRO(s)
#define LOG_ERROR(x) (ROCmLogging::Logger::getInstance()->error(x))
#define LOG_ALARM(x) (ROCmLogging::Logger::getInstance()->alarm(x))
#define LOG_ALWAYS(x) (ROCmLogging::Logger::getInstance()->always(x))
#define LOG_INFO(x) (ROCmLogging::Logger::getInstance()->info(x))
#define LOG_BUFFER(x) (ROCmLogging::Logger::getInstance()->buffer(x))
#define LOG_TRACE(x) (ROCmLogging::Logger::getInstance()->trace(x))
#define LOG_DEBUG(x) (ROCmLogging::Logger::getInstance()->debug(x))
// enum for LOG_LEVEL
typedef enum LOG_LEVEL {
DISABLE_LOG = 1,
LOG_LEVEL_INFO = 2,
LOG_LEVEL_BUFFER = 3,
LOG_LEVEL_TRACE = 4,
LOG_LEVEL_DEBUG = 5,
ENABLE_LOG = 6,
} LogLevel;
// enum for LOG_TYPE
typedef enum LOG_TYPE {
NO_LOG = 1,
CONSOLE = 2,
FILE_LOG = 3,
} LogType;
class Logger {
public:
static Logger* getInstance() throw();
Logger& operator<<(std::string &s) {
switch (this->m_LogLevel) {
case DISABLE_LOG:
break;
case LOG_LEVEL_INFO:
info(s);
break;
case LOG_LEVEL_BUFFER:
buffer(s);
break;
case LOG_LEVEL_TRACE:
trace(s);
break;
case LOG_LEVEL_DEBUG:
debug(s);
break;
case ENABLE_LOG:
always(s);
break;
default:
break;
}
return *getInstance();
};
Logger &operator<<(const char* s) {
return operator<<(std::string(s));
};
template <class T> Logger &operator<<(const T &v) {
std::ostringstream s;
s << v;
std::string str = s.str();
return operator<<(str);
};
// Interface for Error Log
void error(const char* text) throw();
void error(std::string& text) throw();
void error(std::ostringstream& stream) throw();
// Interface for Alarm Log
void alarm(const char* text) throw();
void alarm(std::string& text) throw();
void alarm(std::ostringstream& stream) throw();
// Interface for Always Log
void always(const char* text) throw();
void always(std::string& text) throw();
void always(std::ostringstream& stream) throw();
// Interface for Buffer Log
void buffer(const char* text) throw();
void buffer(std::string& text) throw();
void buffer(std::ostringstream& stream) throw();
// Interface for Info Log
void info(const char* text) throw();
void info(std::string& text) throw();
void info(std::ostringstream& stream) throw();
// Interface for Trace log
void trace(const char* text) throw();
void trace(std::string& text) throw();
void trace(std::ostringstream& stream) throw();
// Interface for Debug log
void debug(const char* text) throw();
void debug(std::string& text) throw();
void debug(std::ostringstream& stream) throw();
// Error and Alarm log must be always enable
// Hence, there is no interfce to control error and alarm logs
// Interfaces to control log levels
void updateLogLevel(LogLevel logLevel);
void enableAllLogLevels(); // Enable all log levels
void disableLog(); // Disable all log levels, except error and alarm
// Interfaces to control log Types
void updateLogType(LogType logType);
void enableConsoleLogging();
void enableFileLogging();
std::string getLogSettings();
bool isLoggerEnabled();
protected:
Logger();
~Logger();
// Wrapper function for lock/unlock
// For Extensible feature, lock and unlock should be in protected
void lock();
void unlock();
std::string getCurrentTime();
private:
static Logger* m_Instance;
std::ofstream m_File;
bool m_loggingIsOn = false;
LogLevel m_LogLevel;
LogType m_LogType;
std::mutex m_Mutex;
std::unique_lock<std::mutex> m_Lock{m_Mutex, std::defer_lock};
void logIntoFile(std::string& data);
void logOnConsole(std::string& data);
void operator=(const Logger&) {}
void initialize_resources();
void destroy_resources();
};
} // namespace ROCmLogging
#endif // End of _ROCM_SMI_LOGGER_H_
+4 -1
View File
@@ -5,7 +5,7 @@
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2017, Advanced Micro Devices, Inc.
* Copyright (c) 2017-2023, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
@@ -113,6 +113,9 @@ class RocmSMI {
uint64_t *weight);
int get_node_index(uint32_t dv_ind, uint32_t *node_ind);
const RocmSMI_env_vars& getEnv(void);
void printEnvVarInfo(void);
bool isLoggingOn(void);
static const std::map<amd::smi::DevInfoTypes, std::string> devInfoTypesStrings;
private:
std::vector<std::shared_ptr<Device>> devices_;
+1 -1
View File
@@ -115,6 +115,7 @@ class Monitor {
std::string path_;
const RocmSMI_env_vars *env_;
std::map<rsmi_temperature_type_t, uint32_t> temp_type_index_map_;
std::map<rsmi_voltage_type_t, uint32_t> volt_type_index_map_;
// This map uses a 64b index instead of 32b (unlike temp_type_index_map_)
// for flexibility and simplicity. Currently, some parts of the
@@ -124,7 +125,6 @@ class Monitor {
// a 64b value. Also, if we need to encode anything else, 64b will give
// us more room to do so, without excessive changes.
std::map<uint64_t, rsmi_temperature_type_t> index_temp_type_map_;
std::map<rsmi_voltage_type_t, uint32_t> volt_type_index_map_;
std::map<uint64_t, rsmi_voltage_type_t> index_volt_type_map_;
};
+17 -5
View File
@@ -3,7 +3,7 @@
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2018, Advanced Micro Devices, Inc.
* Copyright (c) 2018-2023, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
@@ -66,16 +66,24 @@ namespace amd {
namespace smi {
pthread_mutex_t *GetMutex(uint32_t dv_ind);
int SameFile(const std::string fileA, const std::string fileB);
bool FileExists(char const *filename);
std::vector<std::string> globFilesExist(const std::string& filePattern);
int isRegularFile(std::string fname, bool *is_reg);
int ReadSysfsStr(std::string path, std::string *retStr);
int WriteSysfsStr(std::string path, std::string val);
bool IsInteger(const std::string & n_str);
std::pair<bool, std::string> executeCommand(std::string command,
bool stdOut = true);
rsmi_status_t storeTmpFile(uint32_t dv_ind, std::string parameterName,
std::string stateName, std::string storageData);
std::vector<std::string> getListOfAppTmpFiles();
bool containsString(std::string originalString, std::string substring);
std::tuple<bool, std::string> readTmpFile(
uint32_t dv_ind,
std::string stateName,
std::string parameterName);
void displayAppTmpFilesContent(void);
rsmi_status_t handleException();
rsmi_status_t
GetDevValueVec(amd::smi::DevInfoTypes type,
@@ -84,6 +92,10 @@ rsmi_status_t
GetDevBinaryBlob(amd::smi::DevInfoTypes type,
uint32_t dv_ind, std::size_t b_size, void* p_binary_data);
rsmi_status_t ErrnoToRsmiStatus(int err);
std::string getRSMIStatusString(rsmi_status_t ret);
std::tuple<bool, std::string, std::string, std::string, std::string,
std::string, std::string, std::string> getSystemDetails(void);
void logSystemDetails(void);
struct pthread_wrap {
public:
File diff suppressed because it is too large Load Diff
+84 -5
View File
@@ -12,16 +12,16 @@ import os
# Use ROCm installation path if running from standard installation
# With File Reorg rsmiBindings.py will be installed in /opt/rocm/libexec/rocm_smi.
# relative path changed accordingly
path_librocm = os.path.dirname(os.path.realpath(__file__)) + '/../../lib/librocm_smi64.so'
path_librocm = os.path.dirname(os.path.realpath(__file__)) + '/../../@CMAKE_INSTALL_LIBDIR@/librocm_smi64.so.@VERSION_MAJOR@'
if not os.path.isfile(path_librocm):
print('Unable to find %s . Trying /opt/rocm*' % path_librocm)
for root, dirs, files in os.walk('/opt', followlinks=True):
if 'librocm_smi64.so' in files:
path_librocm = os.path.join(os.path.realpath(root), 'librocm_smi64.so')
if 'librocm_smi64.so.@VERSION_MAJOR@' in files:
path_librocm = os.path.join(os.path.realpath(root), 'librocm_smi64.so.@VERSION_MAJOR@')
if os.path.isfile(path_librocm):
print('Using lib from %s' % path_librocm)
else:
print('Unable to find librocm_smi64.so')
print('Unable to find librocm_smi64.so.@VERSION_MAJOR@')
# ----------> TODO: Support static libs as well as SO
@@ -30,7 +30,7 @@ try:
rocmsmi = CDLL(path_librocm)
except OSError:
print('Unable to load the rocm_smi library.\n'\
'Set LD_LIBRARY_PATH to the folder containing librocm_smi64.\n'\
'Set LD_LIBRARY_PATH to the folder containing librocm_smi64.so.@VERSION_MAJOR@\n'\
'{0}Please refer to https://github.com/'\
'RadeonOpenCompute/rocm_smi_lib for the installation guide.{1}'\
.format('\33[33m', '\033[0m'))
@@ -66,9 +66,40 @@ class rsmi_status_t(c_int):
RSMI_STATUS_INTERRUPT = 0xC
RSMI_STATUS_UNEXPECTED_SIZE = 0xD
RSMI_STATUS_NO_DATA = 0xE
RSMI_STATUS_UNEXPECTED_DATA = 0xF
RSMI_STATUS_BUSY = 0x10
RSMI_STATUS_REFCOUNT_OVERFLOW = 0x11
RSMI_STATUS_SETTING_UNAVAILABLE = 0x12
RSMI_STATUS_AMDGPU_RESTART_ERR = 0x13
RSMI_STATUS_UNKNOWN_ERROR = 0xFFFFFFFF
#Dictionary of rsmi ret codes and it's verbose output
rsmi_status_verbose_err_out = {
rsmi_status_t.RSMI_STATUS_SUCCESS: 'Operation was successful',
rsmi_status_t.RSMI_STATUS_INVALID_ARGS: 'Invalid arguments provided',
rsmi_status_t.RSMI_STATUS_NOT_SUPPORTED: 'Not supported on the given system',
rsmi_status_t.RSMI_STATUS_FILE_ERROR: 'Problem accessing a file',
rsmi_status_t.RSMI_STATUS_PERMISSION: 'Permission denied',
rsmi_status_t.RSMI_STATUS_OUT_OF_RESOURCES: 'Unable to acquire memory or other resource',
rsmi_status_t.RSMI_STATUS_INTERNAL_EXCEPTION: 'An internal exception was caught',
rsmi_status_t.RSMI_STATUS_INPUT_OUT_OF_BOUNDS: 'Provided input is out of allowable or safe range',
rsmi_status_t.RSMI_INITIALIZATION_ERROR: 'Error occured during rsmi initialization',
rsmi_status_t.RSMI_STATUS_NOT_YET_IMPLEMENTED: 'Requested function is not implemented on this setup',
rsmi_status_t.RSMI_STATUS_NOT_FOUND: 'Item searched for but not found',
rsmi_status_t.RSMI_STATUS_INSUFFICIENT_SIZE: 'Insufficient resources available',
rsmi_status_t.RSMI_STATUS_INTERRUPT: 'Interrupt occured during execution',
rsmi_status_t.RSMI_STATUS_UNEXPECTED_SIZE: 'Unexpected amount of data read',
rsmi_status_t.RSMI_STATUS_NO_DATA: 'No data found for the given input',
rsmi_status_t.RSMI_STATUS_UNEXPECTED_DATA: 'Unexpected data received',
rsmi_status_t.RSMI_STATUS_BUSY: 'Busy - resources are preventing call the ability to execute',
rsmi_status_t.RSMI_STATUS_REFCOUNT_OVERFLOW: 'Data overflow - data exceeded INT32_MAX',
rsmi_status_t.RSMI_STATUS_SETTING_UNAVAILABLE: 'Requested setting is unavailable for current device',
rsmi_status_t.RSMI_STATUS_AMDGPU_RESTART_ERR: 'Could not successfully restart the amdgpu driver',
rsmi_status_t.RSMI_STATUS_UNKNOWN_ERROR: 'Unknown error occured'
}
class rsmi_init_flags_t(c_int):
RSMI_INIT_FLAG_ALL_GPUS = 0x1
@@ -132,6 +163,7 @@ def perf_level_string(i):
5: 'STABLE_PEAK',
6: 'STABLE_MIN_MCLK',
7: 'STABLE_MIN_SCLK',
8: 'PERF_DETERMINISM',
}
return switcher.get(i, 'UNKNOWN')
@@ -560,3 +592,50 @@ class rsmi_func_id_value_t(Union):
_fields_ = [('id', c_uint64),
('name', c_char_p),
('submodule', submodule_union)]
class rsmi_compute_partition_type_t(c_int):
RSMI_COMPUTE_PARTITION_INVALID = 0
RSMI_COMPUTE_PARTITION_CPX = 1
RSMI_COMPUTE_PARTITION_SPX = 2
RSMI_COMPUTE_PARTITION_DPX = 3
RSMI_COMPUTE_PARTITION_TPX = 4
RSMI_COMPUTE_PARTITION_QPX = 5
rsmi_compute_partition_type_dict = {
#'RSMI_COMPUTE_PARTITION_INVALID': 0,
'CPX': 1,
'SPX': 2,
'DPX': 3,
'TPX': 4,
'QPX': 5
}
rsmi_compute_partition_type = rsmi_compute_partition_type_t
# compute_partition_type_l includes string names for the rsmi_compute_partition_type_t
# Usage example to get corresponding names:
# compute_partition_type_l[rsmi_compute_partition_type_t.RSMI_COMPUTE_PARTITION_CPX]
# will return string 'CPX'
compute_partition_type_l = ['CPX', 'SPX', 'DPX', 'TPX', 'QPX']
class rsmi_nps_mode_type_t(c_int):
RSMI_MEMORY_PARTITION_UNKNOWN = 0
RSMI_MEMORY_PARTITION_NPS1 = 1
RSMI_MEMORY_PARTITION_NPS2 = 2
RSMI_MEMORY_PARTITION_NPS4 = 3
RSMI_MEMORY_PARTITION_NPS8 = 4
rsmi_nps_mode_type_dict = {
'NPS1': 1,
'NPS2': 2,
'NPS4': 3,
'NPS8': 4
}
rsmi_nps_mode_type = rsmi_nps_mode_type_t
# nps_mode_type_l includes string names for the rsmi_compute_partition_type_t
# Usage example to get corresponding names:
# nps_mode_type_l[rsmi_nps_mode_type_t.RSMI_MEMORY_PARTITION_NPS2]
# will return string 'NPS2'
nps_mode_type_l = ['NPS1', 'NPS2', 'NPS4', 'NPS8']
+826 -55
View File
File diff suppressed because it is too large Load Diff
+286 -8
View File
@@ -3,7 +3,7 @@
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2017, Advanced Micro Devices, Inc.
* Copyright (c) 2017-2023, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
@@ -44,10 +44,10 @@
#include <pthread.h>
#include <unistd.h>
#include <sys/types.h>
#include <assert.h>
#include <sys/stat.h>
#include <stdint.h>
#include <string>
#include <map>
#include <fstream>
@@ -58,6 +58,7 @@
#include <memory>
#include <algorithm>
#include <iterator>
#include <cstring>
#include "rocm_smi/rocm_smi_main.h"
#include "rocm_smi/rocm_smi_device.h"
@@ -65,8 +66,11 @@
#include "rocm_smi/rocm_smi_exception.h"
#include "rocm_smi/rocm_smi_utils.h"
#include "rocm_smi/rocm_smi_kfd.h"
#include "rocm_smi/rocm_smi_logger.h"
#include "shared_mutex.h" // NOLINT
using namespace ROCmLogging;
namespace amd {
namespace smi {
@@ -85,6 +89,7 @@ static const char *kDevVendorIDFName = "vendor";
static const char *kDevSubSysDevIDFName = "subsystem_device";
static const char *kDevSubSysVendorIDFName = "subsystem_vendor";
static const char *kDevOverDriveLevelFName = "pp_sclk_od";
static const char *kDevMemOverDriveLevelFName = "pp_mclk_od";
static const char *kDevGPUSClkFName = "pp_dpm_sclk";
static const char *kDevGPUMClkFName = "pp_dpm_mclk";
static const char *kDevDCEFClkFName = "pp_dpm_dcefclk";
@@ -120,6 +125,10 @@ static const char *kDevXGMIErrorFName = "xgmi_error";
static const char *kDevSerialNumberFName = "serial_number";
static const char *kDevNumaNodeFName = "numa_node";
static const char *kDevGpuMetricsFName = "gpu_metrics";
static const char *kDevAvailableComputePartitionFName =
"available_compute_partition";
static const char *kDevComputePartitionFName = "current_compute_partition";
static const char *kDevMemoryPartitionFName = "current_memory_partition";
// Firmware version files
static const char *kDevFwVersionAsdFName = "fw_version/asd_fw_version";
@@ -225,6 +234,7 @@ static const char *kDevPerfLevelUnknownStr = "unknown";
static const std::map<DevInfoTypes, const char *> kDevAttribNameMap = {
{kDevPerfLevel, kDevPerfLevelFName},
{kDevOverDriveLevel, kDevOverDriveLevelFName},
{kDevMemOverDriveLevel, kDevMemOverDriveLevelFName},
{kDevDevProdName, kDevDevProdNameFName},
{kDevDevProdNum, kDevDevProdNumFName},
{kDevDevID, kDevDevIDFName},
@@ -288,6 +298,9 @@ static const std::map<DevInfoTypes, const char *> kDevAttribNameMap = {
{kDevNumaNode, kDevNumaNodeFName},
{kDevGpuMetrics, kDevGpuMetricsFName},
{kDevGpuReset, kDevGpuResetFName},
{kDevAvailableComputePartition, kDevAvailableComputePartitionFName},
{kDevComputePartition, kDevComputePartitionFName},
{kDevMemoryPartition, kDevMemoryPartitionFName},
};
static const std::map<rsmi_dev_perf_level, const char *> kDevPerfLvlMap = {
@@ -388,6 +401,7 @@ static const std::map<const char *, dev_depends_t> kDevFuncDependsMap = {
{"rsmi_dev_busy_percent_get", {{kDevUsageFName}, {}}},
{"rsmi_dev_memory_reserved_pages_get", {{kDevMemPageBadFName}, {}}},
{"rsmi_dev_overdrive_level_get", {{kDevOverDriveLevelFName}, {}}},
{"rsmi_dev_mem_overdrive_level_get", {{kDevMemOverDriveLevelFName}, {}}},
{"rsmi_dev_power_profile_presets_get", {{kDevPowerProfileModeFName}, {}}},
{"rsmi_dev_perf_level_set", {{kDevPerfLevelFName}, {}}},
{"rsmi_dev_perf_level_set_v1", {{kDevPerfLevelFName}, {}}},
@@ -410,6 +424,10 @@ static const std::map<const char *, dev_depends_t> kDevFuncDependsMap = {
{"rsmi_topo_numa_affinity_get", {{kDevNumaNodeFName}, {}}},
{"rsmi_dev_gpu_metrics_info_get", {{kDevGpuMetricsFName}, {}}},
{"rsmi_dev_gpu_reset", {{kDevGpuResetFName}, {}}},
{"rsmi_dev_compute_partition_get", {{kDevComputePartitionFName}, {}}},
{"rsmi_dev_compute_partition_set", {{kDevComputePartitionFName}, {}}},
{"rsmi_dev_memory_partition_get", {{kDevMemoryPartitionFName}, {}}},
{"rsmi_dev_memory_partition_set", {{kDevMemoryPartitionFName}, {}}},
// These functions with variants, but no sensors/units. (May or may not
// have mandatory dependencies.)
@@ -555,14 +573,12 @@ int Device::openDebugFileStream(DevInfoTypes type, T *fs, const char *str) {
template <typename T>
int Device::openSysfsFileStream(DevInfoTypes type, T *fs, const char *str) {
auto sysfs_path = path_;
std::ostringstream ss;
#ifdef DEBUG
if (env_->path_DRM_root_override && type == env_->enum_override) {
if (env_->path_DRM_root_override
&& (env_->enum_overrides.find(type) != env_->enum_overrides.end())) {
sysfs_path = env_->path_DRM_root_override;
if (str) {
sysfs_path += ".write";
}
}
#endif
@@ -575,18 +591,35 @@ int Device::openSysfsFileStream(DevInfoTypes type, T *fs, const char *str) {
int ret = isRegularFile(sysfs_path, &reg_file);
if (ret != 0) {
ss << "File did not exist - SYSFS file (" << sysfs_path
<< ") for DevInfoInfoType (" << RocmSMI::devInfoTypesStrings.at(type)
<< "), returning " << std::to_string(ret);
LOG_ERROR(ss);
return ret;
}
if (!reg_file) {
ss << "File is not a regular file - SYSFS file (" << sysfs_path << ") for "
<< "DevInfoInfoType (" << RocmSMI::devInfoTypesStrings.at(type) << "),"
<< " returning ENOENT (" << std::strerror(ENOENT) << ")";
LOG_ERROR(ss);
return ENOENT;
}
fs->open(sysfs_path);
if (!fs->is_open()) {
return errno;
ss << "Could not open - SYSFS file (" << sysfs_path << ") for "
<< "DevInfoInfoType (" << RocmSMI::devInfoTypesStrings.at(type) << "), "
<< ", returning " << std::to_string(errno) << " ("
<< std::strerror(errno) << ")";
LOG_ERROR(ss);
return errno;
}
ss << "Successfully opened SYSFS file (" << sysfs_path
<< ") for DevInfoInfoType (" << RocmSMI::devInfoTypesStrings.at(type)
<< ")";
LOG_INFO(ss);
return 0;
}
@@ -594,11 +627,16 @@ int Device::readDebugInfoStr(DevInfoTypes type, std::string *retStr) {
std::ifstream fs;
std::string line;
int ret = 0;
std::ostringstream ss;
assert(retStr != nullptr);
ret = openDebugFileStream(type, &fs);
if (ret != 0) {
ss << "Could not read debugInfoStr for DevInfoType ("
<< RocmSMI::devInfoTypesStrings.at(type)<< "), returning "
<< std::to_string(ret);
LOG_ERROR(ss);
return ret;
}
@@ -609,21 +647,34 @@ int Device::readDebugInfoStr(DevInfoTypes type, std::string *retStr) {
fs.close();
ss << "Successfully read debugInfoStr for DevInfoType ("
<< RocmSMI::devInfoTypesStrings.at(type)<< "), retString= " << *retStr;
LOG_INFO(ss);
return 0;
}
int Device::readDevInfoStr(DevInfoTypes type, std::string *retStr) {
std::ifstream fs;
int ret = 0;
std::ostringstream ss;
assert(retStr != nullptr);
ret = openSysfsFileStream(type, &fs);
if (ret != 0) {
ss << "Could not read device info string for DevInfoType ("
<< RocmSMI::devInfoTypesStrings.at(type)<< "), returning "
<< std::to_string(ret);
LOG_ERROR(ss);
return ret;
}
fs >> *retStr;
std::string info = "Successfully read device info string for DevInfoType (" +
RocmSMI::devInfoTypesStrings.at(type) + "): " +
*retStr;
LOG_INFO(info);
fs.close();
return 0;
@@ -633,17 +684,30 @@ int Device::writeDevInfoStr(DevInfoTypes type, std::string valStr) {
auto tempPath = path_;
std::ofstream fs;
int ret;
std::ostringstream ss;
fs.rdbuf()->pubsetbuf(0,0);
ret = openSysfsFileStream(type, &fs, valStr.c_str());
if (ret != 0) {
ss << "Could not write device info string (" << valStr
<< ") for DevInfoType (" << RocmSMI::devInfoTypesStrings.at(type)
<< "), returning " << std::to_string(ret);
LOG_ERROR(ss);
return ret;
}
// We'll catch any exceptions in rocm_smi.cc code.
if (fs << valStr) {
ss << "Successfully wrote device info string (" << valStr
<< ") for DevInfoType (" << RocmSMI::devInfoTypesStrings.at(type)
<< "), returning RSMI_STATUS_SUCCESS";
LOG_INFO(ss);
ret = RSMI_STATUS_SUCCESS;
} else {
ss << "Could not write device info string (" << valStr
<< ") for DevInfoType (" << RocmSMI::devInfoTypesStrings.at(type)
<< "), returning RSMI_STATUS_NOT_SUPPORTED";
LOG_ERROR(ss);
ret = RSMI_STATUS_NOT_SUPPORTED;
}
fs.close();
@@ -693,6 +757,8 @@ int Device::writeDevInfo(DevInfoTypes type, std::string val) {
case kDevPCIEClk:
case kDevPowerODVoltage:
case kDevSOCClk:
case kDevComputePartition:
case kDevMemoryPartition:
return writeDevInfoStr(type, val);
default:
@@ -705,15 +771,23 @@ int Device::writeDevInfo(DevInfoTypes type, std::string val) {
int Device::readDevInfoLine(DevInfoTypes type, std::string *line) {
int ret;
std::ifstream fs;
std::ostringstream ss;
assert(line != nullptr);
ret = openSysfsFileStream(type, &fs);
if (ret != 0) {
ss << "Could not read DevInfoLine for DevInfoType ("
<< RocmSMI::devInfoTypesStrings.at(type) << ")";
LOG_ERROR(ss);
return ret;
}
std::getline(fs, *line);
ss << "Successfully read DevInfoLine for DevInfoType ("
<< RocmSMI::devInfoTypesStrings.at(type) << "), returning *line = "
<< *line;
LOG_INFO(ss);
return 0;
}
@@ -721,20 +795,36 @@ int Device::readDevInfoLine(DevInfoTypes type, std::string *line) {
int Device::readDevInfoBinary(DevInfoTypes type, std::size_t b_size,
void *p_binary_data) {
auto sysfs_path = path_;
std::ostringstream ss;
FILE *ptr;
sysfs_path += "/device/";
sysfs_path += kDevAttribNameMap.at(type);
ptr = fopen(sysfs_path.c_str(), "rb");
if (!ptr) {
ss << "Could not read DevInfoBinary for DevInfoType ("
<< RocmSMI::devInfoTypesStrings.at(type) << ")"
<< " - SYSFS (" << sysfs_path << ")"
<< ", returning " << std::to_string(errno) << " ("
<< std::strerror(errno) << ")";
LOG_ERROR(ss);
return errno;
}
size_t num = fread(p_binary_data, b_size, 1, ptr);
fclose(ptr);
if ((num*b_size) != b_size) {
ss << "Could not read DevInfoBinary for DevInfoType ("
<< RocmSMI::devInfoTypesStrings.at(type) << ") - SYSFS ("
<< sysfs_path << "), binary size error, "
<< ", returning ENOENT (" << std::strerror(ENOENT) << ")";
LOG_ERROR(ss);
return ENOENT;
}
ss << "Successfully read DevInfoBinary for DevInfoType ("
<< RocmSMI::devInfoTypesStrings.at(type) << ") - SYSFS ("
<< sysfs_path << "), returning binaryData = " << p_binary_data;
LOG_INFO(ss);
return 0;
}
@@ -743,6 +833,8 @@ int Device::readDevInfoMultiLineStr(DevInfoTypes type,
std::string line;
int ret;
std::ifstream fs;
std::string allLines;
std::ostringstream ss;
assert(retVec != nullptr);
@@ -756,6 +848,10 @@ int Device::readDevInfoMultiLineStr(DevInfoTypes type,
}
if (retVec->size() == 0) {
ss << "Read devInfoMultiLineStr for DevInfoType ("
<< RocmSMI::devInfoTypesStrings.at(type) << ")"
<< ", but contained no string lines";
LOG_INFO(ss);
return 0;
}
// Remove any *trailing* empty (whitespace) lines
@@ -763,6 +859,23 @@ int Device::readDevInfoMultiLineStr(DevInfoTypes type,
retVec->back().find_first_not_of(" \t\n\v\f\r") == std::string::npos) {
retVec->pop_back();
}
// allow logging output of multiline strings
for (auto l: *retVec) {
allLines += "\n" + l;
}
if (!allLines.empty()) {
ss << "Successfully read devInfoMultiLineStr for DevInfoType ("
<< RocmSMI::devInfoTypesStrings.at(type) << ") "
<< ", returning lines read = " << allLines;
LOG_INFO(ss);
} else {
ss << "Read devInfoMultiLineStr for DevInfoType ("
<< RocmSMI::devInfoTypesStrings.at(type) << ")"
<< ", but lines were empty";
LOG_INFO(ss);
}
return 0;
}
@@ -794,6 +907,7 @@ int Device::readDevInfo(DevInfoTypes type, uint64_t *val) {
case kDevUsage:
case kDevOverDriveLevel:
case kDevMemOverDriveLevel:
case kDevMemTotGTT:
case kDevMemTotVisVRAM:
case kDevMemTotVRAM:
@@ -907,6 +1021,7 @@ int Device::readDevInfo(DevInfoTypes type, std::string *val) {
case kDevPerfLevel:
case kDevUsage:
case kDevOverDriveLevel:
case kDevMemOverDriveLevel:
case kDevDevProdName:
case kDevDevProdNum:
case kDevDevID:
@@ -917,6 +1032,9 @@ int Device::readDevInfo(DevInfoTypes type, std::string *val) {
case kDevVBiosVer:
case kDevPCIEThruPut:
case kDevSerialNumber:
case kDevAvailableComputePartition:
case kDevComputePartition:
case kDevMemoryPartition:
return readDevInfoStr(type, val);
break;
@@ -1097,6 +1215,166 @@ bool Device::DeviceAPISupported(std::string name, uint64_t variant,
return false;
}
rsmi_status_t Device::restartAMDGpuDriver(void) {
REQUIRE_ROOT_ACCESS
bool restartSuccessful = true;
bool success = false;
std::string out = "";
bool wasGdmServiceActive = false;
// sudo systemctl is-active gdm
// we do not care about the success of checking if gdm is active
std::tie(success, out) = executeCommand("systemctl is-active gdm");
(out == "active") ? (restartSuccessful &= success) :
(restartSuccessful = true);
// if gdm is active -> sudo systemctl stop gdm
// TODO: are are there other display manager's we need to take into account?
// see https://en.wikipedia.org/wiki/GNOME_Display_Manager
if (success && (out == "active")) {
wasGdmServiceActive = true;
std::tie(success, out) = executeCommand("systemctl stop gdm&", false);
restartSuccessful &= success;
}
// sudo modprobe -r amdgpu
// sudo modprobe amdgpu
std::tie(success, out) =
executeCommand("modprobe -r amdgpu && modprobe amdgpu&", false);
restartSuccessful &= success;
// if gdm was active -> sudo systemctl start gdm
if (wasGdmServiceActive) {
std::tie(success, out) = executeCommand("systemctl start gdm&", false);
restartSuccessful &= success;
}
return (restartSuccessful ? RSMI_STATUS_SUCCESS :
RSMI_STATUS_AMDGPU_RESTART_ERR);
}
template <typename T> rsmi_status_t storeParameter(uint32_t dv_ind);
// Stores parameters depending on which rsmi type is provided.
// Uses template specialization, to restrict types to identify
// calls needed to complete the function.
// typename - restricted to
// rsmi_compute_partition_type_t or rsmi_compute_partition_type_t
// dv_ind - device index
// tempFileName - base file name
template <>
rsmi_status_t storeParameter<rsmi_compute_partition_type_t>(uint32_t dv_ind) {
rsmi_status_t returnStatus = RSMI_STATUS_SUCCESS;
bool doesFileExist;
std::tie(doesFileExist, std::ignore) = readTmpFile(dv_ind, "boot",
"compute_partition");
// if temporary file exists -> we do not need to store anything new
// if not, read & store the state value
if (doesFileExist) {
return returnStatus;
}
uint32_t length = 128;
char data[length];
rsmi_status_t ret = rsmi_dev_compute_partition_get(dv_ind, data, length);
rsmi_status_t storeRet;
if (ret == RSMI_STATUS_SUCCESS) {
storeRet = storeTmpFile(dv_ind, "compute_partition", "boot", data);
} else if (ret == RSMI_STATUS_NOT_SUPPORTED) {
// not supported is ok
storeRet = storeTmpFile(dv_ind, "compute_partition", "boot", "UNKNOWN");
} else {
storeRet = storeTmpFile(dv_ind, "compute_partition", "boot", "UNKNOWN");
returnStatus = ret;
}
if (storeRet != RSMI_STATUS_SUCCESS) {
// file storage err takes precedence over other errors
returnStatus = storeRet;
}
return returnStatus;
}
// Stores parameters depending on which rsmi type is provided.
// Uses template specialization, to restrict types to identify
// calls needed to complete the function.
// typename - restricted to
// rsmi_compute_partition_type_t or rsmi_compute_partition_type_t
// dv_ind - device index
// tempFileName - base file name
template <> rsmi_status_t storeParameter<rsmi_nps_mode_type_t>(uint32_t dv_ind) {
rsmi_status_t returnStatus = RSMI_STATUS_SUCCESS;
uint32_t length = 128;
char data[length];
bool doesFileExist;
std::tie(doesFileExist, std::ignore) = readTmpFile(dv_ind, "boot",
"nps_mode");
// if temporary file exists -> we do not need to store anything new
// if not, read & store the state value
if (doesFileExist) {
return returnStatus;
}
rsmi_status_t ret = rsmi_dev_nps_mode_get(dv_ind, data, length);
rsmi_status_t storeRet;
if (ret == RSMI_STATUS_SUCCESS) {
storeRet = storeTmpFile(dv_ind, "nps_mode", "boot", data);
} else if (ret == RSMI_STATUS_NOT_SUPPORTED) {
// not supported is ok
storeRet = storeTmpFile(dv_ind, "nps_mode", "boot", "UNKNOWN");
} else {
storeRet = storeTmpFile(dv_ind, "nps_mode", "boot", "UNKNOWN");
returnStatus = ret;
}
if (storeRet != RSMI_STATUS_SUCCESS) {
// file storage err takes precedence over other errors
returnStatus = storeRet;
}
return returnStatus;
}
rsmi_status_t Device::storeDevicePartitions(uint32_t dv_ind) {
rsmi_status_t returnStatus = RSMI_STATUS_SUCCESS;
returnStatus = storeParameter<rsmi_compute_partition_type_t>(dv_ind);
rsmi_status_t npsRet = storeParameter<rsmi_nps_mode_type_t>(dv_ind);
if (returnStatus == RSMI_STATUS_SUCCESS) { // only record earliest error
returnStatus = npsRet;
}
return returnStatus;
}
// Reads a device's boot partition state, depending on which rsmi type is
// provided and device index.
// Uses template specialization, to restrict types to identify
// calls needed to complete the function.
// typename - restricted to rsmi_compute_partition_type_t
// or rsmi_compute_partition_type_t
// dv_ind - device index
template <>
std::string Device::readBootPartitionState<rsmi_compute_partition_type_t>(
uint32_t dv_ind) {
std::string boot_state;
std::tie(std::ignore, boot_state) = readTmpFile(dv_ind, "boot",
"compute_partition");
return boot_state;
}
// Reads a device's boot partition state, depending on which rsmi type is
// provided and device index.
// Uses template specialization, to restrict types to identify
// calls needed to complete the function.
// typename - restricted to rsmi_compute_partition_type_t
// or rsmi_compute_partition_type_t
// dv_ind - device index
template <>
std::string Device::readBootPartitionState<rsmi_nps_mode_type_t>(
uint32_t dv_ind) {
std::string boot_state;
std::tie(std::ignore, boot_state) = readTmpFile(dv_ind, "boot", "nps_mode");
return boot_state;
}
#undef RET_IF_NONZERO
} // namespace smi
} // namespace amd
+3 -2
View File
@@ -3,7 +3,7 @@
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2021, Advanced Micro Devices, Inc.
* Copyright (c) 2017-2023, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
@@ -54,6 +54,7 @@
#include <regex> // NOLINT
#include <vector>
#include <pthread.h>
#include <string.h>
#include "rocm_smi/rocm_smi_common.h" // Should go before rocm_smi.h
#include "rocm_smi/rocm_smi_main.h"
@@ -281,7 +282,7 @@ rsmi_dev_gpu_metrics_info_get(uint32_t dv_ind, rsmi_gpu_metrics_t *smu) {
return RSMI_STATUS_NOT_SUPPORTED;
}
// Initialize the smu fiedls to zero as some of them only valid in
// Initialize the smu fields to zero as some of them only valid in
// a specific version.
*smu = {};
+3
View File
@@ -484,6 +484,7 @@ int GetProcessInfoForPID(uint32_t pid, rsmi_process_info_t *proc,
cu_occupancy_path += "/stats_";
cu_occupancy_path += std::to_string(gpu_id);
cu_occupancy_path += "/cu_occupancy";
err = ReadSysfsStr(cu_occupancy_path, &tmp);
if (err == 0) {
if (!is_number(tmp)) {
@@ -494,6 +495,8 @@ int GetProcessInfoForPID(uint32_t pid, rsmi_process_info_t *proc,
// Collect count of compute units
cu_count += kfd_node_map[gpu_id]->cu_count();
} else {
return err;
}
}
+487
View File
@@ -0,0 +1,487 @@
/*
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2023, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
* Detail Description:
* Implemented complete logging mechanism, supporting multiple logging type
* like as file based logging, console base logging etc. It also supported
* for different log types.
*
* Thread Safe logging mechanism. Compatible with G++ (Linux platform)
*
* Supported Log Type: ERROR, ALARM, ALWAYS, INFO, BUFFER, TRACE, DEBUG
* No control for ERROR, ALRAM and ALWAYS messages. These type of messages
* should be always captured -- IF logging is enabled.
*
* WARNING: Logging is controlled by users environment variable - RSMI_LOGGING.
* Enabling RSMI_LOGGING, by export RSMI_LOGGING=<any value>. No logs will
* be printed, unless RSMI_LOGGING is enabled.
*
* BUFFER log type should be use while logging raw buffer or raw messages
* Having direct interface as well as C++ Singleton inface. Can use
* whatever interface fits your needs.
*/
// C++ Header File(s)
#include <cstdlib>
#include <chrono>
#include <ctime>
#include <iomanip>
#include <iostream>
#include <sstream>
// Code Specific Header Files(s)
#include "rocm_smi/rocm_smi_logger.h"
#include "rocm_smi/rocm_smi_main.h"
#include "rocm_smi/rocm_smi_utils.h"
using namespace ROCmLogging;
Logger* Logger::m_Instance = nullptr;
// Log file name
// WARNING: File name should be changed here and
// pre/post install/remove/upgrade scripts. Changing
// in one place will cause a mismatch in these scripts,
// files may not have proper permissions, and logrotate
// would not function properly.
const std::string logPath = "/var/log/amd_smi_lib/";
const std::string logBaseFName = "AMD-SMI-lib";
const std::string logExtension = ".log";
const std::string logFileName = logPath + logBaseFName + logExtension;
Logger::Logger() {
initialize_resources();
}
Logger::~Logger() {
if (m_loggingIsOn) {
destroy_resources();
}
}
Logger* Logger::getInstance() throw() {
if (m_Instance == nullptr) {
m_Instance = new Logger();
}
return m_Instance;
}
void Logger::lock() {
m_Lock.lock();
}
void Logger::unlock() {
m_Lock.unlock();
}
void Logger::logIntoFile(std::string& data) {
lock();
if(!m_File.is_open()) {
initialize_resources();
if (!m_File.is_open()) {
std::cout << "WARNING: re-initializing resources was unsuccessfull."
<<" Unable to print the following message." << std::endl;
logOnConsole(data);
unlock();
return;
}
}
m_File << getCurrentTime() << " " << data << std::endl;
unlock();
}
void Logger::logOnConsole(std::string& data) {
std::cout << getCurrentTime() << " " << data << std::endl;
}
// Returns: In string format, YY-MM-DD HH:MM:SS.microseconds
std::string Logger::getCurrentTime(void) {
using namespace std::chrono;
std::string currentTime;
// get current time
auto now = system_clock::now();
// get number of milliseconds for the current second
// (remainder after division into seconds)
auto ms = duration_cast<microseconds>(now.time_since_epoch()) % 1000000;
// convert to std::time_t in order to convert to std::tm (broken time)
auto timer = system_clock::to_time_t(now);
// convert to broken time
std::tm bt = *std::localtime(&timer);
std::ostringstream oss;
// YY-MM-DD HH:MM:SS.microseconds
oss << std::put_time(&bt, "%F %T");
oss << '.' << std::setfill('0') << std::setw(4) << ms.count();
currentTime = oss.str();
return currentTime;
}
// Interface for Error Log
void Logger::error(const char* text) throw() {
// By default, logging is disabled
// The check below allows us to toggle logging through RSMI_LOGGING
// set or unset
if (m_loggingIsOn == false) {
return;
}
std::string data;
data.append("[ERROR]: ");
data.append(text);
// ERROR must be capture
if (m_LogType == FILE_LOG) {
logIntoFile(data);
} else if (m_LogType == CONSOLE) {
logOnConsole(data);
}
}
void Logger::error(std::string& text) throw() {
error(text.data());
}
void Logger::error(std::ostringstream& stream) throw() {
std::string text = stream.str();
error(text.data());
stream.str("");
}
// Interface for Alarm Log
void Logger::alarm(const char* text) throw() {
// By default, logging is disabled (ie. no RSMI_LOGGING)
// The check below allows us to toggle logging through RSMI_LOGGING
// set or unset
if (m_loggingIsOn == false) {
return;
}
std::string data;
data.append("[ALARM]: ");
data.append(text);
// ALARM must be capture
if (m_LogType == FILE_LOG) {
logIntoFile(data);
} else if (m_LogType == CONSOLE) {
logOnConsole(data);
}
}
void Logger::alarm(std::string& text) throw() {
alarm(text.data());
}
void Logger::alarm(std::ostringstream& stream) throw() {
std::string text = stream.str();
alarm(text.data());
stream.str("");
}
// Interface for Always Log
void Logger::always(const char* text) throw() {
// By default, logging is disabled (ie. no RSMI_LOGGING)
// The check below allows us to toggle logging through RSMI_LOGGING
// set or unset
if (m_loggingIsOn == false) {
return;
}
std::string data;
data.append("[ALWAYS]: ");
data.append(text);
// No check for ALWAYS logs
if (m_LogType == FILE_LOG) {
logIntoFile(data);
} else if (m_LogType == CONSOLE) {
logOnConsole(data);
}
}
void Logger::always(std::string& text) throw() {
always(text.data());
}
void Logger::always(std::ostringstream& stream) throw() {
std::string text = stream.str();
always(text.data());
stream.str("");
}
// Interface for Buffer Log
void Logger::buffer(const char* text) throw() {
// Buffer is the special case. So don't add log level
// and timestamp in the buffer message. Just log the raw bytes.
if ((m_LogType == FILE_LOG) && (m_LogLevel >= LOG_LEVEL_BUFFER)) {
lock();
if(!m_File.is_open()) {
initialize_resources();
if (!m_File.is_open()) {
std::cout << "WARNING: re-initializing resources was unsuccessfull."
<<" Unable to print the following message." << std::endl;
std::string txtStr(text);
std::cout << txtStr << std::endl;
unlock();
return;
}
}
m_File << text << std::endl;
unlock();
} else if ((m_LogType == CONSOLE) && (m_LogLevel >= LOG_LEVEL_BUFFER)) {
std::cout << text << std::endl;
}
}
void Logger::buffer(std::string& text) throw() {
buffer(text.data());
}
void Logger::buffer(std::ostringstream& stream) throw() {
std::string text = stream.str();
buffer(text.data());
stream.str("");
}
// Interface for Info Log
void Logger::info(const char* text) throw() {
// By default, logging is disabled (ie. no RSMI_LOGGING)
// The check below allows us to toggle logging through RSMI_LOGGING
// set or unset
if (m_loggingIsOn == false) {
return;
}
std::string data;
data.append("[INFO]: ");
data.append(text);
if ((m_LogType == FILE_LOG) && (m_LogLevel >= LOG_LEVEL_INFO)) {
logIntoFile(data);
} else if ((m_LogType == CONSOLE) && (m_LogLevel >= LOG_LEVEL_INFO)) {
logOnConsole(data);
}
}
void Logger::info(std::string& text) throw() {
info(text.data());
}
void Logger::info(std::ostringstream& stream) throw() {
std::string text = stream.str();
info(text.data());
stream.str("");
}
// Interface for Trace Log
void Logger::trace(const char* text) throw() {
// By default, logging is disabled (ie. no RSMI_LOGGING)
// The check below allows us to toggle logging through RSMI_LOGGING
// set or unset
if (m_loggingIsOn == false) {
return;
}
std::string data;
data.append("[TRACE]: ");
data.append(text);
if ((m_LogType == FILE_LOG) && (m_LogLevel >= LOG_LEVEL_TRACE)) {
logIntoFile(data);
} else if ((m_LogType == CONSOLE) && (m_LogLevel >= LOG_LEVEL_TRACE)) {
logOnConsole(data);
}
}
void Logger::trace(std::string& text) throw() {
trace(text.data());
}
void Logger::trace(std::ostringstream& stream) throw() {
std::string text = stream.str();
trace(text.data());
stream.str("");
}
// Interface for Debug Log
void Logger::debug(const char* text) throw() {
// By default, logging is disabled (ie. no RSMI_LOGGING)
// The check below allows us to toggle logging through RSMI_LOGGING
// set or unset
if (m_loggingIsOn == false) {
return;
}
std::string data;
data.append("[DEBUG]: ");
data.append(text);
if ((m_LogType == FILE_LOG) && (m_LogLevel >= LOG_LEVEL_DEBUG)) {
logIntoFile(data);
} else if ((m_LogType == CONSOLE) && (m_LogLevel >= LOG_LEVEL_DEBUG)) {
logOnConsole(data);
}
}
void Logger::debug(std::string& text) throw() {
debug(text.data());
}
void Logger::debug(std::ostringstream& stream) throw() {
std::string text = stream.str();
debug(text.data());
stream.str("");
}
// Interfaces to control log levels
void Logger::updateLogLevel(LogLevel logLevel) {
m_LogLevel = logLevel;
}
void Logger::enableAllLogLevels() {
m_LogLevel = ENABLE_LOG;
}
// Disable all log levels, except error and alarm
void Logger::disableLog() {
m_LogLevel = DISABLE_LOG;
}
// Interfaces to control log Types
void Logger::updateLogType(LogType logType) {
m_LogType = logType;
}
void Logger::enableConsoleLogging() {
m_LogType = CONSOLE;
}
void Logger::enableFileLogging() {
m_LogType = FILE_LOG;
}
// Returns a string of details on current log settings
std::string Logger::getLogSettings() {
std::string logSettings = "";
if (m_File.is_open()) {
logSettings += "OpenStatus = File (" + logFileName + ") is open";
} else {
logSettings += "OpenStatus = File (" + logFileName + ") is not open";
}
logSettings += ", ";
switch (m_LogType) {
case NO_LOG:
logSettings += "LogType = NO_LOG";
break;
case FILE_LOG:
logSettings += "LogType = FILE_LOG";
break;
case CONSOLE:
logSettings += "LogType = CONSOLE";
break;
default:
logSettings += "LogType = <undefined>";
}
logSettings += ", ";
switch (m_LogLevel) {
case DISABLE_LOG:
logSettings += "LogLevel = DISABLE_LOG";
break;
case LOG_LEVEL_INFO:
logSettings += "LogLevel = LOG_LEVEL_INFO";
break;
case LOG_LEVEL_BUFFER:
logSettings += "LogLevel = LOG_LEVEL_BUFFER";
break;
case LOG_LEVEL_TRACE:
logSettings += "LogLevel = LOG_LEVEL_TRACE";
break;
case LOG_LEVEL_DEBUG:
logSettings += "LogLevel = LOG_LEVEL_DEBUG";
break;
case ENABLE_LOG:
logSettings += "LogLevel = ENABLE_LOG";
break;
default:
logSettings += "LogLevel = <undefined>";
}
return logSettings;
}
// Returns current reported enabled logging state. State is controlled by
// user's environment variable RSMI_LOGGING.
bool Logger::isLoggerEnabled() {
return m_loggingIsOn;
}
void Logger::initialize_resources() {
// By default, logging is disabled (ie. no RSMI_LOGGING)
// The check below allows us to toggle logging through RSMI_LOGGING
// set or unset
m_loggingIsOn = amd::smi::RocmSMI::getInstance().isLoggingOn();
if (m_loggingIsOn == false) {
return;
}
m_File.open(logFileName.c_str(), std::ios::out | std::ios::app);
m_LogLevel = LOG_LEVEL_TRACE;
m_LogType = FILE_LOG;
if (!m_File.is_open()) {
std::cout << "WARNING: Issue opening log file (" << logFileName
<< ") to write." << std::endl;
}
if (m_File.fail()) {
std::cout << "WARNING: Failed opening log file." << std::endl;
}
chmod(logFileName.c_str(), S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR|S_IWGRP|S_IWOTH);
}
void Logger::destroy_resources() {
m_File.close();
}
+195 -16
View File
@@ -2,7 +2,7 @@
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2017, Advanced Micro Devices, Inc.
* Copyright (c) 2017-2023, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
@@ -57,6 +57,7 @@
#include <cerrno>
#include <unordered_map>
#include <iostream>
#include <sstream>
#include "rocm_smi/rocm_smi.h"
#include "rocm_smi/rocm_smi_device.h"
@@ -64,6 +65,9 @@
#include "rocm_smi/rocm_smi_exception.h"
#include "rocm_smi/rocm_smi_utils.h"
#include "rocm_smi/rocm_smi_kfd.h"
#include "rocm_smi/rocm_smi_logger.h"
using namespace ROCmLogging;
static const char *kPathDRMRoot = "/sys/class/drm";
static const char *kPathHWMonRoot = "/sys/class/hwmon";
@@ -73,6 +77,81 @@ static const char *kDeviceNamePrefix = "card";
static const char *kAMDMonitorTypes[] = {"radeon", "amdgpu", ""};
static const std::string amdSMI = "amd::smi::";
const std::map<amd::smi::DevInfoTypes, std::string>
amd::smi::RocmSMI::devInfoTypesStrings = {
{amd::smi::kDevPerfLevel, amdSMI + "kDevPerfLevel"},
{amd::smi::kDevOverDriveLevel, amdSMI + "kDevOverDriveLevel"},
{amd::smi::kDevMemOverDriveLevel, amdSMI + "kDevMemOverDriveLevel"},
{amd::smi::kDevDevID, amdSMI + "kDevDevID"},
{amd::smi::kDevDevProdName, amdSMI + "kDevDevProdName"},
{amd::smi::kDevDevProdNum, amdSMI + "kDevDevProdNum"},
{amd::smi::kDevVendorID, amdSMI + "kDevVendorID"},
{amd::smi::kDevSubSysDevID, amdSMI + "kDevSubSysDevID"},
{amd::smi::kDevSubSysVendorID, amdSMI + "kDevSubSysVendorID"},
{amd::smi::kDevGPUMClk, amdSMI + "kDevGPUMClk"},
{amd::smi::kDevGPUSClk, amdSMI + "kDevGPUSClk"},
{amd::smi::kDevDCEFClk, amdSMI + "kDevDCEFClk"},
{amd::smi::kDevFClk, amdSMI + "kDevFClk"},
{amd::smi::kDevSOCClk, amdSMI + "kDevSOCClk"},
{amd::smi::kDevPCIEClk, amdSMI + "kDevPCIEClk"},
{amd::smi::kDevPowerProfileMode, amdSMI + "kDevPowerProfileMode"},
{amd::smi::kDevUsage, amdSMI + "kDevUsage"},
{amd::smi::kDevPowerODVoltage, amdSMI + "kDevPowerODVoltage"},
{amd::smi::kDevVBiosVer, amdSMI + "kDevVBiosVer"},
{amd::smi::kDevPCIEThruPut, amdSMI + "kDevPCIEThruPut"},
{amd::smi::kDevErrCntSDMA, amdSMI + "kDevErrCntSDMA"},
{amd::smi::kDevErrCntUMC, amdSMI + "kDevErrCntUMC"},
{amd::smi::kDevErrCntGFX, amdSMI + "kDevErrCntGFX"},
{amd::smi::kDevErrCntMMHUB, amdSMI + "kDevErrCntMMHUB"},
{amd::smi::kDevErrCntPCIEBIF, amdSMI + "kDevErrCntPCIEBIF"},
{amd::smi::kDevErrCntHDP, amdSMI + "kDevErrCntHDP"},
{amd::smi::kDevErrCntXGMIWAFL, amdSMI + "kDevErrCntXGMIWAFL"},
{amd::smi::kDevErrCntFeatures, amdSMI + "kDevErrCntFeatures"},
{amd::smi::kDevMemTotGTT, amdSMI + "kDevMemTotGTT"},
{amd::smi::kDevMemTotVisVRAM, amdSMI + "kDevMemTotVisVRAM"},
{amd::smi::kDevMemTotVRAM, amdSMI + "kDevMemTotVRAM"},
{amd::smi::kDevMemUsedGTT, amdSMI + "kDevMemUsedGTT"},
{amd::smi::kDevMemUsedVisVRAM, amdSMI + "kDevMemUsedVisVRAM"},
{amd::smi::kDevMemUsedVRAM, amdSMI + "kDevMemUsedVRAM"},
{amd::smi::kDevVramVendor, amdSMI + "kDevVramVendor"},
{amd::smi::kDevPCIEReplayCount, amdSMI + "kDevPCIEReplayCount"},
{amd::smi::kDevUniqueId, amdSMI + "kDevUniqueId"},
{amd::smi::kDevDFCountersAvailable, amdSMI + "kDevDFCountersAvailable"},
{amd::smi::kDevMemBusyPercent, amdSMI + "kDevMemBusyPercent"},
{amd::smi::kDevXGMIError, amdSMI + "kDevXGMIError"},
{amd::smi::kDevFwVersionAsd, amdSMI + "kDevFwVersionAsd"},
{amd::smi::kDevFwVersionCe, amdSMI + "kDevFwVersionCe"},
{amd::smi::kDevFwVersionDmcu, amdSMI + "kDevFwVersionDmcu"},
{amd::smi::kDevFwVersionMc, amdSMI + "kDevFwVersionMc"},
{amd::smi::kDevFwVersionMe, amdSMI + "kDevFwVersionMe"},
{amd::smi::kDevFwVersionMec, amdSMI + "kDevFwVersionMec"},
{amd::smi::kDevFwVersionMec2, amdSMI + "kDevFwVersionMec2"},
{amd::smi::kDevFwVersionPfp, amdSMI + "kDevFwVersionPfp"},
{amd::smi::kDevFwVersionRlc, amdSMI + "kDevFwVersionRlc"},
{amd::smi::kDevFwVersionRlcSrlc, amdSMI + "kDevFwVersionRlcSrlc"},
{amd::smi::kDevFwVersionRlcSrlg, amdSMI + "kDevFwVersionRlcSrlg"},
{amd::smi::kDevFwVersionRlcSrls, amdSMI + "kDevFwVersionRlcSrls"},
{amd::smi::kDevFwVersionSdma, amdSMI + "kDevFwVersionSdma"},
{amd::smi::kDevFwVersionSdma2, amdSMI + "kDevFwVersionSdma2"},
{amd::smi::kDevFwVersionSmc, amdSMI + "kDevFwVersionSmc"},
{amd::smi::kDevFwVersionSos, amdSMI + "kDevFwVersionSos"},
{amd::smi::kDevFwVersionTaRas, amdSMI + "kDevFwVersionTaRas"},
{amd::smi::kDevFwVersionTaXgmi, amdSMI + "kDevFwVersionTaXgmi"},
{amd::smi::kDevFwVersionUvd, amdSMI + "kDevFwVersionUvd"},
{amd::smi::kDevFwVersionVce, amdSMI + "kDevFwVersionVce"},
{amd::smi::kDevFwVersionVcn, amdSMI + "kDevFwVersionVcn"},
{amd::smi::kDevSerialNumber, amdSMI + "kDevSerialNumber"},
{amd::smi::kDevMemPageBad, amdSMI + "kDevMemPageBad"},
{amd::smi::kDevNumaNode, amdSMI + "kDevNumaNode"},
{amd::smi::kDevGpuMetrics, amdSMI + "kDevGpuMetrics"},
{amd::smi::kDevGpuReset, amdSMI + "kDevGpuReset"},
{amd::smi::kDevAvailableComputePartition, amdSMI +
"kDevAvailableComputePartition"},
{amd::smi::kDevComputePartition, amdSMI + "kDevComputePartition"},
{amd::smi::kDevMemoryPartition, amdSMI + "kDevMemoryPartition"}
};
namespace amd {
namespace smi {
@@ -179,18 +258,21 @@ static bool bdfid_from_path(const std::string in_name, uint64_t *bdfid) {
return true;
}
// 0 = successful bdfid found
// 1 = not a good bdfid found
static uint32_t ConstructBDFID(std::string path, uint64_t *bdfid) {
assert(bdfid != nullptr);
char tpath[256] = {'\0'};
const unsigned int MAX_BDF_LENGTH = 512;
char tpath[MAX_BDF_LENGTH] = {'\0'};
ssize_t ret;
memset(tpath,0,256);
memset(tpath,0,MAX_BDF_LENGTH);
ret = readlink(path.c_str(), tpath, 256);
ret = readlink(path.c_str(), tpath, MAX_BDF_LENGTH);
assert(ret > 0);
assert(ret < 256);
assert(ret < MAX_BDF_LENGTH);
if (ret <= 0 || ret >= 256) {
if (ret <= 0 || ret >= MAX_BDF_LENGTH) {
return 1;
}
@@ -221,6 +303,16 @@ RocmSMI::Initialize(uint64_t flags) {
uint32_t ret;
int i_ret;
LOG_ALWAYS("=============== ROCM SMI initialize ================");
Logger::getInstance()->enableAllLogLevels();
// Leaving below to allow developers to check current log settings
// std::string logSettings = Logger::getInstance()->getLogSettings();
// std::cout << "Current log settings:\n" << logSettings << std::endl;
if (Logger::getInstance()->isLoggerEnabled()) {
logSystemDetails();
}
assert(ref_count_ == 1);
if (ref_count_ != 1) {
throw amd::smi::rsmi_exception(RSMI_INITIALIZATION_ERROR,
@@ -232,8 +324,8 @@ RocmSMI::Initialize(uint64_t flags) {
euid_ = geteuid();
GetEnvVariables();
while (env_vars_.debug_inf_loop) {}
// To help debug env variable issues
// printEnvVarInfo();
while (std::string(kAMDMonitorTypes[i]) != "") {
amd_monitor_types_.insert(kAMDMonitorTypes[i]);
@@ -253,8 +345,9 @@ RocmSMI::Initialize(uint64_t flags) {
if (ConstructBDFID(devices_[i]->path(), &bdfid) != 0) {
std::cerr << "Failed to construct BDFID." << std::endl;
ret = 1;
} else {
devices_[i]->set_bdfid(bdfid);
}
devices_[i]->set_bdfid(bdfid);
}
if (ret != 0) {
throw amd::smi::rsmi_exception(RSMI_INITIALIZATION_ERROR,
@@ -296,6 +389,7 @@ RocmSMI::Initialize(uint64_t flags) {
// 1. construct kfd_node_map_ with gpu_id as key and *Device as value
// 2. for each kfd node, write the corresponding dv_ind
// 3. for each amdgpu device, write the corresponding gpu_id
// 4. for each amdgpu device, attempt to store it's boot partition
for (uint32_t dv_ind = 0; dv_ind < devices_.size(); ++dv_ind) {
dev = devices_[dv_ind];
uint64_t bdfid = dev->bdfid();
@@ -310,7 +404,12 @@ RocmSMI::Initialize(uint64_t flags) {
uint64_t gpu_id = tmp_map[bdfid]->gpu_id();
dev->set_kfd_gpu_id(gpu_id);
kfd_node_map_[gpu_id] = tmp_map[bdfid];
// store each device boot partition state, if file doesn't exist
dev->storeDevicePartitions(dv_ind);
}
// Leaving below to help debug temp file issues
// displayAppTmpFilesContent();
}
void
@@ -356,23 +455,61 @@ static uint32_t GetEnvVarUInteger(const char *ev_str) {
return 0;
}
// provides a way to get env variable detail in both debug & release
// helps enable full logging
static bool getRSMIEnvVar_LoggingEnabled(const char *ev_str) {
bool isLoggingEnabled = false;
ev_str = getenv(ev_str);
if (ev_str != nullptr) {
isLoggingEnabled = true;
}
return isLoggingEnabled;
}
static std::unordered_set<uint32_t> GetEnvVarUIntegerSets(const char *ev_str) {
std::unordered_set<uint32_t> returnSet;
#ifndef DEBUG
(void)ev_str;
#else
ev_str = getenv(ev_str);
if(ev_str == nullptr) { return returnSet; }
std::string stringEnv = ev_str;
if (stringEnv.empty() == false) {
// parse out values by commas
std::string parsedVal;
std::istringstream ev_str_ss(stringEnv);
while (std::getline(ev_str_ss, parsedVal, ',')) {
int parsedInt = std::stoi(parsedVal);
assert(parsedInt >= 0);
uint32_t parsedUInt = static_cast<uint32_t>(parsedInt);
returnSet.insert(parsedUInt);
}
}
#endif
return returnSet;
}
// Get and store env. variables in this method
void RocmSMI::GetEnvVariables(void) {
env_vars_.logging_on = getRSMIEnvVar_LoggingEnabled("RSMI_LOGGING");
#ifndef DEBUG
(void)GetEnvVarUInteger(nullptr); // This is to quiet release build warning.
env_vars_.debug_output_bitfield = 0;
env_vars_.path_DRM_root_override = nullptr;
env_vars_.path_HWMon_root_override = nullptr;
env_vars_.path_power_root_override = nullptr;
env_vars_.enum_override = 0;
env_vars_.debug_inf_loop = 0;
env_vars_.enum_overrides.clear();
#else
env_vars_.debug_output_bitfield = GetEnvVarUInteger("RSMI_DEBUG_BITFIELD");
env_vars_.path_DRM_root_override = getenv("RSMI_DEBUG_DRM_ROOT_OVERRIDE");
env_vars_.path_HWMon_root_override = getenv("RSMI_DEBUG_HWMON_ROOT_OVERRIDE");
env_vars_.path_power_root_override = getenv("RSMI_DEBUG_PP_ROOT_OVERRIDE");
env_vars_.enum_override = GetEnvVarUInteger("RSMI_DEBUG_ENUM_OVERRIDE");
env_vars_.debug_inf_loop = GetEnvVarUInteger("RSMI_DEBUG_INFINITE_LOOP");
env_vars_.enum_overrides = GetEnvVarUIntegerSets("RSMI_DEBUG_ENUM_OVERRIDE");
#endif
}
@@ -380,6 +517,53 @@ const RocmSMI_env_vars& RocmSMI::getEnv(void) {
return env_vars_;
}
bool RocmSMI::isLoggingOn(void) {
GetEnvVariables();
return this->env_vars_.logging_on;
}
void RocmSMI::printEnvVarInfo(void) {
std::cout << __PRETTY_FUNCTION__ << " | env_vars_.debug_output_bitfield = "
<< ((env_vars_.debug_output_bitfield == 0) ? "<undefined>"
: std::to_string(env_vars_.debug_output_bitfield))
<< std::endl;
std::cout << __PRETTY_FUNCTION__ << " | env_vars_.path_DRM_root_override = "
<< ((env_vars_.path_DRM_root_override == nullptr)
? "<undefined>" : env_vars_.path_DRM_root_override)
<< std::endl;
std::cout << __PRETTY_FUNCTION__ << " | env_vars_.path_HWMon_root_override = "
<< ((env_vars_.path_HWMon_root_override == nullptr)
? "<undefined>" : env_vars_.path_HWMon_root_override)
<< std::endl;
std::cout << __PRETTY_FUNCTION__ << " | env_vars_.path_power_root_override = "
<< ((env_vars_.path_power_root_override == nullptr)
? "<undefined>" : env_vars_.path_power_root_override)
<< std::endl;
std::cout << __PRETTY_FUNCTION__ << " | env_vars_.debug_inf_loop = "
<< ((env_vars_.debug_inf_loop == 0) ? "<undefined>"
: std::to_string(env_vars_.debug_inf_loop))
<< std::endl;
bool isLoggingOn = (env_vars_.logging_on) ? true : false;
std::cout << __PRETTY_FUNCTION__ << " | env_vars_.logging_on = "
<< (isLoggingOn ? "true" : "false") << std::endl;
std::cout << __PRETTY_FUNCTION__ << " | env_vars_.enum_overrides = {";
if (env_vars_.enum_overrides.empty()) {
std::cout << "}" << std::endl;
return;
}
for (auto it=env_vars_.enum_overrides.begin();
it != env_vars_.enum_overrides.end(); ++it) {
DevInfoTypes type = static_cast<DevInfoTypes>(*it);
std::cout << (std::to_string(*it) + " (" + devInfoTypesStrings.at(type)
+ ")");
auto temp_it = it;
if(++temp_it != env_vars_.enum_overrides.end()) {
std::cout << ", ";
}
}
std::cout << "}" << std::endl;
}
std::shared_ptr<Monitor>
RocmSMI::FindMonitor(std::string monitor_path) {
std::string tmp;
@@ -470,15 +654,10 @@ static const uint32_t kAmdGpuId = 0x1002;
static bool isAMDGPU(std::string dev_path) {
std::string vend_path = dev_path + "/device/vendor";
std::string vbios_v_path = dev_path + "/device/vbios_version";
if (!FileExists(vend_path.c_str())) {
return false;
}
if (!FileExists(vbios_v_path.c_str())) {
return false;
}
std::ifstream fs;
fs.open(vend_path);
+5 -1
View File
@@ -57,6 +57,9 @@
#include "rocm_smi/rocm_smi_monitor.h"
#include "rocm_smi/rocm_smi_utils.h"
#include "rocm_smi/rocm_smi_exception.h"
#include "rocm_smi/rocm_smi_logger.h"
using namespace ROCmLogging;
namespace amd {
namespace smi {
@@ -316,7 +319,8 @@ int Monitor::readMonitor(MonitorTypes type, uint32_t sensor_id,
std::string sysfs_path = MakeMonitorPath(type, sensor_id);
DBG_FILE_ERROR(sysfs_path, (std::string *)nullptr)
return ReadSysfsStr(sysfs_path, val);
int ret = ReadSysfsStr(sysfs_path, val);
return ret;
}
int32_t
+404 -1
View File
@@ -3,7 +3,7 @@
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2018, Advanced Micro Devices, Inc.
* Copyright (c) 2018-2023, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
@@ -43,23 +43,33 @@
#include <assert.h>
#include <errno.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <glob.h>
#include <sys/utsname.h>
#include <fstream>
#include <string>
#include <cstring>
#include <cstdint>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <vector>
#include <regex>
#include "rocm_smi/rocm_smi.h"
#include "rocm_smi/rocm_smi_utils.h"
#include "rocm_smi/rocm_smi_exception.h"
#include "rocm_smi/rocm_smi_main.h"
#include "rocm_smi/rocm_smi_device.h"
#include "rocm_smi/rocm_smi_logger.h"
using namespace ROCmLogging;
namespace amd {
namespace smi {
const std::string kTmpFilePrefix = "rocmsmi_";
// Return 0 if same file, 1 if not, and -1 for error
int SameFile(const std::string fileA, const std::string fileB) {
@@ -93,6 +103,54 @@ bool FileExists(char const *filename) {
return (stat(filename, &buf) == 0);
}
static void debugFilesDiscovered(std::vector<std::string> files) {
std::ostringstream ss;
int numberOfFilesFound = static_cast<int>(files.size());
ss << "fileName.size() = " << numberOfFilesFound
<< "; Files discovered = {";
if(numberOfFilesFound > 0) {
for (auto it = begin(files); it != end(files); ++it) {
auto nextElement = std::next(it);
if (nextElement != files.end()) {
ss << *it << ", ";
} else {
ss << *it;
}
}
} else {
ss << "<none>";
}
ss << "}";
LOG_DEBUG(ss);
}
// Input: string filePattern = can put in * file searches (see example)
// example: globFilesExist("/etc/*release")
// Return a vector containing file paths that matched
// You can obtain if files exist by doing globFilesExist(...).size() > 0
std::vector<std::string> globFilesExist(const std::string& filePattern) {
std::ostringstream ss;
std::vector<std::string> fileNames;
glob_t result_glob;
memset(&result_glob, 0, sizeof(result_glob));
if (glob(filePattern.c_str(), GLOB_TILDE, NULL, &result_glob) != 0) {
globfree(&result_glob);
// Leaving below to help debug issues discovering future glob file searches
// debugFilesDiscovered(fileNames);
return fileNames;
}
for(size_t i = 0; i < result_glob.gl_pathc; ++i) {
fileNames.push_back(std::string(result_glob.gl_pathv[i]));
}
globfree(&result_glob);
// Leaving below to help debug issues discovering future glob file searches
// debugFilesDiscovered(fileNames);
return fileNames;
}
int isRegularFile(std::string fname, bool *is_reg) {
struct stat file_stat;
int ret;
@@ -110,11 +168,16 @@ int isRegularFile(std::string fname, bool *is_reg) {
int WriteSysfsStr(std::string path, std::string val) {
std::ofstream fs;
int ret = 0;
std::ostringstream ss;
fs.open(path);
if (!fs.is_open()) {
ret = errno;
errno = 0;
ss << "Could not write/open SYSFS file (" << path << ") string = " << val
<< ", returning " << std::to_string(ret) << " ("
<< std::strerror(ret) << ")";
LOG_ERROR(ss);
return ret;
}
@@ -123,12 +186,15 @@ int WriteSysfsStr(std::string path, std::string val) {
if (!fs) {
return ENOENT; // Map to NOT_SUPPORT if errors
}
ss << "Successfully wrote to SYSFS file (" << path << ") string = " << val;
LOG_INFO(ss);
return ret;
}
int ReadSysfsStr(std::string path, std::string *retStr) {
std::stringstream ss;
int ret = 0;
std::ostringstream oss;
assert(retStr != nullptr);
@@ -138,6 +204,10 @@ int ReadSysfsStr(std::string path, std::string *retStr) {
if (!fs.is_open()) {
ret = errno;
errno = 0;
oss << "Could not read SYSFS file (" << path << ")"
<< ", returning " << std::to_string(ret) << " ("
<< std::strerror(ret) << ")";
LOG_ERROR(oss);
return ret;
}
ss << fs.rdbuf();
@@ -147,6 +217,9 @@ int ReadSysfsStr(std::string path, std::string *retStr) {
retStr->erase(std::remove(retStr->begin(), retStr->end(), '\n'),
retStr->end());
oss << "Successfully read SYSFS file (" << path << ")"
<< ", returning str = " << *retStr;
LOG_INFO(oss);
return ret;
}
@@ -256,5 +329,335 @@ bool is_vm_guest() {
return false;
}
std::string leftTrim(const std::string &s) {
if (!s.empty()) {
return std::regex_replace(s, std::regex("^\\s+"), "");
}
return s;
}
std::string rightTrim(const std::string &s) {
if (!s.empty()) {
return std::regex_replace(s, std::regex("\\s+$"), "");
}
return s;
}
std::string removeNewLines(const std::string &s) {
if (!s.empty()) {
return std::regex_replace(s, std::regex("\n+"), "");
}
return s;
}
std::string trim(const std::string &s) {
if (!s.empty()) {
// remove new lines -> trim white space at ends
std::string noNewLines = removeNewLines(s);
return leftTrim(rightTrim(noNewLines));
}
return s;
}
// Given original string and string to remove (removeMe)
// Return will provide the resulting modified string with the removed string(s)
std::string removeString(const std::string origStr,
const std::string &removeMe) {
std::string modifiedStr = origStr;
std::string::size_type l = removeMe.length();
for (std::string::size_type i = modifiedStr.find(removeMe);
i != std::string::npos;
i = modifiedStr.find(removeMe)) {
modifiedStr.erase(i, l);
}
return modifiedStr;
}
// defaults to trim stdOut
std::pair<bool, std::string> executeCommand(std::string command, bool stdOut) {
char buffer[128];
std::string stdoutAndErr = "";
bool successfulRun = true;
command = "stdbuf -i0 -o0 -e0 " + command; // remove stdOut and err buffering
FILE *pipe = popen(command.c_str(), "r");
if (!pipe) {
stdoutAndErr = "[ERROR] popen failed to call " + command;
successfulRun = false;
} else {
//read until end of process
while (!feof(pipe)) {
// use buffer to read and add to stdoutAndErr
if (fgets(buffer, sizeof(buffer), pipe) != nullptr) {
stdoutAndErr += buffer;
}
}
}
// any return code other than 0, is a failed execution
if (pclose(pipe) != 0) {
successfulRun = false;
}
if (stdOut) {
// remove leading and trailing spaces of output and new lines
stdoutAndErr = trim(stdoutAndErr);
}
return std::make_pair(successfulRun, stdoutAndErr);
}
// originalstring - string to search for substring
// substring - string looking to find
bool containsString(std::string originalString, std::string substring) {
if (originalString.find(substring) != std::string::npos) {
return true;
} else {
return false;
}
}
// Creates and stores supplied data into a temporary file (within /tmp/).
// All temporary files are removed upon reboot.
// Allows all users/groups to read the temporary file.
//
// For more detail, refer to mkstemp manpage:
// https://man7.org/linux/man-pages/man3/mkstemp.3.html
//
// Temporary file name format:
// <app prefix>_<state name>_<paramenter name>_<device id>
// <app prefix> - prefix for our application's identifier (see kTmpFilePrefix)
// <paramenter name> - name of parameter being stored
// <state name> - state at which the stored value captures
// <device index> - device identifier
//
// dv_ind - device index
// parameterName - name of parameter stored
// stateName - state at which the stored value captures
// storageData - string value of data to be stored
rsmi_status_t storeTmpFile(uint32_t dv_ind, std::string parameterName,
std::string stateName, std::string storageData) {
// Required tags needed to store our files
// Files name format:
// <app prefix>_<stateName>_<parameterName>_<device id>
std::string fullFileName = kTmpFilePrefix + stateName + "_" +
parameterName + "_" + std::to_string(dv_ind);
bool doesFileExist;
std::tie(doesFileExist, std::ignore) =
readTmpFile(dv_ind, stateName, parameterName);
if (doesFileExist) {
// do not store, if file already exists
return RSMI_STATUS_SUCCESS;
}
// template for our file
std::string fullTempFilePath = "/tmp/" + fullFileName + ".XXXXXX";
char *fileName = &fullTempFilePath[0];
int fd = mkstemp(fileName);
if (fd == -1) {
return RSMI_STATUS_FILE_ERROR;
}
chmod(fileName, S_IRUSR|S_IRGRP|S_IROTH);
write(fd, storageData.c_str(), storageData.size());
close(fd);
return RSMI_STATUS_SUCCESS;
}
std::vector<std::string> getListOfAppTmpFiles() {
std::string path = "/tmp";
DIR *dir;
struct dirent *ent;
std::vector<std::string> tmpFiles;
if ((dir = opendir(path.c_str())) != nullptr) {
// captures all files & directories under specified path
while ((ent = readdir(dir)) != nullptr) {
std::string fileDirName = ent->d_name;
// we only want our app specific files
if (containsString(fileDirName, kTmpFilePrefix)) {
tmpFiles.emplace_back(path + "/" + fileDirName);
} else {
continue;
}
}
}
return tmpFiles;
}
// Reads a file in path provided
// If file does not exist, returns an empty string
// If file exists, returns content (which could be an empty string)
std::string readFile(std::string path) {
std::string fileContent;
std::ifstream inFileStream(path);
if (inFileStream.is_open()) {
inFileStream >> fileContent;
}
return fileContent;
}
// Reads a file in path provided
// If file does not exist, returns an empty vector
// If file exists, returns content (each line put into a vector; which
// could be an empty string)
std::vector<std::string> readEntireFile(std::string path) {
std::vector<std::string> fileContent;
std::ifstream inFileStream(path);
if (inFileStream.is_open()) {
std::string line;
while (std::getline(inFileStream, line)) {
std::istringstream ss(line);
if(line.size() > 0) {
fileContent.push_back(line);
}
}
}
return fileContent;
}
// Used to debug application temporary files (identified by kTmpFilePrefix)
// and their content
void displayAppTmpFilesContent() {
std::vector<std::string> tmpFiles = getListOfAppTmpFiles();
if (tmpFiles.empty() == false) {
for (auto &x: tmpFiles) {
std::string out = readFile(x);
std::cout << __PRETTY_FUNCTION__ << " | Temporary file: " << x
<< "; Contained content: " << out << std::endl;
}
} else {
std::cout << __PRETTY_FUNCTION__ << " | No temporary files were found"
<< std::endl;
}
}
// Used to debug vector string list and their content
void displayVectorContent(std::vector<std::string> v) {
std::cout << "Vector = {";
if (v.size() > 0) {
for (auto it=v.begin(); it < v.end(); it++) {
std::cout << *it;
auto temp_it = it;
if(++temp_it != v.end()) {
std::cout << ", ";
}
}
} else {
std::cout << "}" << std::endl;
}
}
// Attempts to read application specific temporary file
// This method is to be used for reading (or determing if it exists),
// in order to keep file naming scheme consistent.
//
// dv_ind - device index
// parameterName - name of parameter stored
// stateName - state at which the stored value captures
// Returns:
// boolean - if temporary file exists
// string - content of temporary file, if it exists (otherwise, an empty
// string is returned)
std::tuple<bool, std::string> readTmpFile(uint32_t dv_ind,
std::string stateName,
std::string parameterName) {
bool fileExists = false;
std::string tmpFileName = kTmpFilePrefix + stateName + "_" +parameterName +
"_" + std::to_string(dv_ind);
std::string fileContent;
std::vector<std::string> tmpFiles = getListOfAppTmpFiles();
if (tmpFiles.empty() == false) {
for (auto &x: tmpFiles) {
if (containsString(x, tmpFileName)) {
fileContent = readFile(x);
fileExists = true;
break;
}
}
}
return std::make_tuple(fileExists, fileContent);
}
// wrapper to return string expression of a rsmi_status_t return
std::string getRSMIStatusString(rsmi_status_t ret) {
const char *err_str;
rsmi_status_string(ret, &err_str);
return std::string(err_str);
}
// Returns a tuple:
// boolean errorDetected = returns true, if error found retrieving system
// details
// string sysname = system name (os name)
// string nodename = name of the system's node on the network
// string release = os's release level
// string version = os's version level
// string machine = hardware type system is running on
// string domainName = domain name of the the system's node on the network
// string os_distribution = pretty name of os distribution
// (typically found in /etc/*-release file)
std::tuple<bool, std::string, std::string, std::string, std::string,
std::string, std::string, std::string> getSystemDetails(void) {
struct utsname buf;
bool errorDetected = false;
std::string temp_data;
std::string sysname, nodename, release, version, machine;
std::string domainName = "<undefined>";
std::string os_distribution = "<undefined>";
if (uname(&buf) < 0) {
errorDetected = true;
} else {
sysname = buf.sysname;
nodename = buf.nodename;
release = buf.release;
version = buf.version;
machine = buf.machine;
#ifdef _GNU_SOURCE
domainName = buf.domainname;
#endif
}
std::string filePath = "/etc/os-release";
bool fileExists = FileExists(filePath.c_str());
if (fileExists == true) {
std::vector<std::string> fileContent = readEntireFile(filePath);
for (auto &line: fileContent) {
if (line.find("PRETTY_NAME=") != std::string::npos) {
temp_data = removeString(line, "PRETTY_NAME=");
temp_data = removeString(temp_data, "\"");
os_distribution = temp_data;
break;
}
}
}
return std::make_tuple(errorDetected, sysname, nodename, release,
version, machine, domainName, os_distribution);
}
// If logging is enabled through RSMI_LOGGING environment variable.
// We display helpful system metrics for debug purposes.
void logSystemDetails(void) {
std::ostringstream ss;
bool errorDetected;
std::string sysname, node, release, version, machine, domain, distName;
std::tie(errorDetected, sysname, node, release, version, machine, domain,
distName) = getSystemDetails();
if (errorDetected == false) {
ss << "====== Gathered system details ============\n"
<< "SYSTEM NAME: " << sysname << "\n"
<< "OS DISTRIBUTION: " << distName << "\n"
<< "NODE NAME: " << node << "\n"
<< "RELEASE: " << release << "\n"
<< "VERSION: " << version << "\n"
<< "MACHINE TYPE: " << machine << "\n"
<< "DOMAIN: " << domain << "\n";
LOG_INFO(ss);
} else {
ss << "====== Gathered system details ============\n"
<< "Could not retrieve system details";
LOG_ERROR(ss);
}
}
} // namespace smi
} // namespace amd
+11 -5
View File
@@ -1444,11 +1444,11 @@ amdsmi_get_power_info(amdsmi_processor_handle processor_handle, amdsmi_power_inf
return status;
}
amdsmi_status_t
amdsmi_get_gpu_driver_version(amdsmi_processor_handle processor_handle, int *length, char *version) {
amdsmi_status_t amdsmi_get_gpu_driver_info(amdsmi_processor_handle processor_handle,
amdsmi_driver_info_t *info) {
AMDSMI_CHECK_INIT();
if (length == nullptr || version == nullptr) {
if (info == nullptr) {
return AMDSMI_STATUS_INVAL;
}
amdsmi_status_t status = AMDSMI_STATUS_SUCCESS;
@@ -1457,11 +1457,17 @@ amdsmi_get_gpu_driver_version(amdsmi_processor_handle processor_handle, int *len
if (r != AMDSMI_STATUS_SUCCESS)
return r;
status = smi_amdgpu_get_driver_version(gpu_device, length, version);
int length = AMDSMI_MAX_STRING_LENGTH;
status = smi_amdgpu_get_driver_version(gpu_device,
&length, info->driver_version);
std::string driver_date;
status = gpu_device->amdgpu_query_driver_date(driver_date);
if (status != AMDSMI_STATUS_SUCCESS) return r;
strncpy(info->driver_date, driver_date.c_str(), AMDSMI_MAX_STRING_LENGTH-1);
return status;
}
amdsmi_status_t
amdsmi_get_gpu_device_uuid(amdsmi_processor_handle processor_handle, unsigned int *uuid_length, char *uuid) {
AMDSMI_CHECK_INIT();
+17 -9
View File
@@ -44,7 +44,6 @@
#include <dirent.h>
#include <fcntl.h>
#include <unistd.h>
#include <xf86drm.h>
#include <string.h>
#include <memory>
#include <regex>
@@ -99,22 +98,19 @@ amdsmi_status_t AMDSmiDrm::init() {
return status;
}
using drmGetVersionType = drmVersionPtr (*)(int); // drmGetVersion
using drmFreeVersionType = void (*)(drmVersionPtr); // drmFreeVersion
using drmGetDeviceType = int(*)(int, drmDevicePtr*); // drmGetDevice
using drmFreeDeviceType = void(*)(drmDevicePtr*); // drmFreeDevice
drmGetVersionType drm_get_version = nullptr;
drmFreeVersionType drm_free_version = nullptr;
drmGetDeviceType drm_get_device = nullptr;
drmFreeDeviceType drm_free_device = nullptr;
drm_get_version_ = nullptr;
drm_free_version_ = nullptr;
status = lib_loader_.load_symbol(&drm_get_version, "drmGetVersion");
status = lib_loader_.load_symbol(&drm_get_version_, "drmGetVersion");
if (status != AMDSMI_STATUS_SUCCESS) {
return status;
}
status = lib_loader_.load_symbol(&drm_free_version, "drmFreeVersion");
status = lib_loader_.load_symbol(&drm_free_version_, "drmFreeVersion");
if (status != AMDSMI_STATUS_SUCCESS) {
return status;
}
@@ -155,7 +151,7 @@ amdsmi_status_t AMDSmiDrm::init() {
amdsmi_bdf_t bdf;
if (fd >= 0) {
auto version = drm_version_ptr(
drm_get_version(fd), drm_free_version);
drm_get_version_(fd), drm_free_version_);
if (strcmp("amdgpu", version->name)) { // only amdgpu
close(fd);
fd = -1;
@@ -201,6 +197,18 @@ amdsmi_status_t AMDSmiDrm::cleanup() {
return AMDSMI_STATUS_SUCCESS;
}
amdsmi_status_t AMDSmiDrm::amdgpu_query_driver_date(int fd, std::string& driver_date) {
// RAII handler
using drm_version_ptr = std::unique_ptr<drmVersion,
decltype(&drmFreeVersion)>;
std::lock_guard<std::mutex> guard(drm_mutex_);
auto version = drm_version_ptr(
drm_get_version_(fd), drm_free_version_);
if (version == nullptr) return AMDSMI_STATUS_DRM_ERROR;
driver_date = version->date;
return AMDSMI_STATUS_SUCCESS;
}
amdsmi_status_t AMDSmiDrm::amdgpu_query_info(int fd, unsigned info_id,
unsigned size, void *value) {
if (drm_cmd_write_ == nullptr) return AMDSMI_STATUS_NOT_SUPPORTED;
+9
View File
@@ -105,6 +105,15 @@ amdsmi_status_t AMDSmiGPUDevice::amdgpu_query_info(unsigned info_id,
return drm_.amdgpu_query_info(fd, info_id, size, value);
}
amdsmi_status_t AMDSmiGPUDevice::amdgpu_query_driver_date(std::string& date) const {
amdsmi_status_t ret;
uint32_t fd = 0;
ret = drm_.get_drm_fd_by_index(gpu_id_, &fd);
if (ret != AMDSMI_STATUS_SUCCESS) return AMDSMI_STATUS_NOT_SUPPORTED;
return drm_.amdgpu_query_driver_date(fd, date);
}
amdsmi_status_t AMDSmiGPUDevice::amdgpu_query_hw_ip(unsigned info_id,
unsigned hw_ip_type, unsigned size, void *value) const {
amdsmi_status_t ret;
+7 -9
View File
@@ -49,12 +49,8 @@ static const uint32_t kAmdGpuId = 0x1002;
static bool isAMDGPU(std::string dev_path) {
std::string vend_path = dev_path + "/device/vendor";
std::string vbios_v_path = dev_path + "/device/vbios_version";
if (!amd::smi::FileExists(vend_path.c_str())) {
return false;
}
if (!amd::smi::FileExists(vbios_v_path.c_str())) {
if (!amd::smi::FileExists(vend_path.c_str())) {
return false;
}
@@ -457,19 +453,21 @@ amdsmi_status_t smi_amdgpu_get_driver_version(amd::smi::AMDSmiGPUDevice* device,
amdsmi_status_t smi_amdgpu_get_pcie_speed_from_pcie_type(uint16_t pcie_type, uint32_t *pcie_speed)
{
switch (pcie_type) {
case 0:
case 1:
*pcie_speed = 2500;
break;
case 1:
case 2:
*pcie_speed = 5000;
break;
case 2:
case 3:
*pcie_speed = 8000;
break;
case 3:
case 4:
*pcie_speed = 16000;
break;
case 5:
*pcie_speed = 32000;
break;
default:
return AMDSMI_STATUS_API_FAILED;
}
+12 -6
View File
@@ -8,7 +8,7 @@ set(CMAKE_INSTALL_RPATH
CACHE STRING "RUNPATH for tests. Helps find libgtest.so and libamd_smi.so")
# Try to find googletest
find_package(GTest 1.11.0)
find_package(GTest 1.12.0)
# GTest_FOUND is set to TRUE if ANY version is found
# GTest_VERSION is set if 1.11.0 or newer version is found
@@ -18,7 +18,7 @@ if(NOT GTest_FOUND STREQUAL "TRUE" OR NOT DEFINED GTest_VERSION)
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG release-1.11.0)
GIT_TAG release-1.12.0)
FetchContent_MakeAvailable(googletest)
endif()
@@ -57,21 +57,27 @@ set(TEST "amdsmitst")
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} tstSources)
# Header file include path
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..)
include_directories(${TEST} ${CMAKE_CURRENT_SOURCE_DIR}/..)
# Build rules
add_executable(${TEST} ${tstSources} ${functionalSources})
target_link_libraries(${TEST} amd_smi c stdc++ pthread GTest::gtest_main)
#AMD_SMI_TARGET?
target_link_libraries(${TEST}
${AMD_SMI_TARGET}
GTest::gtest_main
c
stdc++
pthread)
# Install tests and gtest
# TODO: Remove GTest from here in the future and rely on INSTALL_GTEST?
install(
TARGETS ${TEST} gtest gtest_main
DESTINATION ${SHARE_INSTALL_PREFIX}/tests
COMPONENT tests)
COMPONENT ${TESTS_COMPONENT})
install(
FILES amdsmitst.exclude
DESTINATION ${SHARE_INSTALL_PREFIX}/tests
COMPONENT tests)
COMPONENT ${TESTS_COMPONENT})
-64
View File
@@ -1,64 +0,0 @@
# Required Defines first:
option(INSTALL_GTEST "Install GTest (only useful if GTest is not already installed)" OFF)
# Try to find googletest
find_package(GTest 1.12.0)
# GTest_FOUND is set to TRUE if ANY version is found
# GTest_VERSION is set if 1.11.0 or newer version is found
if(NOT GTest_FOUND STREQUAL "TRUE" OR NOT DEFINED GTest_VERSION)
# Google Test wasn't found. Download and compile ourselves
include(FetchContent)
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG release-1.12.0)
FetchContent_MakeAvailable(googletest)
endif()
enable_testing()
if(WIN32)
message("amd_smi library test suite is not supported on Windows platform")
return()
endif()
#
# Print out the build configuration being used:
#
# Build Src directory
# Build Binary directory
# Build Type: Debug Vs Release
# Compiler Version, etc
#
message("")
message("Build Configuration:")
message("-----------BuildType: " ${CMAKE_BUILD_TYPE})
message("------------Compiler: " ${CMAKE_CXX_COMPILER})
message("-------------Version: " ${CMAKE_CXX_COMPILER_VERSION})
message("--------Proj Src Dir: " ${PROJECT_SOURCE_DIR})
message("--------Proj Bld Dir: " ${PROJECT_BINARY_DIR})
message("--------Proj Lib Dir: " ${PROJECT_BINARY_DIR}/lib)
message("--------Proj Exe Dir: " ${PROJECT_BINARY_DIR}/bin)
message("")
# Other source directories
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/functional functionalSources)
set(TEST "rsmitst64")
# Source files
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} tstSources)
# Header file include path
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..)
# Build rules
add_executable(${TEST} ${tstSources} ${functionalSources})
target_link_libraries(${TEST} rocm_smi64 c stdc++ pthread GTest::gtest_main)
#install(
# TARGETS ${TEST}
# DESTINATION ${SHARE_INSTALL_PREFIX}/tests
# COMPONENT tests)
@@ -1,188 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2019, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#include <stdint.h>
#include <stddef.h>
#include <iostream>
#include <string>
#include <gtest/gtest.h>
#include "rocm_smi/rocm_smi.h"
#include "api_support_read.h"
#include "../test_common.h"
#include "../test_utils.h"
TestAPISupportRead::TestAPISupportRead() : TestBase() {
set_title("RSMI API Support Read Test");
set_description("This test verifies that the supported APIs are corretly "
"identified.");
}
TestAPISupportRead::~TestAPISupportRead(void) {
}
void TestAPISupportRead::SetUp(void) {
TestBase::SetUp();
return;
}
void TestAPISupportRead::DisplayTestInfo(void) {
TestBase::DisplayTestInfo();
}
void TestAPISupportRead::DisplayResults(void) const {
TestBase::DisplayResults();
return;
}
void TestAPISupportRead::Close() {
// This will close handles opened within rsmitst utility calls and call
// rsmi_shut_down(), so it should be done after other hsa cleanup
TestBase::Close();
}
void TestAPISupportRead::Run(void) {
rsmi_status_t err;
TestBase::Run();
if (setup_failed_) {
IF_VERB(STANDARD) {
std::cout << "** SetUp Failed for this test. Skipping.**" << std::endl;
}
return;
}
rsmi_func_id_iter_handle_t iter_handle, var_iter, sub_var_iter;
rsmi_func_id_value_t value;
for (uint32_t x = 0; x < num_iterations(); ++x) {
for (uint32_t i = 0; i < num_monitor_devs(); ++i) {
IF_VERB(STANDARD) {
PrintDeviceHeader(i);
std::cout << "Supported RSMI Functions:" << std::endl;
std::cout << "\tVariants (Monitors)" << std::endl;
}
err = rsmi_dev_supported_func_iterator_open(i, &iter_handle);
CHK_ERR_ASRT(err)
while (1) {
err = rsmi_func_iter_value_get(iter_handle, &value);
CHK_ERR_ASRT(err)
IF_VERB(STANDARD) {
std::cout << "Function Name: " << value.name << std::endl;
}
err = rsmi_dev_supported_variant_iterator_open(iter_handle, &var_iter);
if (err != RSMI_STATUS_NO_DATA) {
CHK_ERR_ASRT(err)
IF_VERB(STANDARD) {
std::cout << "\tVariants/Monitors: ";
}
while (1) {
err = rsmi_func_iter_value_get(var_iter, &value);
CHK_ERR_ASRT(err)
IF_VERB(STANDARD) {
if (value.id == RSMI_DEFAULT_VARIANT) {
std::cout << "Default Variant ";
} else {
std::cout << value.id;
}
std::cout << " (";
}
err =
rsmi_dev_supported_variant_iterator_open(var_iter, &sub_var_iter);
if (err != RSMI_STATUS_NO_DATA) {
CHK_ERR_ASRT(err)
while (1) {
err = rsmi_func_iter_value_get(sub_var_iter, &value);
CHK_ERR_ASRT(err)
IF_VERB(STANDARD) {
std::cout << value.id << ", ";
}
err = rsmi_func_iter_next(sub_var_iter);
if (err == RSMI_STATUS_NO_DATA) {
break;
}
CHK_ERR_ASRT(err)
}
err = rsmi_dev_supported_func_iterator_close(&sub_var_iter);
CHK_ERR_ASRT(err)
}
IF_VERB(STANDARD) {
std::cout << "), ";
}
err = rsmi_func_iter_next(var_iter);
if (err == RSMI_STATUS_NO_DATA) {
break;
}
CHK_ERR_ASRT(err)
}
IF_VERB(STANDARD) {
std::cout << std::endl;
}
err = rsmi_dev_supported_func_iterator_close(&var_iter);
CHK_ERR_ASRT(err)
}
err = rsmi_func_iter_next(iter_handle);
if (err == RSMI_STATUS_NO_DATA) {
break;
}
CHK_ERR_ASRT(err)
// err = rsmi_dev_supported_variant_iterator_open(iter_handle, &var_iter);
//
}
err = rsmi_dev_supported_func_iterator_close(&iter_handle);
CHK_ERR_ASRT(err)
}
}
}
@@ -1,73 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2019, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#ifndef TESTS_ROCM_SMI_TEST_FUNCTIONAL_API_SUPPORT_READ_H_
#define TESTS_ROCM_SMI_TEST_FUNCTIONAL_API_SUPPORT_READ_H_
#include "../test_base.h"
class TestAPISupportRead : public TestBase {
public:
TestAPISupportRead();
// @Brief: Destructor for test case of TestAPISupportRead
virtual ~TestAPISupportRead();
// @Brief: Setup the environment for measurement
virtual void SetUp();
// @Brief: Core measurement execution
virtual void Run();
// @Brief: Clean up and retrive the resource
virtual void Close();
// @Brief: Display results
virtual void DisplayResults() const;
// @Brief: Display information about what this test does
virtual void DisplayTestInfo(void);
};
#endif // TESTS_ROCM_SMI_TEST_FUNCTIONAL_API_SUPPORT_READ_H_
@@ -1,174 +0,0 @@
/*
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2019, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#include <stdint.h>
#include <stddef.h>
#include <iostream>
#include <gtest/gtest.h>
#include "rocm_smi/rocm_smi.h"
#include "err_cnt_read.h"
#include "../test_common.h"
TestErrCntRead::TestErrCntRead() : TestBase() {
set_title("RSMI Error Count Read Test");
set_description("The Error Count Read tests verifies that error counts"
" can be read properly.");
}
TestErrCntRead::~TestErrCntRead(void) {
}
void TestErrCntRead::SetUp(void) {
TestBase::SetUp();
return;
}
void TestErrCntRead::DisplayTestInfo(void) {
TestBase::DisplayTestInfo();
}
void TestErrCntRead::DisplayResults(void) const {
TestBase::DisplayResults();
return;
}
void TestErrCntRead::Close() {
// This will close handles opened within rsmitst utility calls and call
// rsmi_shut_down(), so it should be done after other hsa cleanup
TestBase::Close();
}
void TestErrCntRead::Run(void) {
rsmi_status_t err;
rsmi_error_count_t ec;
uint64_t enabled_mask;
rsmi_ras_err_state_t err_state;
TestBase::Run();
if (setup_failed_) {
IF_VERB(STANDARD) {
std::cout << "** SetUp Failed for this test. Skipping.**" << std::endl;
}
return;
}
for (uint32_t x = 0; x < num_iterations(); ++x) {
for (uint32_t i = 0; i < num_monitor_devs(); ++i) {
PrintDeviceHeader(i);
err = rsmi_dev_ecc_enabled_get(i, &enabled_mask);
if (err == RSMI_STATUS_NOT_SUPPORTED) {
IF_VERB(STANDARD) {
std::cout <<
"\t**Error Count Enabled Mask get is not supported on this machine"
<< std::endl;
}
// Verify api support checking functionality is working
err = rsmi_dev_ecc_enabled_get(i, nullptr);
ASSERT_EQ(err, RSMI_STATUS_NOT_SUPPORTED);
continue;
} else {
CHK_ERR_ASRT(err)
// Verify api support checking functionality is working
err = rsmi_dev_ecc_enabled_get(i, nullptr);
ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS);
IF_VERB(STANDARD) {
std::cout << "Block Error Mask: 0x" << std::hex << enabled_mask <<
std::endl;
}
}
for (uint32_t b = RSMI_GPU_BLOCK_FIRST;
b <= RSMI_GPU_BLOCK_LAST; b = b*2) {
err = rsmi_dev_ecc_status_get(i, static_cast<rsmi_gpu_block_t>(b),
&err_state);
CHK_ERR_ASRT(err)
IF_VERB(STANDARD) {
std::cout << "\t**Error Count status for " <<
GetBlockNameStr(static_cast<rsmi_gpu_block_t>(b)) <<
" block: " << GetErrStateNameStr(err_state) << std::endl;
}
// Verify api support checking functionality is working
err = rsmi_dev_ecc_status_get(i, static_cast<rsmi_gpu_block_t>(b),
nullptr);
ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS);
err = rsmi_dev_ecc_count_get(i, static_cast<rsmi_gpu_block_t>(b), &ec);
if (err == RSMI_STATUS_NOT_SUPPORTED) {
IF_VERB(STANDARD) {
std::cout << "\t**Error Count for " <<
GetBlockNameStr(static_cast<rsmi_gpu_block_t>(b)) <<
": Not supported for this device" << std::endl;
}
// Verify api support checking functionality is working
err = rsmi_dev_ecc_count_get(i, static_cast<rsmi_gpu_block_t>(b),
nullptr);
ASSERT_EQ(err, RSMI_STATUS_NOT_SUPPORTED);
} else {
CHK_ERR_ASRT(err)
IF_VERB(STANDARD) {
std::cout << "\t**Error counts for " <<
GetBlockNameStr(static_cast<rsmi_gpu_block_t>(b)) << " block: "
<< std::endl;
std::cout << "\t\tCorrectable errors: " << ec.correctable_err
<< std::endl;
std::cout << "\t\tUncorrectable errors: " << ec.uncorrectable_err
<< std::endl;
}
// Verify api support checking functionality is working
err = rsmi_dev_ecc_count_get(i, static_cast<rsmi_gpu_block_t>(b),
nullptr);
ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS);
}
}
}
}
}
@@ -1,71 +0,0 @@
/*
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2019, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#ifndef TESTS_ROCM_SMI_TEST_FUNCTIONAL_ERR_CNT_READ_H_
#define TESTS_ROCM_SMI_TEST_FUNCTIONAL_ERR_CNT_READ_H_
#include "../test_base.h"
class TestErrCntRead : public TestBase {
public:
TestErrCntRead();
// @Brief: Destructor for test case of TestErrCntRead
virtual ~TestErrCntRead();
// @Brief: Setup the environment for measurement
virtual void SetUp();
// @Brief: Core measurement execution
virtual void Run();
// @Brief: Clean up and retrive the resource
virtual void Close();
// @Brief: Display results
virtual void DisplayResults() const;
// @Brief: Display information about what this test does
virtual void DisplayTestInfo(void);
};
#endif // TESTS_ROCM_SMI_TEST_FUNCTIONAL_ERR_CNT_READ_H_
@@ -1,197 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2020, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#include <stdint.h>
#include <stddef.h>
#include <iostream>
#include <gtest/gtest.h>
#include "rocm_smi/rocm_smi.h"
#include "evt_notif_read_write.h"
#include "../test_common.h"
#include "../test_utils.h"
TestEvtNotifReadWrite::TestEvtNotifReadWrite() : TestBase() {
set_title("RSMI Event Notification Read/Write Test");
set_description("The Event Notification Read/Write tests verifies that "
"we can configure to collect various event types and then read them");
}
TestEvtNotifReadWrite::~TestEvtNotifReadWrite(void) {
}
void TestEvtNotifReadWrite::SetUp(void) {
TestBase::SetUp();
return;
}
void TestEvtNotifReadWrite::DisplayTestInfo(void) {
TestBase::DisplayTestInfo();
}
void TestEvtNotifReadWrite::DisplayResults(void) const {
TestBase::DisplayResults();
return;
}
void TestEvtNotifReadWrite::Close() {
// This will close handles opened within rsmitst utility calls and call
// rsmi_shut_down(), so it should be done after other hsa cleanup
TestBase::Close();
}
void TestEvtNotifReadWrite::Run(void) {
rsmi_status_t ret;
uint32_t dv_ind;
TestBase::Run();
if (num_monitor_devs() == 0) {
return;
}
if (setup_failed_) {
IF_VERB(STANDARD) {
std::cout << "** SetUp Failed for this test. Skipping.**" <<
std::endl;
}
return;
}
rsmi_evt_notification_type_t evt_type = RSMI_EVT_NOTIF_FIRST;
uint64_t mask = RSMI_EVENT_MASK_FROM_INDEX(evt_type);
while (evt_type <= RSMI_EVT_NOTIF_LAST) {
mask |= RSMI_EVENT_MASK_FROM_INDEX(evt_type);
evt_type = static_cast<rsmi_evt_notification_type_t>(
static_cast<uint32_t>(evt_type)+1);
}
for (dv_ind = 0; dv_ind < num_monitor_devs(); ++dv_ind) {
ret = rsmi_event_notification_init(dv_ind);
if (ret == RSMI_STATUS_NOT_SUPPORTED) {
IF_VERB(STANDARD) {
std::cout <<
"Event notification is not supported for this driver version." <<
std::endl;
}
return;
}
ASSERT_EQ(ret, RSMI_STATUS_SUCCESS);
ret = rsmi_event_notification_mask_set(dv_ind, mask);
ASSERT_EQ(ret, RSMI_STATUS_SUCCESS);
}
rsmi_evt_notification_data_t data[10];
uint32_t num_elem = 10;
bool read_again = false;
ret = rsmi_event_notification_get(10000, &num_elem, data);
if (ret == RSMI_STATUS_SUCCESS || ret == RSMI_STATUS_INSUFFICIENT_SIZE) {
EXPECT_LE(num_elem, 10) <<
"Expected the number of elements found to be <= buffer size (10)";
IF_VERB(STANDARD) {
for (uint32_t i = 0; i < num_elem; ++i) {
std::cout << "\tdv_ind=" << data[i].dv_ind <<
" Type: " << NameFromEvtNotifType(data[i].event) <<
" Mesg: " << data[i].message << std::endl;
if (data[i].event == RSMI_EVT_NOTIF_GPU_PRE_RESET) {
read_again = true;
}
}
}
IF_VERB(STANDARD) {
if (ret == RSMI_STATUS_INSUFFICIENT_SIZE) {
std::cout <<
"\t\tBuffer size is 10, but more than 10 events are available." <<
std::endl;
}
}
} else if (ret == RSMI_STATUS_NO_DATA) {
IF_VERB(STANDARD) {
std::cout << "\tNo events were collected." << std::endl;
}
} else {
// This should always fail. We want to print out the return code.
EXPECT_EQ(ret, RSMI_STATUS_SUCCESS) <<
"Unexpected return code for rsmi_event_notification_get()";
}
// In case GPU Pre reset event was collected in the previous read,
// read again to get the GPU Post reset event.
if (read_again) {
ret = rsmi_event_notification_get(10000, &num_elem, data);
if (ret == RSMI_STATUS_SUCCESS || ret == RSMI_STATUS_INSUFFICIENT_SIZE) {
EXPECT_LE(num_elem, 10) <<
"Expected the number of elements found to be <= buffer size (10)";
IF_VERB(STANDARD) {
for (uint32_t i = 0; i < num_elem; ++i) {
std::cout << "\tdv_ind=" << data[i].dv_ind <<
" Type: " << NameFromEvtNotifType(data[i].event) <<
" Mesg: " << data[i].message << std::endl;
}
}
IF_VERB(STANDARD) {
if (ret == RSMI_STATUS_INSUFFICIENT_SIZE) {
std::cout <<
"\t\tBuffer size is 10, but more than 10 events are available." <<
std::endl;
}
}
} else if (ret == RSMI_STATUS_NO_DATA) {
IF_VERB(STANDARD) {
std::cout << "\tNo further events were collected." << std::endl;
}
} else {
// This should always fail. We want to print out the return code.
EXPECT_EQ(ret, RSMI_STATUS_SUCCESS) <<
"Unexpected return code for rsmi_event_notification_get()";
}
}
for (uint32_t dv_ind = 0; dv_ind < num_monitor_devs(); ++dv_ind) {
ret = rsmi_event_notification_stop(dv_ind);
ASSERT_EQ(ret, RSMI_STATUS_SUCCESS);
}
}
@@ -1,73 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2020, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#ifndef TESTS_ROCM_SMI_TEST_FUNCTIONAL_EVT_NOTIF_READ_WRITE_H_
#define TESTS_ROCM_SMI_TEST_FUNCTIONAL_EVT_NOTIF_READ_WRITE_H_
#include "../test_base.h"
class TestEvtNotifReadWrite : public TestBase {
public:
TestEvtNotifReadWrite();
// @Brief: Destructor for test case of TestEvtNotifReadWrite
virtual ~TestEvtNotifReadWrite();
// @Brief: Setup the environment for measurement
virtual void SetUp();
// @Brief: Core measurement execution
virtual void Run();
// @Brief: Clean up and retrive the resource
virtual void Close();
// @Brief: Display results
virtual void DisplayResults() const;
// @Brief: Display information about what this test does
virtual void DisplayTestInfo(void);
};
#endif // TESTS_ROCM_SMI_TEST_FUNCTIONAL_EVT_NOTIF_READ_WRITE_H_
-144
View File
@@ -1,144 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2019, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#include <stdint.h>
#include <stddef.h>
#include <iostream>
#include <gtest/gtest.h>
#include "rocm_smi/rocm_smi.h"
#include "fan_read.h"
#include "../test_common.h"
TestFanRead::TestFanRead() : TestBase() {
set_title("RSMI Fan Read Test");
set_description("The Fan Read tests verifies that the fan monitors can be "
"read properly.");
}
TestFanRead::~TestFanRead(void) {
}
void TestFanRead::SetUp(void) {
TestBase::SetUp();
return;
}
void TestFanRead::DisplayTestInfo(void) {
TestBase::DisplayTestInfo();
}
void TestFanRead::DisplayResults(void) const {
TestBase::DisplayResults();
return;
}
void TestFanRead::Close() {
// This will close handles opened within rsmitst utility calls and call
// rsmi_shut_down(), so it should be done after other hsa cleanup
TestBase::Close();
}
void TestFanRead::Run(void) {
uint64_t val_ui64;
rsmi_status_t err;
int64_t val_i64;
TestBase::Run();
if (setup_failed_) {
std::cout << "** SetUp Failed for this test. Skipping.**" << std::endl;
return;
}
for (uint32_t x = 0; x < num_iterations(); ++x) {
for (uint32_t i = 0; i < num_monitor_devs(); ++i) {
PrintDeviceHeader(i);
IF_VERB(STANDARD) {
std::cout << "\t**Current Fan Speed: ";
}
err = rsmi_dev_fan_speed_get(i, 0, &val_i64);
if (err == RSMI_STATUS_NOT_SUPPORTED) {
IF_VERB(STANDARD) {
std::cout << "\t**" << ": " <<
"Not supported on this machine" << std::endl;
}
return;
} else {
CHK_ERR_ASRT(err)
}
// Verify api support checking functionality is working
err = rsmi_dev_fan_speed_get(i, 0, nullptr);
ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS);
err = rsmi_dev_fan_speed_max_get(i, 0, &val_ui64);
CHK_ERR_ASRT(err)
IF_VERB(STANDARD) {
std::cout << val_i64/static_cast<float>(val_ui64)*100;
std::cout << "% ("<< val_i64 << "/" << val_ui64 << ")" << std::endl;
}
// Verify api support checking functionality is working
err = rsmi_dev_fan_speed_max_get(i, 0, nullptr);
ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS);
IF_VERB(STANDARD) {
std::cout << "\t**Current fan RPMs: ";
}
err = rsmi_dev_fan_rpms_get(i, 0, &val_i64);
CHK_ERR_ASRT(err)
IF_VERB(STANDARD) {
std::cout << val_i64 << std::endl;
}
// Verify api support checking functionality is working
err = rsmi_dev_fan_rpms_get(i, 0, nullptr);
ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS);
}
}
}
-73
View File
@@ -1,73 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2019, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#ifndef TESTS_ROCM_SMI_TEST_FUNCTIONAL_FAN_READ_H_
#define TESTS_ROCM_SMI_TEST_FUNCTIONAL_FAN_READ_H_
#include "../test_base.h"
class TestFanRead : public TestBase {
public:
TestFanRead();
// @Brief: Destructor for test case of TestFanRead
virtual ~TestFanRead();
// @Brief: Setup the environment for measurement
virtual void SetUp();
// @Brief: Core measurement execution
virtual void Run();
// @Brief: Clean up and retrive the resource
virtual void Close();
// @Brief: Display results
virtual void DisplayResults() const;
// @Brief: Display information about what this test does
virtual void DisplayTestInfo(void);
};
#endif // TESTS_ROCM_SMI_TEST_FUNCTIONAL_FAN_READ_H_
@@ -1,178 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2019, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#include <stdint.h>
#include <stddef.h>
#include <iostream>
#include <gtest/gtest.h>
#include "rocm_smi/rocm_smi.h"
#include "fan_read_write.h"
#include "../test_common.h"
TestFanReadWrite::TestFanReadWrite() : TestBase() {
set_title("RSMI Fan Read/Write Test");
set_description("The Fan Read tests verifies that the fan monitors can be "
"read and controlled properly.");
}
TestFanReadWrite::~TestFanReadWrite(void) {
}
void TestFanReadWrite::SetUp(void) {
TestBase::SetUp();
return;
}
void TestFanReadWrite::DisplayTestInfo(void) {
TestBase::DisplayTestInfo();
}
void TestFanReadWrite::DisplayResults(void) const {
TestBase::DisplayResults();
return;
}
void TestFanReadWrite::Close() {
// This will close handles opened within rsmitst utility calls and call
// rsmi_shut_down(), so it should be done after other hsa cleanup
TestBase::Close();
}
void TestFanReadWrite::Run(void) {
rsmi_status_t ret;
int64_t orig_speed;
int64_t new_speed;
int64_t cur_speed;
uint64_t max_speed;
TestBase::Run();
if (setup_failed_) {
std::cout << "** SetUp Failed for this test. Skipping.**" << std::endl;
return;
}
for (uint32_t dv_ind = 0; dv_ind < num_monitor_devs(); ++dv_ind) {
PrintDeviceHeader(dv_ind);
ret = rsmi_dev_fan_speed_get(dv_ind, 0, &orig_speed);
if (ret == RSMI_STATUS_NOT_SUPPORTED) {
IF_VERB(STANDARD) {
std::cout << "\t**" << ": " <<
"Not supported on this machine" << std::endl;
}
return;
} else {
CHK_ERR_ASRT(ret)
}
IF_VERB(STANDARD) {
std::cout << "Original fan speed: " << orig_speed << std::endl;
}
if (orig_speed == 0) {
std::cout << "***System fan speed value is 0. Skip fan test." <<
std::endl;
return;
}
ret = rsmi_dev_fan_speed_max_get(dv_ind, 0, &max_speed);
CHK_ERR_ASRT(ret)
new_speed = 1.1 * orig_speed;
if (new_speed > static_cast<int64_t>(max_speed)) {
std::cout <<
"***System fan speed value is close to max. Will not adjust upward." <<
std::endl;
continue;
}
IF_VERB(STANDARD) {
std::cout << "Setting fan speed to " << new_speed << std::endl;
}
ret = rsmi_dev_fan_speed_set(dv_ind, 0, new_speed);
CHK_ERR_ASRT(ret)
sleep(4);
ret = rsmi_dev_fan_speed_get(dv_ind, 0, &cur_speed);
CHK_ERR_ASRT(ret)
IF_VERB(STANDARD) {
std::cout << "New fan speed: " << cur_speed << std::endl;
}
// EXPECT_TRUE((cur_speed > 0.95 * new_speed &&
// cur_speed < 1.1 * new_speed) ||
// cur_speed > 0.95 * RSMI_MAX_FAN_SPEED);
IF_VERB(STANDARD) {
if (!((cur_speed > 0.95 * new_speed && cur_speed < 1.1 * new_speed) ||
(cur_speed > 0.95 * RSMI_MAX_FAN_SPEED))) {
std::cout << "WARNING: Fan speed is not within the expected range!" <<
std::endl;
}
}
IF_VERB(STANDARD) {
std::cout << "Resetting fan control to auto..." << std::endl;
}
ret = rsmi_dev_fan_reset(dv_ind, 0);
CHK_ERR_ASRT(ret)
sleep(3);
ret = rsmi_dev_fan_speed_get(dv_ind, 0, &cur_speed);
CHK_ERR_ASRT(ret)
IF_VERB(STANDARD) {
std::cout << "End fan speed: " << cur_speed << std::endl;
}
}
}
@@ -1,73 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2019, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#ifndef TESTS_ROCM_SMI_TEST_FUNCTIONAL_FAN_READ_WRITE_H_
#define TESTS_ROCM_SMI_TEST_FUNCTIONAL_FAN_READ_WRITE_H_
#include "../test_base.h"
class TestFanReadWrite : public TestBase {
public:
TestFanReadWrite();
// @Brief: Destructor for test case of TestFanReadWrite
virtual ~TestFanReadWrite();
// @Brief: Setup the environment for measurement
virtual void SetUp();
// @Brief: Core measurement execution
virtual void Run();
// @Brief: Clean up and retrive the resource
virtual void Close();
// @Brief: Display results
virtual void DisplayResults() const;
// @Brief: Display information about what this test does
virtual void DisplayTestInfo(void);
};
#endif // TESTS_ROCM_SMI_TEST_FUNCTIONAL_FAN_READ_WRITE_H_
@@ -1,167 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2019, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#include <stdint.h>
#include <stddef.h>
#include <iostream>
#include <string>
#include <gtest/gtest.h>
#include "rocm_smi/rocm_smi.h"
#include "frequencies_read.h"
#include "../test_common.h"
TestFrequenciesRead::TestFrequenciesRead() : TestBase() {
set_title("RSMI Frequencies Read Test");
set_description("The Frequency Read tests verifies that the "
"available and current frequency levels can be read properly.");
}
TestFrequenciesRead::~TestFrequenciesRead(void) {
}
void TestFrequenciesRead::SetUp(void) {
TestBase::SetUp();
return;
}
void TestFrequenciesRead::DisplayTestInfo(void) {
TestBase::DisplayTestInfo();
}
void TestFrequenciesRead::DisplayResults(void) const {
TestBase::DisplayResults();
return;
}
void TestFrequenciesRead::Close() {
// This will close handles opened within rsmitst utility calls and call
// rsmi_shut_down(), so it should be done after other hsa cleanup
TestBase::Close();
}
static void print_frequencies(rsmi_frequencies_t *f, uint32_t *l = nullptr) {
assert(f != nullptr);
for (uint32_t j = 0; j < f->num_supported; ++j) {
std::cout << "\t** " << j << ": " << f->frequency[j];
if (l != nullptr) {
std::cout << "T/s; x" << l[j];
} else {
std::cout << "Hz";
}
if (j == f->current) {
std::cout << " *";
}
std::cout << std::endl;
}
}
void TestFrequenciesRead::Run(void) {
rsmi_status_t err;
rsmi_frequencies_t f;
rsmi_pcie_bandwidth_t b;
TestBase::Run();
if (setup_failed_) {
std::cout << "** SetUp Failed for this test. Skipping.**" << std::endl;
return;
}
for (uint32_t x = 0; x < num_iterations(); ++x) {
for (uint32_t i = 0; i < num_monitor_devs(); ++i) {
auto freq_output = [&](rsmi_clk_type_t t, const char *name) {
err = rsmi_dev_gpu_clk_freq_get(i, t, &f);
if (err == RSMI_STATUS_NOT_SUPPORTED) {
std::cout << "\t**Get " << name <<
": Not supported on this machine" << std::endl;
// Verify api support checking functionality is working
err = rsmi_dev_gpu_clk_freq_get(i, t, nullptr);
ASSERT_EQ(err, RSMI_STATUS_NOT_SUPPORTED);
} else {
CHK_ERR_ASRT(err)
IF_VERB(STANDARD) {
std::cout << "\t**Supported " << name << " clock frequencies: ";
std::cout << f.num_supported << std::endl;
print_frequencies(&f);
// Verify api support checking functionality is working
err = rsmi_dev_gpu_clk_freq_get(i, t, nullptr);
ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS);
}
}
};
PrintDeviceHeader(i);
freq_output(RSMI_CLK_TYPE_MEM, "Supported GPU Memory");
freq_output(RSMI_CLK_TYPE_SYS, "Supported GPU");
freq_output(RSMI_CLK_TYPE_DF, "Data Fabric Clock");
freq_output(RSMI_CLK_TYPE_DCEF, "Display Controller Engine Clock");
freq_output(RSMI_CLK_TYPE_SOC, "SOC Clock");
err = rsmi_dev_pci_bandwidth_get(i, &b);
if (err == RSMI_STATUS_NOT_SUPPORTED) {
std::cout << "\t**Get PCIE Bandwidth: Not supported on this machine"
<< std::endl;
// Verify api support checking functionality is working
err = rsmi_dev_pci_bandwidth_get(i, nullptr);
ASSERT_EQ(err, RSMI_STATUS_NOT_SUPPORTED);
} else {
CHK_ERR_ASRT(err)
IF_VERB(STANDARD) {
std::cout << "\t**Supported PCIe bandwidths: ";
std::cout << b.transfer_rate.num_supported << std::endl;
print_frequencies(&b.transfer_rate, b.lanes);
// Verify api support checking functionality is working
err = rsmi_dev_pci_bandwidth_get(i, nullptr);
ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS);
}
}
}
}
}
@@ -1,73 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2019, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#ifndef TESTS_ROCM_SMI_TEST_FUNCTIONAL_FREQUENCIES_READ_H_
#define TESTS_ROCM_SMI_TEST_FUNCTIONAL_FREQUENCIES_READ_H_
#include "../test_base.h"
class TestFrequenciesRead : public TestBase {
public:
TestFrequenciesRead();
// @Brief: Destructor for test case of TestFrequenciesRead
virtual ~TestFrequenciesRead();
// @Brief: Setup the environment for measurement
virtual void SetUp();
// @Brief: Core measurement execution
virtual void Run();
// @Brief: Clean up and retrive the resource
virtual void Close();
// @Brief: Display results
virtual void DisplayResults() const;
// @Brief: Display information about what this test does
virtual void DisplayTestInfo(void);
};
#endif // TESTS_ROCM_SMI_TEST_FUNCTIONAL_FREQUENCIES_READ_H_
@@ -1,220 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2019, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#include <stdint.h>
#include <stddef.h>
#include <iostream>
#include <map>
#include <bitset>
#include <string>
#include <algorithm>
#include <gtest/gtest.h>
#include "rocm_smi/rocm_smi.h"
#include "frequencies_read_write.h"
#include "../test_common.h"
TestFrequenciesReadWrite::TestFrequenciesReadWrite() : TestBase() {
set_title("RSMI Frequencies Read/Write Test");
set_description("The Frequencies tests verify that the frequency "
"settings can be read and controlled properly.");
}
TestFrequenciesReadWrite::~TestFrequenciesReadWrite(void) {
}
void TestFrequenciesReadWrite::SetUp(void) {
TestBase::SetUp();
return;
}
void TestFrequenciesReadWrite::DisplayTestInfo(void) {
TestBase::DisplayTestInfo();
}
void TestFrequenciesReadWrite::DisplayResults(void) const {
TestBase::DisplayResults();
return;
}
void TestFrequenciesReadWrite::Close() {
// This will close handles opened within rsmitst utility calls and call
// rsmi_shut_down(), so it should be done after other hsa cleanup
TestBase::Close();
}
void TestFrequenciesReadWrite::Run(void) {
rsmi_status_t ret;
rsmi_frequencies_t f;
uint32_t freq_bitmask;
rsmi_clk_type rsmi_clk;
TestBase::Run();
if (setup_failed_) {
std::cout << "** SetUp Failed for this test. Skipping.**" << std::endl;
return;
}
for (uint32_t dv_ind = 0; dv_ind < num_monitor_devs(); ++dv_ind) {
PrintDeviceHeader(dv_ind);
for (uint32_t clk = (uint32_t)RSMI_CLK_TYPE_FIRST;
clk <= RSMI_CLK_TYPE_LAST; ++clk) {
rsmi_clk = (rsmi_clk_type)clk;
auto freq_read = [&]() -> bool {
ret = rsmi_dev_gpu_clk_freq_get(dv_ind, rsmi_clk, &f);
if (ret == RSMI_STATUS_NOT_SUPPORTED) {
std::cout << "\t**Set " << FreqEnumToStr(rsmi_clk) <<
": Not supported on this machine" << std::endl;
return false;
} else {
// CHK_ERR_ASRT(ret)
IF_VERB(STANDARD) {
std::cout << "Initial frequency for clock " <<
FreqEnumToStr(rsmi_clk) << " is " << f.current << std::endl;
}
return true;
}
};
auto freq_write = [&]() {
// Set clocks to something other than the usual default of the lowest
// frequency.
freq_bitmask = 0b01100; // Try the 3rd and 4th clocks
std::string freq_bm_str =
std::bitset<RSMI_MAX_NUM_FREQUENCIES>(freq_bitmask).to_string();
freq_bm_str.erase(0, std::min(freq_bm_str.find_first_not_of('0'),
freq_bm_str.size()-1));
IF_VERB(STANDARD) {
std::cout << "Setting frequency mask for " <<
FreqEnumToStr(rsmi_clk) << " to 0b" << freq_bm_str << " ..." <<
std::endl;
}
ret = rsmi_dev_gpu_clk_freq_set(dv_ind, rsmi_clk, freq_bitmask);
//Certain ASICs does not allow to set particular clocks. If set function for a clock returns
//permission error despite root access, manually set ret value to success and return
if (ret == RSMI_STATUS_PERMISSION && geteuid() == 0) {
std::cout << "\t**Set " << FreqEnumToStr(rsmi_clk) <<
": Not supported on this machine. Skipping..." << std::endl;
ret = RSMI_STATUS_SUCCESS;
return;
}
CHK_ERR_ASRT(ret)
ret = rsmi_dev_gpu_clk_freq_get(dv_ind, rsmi_clk, &f);
if (ret != RSMI_STATUS_SUCCESS) {
return;
}
IF_VERB(STANDARD) {
std::cout << "Frequency is now index " << f.current << std::endl;
std::cout << "Resetting mask to all frequencies." << std::endl;
}
ret = rsmi_dev_gpu_clk_freq_set(dv_ind, rsmi_clk, 0xFFFFFFFF);
if (ret != RSMI_STATUS_SUCCESS) {
return;
}
ret = rsmi_dev_perf_level_set(dv_ind, RSMI_DEV_PERF_LEVEL_AUTO);
if (ret != RSMI_STATUS_SUCCESS) {
return;
}
};
if (freq_read()) {
CHK_ERR_ASRT(ret)
} else {
continue;
}
freq_write();
CHK_ERR_ASRT(ret)
#if 0
ret = rsmi_dev_gpu_clk_freq_get(dv_ind, rsmi_clk, &f);
CHK_ERR_ASRT(ret)
IF_VERB(STANDARD) {
std::cout << "Initial frequency for clock " << rsmi_clk << " is " <<
f.current << std::endl;
}
// Set clocks to something other than the usual default of the lowest
// frequency.
freq_bitmask = 0b01100; // Try the 3rd and 4th clocks
std::string freq_bm_str =
std::bitset<RSMI_MAX_NUM_FREQUENCIES>(freq_bitmask).to_string();
freq_bm_str.erase(0, std::min(freq_bm_str.find_first_not_of('0'),
freq_bm_str.size()-1));
IF_VERB(STANDARD) {
std::cout << "Setting frequency mask for clock " << rsmi_clk <<
" to 0b" << freq_bm_str << " ..." << std::endl;
}
ret = rsmi_dev_gpu_clk_freq_set(dv_ind, rsmi_clk, freq_bitmask);
CHK_ERR_ASRT(ret)
ret = rsmi_dev_gpu_clk_freq_get(dv_ind, rsmi_clk, &f);
CHK_ERR_ASRT(ret)
IF_VERB(STANDARD) {
std::cout << "Frequency is now index " << f.current << std::endl;
std::cout << "Resetting mask to all frequencies." << std::endl;
}
ret = rsmi_dev_gpu_clk_freq_set(dv_ind, rsmi_clk, 0xFFFFFFFF);
CHK_ERR_ASRT(ret)
ret = rsmi_dev_perf_level_set(dv_ind, RSMI_DEV_PERF_LEVEL_AUTO);
CHK_ERR_ASRT(ret)
#endif
}
}
}
@@ -1,73 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2019, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#ifndef TESTS_ROCM_SMI_TEST_FUNCTIONAL_FREQUENCIES_READ_WRITE_H_
#define TESTS_ROCM_SMI_TEST_FUNCTIONAL_FREQUENCIES_READ_WRITE_H_
#include "../test_base.h"
class TestFrequenciesReadWrite : public TestBase {
public:
TestFrequenciesReadWrite();
// @Brief: Destructor for test case of TestFrequenciesReadWrite
virtual ~TestFrequenciesReadWrite();
// @Brief: Setup the environment for measurement
virtual void SetUp();
// @Brief: Core measurement execution
virtual void Run();
// @Brief: Clean up and retrive the resource
virtual void Close();
// @Brief: Display results
virtual void DisplayResults() const;
// @Brief: Display information about what this test does
virtual void DisplayTestInfo(void);
};
#endif // TESTS_ROCM_SMI_TEST_FUNCTIONAL_FREQUENCIES_READ_WRITE_H_
@@ -1,120 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2019, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#include <stdint.h>
#include <stddef.h>
#include <iostream>
#include <string>
#include <gtest/gtest.h>
#include "rocm_smi/rocm_smi.h"
#include "gpu_busy_read.h"
#include "../test_common.h"
TestGPUBusyRead::TestGPUBusyRead() : TestBase() {
set_title("RSMI GPU Busy Read Test");
set_description("The GPU Busy Read tests verifies that the gpu busy "
"percentage can be read properly.");
}
TestGPUBusyRead::~TestGPUBusyRead(void) {
}
void TestGPUBusyRead::SetUp(void) {
TestBase::SetUp();
return;
}
void TestGPUBusyRead::DisplayTestInfo(void) {
TestBase::DisplayTestInfo();
}
void TestGPUBusyRead::DisplayResults(void) const {
TestBase::DisplayResults();
return;
}
void TestGPUBusyRead::Close() {
// This will close handles opened within rsmitst utility calls and call
// rsmi_shut_down(), so it should be done after other hsa cleanup
TestBase::Close();
}
void TestGPUBusyRead::Run(void) {
rsmi_status_t err;
uint32_t val_ui32;
TestBase::Run();
if (setup_failed_) {
std::cout << "** SetUp Failed for this test. Skipping.**" << std::endl;
return;
}
for (uint32_t x = 0; x < num_iterations(); ++x) {
for (uint32_t i = 0; i < num_monitor_devs(); ++i) {
PrintDeviceHeader(i);
err = rsmi_dev_busy_percent_get(i, &val_ui32);
if (err != RSMI_STATUS_SUCCESS) {
if (err == RSMI_STATUS_FILE_ERROR) {
IF_VERB(STANDARD) {
std::cout << "\t**GPU Busy Percent: Not supported on this machine"
<< std::endl;
}
} else {
CHK_ERR_ASRT(err)
}
} else {
IF_VERB(STANDARD) {
std::cout << "\t**GPU Busy Percent (Percent Idle):" << std::dec <<
val_ui32 << " (" << 100 - val_ui32 << ")" << std::endl;
}
}
}
}
}
@@ -1,73 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2019, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#ifndef TESTS_ROCM_SMI_TEST_FUNCTIONAL_GPU_BUSY_READ_H_
#define TESTS_ROCM_SMI_TEST_FUNCTIONAL_GPU_BUSY_READ_H_
#include "../test_base.h"
class TestGPUBusyRead : public TestBase {
public:
TestGPUBusyRead();
// @Brief: Destructor for test case of TestGPUBusyRead
virtual ~TestGPUBusyRead();
// @Brief: Setup the environment for measurement
virtual void SetUp();
// @Brief: Core measurement execution
virtual void Run();
// @Brief: Clean up and retrive the resource
virtual void Close();
// @Brief: Display results
virtual void DisplayResults() const;
// @Brief: Display information about what this test does
virtual void DisplayTestInfo(void);
};
#endif // TESTS_ROCM_SMI_TEST_FUNCTIONAL_GPU_BUSY_READ_H_
@@ -1,194 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2020, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#include <stdint.h>
#include <stddef.h>
#include <iostream>
#include <string>
#include <map>
#include <gtest/gtest.h>
#include "rocm_smi/rocm_smi.h"
#include "gpu_metrics_read.h"
#include "../test_common.h"
TestGpuMetricsRead::TestGpuMetricsRead() : TestBase() {
set_title("RSMI GPU Metrics Read Test");
set_description("The GPU Metrics tests verifies that "
"the gpu metrics info can be read properly.");
}
TestGpuMetricsRead::~TestGpuMetricsRead(void) {
}
void TestGpuMetricsRead::SetUp(void) {
TestBase::SetUp();
return;
}
void TestGpuMetricsRead::DisplayTestInfo(void) {
TestBase::DisplayTestInfo();
}
void TestGpuMetricsRead::DisplayResults(void) const {
TestBase::DisplayResults();
return;
}
void TestGpuMetricsRead::Close() {
// This will close handles opened within rsmitst utility calls and call
// rsmi_shut_down(), so it should be done after other hsa cleanup
TestBase::Close();
}
void TestGpuMetricsRead::Run(void) {
rsmi_status_t err;
TestBase::Run();
if (setup_failed_) {
std::cout << "** SetUp Failed for this test. Skipping.**" << std::endl;
return;
}
for (uint32_t i = 0; i < num_monitor_devs(); ++i) {
PrintDeviceHeader(i);
IF_VERB(STANDARD) {
std::cout << "\t**GPU METRICS:\n";
}
rsmi_gpu_metrics_t smu;
err = rsmi_dev_gpu_metrics_info_get(i, &smu);
if (err != RSMI_STATUS_SUCCESS) {
if (err == RSMI_STATUS_NOT_SUPPORTED) {
IF_VERB(STANDARD) {
std::cout << "\t**" <<
"Not supported on this machine" << std::endl;
return;
}
}
} else {
CHK_ERR_ASRT(err);
IF_VERB(STANDARD) {
std::cout << std::dec << "system_clock_counter="
<< smu.system_clock_counter << '\n';
std::cout << std::dec << "temperature_edge="
<< smu.temperature_edge << '\n';
std::cout << std::dec << "temperature_hotspot="
<< smu.temperature_hotspot << '\n';
std::cout << std::dec << "temperature_mem="
<< smu.temperature_mem << '\n';
std::cout << std::dec << "temperature_vrgfx="
<< smu.temperature_vrgfx << '\n';
std::cout << std::dec << "temperature_vrsoc="
<< smu.temperature_vrsoc << '\n';
std::cout << std::dec << "temperature_vrmem="
<< smu.temperature_vrmem << '\n';
std::cout << std::dec << "average_gfx_activity="
<< smu.average_gfx_activity << '\n';
std::cout << std::dec << "average_umc_activity="
<< smu.average_umc_activity << '\n';
std::cout << std::dec << "average_mm_activity="
<< smu.average_mm_activity << '\n';
std::cout << std::dec << "average_socket_power="
<< smu.average_socket_power << '\n';
std::cout << std::dec << "energy_accumulator="
<< smu.energy_accumulator << '\n';
std::cout << std::dec << "average_gfxclk_frequency="
<< smu.average_gfxclk_frequency << '\n';
std::cout << std::dec << "average_gfxclk_frequency="
<< smu.average_gfxclk_frequency << '\n';
std::cout << std::dec << "average_uclk_frequency="
<< smu.average_uclk_frequency << '\n';
std::cout << std::dec << "average_vclk0_frequency="
<< smu.average_vclk0_frequency << '\n';
std::cout << std::dec << "average_dclk0_frequency="
<< smu.average_dclk0_frequency << '\n';
std::cout << std::dec << "average_vclk1_frequency="
<< smu.average_vclk1_frequency << '\n';
std::cout << std::dec << "average_dclk1_frequency="
<< smu.average_dclk1_frequency << '\n';
std::cout << std::dec << "current_gfxclk="
<< smu.current_gfxclk << '\n';
std::cout << std::dec << "current_socclk="
<< smu.current_socclk << '\n';
std::cout << std::dec << "current_uclk="
<< smu.current_uclk << '\n';
std::cout << std::dec << "current_vclk0="
<< smu.current_vclk0 << '\n';
std::cout << std::dec << "current_dclk0="
<< smu.current_dclk0 << '\n';
std::cout << std::dec << "current_vclk1="
<< smu.current_vclk1 << '\n';
std::cout << std::dec << "current_dclk1="
<< smu.current_dclk1 << '\n';
std::cout << std::dec << "throttle_status="
<< smu.throttle_status << '\n';
std::cout << std::dec << "current_fan_speed="
<< smu.current_fan_speed << '\n';
std::cout << "pcie_link_width="
<< std::to_string(smu.pcie_link_width) << '\n';
std::cout << "pcie_link_width="
<< std::to_string(smu.pcie_link_speed) << '\n';
std::cout << "gfx_activity_acc="
<< std::dec << smu.gfx_activity_acc << '\n';
std::cout << "mem_actvity_acc="
<< std::dec << smu.mem_actvity_acc << '\n';
for (int i = 0; i < RSMI_NUM_HBM_INSTANCES; ++i) {
std::cout << "temperature_hbm[" << i << "]=" << std::dec <<
smu.temperature_hbm[i] << '\n';
}
}
}
// Verify api support checking functionality is working
err = rsmi_dev_gpu_metrics_info_get(i, nullptr);
ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS);
}
}
@@ -1,73 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2020, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#ifndef TESTS_ROCM_SMI_TEST_FUNCTIONAL_GPU_METRICS_READ_H_
#define TESTS_ROCM_SMI_TEST_FUNCTIONAL_GPU_METRICS_READ_H_
#include "../test_base.h"
class TestGpuMetricsRead : public TestBase {
public:
TestGpuMetricsRead();
// @Brief: Destructor for test case of TestVOltRead
virtual ~TestGpuMetricsRead();
// @Brief: Setup the environment for measurement
virtual void SetUp();
// @Brief: Core measurement execution
virtual void Run();
// @Brief: Clean up and retrive the resource
virtual void Close();
// @Brief: Display results
virtual void DisplayResults() const;
// @Brief: Display information about what this test does
virtual void DisplayTestInfo(void);
};
#endif // TESTS_ROCM_SMI_TEST_FUNCTIONAL_GPU_METRICS_READ_H_
@@ -1,304 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2020, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#include <stdint.h>
#include <stddef.h>
#include <iostream>
#include <string>
#include <vector>
#include <gtest/gtest.h>
#include "rocm_smi/rocm_smi.h"
#include "hw_topology_read.h"
#include "../test_common.h"
typedef struct {
std::string type;
uint64_t hops;
uint64_t weight;
bool accessible;
} gpu_link_t;
TestHWTopologyRead::TestHWTopologyRead() : TestBase() {
set_title("RSMI Hardware Topology Read Test");
set_description(
"This test verifies that Hardware Topology can be read properly.");
}
TestHWTopologyRead::~TestHWTopologyRead(void) {
}
void TestHWTopologyRead::SetUp(void) {
TestBase::SetUp();
return;
}
void TestHWTopologyRead::DisplayTestInfo(void) {
TestBase::DisplayTestInfo();
}
void TestHWTopologyRead::DisplayResults(void) const {
TestBase::DisplayResults();
return;
}
void TestHWTopologyRead::Close() {
// This will close handles opened within rsmitst utility calls and call
// rsmi_shut_down(), so it should be done after other cleanup
TestBase::Close();
}
void TestHWTopologyRead::Run(void) {
rsmi_status_t err;
uint32_t i, j;
TestBase::Run();
if (setup_failed_) {
IF_VERB(STANDARD) {
std::cout << "** SetUp Failed for this test. Skipping.**" << std::endl;
}
return;
}
uint32_t num_devices;
err = rsmi_num_monitor_devices(&num_devices);
CHK_ERR_ASRT(err)
// gpu_link_t gpu_links[num_devices][num_devices];
std::vector<std::vector<gpu_link_t>> gpu_links(num_devices,
std::vector<gpu_link_t>(num_devices));
// uint32_t numa_numbers[num_devices];
std::vector<uint32_t> numa_numbers(num_devices);
for (uint32_t dv_ind = 0; dv_ind < num_devices; ++dv_ind) {
err = rsmi_topo_get_numa_node_number(dv_ind, &numa_numbers[dv_ind]);
if (err != RSMI_STATUS_SUCCESS) {
if (err == RSMI_STATUS_NOT_SUPPORTED) {
IF_VERB(STANDARD) {
std::cout <<
"\t**Numa Node Number. read: Not supported on this machine" <<
std::endl;
return;
}
} else {
CHK_ERR_ASRT(err)
}
}
}
for (uint32_t dv_ind_src = 0; dv_ind_src < num_devices; dv_ind_src++) {
for (uint32_t dv_ind_dst = 0; dv_ind_dst < num_devices; dv_ind_dst++) {
if (dv_ind_src == dv_ind_dst) {
gpu_links[dv_ind_src][dv_ind_dst].type = "X";
gpu_links[dv_ind_src][dv_ind_dst].hops = 0;
gpu_links[dv_ind_src][dv_ind_dst].weight = 0;
gpu_links[dv_ind_src][dv_ind_dst].accessible = true;
} else {
RSMI_IO_LINK_TYPE type;
err = rsmi_topo_get_link_type(dv_ind_src, dv_ind_dst,
&gpu_links[dv_ind_src][dv_ind_dst].hops, &type);
if (err != RSMI_STATUS_SUCCESS) {
if (err == RSMI_STATUS_NOT_SUPPORTED) {
IF_VERB(STANDARD) {
std::cout <<
"\t**Link Type. read: Not supported on this machine"
<< std::endl;
return;
}
} else {
CHK_ERR_ASRT(err)
}
} else {
switch (type) {
case RSMI_IOLINK_TYPE_PCIEXPRESS:
gpu_links[dv_ind_src][dv_ind_dst].type = "PCIE";
break;
case RSMI_IOLINK_TYPE_XGMI:
gpu_links[dv_ind_src][dv_ind_dst].type = "XGMI";
break;
default:
gpu_links[dv_ind_src][dv_ind_dst].type = "XXXX";
IF_VERB(STANDARD) {
std::cout << "\t**Invalid IO LINK type. type=" << type <<
std::endl;
}
}
}
err = rsmi_topo_get_link_weight(dv_ind_src, dv_ind_dst,
&gpu_links[dv_ind_src][dv_ind_dst].weight);
if (err != RSMI_STATUS_SUCCESS) {
if (err == RSMI_STATUS_NOT_SUPPORTED) {
IF_VERB(STANDARD) {
std::cout <<
"\t**Link Weight. read: Not supported on this machine"
<< std::endl;
return;
}
} else {
CHK_ERR_ASRT(err)
}
}
err = rsmi_is_P2P_accessible(dv_ind_src, dv_ind_dst,
&gpu_links[dv_ind_src][dv_ind_dst].accessible);
if (err != RSMI_STATUS_SUCCESS) {
if (err == RSMI_STATUS_NOT_SUPPORTED) {
IF_VERB(STANDARD) {
std::cout <<
"\t**P2P Access. check: Not supported on this machine"
<< std::endl;
return;
}
} else {
CHK_ERR_ASRT(err)
}
}
}
}
}
IF_NVERB(STANDARD) {
return;
}
std::cout << "**NUMA node number of GPUs**" << std::endl;
std::cout << std::setw(12) << std::left <<"GPU#";
std::cout <<"NUMA node number";
std::cout << std::endl;
for (i = 0; i < num_devices; ++i) {
std::cout << std::setw(12) << std::left << i;
std::cout << numa_numbers[i];
std::cout << std::endl;
}
std::cout << std::endl;
std::cout << std::endl;
std::string tmp;
std::cout << "**Type between two GPUs**" << std::endl;
std::cout << " ";
for (i = 0; i < num_devices; ++i) {
tmp = "GPU" + std::to_string(i);
std::cout << std::setw(12) << std::left << tmp;
}
std::cout << std::endl;
for (i = 0; i < num_devices; i++) {
tmp = "GPU" + std::to_string(i);
std::cout << std::setw(6) << std::left << tmp;
for (j = 0; j < num_devices; j++) {
if (i == j) {
std::cout << std::setw(12) << std::left << "X";
} else {
std::cout << std::setw(12) << std::left << gpu_links[i][j].type;
}
}
std::cout << std::endl;
}
std::cout << std::endl;
std::cout << "**Hops between two GPUs**" << std::endl;
std::cout << " ";
for (i = 0; i < num_devices; ++i) {
tmp = "GPU" + std::to_string(i);
std::cout << std::setw(12) << std::left << tmp;
}
std::cout << std::endl;
for (i = 0; i < num_devices; i++) {
tmp = "GPU" + std::to_string(i);
std::cout << std::setw(6) << std::left << tmp;
for (j = 0; j < num_devices; j++) {
if (i == j) {
std::cout << std::setw(12) << std::left << "X";
} else {
std::cout << std::setw(12) << std::left << gpu_links[i][j].hops;
}
}
std::cout << std::endl;
}
std::cout << std::endl;
std::cout << "**Weight between two GPUs**" << std::endl;
std::cout << " ";
for (i = 0; i < num_devices; ++i) {
tmp = "GPU" + std::to_string(i);
std::cout << std::setw(12) << std::left << tmp;
}
std::cout << std::endl;
for (i = 0; i < num_devices; i++) {
tmp = "GPU" + std::to_string(i);
std::cout << std::setw(6) << std::left << tmp;
for (j = 0; j < num_devices; j++) {
if (i == j) {
std::cout << std::setw(12) << std::left << "X";
} else {
std::cout << std::setw(12) << std::left << gpu_links[i][j].weight;
}
}
std::cout << std::endl;
}
std::cout << std::endl;
std::cout << "**Access between two GPUs**" << std::endl;
std::cout << " ";
for (i = 0; i < num_devices; ++i) {
tmp = "GPU" + std::to_string(i);
std::cout << std::setw(12) << std::left << tmp;
}
std::cout << std::endl;
for (i = 0; i < num_devices; i++) {
tmp = "GPU" + std::to_string(i);
std::cout << std::setw(6) << std::left << tmp;
for (j = 0; j < num_devices; j++) {
std::cout << std::boolalpha;
std::cout << std::setw(12) << std::left << gpu_links[i][j].accessible;
}
std::cout << std::endl;
}
std::cout << std::endl;
}
@@ -1,73 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2020, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#ifndef TESTS_ROCM_SMI_TEST_FUNCTIONAL_HW_TOPOLOGY_READ_H_
#define TESTS_ROCM_SMI_TEST_FUNCTIONAL_HW_TOPOLOGY_READ_H_
#include "../test_base.h"
class TestHWTopologyRead : public TestBase {
public:
TestHWTopologyRead();
// @Brief: Destructor for test case of TestHWTopologyRead
virtual ~TestHWTopologyRead();
// @Brief: Setup the environment for measurement
virtual void SetUp();
// @Brief: Core measurement execution
virtual void Run();
// @Brief: Clean up and retrieve the resource
virtual void Close();
// @Brief: Display results
virtual void DisplayResults() const;
// @Brief: Display information about what this test does
virtual void DisplayTestInfo(void);
};
#endif // TESTS_ROCM_SMI_TEST_FUNCTIONAL_HW_TOPOLOGY_READ_H_
@@ -1,307 +0,0 @@
/*
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2019, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#include <stdint.h>
#include <stddef.h>
#include <iostream>
#include <string>
#include <gtest/gtest.h>
#include "rocm_smi/rocm_smi.h"
#include "id_info_read.h"
#include "../test_common.h"
TestIdInfoRead::TestIdInfoRead() : TestBase() {
set_title("RSMI ID Info Read Test");
set_description("This test verifies that ID information such as the "
"device, subsystem and vendor IDs can be read properly.");
}
TestIdInfoRead::~TestIdInfoRead(void) {
}
void TestIdInfoRead::SetUp(void) {
TestBase::SetUp();
return;
}
void TestIdInfoRead::DisplayTestInfo(void) {
TestBase::DisplayTestInfo();
}
void TestIdInfoRead::DisplayResults(void) const {
TestBase::DisplayResults();
return;
}
void TestIdInfoRead::Close() {
// This will close handles opened within rsmitst utility calls and call
// rsmi_shut_down(), so it should be done after other hsa cleanup
TestBase::Close();
}
static const uint32_t kBufferLen = 80;
void TestIdInfoRead::Run(void) {
rsmi_status_t err;
uint16_t id;
uint64_t val_ui64;
uint32_t drm_render_minor;
char buffer[kBufferLen];
TestBase::Run();
if (setup_failed_) {
std::cout << "** SetUp Failed for this test. Skipping.**" << std::endl;
return;
}
for (uint32_t i = 0; i < num_monitor_devs(); ++i) {
IF_VERB(STANDARD) {
std::cout << "\t*************************" << std::endl;
std::cout << "\t**Device index: " << i << std::endl;
}
// Get the device ID, name, vendor ID and vendor name for the device
err = rsmi_dev_id_get(i, &id);
if (err == RSMI_STATUS_NOT_SUPPORTED) {
rsmi_status_t ret;
// Verify api support checking functionality is working
ret = rsmi_dev_id_get(i, nullptr);
ASSERT_EQ(ret, RSMI_STATUS_NOT_SUPPORTED);
} else {
CHK_ERR_ASRT(err)
IF_VERB(STANDARD) {
std::cout << "\t**Device ID: 0x" << std::hex << id << std::endl;
}
// Verify api support checking functionality is working
err = rsmi_dev_id_get(i, nullptr);
ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS);
}
err = rsmi_dev_name_get(i, buffer, kBufferLen);
if (err == RSMI_STATUS_NOT_SUPPORTED) {
std::cout << "\t**Device Marketing name not found on this system." <<
std::endl;
// Verify api support checking functionality is working
err = rsmi_dev_name_get(i, nullptr, kBufferLen);
ASSERT_EQ(err, RSMI_STATUS_NOT_SUPPORTED);
} else {
CHK_ERR_ASRT(err)
IF_VERB(STANDARD) {
std::cout << "\t**Device Marketing name: " << buffer << std::endl;
}
// Verify api support checking functionality is working
err = rsmi_dev_name_get(i, nullptr, kBufferLen);
ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS);
}
err = rsmi_dev_brand_get(i, buffer, kBufferLen);
if (err == RSMI_STATUS_NOT_SUPPORTED) {
// Verify api support checking functionality is working
err = rsmi_dev_brand_get(i, nullptr, kBufferLen);
ASSERT_EQ(err, RSMI_STATUS_NOT_SUPPORTED);
} else {
CHK_ERR_ASRT(err)
IF_VERB(STANDARD) {
std::cout << "\t**Device Brand name: " << buffer << std::endl;
}
// Verify api support checking functionality is working
err = rsmi_dev_brand_get(i, nullptr, kBufferLen);
ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS);
}
err = rsmi_dev_vram_vendor_get(i, buffer, kBufferLen);
if (err == RSMI_STATUS_NOT_SUPPORTED) {
std::cout <<
"\t**Vram Vendor string not supported on this system." << std::endl;
err = rsmi_dev_vram_vendor_get(i, nullptr, kBufferLen);
ASSERT_EQ(err, RSMI_STATUS_NOT_SUPPORTED);
} else {
CHK_ERR_ASRT(err)
IF_VERB(STANDARD) {
std::cout << "\t**Device Vram Vendor name: " << buffer << std::endl;
}
err = rsmi_dev_brand_get(i, nullptr, kBufferLen);
ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS);
}
err = rsmi_dev_vendor_id_get(i, &id);
if (err == RSMI_STATUS_NOT_SUPPORTED) {
// Verify api support checking functionality is working
err = rsmi_dev_vendor_id_get(i, nullptr);
ASSERT_EQ(err, RSMI_STATUS_NOT_SUPPORTED);
} else {
CHK_ERR_ASRT(err)
IF_VERB(STANDARD) {
std::cout << "\t**Vendor ID: 0x" << std::hex << id << std::endl;
}
// Verify api support checking functionality is working
err = rsmi_dev_vendor_id_get(i, nullptr);
ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS);
}
err = rsmi_dev_drm_render_minor_get(i, &drm_render_minor);
if (err == RSMI_STATUS_NOT_SUPPORTED) {
// Verify api support checking functionality is working
err = rsmi_dev_drm_render_minor_get(i, nullptr);
ASSERT_EQ(err, RSMI_STATUS_NOT_SUPPORTED);
} else {
CHK_ERR_ASRT(err)
IF_VERB(STANDARD) {
std::cout << "\t**DRM Render Minor: " << drm_render_minor << std::endl;
}
// Verify api support checking functionality is working
err = rsmi_dev_drm_render_minor_get(i, nullptr);
ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS);
}
err = rsmi_dev_vendor_name_get(i, buffer, kBufferLen);
if (err == RSMI_STATUS_NOT_SUPPORTED) {
std::cout << "\t**Device Vendor name string not found on this system." <<
std::endl;
// Verify api support checking functionality is working
err = rsmi_dev_vendor_name_get(i, nullptr, kBufferLen);
ASSERT_EQ(err, RSMI_STATUS_NOT_SUPPORTED);
} else {
CHK_ERR_ASRT(err)
IF_VERB(STANDARD) {
std::cout << "\t**Device Vendor name: " << buffer << std::endl;
}
// Verify api support checking functionality is working
err = rsmi_dev_vendor_name_get(i, nullptr, kBufferLen);
ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS);
}
// Get the device ID, name, vendor ID and vendor name for the sub-device
err = rsmi_dev_subsystem_id_get(i, &id);
if (err == RSMI_STATUS_NOT_SUPPORTED) {
// Verify api support checking functionality is working
err = rsmi_dev_subsystem_id_get(i, nullptr);
ASSERT_EQ(err, RSMI_STATUS_NOT_SUPPORTED);
} else {
CHK_ERR_ASRT(err)
IF_VERB(STANDARD) {
std::cout << "\t**Subsystem ID: 0x" << std::hex << id << std::endl;
}
// Verify api support checking functionality is working
err = rsmi_dev_subsystem_id_get(i, nullptr);
ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS);
}
err = rsmi_dev_subsystem_name_get(i, buffer, kBufferLen);
if (err == RSMI_STATUS_NOT_SUPPORTED) {
std::cout << "\t**Subsystem name string not found on this system." <<
std::endl;
// Verify api support checking functionality is working
err = rsmi_dev_subsystem_name_get(i, nullptr, kBufferLen);
ASSERT_EQ(err, RSMI_STATUS_NOT_SUPPORTED);
} else {
CHK_ERR_ASRT(err)
IF_VERB(STANDARD) {
std::cout << "\t**Subsystem name: " << buffer << std::endl;
}
// Verify api support checking functionality is working
err = rsmi_dev_subsystem_name_get(i, nullptr, kBufferLen);
ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS);
}
err = rsmi_dev_subsystem_vendor_id_get(i, &id);
if (err == RSMI_STATUS_NOT_SUPPORTED) {
// Verify api support checking functionality is working
err = rsmi_dev_subsystem_vendor_id_get(i, nullptr);
ASSERT_EQ(err, RSMI_STATUS_NOT_SUPPORTED);
} else {
CHK_ERR_ASRT(err)
IF_VERB(STANDARD) {
std::cout << "\t**Sub-system Vendor ID: 0x" << std::hex <<
id << std::endl;
}
// Verify api support checking functionality is working
err = rsmi_dev_subsystem_vendor_id_get(i, nullptr);
ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS);
}
err = rsmi_dev_vendor_name_get(i, buffer, kBufferLen);
if (err == RSMI_STATUS_NOT_SUPPORTED) {
std::cout <<
"\t**Subsystem Vendor name string not found on this system." <<
std::endl;
// Verify api support checking functionality is working
err = rsmi_dev_vendor_name_get(i, nullptr, kBufferLen);
ASSERT_EQ(err, RSMI_STATUS_NOT_SUPPORTED);
} else {
CHK_ERR_ASRT(err)
IF_VERB(STANDARD) {
std::cout << "\t**Subsystem Vendor name: " << buffer << std::endl;
}
// Verify api support checking functionality is working
err = rsmi_dev_vendor_name_get(i, nullptr, kBufferLen);
ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS);
}
err = rsmi_dev_pci_id_get(i, &val_ui64);
// Don't check for RSMI_STATUS_NOT_SUPPORTED since this should always be
// supported. It is not based on a sysfs file.
CHK_ERR_ASRT(err)
IF_VERB(STANDARD) {
std::cout << "\t**PCI ID (BDFID): 0x" << std::hex << val_ui64;
std::cout << " (" << std::dec << val_ui64 << ")" << std::endl;
}
// Verify api support checking functionality is working
err = rsmi_dev_pci_id_get(i, nullptr);
ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS);
err = rsmi_dev_serial_number_get(i, buffer, kBufferLen);
if (err == RSMI_STATUS_NOT_SUPPORTED) {
// Verify api support checking functionality is working
err = rsmi_dev_serial_number_get(i, nullptr, kBufferLen);
ASSERT_EQ(err, RSMI_STATUS_NOT_SUPPORTED);
std::cout <<
"\t**Serial Number string not supported on this system." << std::endl;
} else {
CHK_ERR_ASRT(err)
IF_VERB(STANDARD) {
std::cout << "\t**Device Serial Number:" << buffer << std::endl;
}
// Verify api support checking functionality is working
err = rsmi_dev_serial_number_get(i, nullptr, kBufferLen);
ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS);
}
}
}
@@ -1,73 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2019, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#ifndef TESTS_ROCM_SMI_TEST_FUNCTIONAL_ID_INFO_READ_H_
#define TESTS_ROCM_SMI_TEST_FUNCTIONAL_ID_INFO_READ_H_
#include "../test_base.h"
class TestIdInfoRead : public TestBase {
public:
TestIdInfoRead();
// @Brief: Destructor for test case of TestIdInfoRead
virtual ~TestIdInfoRead();
// @Brief: Setup the environment for measurement
virtual void SetUp();
// @Brief: Core measurement execution
virtual void Run();
// @Brief: Clean up and retrive the resource
virtual void Close();
// @Brief: Display results
virtual void DisplayResults() const;
// @Brief: Display information about what this test does
virtual void DisplayTestInfo(void);
};
#endif // TESTS_ROCM_SMI_TEST_FUNCTIONAL_ID_INFO_READ_H_
@@ -1,240 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2020, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#include <pthread.h>
#include <algorithm>
#include <iostream>
#include <thread> // NOLINT
#include <random>
#include <chrono> // NOLINT
#include "init_shutdown_refcount.h"
#include <gtest/gtest.h>
#include "rocm_smi/rocm_smi.h"
#include "../test_common.h"
extern int32_t
rsmi_test_refcount(uint64_t refcnt_type);
static void rand_sleep_mod(int msec) {
assert(msec > 10);
unsigned int seed = time(NULL);
std::mt19937_64 eng{seed};
std::uniform_int_distribution<> dist{10, msec};
std::this_thread::sleep_for(std::chrono::milliseconds{dist(eng)});
}
static void* RSMIInitFunction(void* args) {
rsmi_status_t status;
(void)args;
rand_sleep_mod(100);
status = rsmi_init(0);
EXPECT_EQ(RSMI_STATUS_SUCCESS, status);
pthread_exit(nullptr);
return nullptr;
}
static void* RSMIShutDownFunction(void* args) {
rsmi_status_t status;
(void)args;
rand_sleep_mod(100);
status = rsmi_shut_down();
EXPECT_EQ(RSMI_STATUS_SUCCESS, status);
pthread_exit(nullptr);
return nullptr;
}
static void *RSMIInitShutDownFunction(void* args) {
rsmi_status_t status;
(void)args;
rand_sleep_mod(100);
status = rsmi_init(0);
EXPECT_EQ(RSMI_STATUS_SUCCESS, status);
rand_sleep_mod(100);
status = rsmi_shut_down();
EXPECT_EQ(RSMI_STATUS_SUCCESS, status);
pthread_exit(nullptr);
return nullptr;
}
static const int NumOfThreads = 100;
TestConcurrentInit::TestConcurrentInit(void) : TestBase() {
set_title("RSMI Concurrent Init Test");
set_description("This test initializes RSMI concurrently to verify "
"reference counting functionality.");
}
TestConcurrentInit::~TestConcurrentInit(void) {
}
void TestConcurrentInit::SetUp(void) {
// TestBase::SetUp(); // Skip usual SetUp to avoid doing the usual rsmi_init
return;
}
// Compare required profile for this test case with what we're actually
// running on
void TestConcurrentInit::DisplayTestInfo(void) {
IF_VERB(STANDARD) {
TestBase::DisplayTestInfo();
}
return;
}
void TestConcurrentInit::DisplayResults(void) const {
IF_VERB(STANDARD) {
TestBase::DisplayResults();
}
return;
}
void TestConcurrentInit::Close() {
// This will close handles opened within rsmitst utility calls and call
// rsmi_shut_down(), so it should be done after other hsa cleanup
TestBase::Close();
}
// Compare required profile for this test case with what we're actually
// running on
void TestConcurrentInit::Run(void) {
if (setup_failed_) {
IF_VERB(STANDARD) {
std::cout << "** SetUp Failed for this test. Skipping.**" << std::endl;
}
return;
}
pthread_t ThreadId[NumOfThreads];
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
IF_VERB(STANDARD) {
std::cout << "Testing concurrent rsmi_init()..." << std::endl;
}
for (int Id = 0; Id < NumOfThreads; ++Id) {
int ThreadStatus = pthread_create(&ThreadId[Id], &attr,
RSMIInitFunction, nullptr);
ASSERT_EQ(0, ThreadStatus) << "pthead_create failed.";
}
for (int Id = 0; Id < NumOfThreads; ++Id) {
int err = pthread_join(ThreadId[Id], nullptr);
ASSERT_EQ(0, err) << "pthread_join failed.";
}
// Invoke hsa_shut_down and verify that all the hsa_init's were counted.
// HSA should be exactly closed after NumOfThreads calls.
for (int Id = 0; Id < NumOfThreads; ++Id) {
rsmi_status_t err = rsmi_shut_down();
ASSERT_EQ(RSMI_STATUS_SUCCESS, err) << "An rsmi_init was missed.";
}
rsmi_status_t err = rsmi_shut_down();
ASSERT_EQ(RSMI_INITIALIZATION_ERROR, err) <<
"rsmi_init reference count was too high.";
int32_t refcnt = rsmi_test_refcount(0);
ASSERT_EQ(0, refcnt);
IF_VERB(STANDARD) {
std::cout << "Concurrent rsmi_init() test passed." <<
std::endl << std::endl;
std::cout << "Testing concurrent rsmi_shut_down()..." << std::endl;
}
// Invoke hsa_shut_down and verify that all the hsa_init's were counted.
// HSA should be exactly closed after NumOfThreads calls.
for (int Id = 0; Id < NumOfThreads; ++Id) {
rsmi_status_t err = rsmi_init(0);
ASSERT_EQ(RSMI_STATUS_SUCCESS, err);
}
for (int Id = 0; Id < NumOfThreads; ++Id) {
int ThreadStatus =
pthread_create(&ThreadId[Id], &attr, RSMIShutDownFunction, nullptr);
ASSERT_EQ(0, ThreadStatus) << "pthead_create failed.";
}
for (int Id = 0; Id < NumOfThreads; ++Id) {
int err = pthread_join(ThreadId[Id], nullptr);
ASSERT_EQ(0, err) << "pthread_join failed.";
}
refcnt = rsmi_test_refcount(0);
ASSERT_EQ(0, refcnt);
IF_VERB(STANDARD) {
std::cout << "Concurrent rsmi_shut_down() passed." << std::endl;
std::cout <<
"Testing concurrent rsmi_init() followed by rsmi_shut_down()..." <<
std::endl;
}
for (int Id = 0; Id < NumOfThreads; ++Id) {
int ThreadStatus =
pthread_create(&ThreadId[Id], &attr, RSMIInitShutDownFunction, nullptr);
ASSERT_EQ(0, ThreadStatus) << "pthead_create failed.";
}
for (int Id = 0; Id < NumOfThreads; ++Id) {
int err = pthread_join(ThreadId[Id], nullptr);
ASSERT_EQ(0, err) << "pthread_join failed.";
}
refcnt = rsmi_test_refcount(0);
ASSERT_EQ(0, refcnt);
IF_VERB(STANDARD) {
std::cout <<
"Concurrent rsmi_init() followed by rsmi_shut_down() passed." <<
std::endl;
}
}
@@ -1,74 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2020, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#ifndef TESTS_ROCM_SMI_TEST_FUNCTIONAL_INIT_SHUTDOWN_REFCOUNT_H_
#define TESTS_ROCM_SMI_TEST_FUNCTIONAL_INIT_SHUTDOWN_REFCOUNT_H_
#include "../test_base.h"
class TestConcurrentInit : public TestBase {
public:
TestConcurrentInit();
// @Brief: Destructor for the TestConcurrentInit class
virtual ~TestConcurrentInit();
// @Brief: Setup the environment for measurement
virtual void SetUp();
// @Brief: Core measurement execution
virtual void Run();
// @Brief: Clean up and retrive the resource
virtual void Close();
// @Brief: Display results
virtual void DisplayResults() const;
// @Brief: Display information about what this test does
virtual void DisplayTestInfo(void);
};
#endif // TESTS_ROCM_SMI_TEST_FUNCTIONAL_INIT_SHUTDOWN_REFCOUNT_H_
@@ -1,169 +0,0 @@
/*
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2019, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#include <stdint.h>
#include <stddef.h>
#include <iostream>
#include <string>
#include <gtest/gtest.h>
#include "rocm_smi/rocm_smi.h"
#include "mem_page_info_read.h"
#include "../test_common.h"
TestMemPageInfoRead::TestMemPageInfoRead() : TestBase() {
set_title("RSMI Memory Page Info Test");
set_description("The Memory Page Info. test verifies that we can read "
"memory page information, and then displays the information read");
}
TestMemPageInfoRead::~TestMemPageInfoRead(void) {
}
void TestMemPageInfoRead::SetUp(void) {
TestBase::SetUp();
return;
}
void TestMemPageInfoRead::DisplayTestInfo(void) {
TestBase::DisplayTestInfo();
}
void TestMemPageInfoRead::DisplayResults(void) const {
TestBase::DisplayResults();
return;
}
void TestMemPageInfoRead::Close() {
// This will close handles opened within rsmitst utility calls and call
// rsmi_shut_down(), so it should be done after other hsa cleanup
TestBase::Close();
}
void TestMemPageInfoRead::Run(void) {
rsmi_status_t err;
rsmi_retired_page_record_t *records;
uint32_t num_pages;
TestBase::Run();
if (setup_failed_) {
std::cout << "** SetUp Failed for this test. Skipping.**" << std::endl;
return;
}
for (uint32_t i = 0; i < num_monitor_devs(); ++i) {
PrintDeviceHeader(i);
err = rsmi_dev_memory_reserved_pages_get(i, &num_pages, nullptr);
if (err == RSMI_STATUS_NOT_SUPPORTED) {
std::cout <<
"\t**Memory page information is not supported for this device"
<< std::endl;
// Verify api support checking functionality is working
err = rsmi_dev_memory_reserved_pages_get(i, nullptr, nullptr);
ASSERT_EQ(err, RSMI_STATUS_NOT_SUPPORTED);
continue;
} else {
CHK_ERR_ASRT(err)
IF_VERB(STANDARD) {
std::cout << "\tNumber of memory page records: " << num_pages <<
std::endl;
}
// Verify api support checking functionality is working
err = rsmi_dev_memory_reserved_pages_get(i, nullptr, nullptr);
ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS);
}
if (num_pages > 0) {
records = new rsmi_retired_page_record_t[num_pages];
assert(records != nullptr);
err = rsmi_dev_memory_reserved_pages_get(i, &num_pages, records);
if (err == RSMI_STATUS_NOT_SUPPORTED) {
std::cout << "\t**Getting Memory Page Retirement Status not "
"supported for this device" << std::endl;
continue;
} else {
CHK_ERR_ASRT(err)
}
IF_VERB(STANDARD) {
std::cout.setf(std::ios::hex, std::ios::basefield);
std::string page_state;
for (uint32_t p = 0; p < num_pages; ++p) {
std::cout << "\t\tAddress: 0x" << records[p].page_address;
std::cout << " Size: " << records[p].page_size;
switch (records[p].status) {
case RSMI_MEM_PAGE_STATUS_RESERVED:
page_state = "Retired";
break;
case RSMI_MEM_PAGE_STATUS_PENDING:
page_state = "Pending";
break;
case RSMI_MEM_PAGE_STATUS_UNRESERVABLE:
page_state = "Unreservable";
break;
default:
ASSERT_EQ(0, 1) << "Unexpected memory page status";
}
std::cout << " Status: " << page_state << std::endl;
}
std::cout.setf(std::ios::dec, std::ios::basefield);
}
delete []records;
} else {
continue;
}
}
}
@@ -1,71 +0,0 @@
/*
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2019, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#ifndef TESTS_ROCM_SMI_TEST_FUNCTIONAL_MEM_PAGE_INFO_READ_H_
#define TESTS_ROCM_SMI_TEST_FUNCTIONAL_MEM_PAGE_INFO_READ_H_
#include "../test_base.h"
class TestMemPageInfoRead : public TestBase {
public:
TestMemPageInfoRead();
// @Brief: Destructor for test case of TestMemPageInfoRead
virtual ~TestMemPageInfoRead();
// @Brief: Setup the environment for measurement
virtual void SetUp();
// @Brief: Core measurement execution
virtual void Run();
// @Brief: Clean up and retrive the resource
virtual void Close();
// @Brief: Display results
virtual void DisplayResults() const;
// @Brief: Display information about what this test does
virtual void DisplayTestInfo(void);
};
#endif // TESTS_ROCM_SMI_TEST_FUNCTIONAL_MEM_PAGE_INFO_READ_H_
@@ -1,158 +0,0 @@
/*
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2019, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#include <stdint.h>
#include <stddef.h>
#include <iostream>
#include <string>
#include <map>
#include <gtest/gtest.h>
#include "rocm_smi/rocm_smi.h"
#include "mem_util_read.h"
#include "../test_common.h"
TestMemUtilRead::TestMemUtilRead() : TestBase() {
set_title("Memory Utilization Read Test");
set_description("The Memory Utilization Read tests verifies that "
"memory busy percent, size and amount used can be read properly.");
}
TestMemUtilRead::~TestMemUtilRead(void) {
}
void TestMemUtilRead::SetUp(void) {
TestBase::SetUp();
return;
}
void TestMemUtilRead::DisplayTestInfo(void) {
TestBase::DisplayTestInfo();
}
void TestMemUtilRead::DisplayResults(void) const {
TestBase::DisplayResults();
return;
}
void TestMemUtilRead::Close() {
// This will close handles opened within rsmitst utility calls and call
// rsmi_shut_down(), so it should be done after other hsa cleanup
TestBase::Close();
}
static const std::map<rsmi_memory_type_t, const char *>
kDevMemoryTypeNameMap = {
{RSMI_MEM_TYPE_VRAM, "VRAM memory"},
{RSMI_MEM_TYPE_VIS_VRAM, "Visible VRAM memory"},
{RSMI_MEM_TYPE_GTT, "GTT memory"},
};
void TestMemUtilRead::Run(void) {
rsmi_status_t err;
uint64_t total;
uint64_t usage;
TestBase::Run();
if (setup_failed_) {
std::cout << "** SetUp Failed for this test. Skipping.**" << std::endl;
return;
}
auto err_chk = [&](const char *str) {
if (err != RSMI_STATUS_SUCCESS) {
if (err == RSMI_STATUS_FILE_ERROR) {
IF_VERB(STANDARD) {
std::cout << "\t** " << str << ": Not supported on this machine"
<< std::endl;
}
} else {
CHK_ERR_ASRT(err)
}
}
};
for (uint32_t x = 0; x < num_iterations(); ++x) {
for (uint32_t i = 0; i < num_monitor_devs(); ++i) {
PrintDeviceHeader(i);
#if 0
err = rsmi_dev_memory_busy_percent_get(i, &mem_busy_percent);
err_chk("rsmi_dev_memory_busy_percent_get()");
if (err != RSMI_STATUS_SUCCESS) {
return;
}
IF_VERB(STANDARD) {
std::cout << "\t**" << "GPU Memory Busy %: " << mem_busy_percent <<
std::endl;
}
#endif
for (uint32_t mem_type = RSMI_MEM_TYPE_FIRST;
mem_type <= RSMI_MEM_TYPE_LAST; ++mem_type) {
err = rsmi_dev_memory_total_get(i,
static_cast<rsmi_memory_type_t>(mem_type), &total);
err_chk("rsmi_dev_memory_total_get()");
if (err != RSMI_STATUS_SUCCESS) {
return;
}
err = rsmi_dev_memory_usage_get(i,
static_cast<rsmi_memory_type_t>(mem_type), &usage);
err_chk("rsmi_dev_memory_usage_get()");
if (err != RSMI_STATUS_SUCCESS) {
return;
}
IF_VERB(STANDARD) {
std::cout << "\t**" <<
kDevMemoryTypeNameMap.at(static_cast<rsmi_memory_type_t>(mem_type))
<< " Calculated Utilization: " <<
(static_cast<float>(usage)*100)/total << "% ("<< usage <<
"/" << total << ")" << std::endl;
}
}
}
}
}
@@ -1,71 +0,0 @@
/*
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2019, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#ifndef TESTS_ROCM_SMI_TEST_FUNCTIONAL_MEM_UTIL_READ_H_
#define TESTS_ROCM_SMI_TEST_FUNCTIONAL_MEM_UTIL_READ_H_
#include "../test_base.h"
class TestMemUtilRead : public TestBase {
public:
TestMemUtilRead();
// @Brief: Destructor for test case of TestMemUtilRead
virtual ~TestMemUtilRead();
// @Brief: Setup the environment for measurement
virtual void SetUp();
// @Brief: Core measurement execution
virtual void Run();
// @Brief: Clean up and retrive the resource
virtual void Close();
// @Brief: Display results
virtual void DisplayResults() const;
// @Brief: Display information about what this test does
virtual void DisplayTestInfo(void);
};
#endif // TESTS_ROCM_SMI_TEST_FUNCTIONAL_MEM_UTIL_READ_H_
@@ -1,165 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2021, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#include <stdint.h>
#include <stddef.h>
#include <iostream>
#include <string>
#include <map>
#include <gtest/gtest.h>
#include "rocm_smi/rocm_smi.h"
#include "metrics_counter_read.h"
#include "../test_common.h"
TestMetricsCounterRead::TestMetricsCounterRead() : TestBase() {
set_title("RSMI GPU Metrics Counter Read Test");
set_description("The GPU Metrics Counter tests verifies that "
"the gpu metrics counter info can be read properly.");
}
TestMetricsCounterRead::~TestMetricsCounterRead(void) {
}
void TestMetricsCounterRead::SetUp(void) {
TestBase::SetUp();
return;
}
void TestMetricsCounterRead::DisplayTestInfo(void) {
TestBase::DisplayTestInfo();
}
void TestMetricsCounterRead::DisplayResults(void) const {
TestBase::DisplayResults();
return;
}
void TestMetricsCounterRead::Close() {
// This will close handles opened within rsmitst utility calls and call
// rsmi_shut_down(), so it should be done after other hsa cleanup
TestBase::Close();
}
void TestMetricsCounterRead::Run(void) {
rsmi_status_t err;
TestBase::Run();
if (setup_failed_) {
std::cout << "** SetUp Failed for this test. Skipping.**" << std::endl;
return;
}
for (uint32_t i = 0; i < num_monitor_devs(); ++i) {
PrintDeviceHeader(i);
IF_VERB(STANDARD) {
std::cout << "\t**GPU METRICS ENERGY COUNTER:\n";
}
uint64_t power;
uint64_t timestamp;
float counter_resolution;
err = rsmi_dev_energy_count_get(i, &power, &counter_resolution, &timestamp);
if (err != RSMI_STATUS_SUCCESS) {
if (err == RSMI_STATUS_NOT_SUPPORTED) {
IF_VERB(STANDARD) {
std::cout << "\t**" <<
"Not supported on this machine" << std::endl;
return;
}
}
} else {
CHK_ERR_ASRT(err);
IF_VERB(STANDARD) {
std::cout << std::dec << "power counter="
<< power << '\n';
std::cout << "power in uJ="
<< (double)(power * counter_resolution) << '\n';
std::cout << std::dec << "timestamp="
<< timestamp << '\n';
}
}
// Verify api support checking functionality is working
err = rsmi_dev_energy_count_get(i, nullptr, nullptr, nullptr);
ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS);
// Coarse Grain counters
rsmi_utilization_counter_t utilization_counters[2];
utilization_counters[0].type = RSMI_COARSE_GRAIN_GFX_ACTIVITY;
utilization_counters[1].type = RSMI_COARSE_GRAIN_MEM_ACTIVITY;
err = rsmi_utilization_count_get(i, utilization_counters,
2, &timestamp);
if (err != RSMI_STATUS_SUCCESS) {
if (err == RSMI_STATUS_NOT_SUPPORTED) {
IF_VERB(STANDARD) {
std::cout << "\t**" <<
"Not supported on this machine" << std::endl;
return;
}
}
} else {
CHK_ERR_ASRT(err);
IF_VERB(STANDARD) {
std::cout << std::dec << "gfx_activity="
<< utilization_counters[0].value << '\n';
std::cout << std::dec << "mem_activity="
<< utilization_counters[1].value << '\n';
std::cout << std::dec << "timestamp="
<< timestamp << '\n';
}
}
// Verify api support checking functionality is working
err = rsmi_utilization_count_get(i, nullptr,
1 , nullptr);
ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS);
} // end for
}
@@ -1,73 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2021, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#ifndef TESTS_ROCM_SMI_TEST_FUNCTIONAL_METRICS_COUNTER_READ_H_
#define TESTS_ROCM_SMI_TEST_FUNCTIONAL_METRICS_COUNTER_READ_H_
#include "../test_base.h"
class TestMetricsCounterRead : public TestBase {
public:
TestMetricsCounterRead();
// @Brief: Destructor for test case of TestVOltRead
virtual ~TestMetricsCounterRead();
// @Brief: Setup the environment for measurement
virtual void SetUp();
// @Brief: Core measurement execution
virtual void Run();
// @Brief: Clean up and retrive the resource
virtual void Close();
// @Brief: Display results
virtual void DisplayResults() const;
// @Brief: Display information about what this test does
virtual void DisplayTestInfo(void);
};
#endif // TESTS_ROCM_SMI_TEST_FUNCTIONAL_METRICS_COUNTER_READ_H_
@@ -1,324 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2020, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#include <stdint.h>
#include <stddef.h>
#include <iostream>
#include <string>
#include <map>
#include <gtest/gtest.h>
#include "rocm_smi/rocm_smi.h"
#include "mutual_exclusion.h"
#include "../test_common.h"
TestMutualExclusion::TestMutualExclusion() : TestBase() {
set_title("Mutual Exclusion Test");
set_description("Verify that RSMI only allows 1 process at a time"
" to access RSMI resources (primarily sysfs files). This test has one "
"process that obtains the mutex that ensures only 1 process accesses a "
"device's sysfs files at a time, and another process that attempts "
"to access the device's sysfs files. The second process should fail "
"in these attempts.");
}
TestMutualExclusion::~TestMutualExclusion(void) {
}
extern rsmi_status_t rsmi_test_sleep(uint32_t dv_ind, uint32_t seconds);
void TestMutualExclusion::SetUp(void) {
std::string label;
rsmi_status_t ret;
// TestBase::SetUp(RSMI_INIT_FLAG_RESRV_TEST1);
IF_VERB(STANDARD) {
MakeHeaderStr(kSetupLabel, &label);
printf("\n\t%s\n", label.c_str());
}
sleeper_process_ = false;
child_ = 0;
child_ = fork();
if (child_ != 0) {
sleeper_process_ = true; // sleeper_process is parent
// RSMI_INIT_FLAG_RESRV_TEST1 tells rsmi to fail immediately
// if it can't get the mutex instead of waiting.
ret = rsmi_init(RSMI_INIT_FLAG_RESRV_TEST1);
if (ret != RSMI_STATUS_SUCCESS) {
setup_failed_ = true;
}
ASSERT_EQ(ret, RSMI_STATUS_SUCCESS);
sleep(2); // Let both processes get through rsmi_init
} else {
sleep(1); // Let the sleeper process get through rsmi_init() before
// this one goes, so it doesn't fail.
ret = rsmi_init(RSMI_INIT_FLAG_RESRV_TEST1);
if (ret != RSMI_STATUS_SUCCESS) {
setup_failed_ = true;
}
ASSERT_EQ(ret, RSMI_STATUS_SUCCESS);
sleep(2); // Let both processes get through rsmi_init;
}
ret = rsmi_num_monitor_devices(&num_monitor_devs_);
if (ret != RSMI_STATUS_SUCCESS) {
setup_failed_ = true;
}
ASSERT_EQ(ret, RSMI_STATUS_SUCCESS);
if (num_monitor_devs_ == 0) {
std::cout << "No monitor devices found on this machine." << std::endl;
std::cout << "No ROCm SMI tests can be run." << std::endl;
setup_failed_ = true;
}
return;
}
void TestMutualExclusion::DisplayTestInfo(void) {
IF_VERB(STANDARD) {
TestBase::DisplayTestInfo();
}
}
void TestMutualExclusion::DisplayResults(void) const {
IF_VERB(STANDARD) {
TestBase::DisplayResults();
}
return;
}
void TestMutualExclusion::Close() {
// This will close handles opened within rsmitst utility calls and call
// rsmi_shut_down(), so it should be done after other hsa cleanup
TestBase::Close();
}
extern rsmi_status_t
rsmi_test_sleep(uint32_t dv_ind, uint32_t seconds);
void TestMutualExclusion::Run(void) {
rsmi_status_t ret;
if (setup_failed_) {
std::cout << "** SetUp Failed for this test. Skipping.**" << std::endl;
return;
}
if (sleeper_process_) {
IF_VERB(STANDARD) {
std::cout << "MUTEX_HOLDER process: started sleeping for 10 seconds..." <<
std::endl;
}
ret = rsmi_test_sleep(0, 10);
ASSERT_EQ(ret, RSMI_STATUS_SUCCESS);
IF_VERB(STANDARD) {
std::cout << "MUTEX_HOLDER process: Sleep process woke up." << std::endl;
}
pid_t cpid = wait(nullptr);
ASSERT_EQ(cpid, child_);
} else {
// Both processes should have completed rsmi_init().
// let the other process get started on rsmi_test_sleep().
sleep(2);
TestBase::Run();
IF_VERB(STANDARD) {
std::cout << "TESTER process: verifing that all rsmi_dev_* functions "
"return RSMI_STATUS_BUSY because MUTEX_HOLDER process "
"holds the mutex" << std::endl;
}
// Try all the device related rsmi calls. They should all fail with
// RSMI_STATUS_BUSY
// Set dummy values should to working, deterministic values.
uint16_t dmy_ui16 = 0;
uint32_t dmy_ui32 = 1;
int32_t dmy_i32 = 0;
uint64_t dmy_ui64 = 0;
int64_t dmy_i64 = 0;
char dmy_str[10];
rsmi_dev_perf_level_t dmy_perf_lvl;
rsmi_frequencies_t dmy_freqs;
rsmi_od_volt_freq_data_t dmy_od_volt;
rsmi_freq_volt_region_t dmy_vlt_reg;
rsmi_error_count_t dmy_err_cnt;
rsmi_ras_err_state_t dmy_ras_err_st;
// This can be replaced with ASSERT_EQ() once env. stabilizes
#define CHECK_RET(A, B) { \
if ((A) != (B)) { \
std::cout << "Expected return value of " << B << \
" but got " << A << std::endl; \
std::cout << "at " << __FILE__ << ":" << __LINE__ << std::endl; \
} \
}
ret = rsmi_dev_id_get(0, &dmy_ui16);
CHECK_RET(ret, RSMI_STATUS_BUSY);
ret = rsmi_dev_vendor_id_get(0, &dmy_ui16);
CHECK_RET(ret, RSMI_STATUS_BUSY);
ret = rsmi_dev_name_get(0, dmy_str, 10);
CHECK_RET(ret, RSMI_STATUS_BUSY);
ret = rsmi_dev_brand_get(0, dmy_str, 10);
CHECK_RET(ret, RSMI_STATUS_BUSY);
ret = rsmi_dev_vendor_name_get(0, dmy_str, 10);
CHECK_RET(ret, RSMI_STATUS_BUSY);
ret = rsmi_dev_vram_vendor_get(0, dmy_str, 10);
CHECK_RET(ret, RSMI_STATUS_BUSY);
ret = rsmi_dev_serial_number_get(0, dmy_str, 10);
CHECK_RET(ret, RSMI_STATUS_BUSY);
ret = rsmi_dev_subsystem_id_get(0, &dmy_ui16);
CHECK_RET(ret, RSMI_STATUS_BUSY);
ret = rsmi_dev_subsystem_vendor_id_get(0, &dmy_ui16);
CHECK_RET(ret, RSMI_STATUS_BUSY);
ret = rsmi_dev_unique_id_get(0, &dmy_ui64);
CHECK_RET(ret, RSMI_STATUS_BUSY);
ret = rsmi_dev_pci_id_get(0, &dmy_ui64);
CHECK_RET(ret, RSMI_STATUS_BUSY);
ret = rsmi_dev_pci_throughput_get(0, &dmy_ui64, &dmy_ui64, &dmy_ui64);
CHECK_RET(ret, RSMI_STATUS_BUSY);
ret = rsmi_dev_pci_replay_counter_get(0, &dmy_ui64);
CHECK_RET(ret, RSMI_STATUS_BUSY);
ret = rsmi_dev_pci_bandwidth_set(0, 0);
CHECK_RET(ret, RSMI_STATUS_BUSY);
ret = rsmi_dev_fan_rpms_get(0, dmy_ui32, &dmy_i64);
CHECK_RET(ret, RSMI_STATUS_BUSY);
ret = rsmi_dev_fan_speed_get(0, 0, &dmy_i64);
CHECK_RET(ret, RSMI_STATUS_BUSY);
ret = rsmi_dev_fan_speed_max_get(0, 0, &dmy_ui64);
CHECK_RET(ret, RSMI_STATUS_BUSY);
ret = rsmi_dev_temp_metric_get(0, dmy_ui32, RSMI_TEMP_CURRENT, &dmy_i64);
CHECK_RET(ret, RSMI_STATUS_BUSY);
ret = rsmi_dev_fan_reset(0, 0);
CHECK_RET(ret, RSMI_STATUS_BUSY);
ret = rsmi_dev_fan_speed_set(0, dmy_ui32, 0);
CHECK_RET(ret, RSMI_STATUS_BUSY);
ret = rsmi_dev_perf_level_get(0, &dmy_perf_lvl);
CHECK_RET(ret, RSMI_STATUS_BUSY);
ret = rsmi_dev_overdrive_level_get(0, &dmy_ui32);
CHECK_RET(ret, RSMI_STATUS_BUSY);
ret = rsmi_dev_gpu_clk_freq_get(0, RSMI_CLK_TYPE_SYS, &dmy_freqs);
CHECK_RET(ret, RSMI_STATUS_BUSY);
ret = rsmi_dev_od_volt_info_get(0, &dmy_od_volt);
CHECK_RET(ret, RSMI_STATUS_BUSY);
ret = rsmi_dev_od_volt_curve_regions_get(0, &dmy_ui32, &dmy_vlt_reg);
CHECK_RET(ret, RSMI_STATUS_BUSY);
ret = rsmi_dev_overdrive_level_set_v1(dmy_i32, 0);
CHECK_RET(ret, RSMI_STATUS_BUSY);
ret = rsmi_dev_gpu_clk_freq_set(0, RSMI_CLK_TYPE_SYS, 0);
CHECK_RET(ret, RSMI_STATUS_BUSY);
ret = rsmi_dev_ecc_count_get(0, RSMI_GPU_BLOCK_UMC, &dmy_err_cnt);
CHECK_RET(ret, RSMI_STATUS_BUSY);
ret = rsmi_dev_ecc_enabled_get(0, &dmy_ui64);
CHECK_RET(ret, RSMI_STATUS_BUSY);
ret = rsmi_dev_ecc_status_get(0, RSMI_GPU_BLOCK_UMC, &dmy_ras_err_st);
CHECK_RET(ret, RSMI_STATUS_BUSY);
/* Other functions holding device mutexes. Listed for reference.
rsmi_dev_sku_get
rsmi_dev_perf_level_set_v1
rsmi_dev_od_clk_info_set
rsmi_dev_od_volt_info_set
rsmi_dev_firmware_version_get
rsmi_dev_firmware_version_get
rsmi_dev_name_get
rsmi_dev_brand_get
rsmi_dev_vram_vendor_get
rsmi_dev_subsystem_name_get
rsmi_dev_drm_render_minor_get
rsmi_dev_vendor_name_get
rsmi_dev_pci_bandwidth_get
rsmi_dev_pci_bandwidth_set
rsmi_dev_pci_throughput_get
rsmi_dev_temp_metric_get
rsmi_dev_volt_metric_get
rsmi_dev_fan_speed_get
rsmi_dev_fan_rpms_get
rsmi_dev_fan_reset
rsmi_dev_fan_speed_set
rsmi_dev_fan_speed_max_get
rsmi_dev_od_volt_info_get
rsmi_dev_gpu_metrics_info_get
rsmi_dev_od_volt_curve_regions_get
rsmi_dev_power_max_get
rsmi_dev_power_ave_get
rsmi_dev_power_cap_get
rsmi_dev_power_cap_range_get
rsmi_dev_power_cap_set
rsmi_dev_power_profile_presets_get
rsmi_dev_power_profile_set
rsmi_dev_memory_total_get
rsmi_dev_memory_usage_get
rsmi_dev_memory_busy_percent_get
rsmi_dev_busy_percent_get
rsmi_dev_vbios_version_get
rsmi_dev_serial_number_get
rsmi_dev_pci_replay_counter_get
rsmi_dev_unique_id_get
rsmi_dev_counter_create
rsmi_counter_available_counters_get
rsmi_dev_counter_group_supported
rsmi_dev_memory_reserved_pages_get
rsmi_dev_xgmi_error_status
rsmi_dev_xgmi_error_reset
rsmi_dev_xgmi_hive_id_get
rsmi_topo_get_link_weight
rsmi_event_notification_mask_set
rsmi_event_notification_init
rsmi_event_notification_stop
*/
IF_VERB(STANDARD) {
std::cout << "TESTER process: Finished verifying that all "
"rsmi_dev_* functions returned RSMI_STATUS_BUSY" << std::endl;
}
exit(0);
}
}
@@ -1,77 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2020, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#ifndef TESTS_ROCM_SMI_TEST_FUNCTIONAL_MUTUAL_EXCLUSION_H_
#define TESTS_ROCM_SMI_TEST_FUNCTIONAL_MUTUAL_EXCLUSION_H_
#include "../test_base.h"
class TestMutualExclusion : public TestBase {
public:
TestMutualExclusion();
// @Brief: Destructor for test case of TestMutualExclusion
virtual ~TestMutualExclusion();
// @Brief: Setup the environment for measurement
virtual void SetUp();
// @Brief: Core measurement execution
virtual void Run();
// @Brief: Clean up and retrive the resource
virtual void Close();
// @Brief: Display results
virtual void DisplayResults() const;
// @Brief: Display information about what this test does
virtual void DisplayTestInfo(void);
private:
bool sleeper_process_;
int child_;
};
#endif // TESTS_ROCM_SMI_TEST_FUNCTIONAL_MUTUAL_EXCLUSION_H_
@@ -1,110 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2019, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#include <stdint.h>
#include <stddef.h>
#include <iostream>
#include <string>
#include <gtest/gtest.h>
#include "rocm_smi/rocm_smi.h"
#include "overdrive_read.h"
#include "../test_common.h"
TestOverdriveRead::TestOverdriveRead() : TestBase() {
set_title("RSMI Overdrive Read Test");
set_description("The Overdrive Read tests verifies that the "
"current overdrive level can be read properly.");
}
TestOverdriveRead::~TestOverdriveRead(void) {
}
void TestOverdriveRead::SetUp(void) {
TestBase::SetUp();
return;
}
void TestOverdriveRead::DisplayTestInfo(void) {
TestBase::DisplayTestInfo();
}
void TestOverdriveRead::DisplayResults(void) const {
TestBase::DisplayResults();
return;
}
void TestOverdriveRead::Close() {
// This will close handles opened within rsmitst utility calls and call
// rsmi_shut_down(), so it should be done after other hsa cleanup
TestBase::Close();
}
void TestOverdriveRead::Run(void) {
rsmi_status_t err;
uint32_t val_ui32;
TestBase::Run();
if (setup_failed_) {
std::cout << "** SetUp Failed for this test. Skipping.**" << std::endl;
return;
}
for (uint32_t i = 0; i < num_monitor_devs(); ++i) {
PrintDeviceHeader(i);
err = rsmi_dev_overdrive_level_get(i, &val_ui32);
CHK_ERR_ASRT(err)
IF_VERB(STANDARD) {
std::cout << "\t**OverDrive Level:" << val_ui32 << std::endl;
// Verify api support checking functionality is working
err = rsmi_dev_overdrive_level_get(i, nullptr);
ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS);
}
}
}
@@ -1,73 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2019, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#ifndef TESTS_ROCM_SMI_TEST_FUNCTIONAL_OVERDRIVE_READ_H_
#define TESTS_ROCM_SMI_TEST_FUNCTIONAL_OVERDRIVE_READ_H_
#include "../test_base.h"
class TestOverdriveRead : public TestBase {
public:
TestOverdriveRead();
// @Brief: Destructor for test case of TestOverdriveRead
virtual ~TestOverdriveRead();
// @Brief: Setup the environment for measurement
virtual void SetUp();
// @Brief: Core measurement execution
virtual void Run();
// @Brief: Clean up and retrive the resource
virtual void Close();
// @Brief: Display results
virtual void DisplayResults() const;
// @Brief: Display information about what this test does
virtual void DisplayTestInfo(void);
};
#endif // TESTS_ROCM_SMI_TEST_FUNCTIONAL_OVERDRIVE_READ_H_
@@ -1,124 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2019, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#include <stdint.h>
#include <stddef.h>
#include <iostream>
#include <gtest/gtest.h>
#include "rocm_smi/rocm_smi.h"
#include "overdrive_read_write.h"
#include "../test_common.h"
TestOverdriveReadWrite::TestOverdriveReadWrite() : TestBase() {
set_title("RSMI Overdrive Read/Write Test");
set_description("The Fan Read tests verifies that the overdrive settings "
"can be read and controlled properly.");
}
TestOverdriveReadWrite::~TestOverdriveReadWrite(void) {
}
void TestOverdriveReadWrite::SetUp(void) {
TestBase::SetUp();
return;
}
void TestOverdriveReadWrite::DisplayTestInfo(void) {
TestBase::DisplayTestInfo();
}
void TestOverdriveReadWrite::DisplayResults(void) const {
TestBase::DisplayResults();
return;
}
void TestOverdriveReadWrite::Close() {
// This will close handles opened within rsmitst utility calls and call
// rsmi_shut_down(), so it should be done after other hsa cleanup
TestBase::Close();
}
void TestOverdriveReadWrite::Run(void) {
rsmi_status_t ret;
uint32_t val;
TestBase::Run();
if (setup_failed_) {
std::cout << "** SetUp Failed for this test. Skipping.**" << std::endl;
return;
}
for (uint32_t dv_ind = 0; dv_ind < num_monitor_devs(); ++dv_ind) {
PrintDeviceHeader(dv_ind);
IF_VERB(STANDARD) {
std::cout << "Set Overdrive level to 0%..." << std::endl;
}
ret = rsmi_dev_overdrive_level_set(dv_ind, 0);
CHK_ERR_ASRT(ret)
IF_VERB(STANDARD) {
std::cout << "Set Overdrive level to 10%..." << std::endl;
}
ret = rsmi_dev_overdrive_level_set(dv_ind, 10);
CHK_ERR_ASRT(ret)
ret = rsmi_dev_overdrive_level_get(dv_ind, &val);
CHK_ERR_ASRT(ret)
IF_VERB(STANDARD) {
std::cout << "\t**New OverDrive Level:" << val << std::endl;
std::cout << "Reset Overdrive level to 0%..." << std::endl;
}
ret = rsmi_dev_overdrive_level_set(dv_ind, 0);
CHK_ERR_ASRT(ret)
ret = rsmi_dev_overdrive_level_get(dv_ind, &val);
CHK_ERR_ASRT(ret)
IF_VERB(STANDARD) {
std::cout << "\t**New OverDrive Level:" << val << std::endl;
}
}
}
@@ -1,73 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2019, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#ifndef TESTS_ROCM_SMI_TEST_FUNCTIONAL_OVERDRIVE_READ_WRITE_H_
#define TESTS_ROCM_SMI_TEST_FUNCTIONAL_OVERDRIVE_READ_WRITE_H_
#include "../test_base.h"
class TestOverdriveReadWrite : public TestBase {
public:
TestOverdriveReadWrite();
// @Brief: Destructor for test case of TestOverdriveReadWrite
virtual ~TestOverdriveReadWrite();
// @Brief: Setup the environment for measurement
virtual void SetUp();
// @Brief: Core measurement execution
virtual void Run();
// @Brief: Clean up and retrive the resource
virtual void Close();
// @Brief: Display results
virtual void DisplayResults() const;
// @Brief: Display information about what this test does
virtual void DisplayTestInfo(void);
};
#endif // TESTS_ROCM_SMI_TEST_FUNCTIONAL_OVERDRIVE_READ_WRITE_H_
@@ -1,199 +0,0 @@
/*
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2019, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#include <stdint.h>
#include <stddef.h>
#include <iostream>
#include <bitset>
#include <string>
#include <algorithm>
#include <gtest/gtest.h>
#include "rocm_smi/rocm_smi.h"
#include "pci_read_write.h"
#include "../test_common.h"
TestPciReadWrite::TestPciReadWrite() : TestBase() {
set_title("RSMI PCIe Bandwidth Read/Write Test");
set_description("The PCIe Bandwidth tests verify that the PCIe bandwidth "
"settings can be read and controlled properly.");
}
TestPciReadWrite::~TestPciReadWrite(void) {
}
void TestPciReadWrite::SetUp(void) {
TestBase::SetUp();
return;
}
void TestPciReadWrite::DisplayTestInfo(void) {
TestBase::DisplayTestInfo();
}
void TestPciReadWrite::DisplayResults(void) const {
TestBase::DisplayResults();
return;
}
void TestPciReadWrite::Close() {
// This will close handles opened within rsmitst utility calls and call
// rsmi_shut_down(), so it should be done after other hsa cleanup
TestBase::Close();
}
void TestPciReadWrite::Run(void) {
rsmi_status_t ret;
rsmi_pcie_bandwidth_t bw;
uint32_t freq_bitmask;
uint64_t sent, received, max_pkt_sz, u64int;
TestBase::Run();
if (setup_failed_) {
std::cout << "** SetUp Failed for this test. Skipping.**" << std::endl;
return;
}
for (uint32_t dv_ind = 0; dv_ind < num_monitor_devs(); ++dv_ind) {
PrintDeviceHeader(dv_ind);
ret = rsmi_dev_pci_replay_counter_get(dv_ind, &u64int);
if (ret == RSMI_STATUS_NOT_SUPPORTED) {
std::cout <<
"\t**rsmi_dev_pci_replay_counter_get() is not supported"
" on this machine" << std::endl;
// Verify api support checking functionality is working
ret = rsmi_dev_pci_replay_counter_get(dv_ind, nullptr);
ASSERT_EQ(ret, RSMI_STATUS_NOT_SUPPORTED);
} else {
CHK_ERR_ASRT(ret)
IF_VERB(STANDARD) {
std::cout << "\tPCIe Replay Counter: " << u64int << std::endl;
}
// Verify api support checking functionality is working
ret = rsmi_dev_pci_replay_counter_get(dv_ind, nullptr);
ASSERT_EQ(ret, RSMI_STATUS_INVALID_ARGS);
}
ret = rsmi_dev_pci_throughput_get(dv_ind, &sent, &received, &max_pkt_sz);
if (ret == RSMI_STATUS_NOT_SUPPORTED) {
std::cout << "TEST FAILURE: Current PCIe throughput is not detected. "
"This is likely because it is not indicated in the pcie_bw sysfs "
"file. Aborting test." << std::endl;
// We don't need to verify api support checking functionality is working
// as the user may choose to have any of the input parameters as 0.
return;
}
CHK_ERR_ASRT(ret)
IF_VERB(STANDARD) {
std::cout << "\tPCIe Throughput (1 sec.): " << std::endl;
std::cout << "\t\tSent: " << sent << " bytes" << std::endl;
std::cout << "\t\tReceived: " << received << " bytes" << std::endl;
std::cout << "\t\tMax Packet Size: " << max_pkt_sz << " bytes" <<
std::endl;
std::cout << std::endl;
}
ret = rsmi_dev_pci_bandwidth_get(dv_ind, &bw);
if (ret == RSMI_STATUS_NOT_SUPPORTED) {
std::cout << "TEST FAILURE: Current PCIe bandwidth is not detected. "
"This is likely because it is not indicated in the pp_dpm_pcie sysfs "
"file. Aborting test." << std::endl;
// Verify api support checking functionality is working
ret = rsmi_dev_pci_bandwidth_get(dv_ind, nullptr);
ASSERT_EQ(ret, RSMI_STATUS_NOT_SUPPORTED);
return;
}
CHK_ERR_ASRT(ret)
IF_VERB(STANDARD) {
std::cout << "\tInitial PCIe BW index is " << bw.transfer_rate.current <<
std::endl;
}
// Verify api support checking functionality is working
ret = rsmi_dev_pci_bandwidth_get(dv_ind, nullptr);
ASSERT_EQ(ret, RSMI_STATUS_INVALID_ARGS);
// First set the bitmask to all supported bandwidths
freq_bitmask = ~(~0u << bw.transfer_rate.num_supported);
// Then, set the bitmask to all bandwidths besides the initial BW
freq_bitmask ^= (1 << bw.transfer_rate.current);
std::string freq_bm_str =
std::bitset<RSMI_MAX_NUM_FREQUENCIES>(freq_bitmask).to_string();
freq_bm_str.erase(0, std::min(freq_bm_str.find_first_not_of('0'),
freq_bm_str.size()-1));
IF_VERB(STANDARD) {
std::cout << "\tSetting bandwidth mask to " << "0b" << freq_bm_str <<
" ..." << std::endl;
}
ret = rsmi_dev_pci_bandwidth_set(dv_ind, freq_bitmask);
CHK_ERR_ASRT(ret)
ret = rsmi_dev_pci_bandwidth_get(dv_ind, &bw);
CHK_ERR_ASRT(ret)
IF_VERB(STANDARD) {
std::cout << "\tBandwidth is now index " << bw.transfer_rate.current <<
std::endl;
std::cout << "\tResetting mask to all bandwidths." << std::endl;
}
ret = rsmi_dev_pci_bandwidth_set(dv_ind, 0xFFFFFFFF);
CHK_ERR_ASRT(ret)
ret = rsmi_dev_perf_level_set(dv_ind, RSMI_DEV_PERF_LEVEL_AUTO);
CHK_ERR_ASRT(ret)
}
}
@@ -1,73 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2019, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#ifndef TESTS_ROCM_SMI_TEST_FUNCTIONAL_PCI_READ_WRITE_H_
#define TESTS_ROCM_SMI_TEST_FUNCTIONAL_PCI_READ_WRITE_H_
#include "../test_base.h"
class TestPciReadWrite : public TestBase {
public:
TestPciReadWrite();
// @Brief: Destructor for test case of TestPciReadWrite
virtual ~TestPciReadWrite();
// @Brief: Setup the environment for measurement
virtual void SetUp();
// @Brief: Core measurement execution
virtual void Run();
// @Brief: Clean up and retrive the resource
virtual void Close();
// @Brief: Display results
virtual void DisplayResults() const;
// @Brief: Display information about what this test does
virtual void DisplayTestInfo(void);
};
#endif // TESTS_ROCM_SMI_TEST_FUNCTIONAL_PCI_READ_WRITE_H_
@@ -1,374 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2019, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#include <stdint.h>
#include <stddef.h>
#include <iostream>
#include <bitset>
#include <string>
#include <algorithm>
#include <vector>
#include <memory>
#include <gtest/gtest.h>
#include "rocm_smi/rocm_smi.h"
#include "perf_cntr_read_write.h"
#include "../test_common.h"
PerfCntrEvtGrp::PerfCntrEvtGrp(rsmi_event_group_t grp, uint32_t first,
uint32_t last, std::string name) : grp_(grp), first_evt_(first),
last_evt_(last), name_(name) {
num_events_ = last_evt_ - first_evt_ + 1;
}
PerfCntrEvtGrp::~PerfCntrEvtGrp() {}
// Add new event groups to test here
#define PC_EVT_GRP(SHRT, NAME) \
PerfCntrEvtGrp(RSMI_EVNT_GRP_##SHRT, RSMI_EVNT_##SHRT##_FIRST, \
RSMI_EVNT_##SHRT##_LAST, NAME)
static const std::vector<PerfCntrEvtGrp> s_event_groups = {
PC_EVT_GRP(XGMI, "XGMI"),
PC_EVT_GRP(XGMI_DATA_OUT, "XGMI_DATA_OUT")
};
TestPerfCntrReadWrite::TestPerfCntrReadWrite() : TestBase() {
set_title("RSMI Performance Counter Read/Write Test");
set_description("The Performance counter tests verify that performance"
" counters can be controlled and read properly.");
}
TestPerfCntrReadWrite::~TestPerfCntrReadWrite(void) {
}
void TestPerfCntrReadWrite::SetUp(void) {
TestBase::SetUp();
return;
}
void TestPerfCntrReadWrite::DisplayTestInfo(void) {
TestBase::DisplayTestInfo();
}
void TestPerfCntrReadWrite::DisplayResults(void) const {
TestBase::DisplayResults();
return;
}
void TestPerfCntrReadWrite::Close() {
// This will close handles opened within rsmitst utility calls and call
// rsmi_shut_down(), so it should be done after other hsa cleanup
TestBase::Close();
}
#define RSMI_EVNT_ENUM_FIRST(GRP_NAME) RSMI_EVNT_##GRP_NAME##_FIRST
#define RSMI_EVNT_ENUM_LAST(GRP_NAME) RSMI_EVNT_##GRP_NAME##_LAST
// Refactor this to handle different event groups once we have > 1 event group
void TestPerfCntrReadWrite::CountEvents(uint32_t dv_ind,
rsmi_event_type_t evnt, rsmi_counter_value_t *val, int32_t sleep_sec) {
rsmi_event_handle_t evt_handle;
rsmi_status_t ret;
ret = rsmi_dev_counter_create(dv_ind,
static_cast<rsmi_event_type_t>(evnt), &evt_handle);
CHK_ERR_ASRT(ret)
// Note that rsmi_dev_counter_create() should never return
// RSMI_STATUS_NOT_SUPPORTED. It will return RSMI_STATUS_OUT_OF_RESOURCES
// if it is unable to create a counter.
ret = rsmi_dev_counter_create(dv_ind,
static_cast<rsmi_event_type_t>(evnt), nullptr);
ASSERT_EQ(ret, RSMI_STATUS_INVALID_ARGS);
ret = rsmi_counter_control(evt_handle, RSMI_CNTR_CMD_START, nullptr);
if (ret == RSMI_STATUS_NOT_SUPPORTED) {
std::cout << "rsmi_counter_control() returned "
"RSMI_STATUS_NOT_SUPPORTED" << std::endl;
throw RSMI_STATUS_NOT_SUPPORTED;
} else {
CHK_ERR_ASRT(ret)
}
sleep(sleep_sec);
ret = rsmi_counter_read(evt_handle, val);
CHK_ERR_ASRT(ret)
IF_VERB(STANDARD) {
std::cout << "\t\t\tValue: " << val->value << std::endl;
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;
}
ret = rsmi_dev_counter_destroy(evt_handle);
CHK_ERR_ASRT(ret)
}
static const uint64_t kGigByte = 1073741824; // 1024^3
static const uint64_t kGig = 1000000000;
static const uint64_t kVg20Level1Bandwidth = 23; // 23 GB/sec
void
TestPerfCntrReadWrite::testEventsIndividually(uint32_t dv_ind) {
rsmi_status_t ret;
rsmi_counter_value_t val;
uint64_t throughput;
std::cout << "Test events sequentially (device " <<
dv_ind << ")" << std::endl;
auto utiliz = [&](rsmi_event_type_t evt, uint32_t chan) {
IF_VERB(STANDARD) {
std::cout << "****************************" << std::endl;
std::cout << "Test XGMI Link Utilization (channel " <<
chan << ")" << std::endl;
std::cout << "****************************" << std::endl;
std::cout << "Assumed Level 1 Bandwidth: " <<
kVg20Level1Bandwidth << "GB/sec" << std::endl;
}
uint32_t tmp_verbosity = verbosity();
set_verbosity(0);
for (int i = 0; i < 5; ++i) {
std::cout << "\t\tPass " << i << ":" << std::endl;
CountEvents(dv_ind, evt, &val, 1);
double coll_time_sec = static_cast<double>(val.time_running)/kGig;
throughput = (val.value * 32)/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) <<
"%" << std::endl;
std::cout << "\t\t\t****" << std::endl;
}
set_verbosity(tmp_verbosity);
};
IF_VERB(STANDARD) {
std::cout << "****************************" << std::endl;
std::cout << "Test each event individually" << std::endl;
std::cout << "****************************" << std::endl;
}
for (PerfCntrEvtGrp grp : s_event_groups) {
ret = rsmi_dev_counter_group_supported(dv_ind, grp.group());
if (ret == RSMI_STATUS_NOT_SUPPORTED) {
continue;
}
IF_VERB(STANDARD) {
std::cout << "Testing Event Group " << grp.name() << std::endl;
}
if (grp.group() == RSMI_EVNT_GRP_XGMI_DATA_OUT) {
utiliz(RSMI_EVNT_XGMI_DATA_OUT_0, 0);
utiliz(RSMI_EVNT_XGMI_DATA_OUT_1, 1);
utiliz(RSMI_EVNT_XGMI_DATA_OUT_2, 2);
utiliz(RSMI_EVNT_XGMI_DATA_OUT_3, 3);
utiliz(RSMI_EVNT_XGMI_DATA_OUT_4, 4);
utiliz(RSMI_EVNT_XGMI_DATA_OUT_5, 5);
} else if (grp.group() == RSMI_EVNT_GRP_XGMI) {
utiliz(RSMI_EVNT_XGMI_1_BEATS_TX, 1);
utiliz(RSMI_EVNT_XGMI_0_BEATS_TX, 0);
}
for (uint32_t evnt = grp.first_evt(); evnt <= grp.last_evt(); ++evnt) {
IF_VERB(STANDARD) {
std::cout << "\tTesting Event Type " << evnt << std::endl;
}
CountEvents(dv_ind, static_cast<rsmi_event_type_t>(evnt), &val);
}
}
}
void
TestPerfCntrReadWrite::testEventsSimultaneously(uint32_t dv_ind) {
rsmi_status_t ret;
rsmi_counter_value_t val;
uint32_t avail_counters;
IF_VERB(STANDARD) {
std::cout << "****************************" << std::endl;
std::cout << "Test events simultaneously (device " <<
dv_ind << ")" << std::endl;
std::cout << "****************************" << std::endl;
}
/* This code is a little convoluted. The reason is that it is meant to test
* having multiple events being used at one time, rather than sequentially
* handling 1 event at a time.
*/
for (PerfCntrEvtGrp grp : s_event_groups) {
ret = rsmi_dev_counter_group_supported(dv_ind, grp.group());
if (ret == RSMI_STATUS_NOT_SUPPORTED) {
IF_VERB(STANDARD) {
std::cout << "\tEvent Group " << grp.name() <<
" is not supported. Skipping." << std::endl;
}
continue;
}
IF_VERB(STANDARD) {
std::cout << "Testing Event Group " << grp.name() << std::endl;
}
ret = rsmi_counter_available_counters_get(dv_ind, grp.group(),
&avail_counters);
IF_VERB(STANDARD) {
std::cout << "Available Counters: " << avail_counters << std::endl;
}
CHK_ERR_ASRT(ret)
std::shared_ptr<rsmi_event_handle_t> evt_handle =
std::shared_ptr<rsmi_event_handle_t>(
new rsmi_event_handle_t[avail_counters]);
uint32_t tmp, j;
uint32_t num_created = 0;
for (uint32_t evnt = grp.first_evt(); evnt <= grp.last_evt();
evnt += avail_counters) {
IF_VERB(STANDARD) {
std::cout << "\tTesting Event Type " << evnt << std::endl;
}
IF_VERB(STANDARD) {
std::cout << "\tCreating events..." << std::endl;
}
for (j = 0; j < avail_counters; ++j) {
tmp = static_cast<rsmi_event_type_t>(evnt + j);
if (tmp > grp.last_evt()) {
break;
}
IF_VERB(STANDARD) {
std::cout << "\tEvent Type " << tmp << std::endl;
}
ret = rsmi_dev_counter_create(dv_ind,
static_cast<rsmi_event_type_t>(tmp), &evt_handle.get()[j]);
CHK_ERR_ASRT(ret)
}
num_created = j;
IF_VERB(STANDARD) {
std::cout << "\tStart Counters..." << std::endl;
}
uint32_t tmp_cntrs;
for (j = 0; j < num_created; ++j) {
tmp = static_cast<rsmi_event_type_t>(evnt + j);
ret = rsmi_counter_control(evt_handle.get()[j], RSMI_CNTR_CMD_START,
nullptr);
CHK_ERR_ASRT(ret)
ret = rsmi_counter_available_counters_get(dv_ind, grp.group(),
&tmp_cntrs);
CHK_ERR_ASRT(ret)
ASSERT_EQ(tmp_cntrs, (avail_counters - j - 1));
}
sleep(1);
IF_VERB(STANDARD) {
std::cout << "\tRead Counters..." << std::endl;
}
for (j = 0; j < num_created; ++j) {
tmp = static_cast<rsmi_event_type_t>(evnt + j);
ret = rsmi_counter_read(evt_handle.get()[j], &val);
CHK_ERR_ASRT(ret)
IF_VERB(STANDARD) {
std::cout << "\tCounter: " << tmp << std::endl;
std::cout << "\tSuccessfully read value: " << std::endl;
std::cout << "\t\tValue: " << val.value << std::endl;
std::cout << "\t\tTime Enabled: " << val.time_enabled << std::endl;
std::cout << "\t\tTime Running: " << val.time_running << std::endl;
}
}
for (j = 0; j < num_created; ++j) {
ret = rsmi_dev_counter_destroy(evt_handle.get()[j]);
CHK_ERR_ASRT(ret)
}
}
}
}
void TestPerfCntrReadWrite::Run(void) {
TestBase::Run();
if (setup_failed_) {
std::cout << "** SetUp Failed for this test. Skipping.**" << std::endl;
return;
}
for (uint32_t dv_ind = 0; dv_ind < num_monitor_devs(); ++dv_ind) {
PrintDeviceHeader(dv_ind);
try {
testEventsIndividually(dv_ind);
testEventsSimultaneously(dv_ind);
} catch(rsmi_status_t r) {
switch (r) {
case RSMI_STATUS_NOT_SUPPORTED:
std::cout << "The performance counter event tried is not "
"supported for this device" << std::endl;
break;
default:
std::cout << "Unexpected exception caught with rsmi "
"return value of " << r << std::endl;
}
} catch(...) {
ASSERT_FALSE("Unexpected exception caught");
}
}
}
@@ -1,101 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2019, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#ifndef TESTS_ROCM_SMI_TEST_FUNCTIONAL_PERF_CNTR_READ_WRITE_H_
#define TESTS_ROCM_SMI_TEST_FUNCTIONAL_PERF_CNTR_READ_WRITE_H_
#include <string>
#include "../test_base.h"
class TestPerfCntrReadWrite : public TestBase {
public:
TestPerfCntrReadWrite();
// @Brief: Destructor for test case of TestPerfCntrReadWrite
virtual ~TestPerfCntrReadWrite();
// @Brief: Setup the environment for measurement
virtual void SetUp();
// @Brief: Core measurement execution
virtual void Run();
// @Brief: Clean up and retrive the resource
virtual void Close();
// @Brief: Display results
virtual void DisplayResults() const;
// @Brief: Display information about what this test does
virtual void DisplayTestInfo(void);
private:
void CountEvents(uint32_t dv_ind,
rsmi_event_type_t evnt, rsmi_counter_value_t *val,
int32_t sleep_sec = 1);
void testEventsIndividually(uint32_t dv_ind);
void testEventsSimultaneously(uint32_t dv_ind);
};
class PerfCntrEvtGrp {
public:
explicit PerfCntrEvtGrp(rsmi_event_group_t grp,
uint32_t first, uint32_t last, std::string name);
~PerfCntrEvtGrp();
rsmi_event_group_t group(void) const { return grp_;}
uint32_t first_evt(void) const {return first_evt_;}
uint32_t last_evt(void) const {return last_evt_;}
uint32_t num_events(void) const {return num_events_;}
std::string name(void) const { return name_;}
private:
rsmi_event_group_t grp_;
uint32_t first_evt_;
uint32_t last_evt_;
uint32_t num_events_;
std::string name_;
};
#endif // TESTS_ROCM_SMI_TEST_FUNCTIONAL_PERF_CNTR_READ_WRITE_H_
@@ -1,144 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2020, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#include <stdint.h>
#include <stddef.h>
#include <iostream>
#include <string>
#include <map>
#include <bitset>
#include <algorithm>
#include <gtest/gtest.h>
#include "rocm_smi/rocm_smi.h"
#include "perf_determinism.h"
#include "../test_common.h"
TestPerfDeterminism::TestPerfDeterminism() : TestBase() {
set_title("RSMI Performance Determinism Test");
set_description("The Performance Determinism tests verifies "
"Enabling/Disabling performance determinism mode.");
}
TestPerfDeterminism::~TestPerfDeterminism(void) {
}
void TestPerfDeterminism::SetUp(void) {
TestBase::SetUp();
return;
}
void TestPerfDeterminism::DisplayTestInfo(void) {
TestBase::DisplayTestInfo();
}
void TestPerfDeterminism::DisplayResults(void) const {
TestBase::DisplayResults();
return;
}
void TestPerfDeterminism::Close() {
// This will close handles opened within rsmitst utility calls and call
// rsmi_shut_down(), so it should be done after other hsa cleanup
TestBase::Close();
}
void TestPerfDeterminism::Run(void) {
rsmi_status_t err;
rsmi_dev_perf_level_t pfl;
rsmi_od_volt_freq_data_t odv;
rsmi_status_t ret;
uint64_t clkvalue;
TestBase::Run();
if (setup_failed_) {
std::cout << "** SetUp Failed for this test. Skipping.**" << std::endl;
return;
}
for (uint32_t i = 0; i < num_monitor_devs(); ++i) {
PrintDeviceHeader(i);
err = rsmi_dev_od_volt_info_get(i, &odv);
if (err == RSMI_STATUS_NOT_SUPPORTED) {
IF_VERB(STANDARD) {
std::cout << "\t** Not supported on this machine" << std::endl;
}
return;
}
else{
clkvalue = (odv.curr_sclk_range.lower_bound/1000000) + 50;
}
err = rsmi_perf_determinism_mode_set(i, clkvalue);
if (err == RSMI_STATUS_NOT_SUPPORTED) {
IF_VERB(STANDARD) {
std::cout << "\t**Not supported on this machine" << std::endl;
}
return;
} else {
ret = rsmi_dev_perf_level_get(i, &pfl);
CHK_ERR_ASRT(ret)
IF_VERB(STANDARD) {
std::cout << "\t**New Perf Level:" << GetPerfLevelStr(pfl) <<
std::endl;
std::cout << "\t**SCLK is now set to " << clkvalue << std::endl;
}
std::cout << "\t**Resetting performance determinism" << std::endl;
err = rsmi_dev_perf_level_set(i, RSMI_DEV_PERF_LEVEL_AUTO);;
CHK_ERR_ASRT(err)
ret = rsmi_dev_perf_level_get(i, &pfl);
CHK_ERR_ASRT(ret)
IF_VERB(STANDARD) {
std::cout << "\t**New Perf Level:" << GetPerfLevelStr(pfl) <<
std::endl;
}
return;
}
}
}
@@ -1,73 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2020, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#ifndef TESTS_ROCM_SMI_TEST_FUNCTIONAL_PERF_DETERMINISM_H_
#define TESTS_ROCM_SMI_TEST_FUNCTIONAL_PERF_DETERMINISM_H_
#include "../test_base.h"
class TestPerfDeterminism : public TestBase {
public:
TestPerfDeterminism();
// @Brief: Destructor for test case of TestVOltRead
virtual ~TestPerfDeterminism();
// @Brief: Setup the environment for measurement
virtual void SetUp();
// @Brief: Core measurement execution
virtual void Run();
// @Brief: Clean up and retrive the resource
virtual void Close();
// @Brief: Display results
virtual void DisplayResults() const;
// @Brief: Display information about what this test does
virtual void DisplayTestInfo(void);
};
#endif // TESTS_ROCM_SMI_TEST_FUNCTIONAL_PERF_DETERMINISM_H_
@@ -1,111 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2019, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#include <stdint.h>
#include <stddef.h>
#include <iostream>
#include <string>
#include <gtest/gtest.h>
#include "rocm_smi/rocm_smi.h"
#include "perf_level_read.h"
#include "../test_common.h"
TestPerfLevelRead::TestPerfLevelRead() : TestBase() {
set_title("RSMI Performance Level Read Test");
set_description("The Performance Level Read tests verifies that the "
"performance level monitors can be read properly.");
}
TestPerfLevelRead::~TestPerfLevelRead(void) {
}
void TestPerfLevelRead::SetUp(void) {
TestBase::SetUp();
return;
}
void TestPerfLevelRead::DisplayTestInfo(void) {
TestBase::DisplayTestInfo();
}
void TestPerfLevelRead::DisplayResults(void) const {
TestBase::DisplayResults();
return;
}
void TestPerfLevelRead::Close() {
// This will close handles opened within rsmitst utility calls and call
// rsmi_shut_down(), so it should be done after other hsa cleanup
TestBase::Close();
}
void TestPerfLevelRead::Run(void) {
rsmi_status_t err;
rsmi_dev_perf_level_t pfl;
TestBase::Run();
if (setup_failed_) {
std::cout << "** SetUp Failed for this test. Skipping.**" << std::endl;
return;
}
for (uint32_t i = 0; i < num_monitor_devs(); ++i) {
PrintDeviceHeader(i);
err = rsmi_dev_perf_level_get(i, &pfl);
CHK_ERR_ASRT(err)
IF_VERB(STANDARD) {
std::cout << "\t**Performance Level:" << std::dec << (uint32_t)pfl <<
std::endl;
}
// Verify api support checking functionality is working
err = rsmi_dev_perf_level_get(i, nullptr);
ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS);
}
}
@@ -1,73 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2019, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#ifndef TESTS_ROCM_SMI_TEST_FUNCTIONAL_PERF_LEVEL_READ_H_
#define TESTS_ROCM_SMI_TEST_FUNCTIONAL_PERF_LEVEL_READ_H_
#include "../test_base.h"
class TestPerfLevelRead : public TestBase {
public:
TestPerfLevelRead();
// @Brief: Destructor for test case of TestPerfLevelRead
virtual ~TestPerfLevelRead();
// @Brief: Setup the environment for measurement
virtual void SetUp();
// @Brief: Core measurement execution
virtual void Run();
// @Brief: Clean up and retrive the resource
virtual void Close();
// @Brief: Display results
virtual void DisplayResults() const;
// @Brief: Display information about what this test does
virtual void DisplayTestInfo(void);
};
#endif // TESTS_ROCM_SMI_TEST_FUNCTIONAL_PERF_LEVEL_READ_H_
@@ -1,152 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2019, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#include <stdint.h>
#include <stddef.h>
#include <iostream>
#include <map>
#include <gtest/gtest.h>
#include "rocm_smi/rocm_smi.h"
#include "perf_level_read_write.h"
#include "../test_common.h"
TestPerfLevelReadWrite::TestPerfLevelReadWrite() : TestBase() {
set_title("RSMI Performance Level Read/Write Test");
set_description("The Performance Level tests verify that the performance "
"level settings can be read and controlled properly.");
}
TestPerfLevelReadWrite::~TestPerfLevelReadWrite(void) {
}
void TestPerfLevelReadWrite::SetUp(void) {
TestBase::SetUp();
return;
}
void TestPerfLevelReadWrite::DisplayTestInfo(void) {
TestBase::DisplayTestInfo();
}
void TestPerfLevelReadWrite::DisplayResults(void) const {
TestBase::DisplayResults();
return;
}
void TestPerfLevelReadWrite::Close() {
// This will close handles opened within rsmitst utility calls and call
// rsmi_shut_down(), so it should be done after other hsa cleanup
TestBase::Close();
}
void TestPerfLevelReadWrite::Run(void) {
rsmi_status_t ret;
rsmi_dev_perf_level_t pfl, orig_pfl;
TestBase::Run();
if (setup_failed_) {
IF_VERB(STANDARD) {
std::cout << "** SetUp Failed for this test. Skipping.**" << std::endl;
}
return;
}
for (uint32_t dv_ind = 0; dv_ind < num_monitor_devs(); ++dv_ind) {
PrintDeviceHeader(dv_ind);
ret = rsmi_dev_perf_level_get(dv_ind, &orig_pfl);
CHK_ERR_ASRT(ret)
IF_VERB(STANDARD) {
std::cout << "\t**Original Perf Level:" <<
GetPerfLevelStr(orig_pfl) << std::endl;
}
uint32_t pfl_i = static_cast<uint32_t>(RSMI_DEV_PERF_LEVEL_FIRST);
for (; pfl_i <= static_cast<uint32_t>(RSMI_DEV_PERF_LEVEL_LAST); pfl_i++) {
if (pfl_i == static_cast<uint32_t>(orig_pfl)) {
continue;
}
IF_VERB(STANDARD) {
std::cout << "Set Performance Level to " <<
GetPerfLevelStr(static_cast<rsmi_dev_perf_level_t>(pfl_i)) <<
" ..." << std::endl;
}
ret = rsmi_dev_perf_level_set(dv_ind,
static_cast<rsmi_dev_perf_level_t>(pfl_i));
if (ret == RSMI_STATUS_NOT_SUPPORTED) {
std::cout << "\t**" << GetPerfLevelStr(static_cast<rsmi_dev_perf_level_t>(pfl_i))
<< " returned RSMI_STATUS_NOT_SUPPORTED" << std::endl;
} else {
CHK_ERR_ASRT(ret)
ret = rsmi_dev_perf_level_get(dv_ind, &pfl);
CHK_ERR_ASRT(ret)
IF_VERB(STANDARD) {
std::cout << "\t**New Perf Level:" << GetPerfLevelStr(pfl) <<
std::endl;
}
}
}
IF_VERB(STANDARD) {
std::cout << "Reset Perf level to " << GetPerfLevelStr(orig_pfl) <<
" ..." << std::endl;
}
ret = rsmi_dev_perf_level_set(dv_ind, orig_pfl);
CHK_ERR_ASRT(ret)
ret = rsmi_dev_perf_level_get(dv_ind, &pfl);
CHK_ERR_ASRT(ret)
IF_VERB(STANDARD) {
std::cout << "\t**New Perf Level:" << GetPerfLevelStr(pfl) <<
std::endl;
}
}
}
@@ -1,73 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2019, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#ifndef TESTS_ROCM_SMI_TEST_FUNCTIONAL_PERF_LEVEL_READ_WRITE_H_
#define TESTS_ROCM_SMI_TEST_FUNCTIONAL_PERF_LEVEL_READ_WRITE_H_
#include "../test_base.h"
class TestPerfLevelReadWrite : public TestBase {
public:
TestPerfLevelReadWrite();
// @Brief: Destructor for test case of TestPerfLevelReadWrite
virtual ~TestPerfLevelReadWrite();
// @Brief: Setup the environment for measurement
virtual void SetUp();
// @Brief: Core measurement execution
virtual void Run();
// @Brief: Clean up and retrive the resource
virtual void Close();
// @Brief: Display results
virtual void DisplayResults() const;
// @Brief: Display information about what this test does
virtual void DisplayTestInfo(void);
};
#endif // TESTS_ROCM_SMI_TEST_FUNCTIONAL_PERF_LEVEL_READ_WRITE_H_
@@ -1,153 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2019, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#include <stdint.h>
#include <stddef.h>
#include <iostream>
#include <bitset>
#include <string>
#include <algorithm>
#include <gtest/gtest.h>
#include "rocm_smi/rocm_smi.h"
#include "power_cap_read_write.h"
#include "../test_common.h"
TestPowerCapReadWrite::TestPowerCapReadWrite() : TestBase() {
set_title("RSMI Power Cap Read/Write Test");
set_description("The Power Cap tests verify that the power profile "
"settings can be read and written properly.");
}
TestPowerCapReadWrite::~TestPowerCapReadWrite(void) {
}
void TestPowerCapReadWrite::SetUp(void) {
TestBase::SetUp();
return;
}
void TestPowerCapReadWrite::DisplayTestInfo(void) {
TestBase::DisplayTestInfo();
}
void TestPowerCapReadWrite::DisplayResults(void) const {
TestBase::DisplayResults();
return;
}
void TestPowerCapReadWrite::Close() {
// This will close handles opened within rsmitst utility calls and call
// rsmi_shut_down(), so it should be done after other hsa cleanup
TestBase::Close();
}
void TestPowerCapReadWrite::Run(void) {
rsmi_status_t ret;
uint64_t orig, min, max, new_cap;
clock_t start, end;
double cpu_time_used;
TestBase::Run();
if (setup_failed_) {
std::cout << "** SetUp Failed for this test. Skipping.**" << std::endl;
return;
}
for (uint32_t dv_ind = 0; dv_ind < num_monitor_devs(); ++dv_ind) {
PrintDeviceHeader(dv_ind);
ret = rsmi_dev_power_cap_range_get(dv_ind, 0, &max, &min);
CHK_ERR_ASRT(ret)
// Verify api support checking functionality is working
ret = rsmi_dev_power_cap_range_get(dv_ind, 0, nullptr, nullptr);
ASSERT_EQ(ret, RSMI_STATUS_INVALID_ARGS);
ret = rsmi_dev_power_cap_get(dv_ind, 0, &orig);
CHK_ERR_ASRT(ret)
// Verify api support checking functionality is working
ret = rsmi_dev_power_cap_get(dv_ind, 0, nullptr);
ASSERT_EQ(ret, RSMI_STATUS_INVALID_ARGS);
new_cap = (max + min)/2;
IF_VERB(STANDARD) {
std::cout << "Original Power Cap: " << orig << " uW" << std::endl;
std::cout << "Power Cap Range: " << max << " uW to " << min <<
" uW" << std::endl;
std::cout << "Setting new cap to " << new_cap << "..." << std::endl;
}
start = clock();
ret = rsmi_dev_power_cap_set(dv_ind, 0, new_cap);
end = clock();
cpu_time_used = ((double) (end - start)) * 1000000UL / CLOCKS_PER_SEC;
CHK_ERR_ASRT(ret)
ret = rsmi_dev_power_cap_get(dv_ind, 0, &new_cap);
CHK_ERR_ASRT(ret)
// TODO(cfreehil) add some kind of assertion to verify new_cap is correct
// (or within a range)
IF_VERB(STANDARD) {
std::cout << "Time spent: " << cpu_time_used << " uS" << std::endl;
std::cout << "New Power Cap: " << new_cap << " uW" << std::endl;
std::cout << "Resetting cap to " << orig << "..." << std::endl;
}
ret = rsmi_dev_power_cap_set(dv_ind, 0, orig);
CHK_ERR_ASRT(ret)
ret = rsmi_dev_power_cap_get(dv_ind, 0, &new_cap);
CHK_ERR_ASRT(ret)
IF_VERB(STANDARD) {
std::cout << "Current Power Cap: " << new_cap << " uW" << std::endl;
}
}
}
@@ -1,73 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2019, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#ifndef TESTS_ROCM_SMI_TEST_FUNCTIONAL_POWER_CAP_READ_WRITE_H_
#define TESTS_ROCM_SMI_TEST_FUNCTIONAL_POWER_CAP_READ_WRITE_H_
#include "../test_base.h"
class TestPowerCapReadWrite : public TestBase {
public:
TestPowerCapReadWrite();
// @Brief: Destructor for test case of TestPowerCapReadWrite
virtual ~TestPowerCapReadWrite();
// @Brief: Setup the environment for measurement
virtual void SetUp();
// @Brief: Core measurement execution
virtual void Run();
// @Brief: Clean up and retrive the resource
virtual void Close();
// @Brief: Display results
virtual void DisplayResults() const;
// @Brief: Display information about what this test does
virtual void DisplayTestInfo(void);
};
#endif // TESTS_ROCM_SMI_TEST_FUNCTIONAL_POWER_CAP_READ_WRITE_H_
@@ -1,132 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2019, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#include <stdint.h>
#include <stddef.h>
#include <iostream>
#include <string>
#include <gtest/gtest.h>
#include "rocm_smi/rocm_smi.h"
#include "power_read.h"
#include "../test_common.h"
TestPowerRead::TestPowerRead() : TestBase() {
set_title("RSMI Power Read Test");
set_description("The Power Read tests verifies that "
"power related values can be read properly.");
}
TestPowerRead::~TestPowerRead(void) {
}
void TestPowerRead::SetUp(void) {
TestBase::SetUp();
return;
}
void TestPowerRead::DisplayTestInfo(void) {
TestBase::DisplayTestInfo();
}
void TestPowerRead::DisplayResults(void) const {
TestBase::DisplayResults();
return;
}
void TestPowerRead::Close() {
// This will close handles opened within rsmitst utility calls and call
// rsmi_shut_down(), so it should be done after other hsa cleanup
TestBase::Close();
}
void TestPowerRead::Run(void) {
rsmi_status_t err;
uint64_t val_ui64, val2_ui64;
TestBase::Run();
if (setup_failed_) {
std::cout << "** SetUp Failed for this test. Skipping.**" << std::endl;
return;
}
for (uint32_t x = 0; x < num_iterations(); ++x) {
for (uint32_t i = 0; i < num_monitor_devs(); ++i) {
PrintDeviceHeader(i);
err = rsmi_dev_power_cap_get(i, 0, &val_ui64);
CHK_ERR_ASRT(err)
IF_VERB(STANDARD) {
std::cout << "\t**Current Power Cap: " << val_ui64 << "uW" <<std::endl;
}
err = rsmi_dev_power_cap_default_get(i, &val_ui64);
CHK_ERR_ASRT(err)
IF_VERB(STANDARD) {
std::cout << "\t**Default Power Cap: " << val_ui64 << "uW" <<std::endl;
}
err = rsmi_dev_power_cap_range_get(i, 0, &val_ui64, &val2_ui64);
CHK_ERR_ASRT(err)
IF_VERB(STANDARD) {
std::cout << "\t**Power Cap Range: " << val2_ui64 << " to " <<
val_ui64 << " uW" << std::endl;
}
err = rsmi_dev_power_ave_get(i, 0, &val_ui64);
IF_VERB(STANDARD) {
std::cout << "\t**Averge Power Usage: ";
CHK_RSMI_PERM_ERR(err)
if (err == RSMI_STATUS_SUCCESS) {
std::cout << static_cast<float>(val_ui64)/1000 << " mW" << std::endl;
}
// Verify api support checking functionality is working
err = rsmi_dev_power_ave_get(i, 0, nullptr);
ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS);
}
}
}
}
@@ -1,73 +0,0 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2019, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#ifndef TESTS_ROCM_SMI_TEST_FUNCTIONAL_POWER_READ_H_
#define TESTS_ROCM_SMI_TEST_FUNCTIONAL_POWER_READ_H_
#include "../test_base.h"
class TestPowerRead : public TestBase {
public:
TestPowerRead();
// @Brief: Destructor for test case of TestPowerRead
virtual ~TestPowerRead();
// @Brief: Setup the environment for measurement
virtual void SetUp();
// @Brief: Core measurement execution
virtual void Run();
// @Brief: Clean up and retrive the resource
virtual void Close();
// @Brief: Display results
virtual void DisplayResults() const;
// @Brief: Display information about what this test does
virtual void DisplayTestInfo(void);
};
#endif // TESTS_ROCM_SMI_TEST_FUNCTIONAL_POWER_READ_H_

Some files were not shown because too many files have changed in this diff Show More