diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..3e3944a39c --- /dev/null +++ b/.editorconfig @@ -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 diff --git a/.gitignore b/.gitignore index 28441fe2f8..014ca7c138 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000..381efe9b17 --- /dev/null +++ b/CHANGELOG.md @@ -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. diff --git a/CMakeLists.txt b/CMakeLists.txt index 9c776b2fba..97fa12d871 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/DEBIAN/control b/DEBIAN/control index 6c47d78dd6..81f02bf7f2 100644 --- a/DEBIAN/control +++ b/DEBIAN/control @@ -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 diff --git a/DEBIAN/postinst.in b/DEBIAN/postinst.in index 5fda052286..cb52dd1a08 100755 --- a/DEBIAN/postinst.in +++ b/DEBIAN/postinst.in @@ -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" diff --git a/DEBIAN/prerm.in b/DEBIAN/prerm.in index 65ec3de3ad..615428771e 100755 --- a/DEBIAN/prerm.in +++ b/DEBIAN/prerm.in @@ -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 ) ;; diff --git a/RPM/post.in b/RPM/post.in index df1074537a..0822d298e6 100755 --- a/RPM/post.in +++ b/RPM/post.in @@ -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 \ No newline at end of file diff --git a/RPM/postun.in b/RPM/postun.in index d54cd9b2ea..0dd41d82d8 100755 --- a/RPM/postun.in +++ b/RPM/postun.in @@ -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 diff --git a/RPM/preun.in b/RPM/preun.in new file mode 100755 index 0000000000..6d42dd5a72 --- /dev/null +++ b/RPM/preun.in @@ -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 diff --git a/amdsmi_cli/README.md b/amdsmi_cli/README.md index a823bd804b..86e35b2914 100644 --- a/amdsmi_cli/README.md +++ b/amdsmi_cli/README.md @@ -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 diff --git a/amdsmi_cli/amdsmi_commands.py b/amdsmi_cli/amdsmi_commands.py index 9cb2b1226b..eb119f8b5f 100644 --- a/amdsmi_cli/amdsmi_commands.py +++ b/amdsmi_cli/amdsmi_commands.py @@ -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: diff --git a/amdsmi_cli/amdsmi_helpers.py b/amdsmi_cli/amdsmi_helpers.py index 3bb0f1cce2..f5df6c72db 100644 --- a/amdsmi_cli/amdsmi_helpers.py +++ b/amdsmi_cli/amdsmi_helpers.py @@ -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: diff --git a/amdsmi_cli/amdsmi_parser.py b/amdsmi_cli/amdsmi_parser.py index 4c52a0e5d6..bdbe10f5d4 100644 --- a/amdsmi_cli/amdsmi_parser.py +++ b/amdsmi_cli/amdsmi_parser.py @@ -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(): diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 0000000000..b8ea6fcbcd --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1,9 @@ +!.sphinx/ +!.doxygen/ +/_build/ +/_doxygen/ +/_images/ +/_static/ +/_templates/ +/html/ +/latex/ diff --git a/docs/doxygen/Doxyfile b/docs/doxygen/Doxyfile index 2cc464402e..adeb41a5b0 100644 --- a/docs/doxygen/Doxyfile +++ b/docs/doxygen/Doxyfile @@ -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 diff --git a/example/amd_smi_drm_example.cc b/example/amd_smi_drm_example.cc index d8e71a601b..6b5767742a 100644 --- a/example/amd_smi_drm_example.cc +++ b/example/amd_smi_drm_example.cc @@ -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; diff --git a/include/amd_smi/amdsmi.h b/include/amd_smi/amdsmi.h index 3a2b082bdb..529c795fa8 100644 --- a/include/amd_smi/amdsmi.h +++ b/include/amd_smi/amdsmi.h @@ -53,6 +53,10 @@ #ifdef __cplusplus extern "C" { #include +#ifdef ENABLE_ESMI_LIB + #include +#endif + #else #include #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 diff --git a/include/amd_smi/impl/amd_smi_drm.h b/include/amd_smi/impl/amd_smi_drm.h index d38740c056..cb9fde0c42 100644 --- a/include/amd_smi/impl/amd_smi_drm.h +++ b/include/amd_smi/impl/amd_smi_drm.h @@ -45,6 +45,7 @@ #define AMD_SMI_INCLUDE_IMPL_AMD_SMI_DRM_H_ #include +#include #include #include #include // 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_; }; diff --git a/include/amd_smi/impl/amd_smi_gpu_device.h b/include/amd_smi/impl/amd_smi_gpu_device.h index 002e177146..fdd97d8cfd 100644 --- a/include/amd_smi/impl/amd_smi_gpu_device.h +++ b/include/amd_smi/impl/amd_smi_gpu_device.h @@ -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_; diff --git a/py-interface/README.md b/py-interface/README.md index ab7f162110..9eec994c77 100644 --- a/py-interface/README.md +++ b/py-interface/README.md @@ -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) ``` diff --git a/py-interface/__init__.py b/py-interface/__init__.py index 16a73ac8d9..61243ab046 100644 --- a/py-interface/__init__.py +++ b/py-interface/__init__.py @@ -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 diff --git a/py-interface/amdsmi_interface.py b/py-interface/amdsmi_interface.py index 5ab5ad4be4..b3f6296cfc 100644 --- a/py-interface/amdsmi_interface.py +++ b/py-interface/amdsmi_interface.py @@ -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( diff --git a/py-interface/amdsmi_wrapper.py b/py-interface/amdsmi_wrapper.py index 9b84553aae..488f68854f 100644 --- a/py-interface/amdsmi_wrapper.py +++ b/py-interface/amdsmi_wrapper.py @@ -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', diff --git a/rocm_smi/CMakeLists.txt b/rocm_smi/CMakeLists.txt index 43b723a7d0..3fa6a8972a 100755 --- a/rocm_smi/CMakeLists.txt +++ b/rocm_smi/CMakeLists.txt @@ -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}) diff --git a/rocm_smi/docs/ROCm_SMI_Manual.pdf b/rocm_smi/docs/ROCm_SMI_Manual.pdf index 8f5857f007..e3d1972458 100644 Binary files a/rocm_smi/docs/ROCm_SMI_Manual.pdf and b/rocm_smi/docs/ROCm_SMI_Manual.pdf differ diff --git a/rocm_smi/example/rocm_smi_example.cc b/rocm_smi/example/rocm_smi_example.cc index 08f7710451..bb456f7a0e 100755 --- a/rocm_smi/example/rocm_smi_example.cc +++ b/rocm_smi/example/rocm_smi_example.cc @@ -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 #include #include +#include #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 +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 +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(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(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 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(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(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" <(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(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; diff --git a/rocm_smi/include/rocm_smi/rocm_smi.h b/rocm_smi/include/rocm_smi/rocm_smi.h index 42d8da5357..8e4bacd03a 100755 --- a/rocm_smi/include/rocm_smi/rocm_smi.h +++ b/rocm_smi/include/rocm_smi/rocm_smi.h @@ -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 diff --git a/rocm_smi/include/rocm_smi/rocm_smi_common.h b/rocm_smi/include/rocm_smi/rocm_smi_common.h index dad39ad13f..bff8c8edc5 100755 --- a/rocm_smi/include/rocm_smi/rocm_smi_common.h +++ b/rocm_smi/include/rocm_smi/rocm_smi_common.h @@ -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 #include #include +#include #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 enum_overrides; + + // If RSMI_LOGGING is set, enables logging. + // Otherwise unset values, signify logging is turned off. + uint32_t logging_on; // Sysfs path overrides diff --git a/rocm_smi/include/rocm_smi/rocm_smi_device.h b/rocm_smi/include/rocm_smi/rocm_smi_device.h index a21a64a9ce..c975baae55 100755 --- a/rocm_smi/include/rocm_smi/rocm_smi_device.h +++ b/rocm_smi/include/rocm_smi/rocm_smi_device.h @@ -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 std::string readBootPartitionState(uint32_t dv_ind); private: std::shared_ptr monitor_; diff --git a/rocm_smi/include/rocm_smi/rocm_smi_logger.h b/rocm_smi/include/rocm_smi/rocm_smi_logger.h new file mode 100644 index 0000000000..3ff1070418 --- /dev/null +++ b/rocm_smi/include/rocm_smi/rocm_smi_logger.h @@ -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 , + * 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=. 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 +#include +#include +#include +#include + +// POSIX Socket Header File(s) +#include + +// 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 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 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_ diff --git a/rocm_smi/include/rocm_smi/rocm_smi_main.h b/rocm_smi/include/rocm_smi/rocm_smi_main.h index 126bbd7436..a64adddcc5 100755 --- a/rocm_smi/include/rocm_smi/rocm_smi_main.h +++ b/rocm_smi/include/rocm_smi/rocm_smi_main.h @@ -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 devInfoTypesStrings; private: std::vector> devices_; diff --git a/rocm_smi/include/rocm_smi/rocm_smi_monitor.h b/rocm_smi/include/rocm_smi/rocm_smi_monitor.h index c6bba27a60..648e159b65 100755 --- a/rocm_smi/include/rocm_smi/rocm_smi_monitor.h +++ b/rocm_smi/include/rocm_smi/rocm_smi_monitor.h @@ -115,6 +115,7 @@ class Monitor { std::string path_; const RocmSMI_env_vars *env_; std::map temp_type_index_map_; + std::map 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 index_temp_type_map_; - std::map volt_type_index_map_; std::map index_volt_type_map_; }; diff --git a/rocm_smi/include/rocm_smi/rocm_smi_utils.h b/rocm_smi/include/rocm_smi/rocm_smi_utils.h index d40b4e5404..a4558dbd2d 100755 --- a/rocm_smi/include/rocm_smi/rocm_smi_utils.h +++ b/rocm_smi/include/rocm_smi/rocm_smi_utils.h @@ -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 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 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 getListOfAppTmpFiles(); +bool containsString(std::string originalString, std::string substring); +std::tuple 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 getSystemDetails(void); +void logSystemDetails(void); struct pthread_wrap { public: diff --git a/rocm_smi/python_smi_tools/rocm_smi.py b/rocm_smi/python_smi_tools/rocm_smi.py index 2224edd8ec..5c12624142 100755 --- a/rocm_smi/python_smi_tools/rocm_smi.py +++ b/rocm_smi/python_smi_tools/rocm_smi.py @@ -18,6 +18,9 @@ import sys import subprocess import _thread import time +import multiprocessing +import trace +from io import StringIO from time import ctime from subprocess import check_output from rsmiBindings import * @@ -44,7 +47,7 @@ headerString = ' ROCm System Management Interface ' footerString = ' End of ROCm SMI Log ' # Output formatting -appWidth = 80 +appWidth = 84 deviceList = [] # Enable or disable serialized format @@ -194,7 +197,7 @@ def getBus(device): function = bdfid.value & 0x7 pic_id = '{:04X}:{:02X}:{:02X}.{:0X}'.format(domain, bus, device, function) - if rsmi_ret_ok(ret, device): + if rsmi_ret_ok(ret, device, 'get_pci_id'): return pic_id @@ -212,10 +215,10 @@ def getFanSpeed(device): fm = 0 ret = rocmsmi.rsmi_dev_fan_speed_get(device, sensor_ind, byref(fanLevel)) - if rsmi_ret_ok(ret, device, None, True): + if rsmi_ret_ok(ret, device, 'get_fan_speed', True): fl = fanLevel.value ret = rocmsmi.rsmi_dev_fan_speed_max_get(device, sensor_ind, byref(fanMax)) - if rsmi_ret_ok(ret, device, None, True): + if rsmi_ret_ok(ret, device, 'get_fan_max_speed', True): fm = fanMax.value if fl == 0 or fm == 0: return (fl, 0) # to prevent division by zero crash @@ -242,7 +245,7 @@ def getId(device): """ dv_id = c_short() ret = rocmsmi.rsmi_dev_id_get(device, byref(dv_id)) - if rsmi_ret_ok(ret, device): + if rsmi_ret_ok(ret, device, 'get_device_id'): return hex(dv_id.value) @@ -253,16 +256,21 @@ def getMaxPower(device): """ power_cap = c_uint64() ret = rocmsmi.rsmi_dev_power_cap_get(device, 0, byref(power_cap)) - if rsmi_ret_ok(ret, device): + if rsmi_ret_ok(ret, device, 'get_power_cap'): return power_cap.value / 1000000 return -1 -def getMemInfo(device, memType): - """ Return the specified memory usage for the specified device +def getMemInfo(device, memType, quiet=False): + """ Returns a tuple of (memory_used, memory_total) of + the requested memory type usage for the device specified @param device: DRM device identifier @param type: [vram|vis_vram|gtt] Memory type to return + @param quiet=Turn on to silience error output + (you plan to handle manually). Default is off, + which exposes any issue accessing the different + memory types. """ memType = memType.upper() if memType not in memory_type_l: @@ -275,11 +283,11 @@ def getMemInfo(device, memType): memTotal = None ret = rocmsmi.rsmi_dev_memory_usage_get(device, memory_type_l.index(memType), byref(memoryUse)) - if rsmi_ret_ok(ret, device, memType): + if rsmi_ret_ok(ret, device, 'get_memory_usage_' + str(memType), quiet): memUsed = memoryUse.value ret = rocmsmi.rsmi_dev_memory_total_get(device, memory_type_l.index(memType), byref(memoryTot)) - if rsmi_ret_ok(ret, device, memType + ' total'): + if rsmi_ret_ok(ret, device, 'get_memory_total_' + str(memType), quiet): memTotal = memoryTot.value return (memUsed, memTotal) @@ -316,9 +324,9 @@ def getPerfLevel(device): """ perf = rsmi_dev_perf_level_t() ret = rocmsmi.rsmi_dev_perf_level_get(device, byref(perf)) - if rsmi_ret_ok(ret, device): + if rsmi_ret_ok(ret, device, 'get_perf_level'): return perf_level_string(perf.value) - return -1 + return 'N/A' def getPid(name): @@ -333,7 +341,7 @@ def getPidList(): """ Return a list of KFD process IDs """ num_items = c_uint32() ret = rocmsmi.rsmi_compute_process_info_get(None, byref(num_items)) - if rsmi_ret_ok(ret): + if rsmi_ret_ok(ret, metric='get_compute_process_info'): buff_sz = num_items.value + 10 procs = (rsmi_process_info_t * buff_sz)() procList = [] @@ -351,7 +359,7 @@ def getPower(device): """ power = c_uint32() ret = rocmsmi.rsmi_dev_power_ave_get(device, 0, byref(power)) - if rsmi_ret_ok(ret, device, 'power'): + if rsmi_ret_ok(ret, device, 'get_power_avg'): return power.value / 1000000 return 'N/A' @@ -365,7 +373,7 @@ def getRasEnablement(device, block): state = rsmi_ras_err_state_t() ret = rocmsmi.rsmi_dev_ecc_status_get(device, rsmi_gpu_block_d[block], byref(state)) - if rsmi_ret_ok(ret, device, block, True): + if rsmi_ret_ok(ret, device, 'get_ecc_status_' + str(block), True): return rsmi_ras_err_stale_machine[state.value].upper() return 'N/A' @@ -379,7 +387,7 @@ def getTemp(device, sensor): temp = c_int64(0) metric = rsmi_temperature_metric_t.RSMI_TEMP_CURRENT ret = rocmsmi.rsmi_dev_temp_metric_get(c_uint32(device), temp_type_lst.index(sensor), metric, byref(temp)) - if rsmi_ret_ok(ret, device, sensor, True): + if rsmi_ret_ok(ret, device, 'get_temp_metric' + str(sensor), True): return temp.value / 1000 return 'N/A' @@ -403,11 +411,35 @@ def getVersion(deviceList, component): """ ver_str = create_string_buffer(256) ret = rocmsmi.rsmi_version_str_get(component, ver_str, 256) - if rsmi_ret_ok(ret, None, component): + if rsmi_ret_ok(ret, None, 'get_version_str_' + str(component)): return ver_str.value.decode() return None +def getComputePartition(device): + """ Return the current compute partition of a given device + + @param device: DRM device identifier + """ + currentComputePartition = create_string_buffer(256) + ret = rocmsmi.rsmi_dev_compute_partition_get(device, currentComputePartition, 256) + if rsmi_ret_ok(ret, device, 'get_compute_partition', silent=True) and currentComputePartition.value.decode(): + return str(currentComputePartition.value.decode()) + return "UNKNOWN" + + +def getMemoryPartition(device): + """ Return the current memory partition of a given device + + @param device: DRM device identifier + """ + currentNPSMode = create_string_buffer(256) + ret = rocmsmi.rsmi_dev_nps_mode_get(device, currentNPSMode, 256) + if rsmi_ret_ok(ret, device, 'get_NPS_mode', silent=True) and currentNPSMode.value.decode(): + return str(currentNPSMode.value.decode()) + return "UNKNOWN" + + def print2DArray(dataArray): """ Print 2D Array with uniform spacing """ global PRINT_JSON @@ -455,13 +487,33 @@ def printErrLog(device, err): global PRINT_JSON devName = device for line in err.split('\n'): - errstr = 'GPU[%s] \t\t: %s' % (devName, line) + errstr = 'GPU[%s]\t: %s' % (devName, line) if not PRINT_JSON: logging.error(errstr) else: logging.debug(errstr) +def printInfoLog(device, metricName, value): + """ Print out an info line to the SMI log + + @param device: DRM device identifier + @param metricName: Title of the item to print to the log + @param value: The item's value to print to the log + """ + global PRINT_JSON + + if not PRINT_JSON: + if value is not None: + logstr = 'GPU[%s]\t: %s: %s' % (device, metricName, value) + else: + logstr = 'GPU[%s]\t: %s' % (device, metricName) + if device is None: + logstr = logstr[13:] + + logging.info(logstr) + + def printEventList(device, delay, eventList): """ Print out notification events for a specified device @@ -471,13 +523,13 @@ def printEventList(device, delay, eventList): """ mask = 0 ret = rocmsmi.rsmi_event_notification_init(device) - if not rsmi_ret_ok(ret, device): + if not rsmi_ret_ok(ret, device, 'event_notification_init'): printErrLog(device, 'Unable to initialize event notifications.') return for eventType in eventList: mask |= 2 ** notification_type_names.index(eventType.upper()) ret = rocmsmi.rsmi_event_notification_mask_set(device, mask) - if not rsmi_ret_ok(ret, device): + if not rsmi_ret_ok(ret, device, 'set_event_notification_mask'): printErrLog(device, 'Unable to set event notification mask.') return while 1: # Exit condition from user keyboard input of 'q' or 'ctrl + c' @@ -488,8 +540,7 @@ def printEventList(device, delay, eventList): print2DArray([['\rGPU[%d]:\t' % (device), ctime().split()[3], notification_type_names[data.event.value - 1], data.message.decode('utf8') + '\r']]) - -def printLog(device, metricName, value): +def printLog(device, metricName, value=None, extraSpace=False): """ Print out to the SMI log @param device: DRM device identifier @@ -508,10 +559,15 @@ def printLog(device, metricName, value): else: logstr = 'GPU[%s]\t\t: %s' % (device, metricName) if device is None: - logstr = logstr[13:] - logging.debug(logstr) + logstr = logstr.split(':', 1)[1][1:] # Force thread safe printing - print(logstr + '\n', end='') + lock = multiprocessing.Lock() + lock.acquire() + if extraSpace: + print('\n' + logstr + '\n', end='', flush=True) + else: + print(logstr + '\n', end='', flush=True) + lock.release() def printListLog(metricName, valuesList): @@ -635,13 +691,13 @@ def checkIfSecondaryDie(device): power_cap = c_uint64() # secondary die can currently be determined by checking if all power1_* (power cap) values are equal to zero. ret = rocmsmi.rsmi_dev_power_cap_get(device, 0, byref(power_cap)) - if not (rsmi_ret_ok(ret, None, None, False) and power_cap.value == 0): + if not (rsmi_ret_ok(ret, None, 'get_power_cap', False) and power_cap.value == 0): return False ret = rocmsmi.rsmi_dev_power_cap_default_get(device, byref(power_cap)) - if not (rsmi_ret_ok(ret, None, None, False) and power_cap.value == 0): + if not (rsmi_ret_ok(ret, None, 'get_power_cap_default', False) and power_cap.value == 0): return False ret = rocmsmi.rsmi_dev_power_ave_get(device, 0, byref(power_cap)) - if not (rsmi_ret_ok(ret, None, None, False) and power_cap.value == 0): + if not (rsmi_ret_ok(ret, None, 'get_power_avg', False) and power_cap.value == 0): return False return True @@ -657,17 +713,17 @@ def resetClocks(deviceList): printLogSpacer(' Reset Clocks ') for device in deviceList: ret = rocmsmi.rsmi_dev_overdrive_level_set(device, rsmi_dev_perf_level_t(0)) - if rsmi_ret_ok(ret, device): + if rsmi_ret_ok(ret, device, 'set_overdrive_level'): printLog(device, 'OverDrive set to 0', None) else: printLog(device, 'Unable to reset OverDrive', None) ret = rocmsmi.rsmi_dev_perf_level_set(device, rsmi_dev_perf_level_t(0)) - if rsmi_ret_ok(ret, device): + if rsmi_ret_ok(ret, device, 'set_perf_level'): printLog(device, 'Successfully reset clocks', None) else: printLog(device, 'Unable to reset clocks', None) ret = rocmsmi.rsmi_dev_perf_level_set(device, rsmi_dev_perf_level_t(0)) - if rsmi_ret_ok(ret, device): + if rsmi_ret_ok(ret, device, 'set_perf_level'): printLog(device, 'Performance level reset to auto', None) else: printLog(device, 'Unable to reset performance level to auto', None) @@ -682,7 +738,7 @@ def resetFans(deviceList): for device in deviceList: sensor_ind = c_uint32(0) ret = rocmsmi.rsmi_dev_fan_reset(device, sensor_ind) - if rsmi_ret_ok(ret, device): + if rsmi_ret_ok(ret, device, 'reset_fan'): printLog(device, 'Successfully reset fan speed to driver control', None) printLogSpacer() @@ -703,12 +759,12 @@ def resetProfile(deviceList): printLogSpacer(' Reset Profile ') for device in deviceList: ret = rocmsmi.rsmi_dev_power_profile_set(device, 0, profileString('BOOTUP DEFAULT')) - if rsmi_ret_ok(ret, device): + if rsmi_ret_ok(ret, device, 'set_power_profile'): printLog(device, 'Successfully reset Power Profile', None) else: printErrLog(device, 'Unable to reset Power Profile') ret = rocmsmi.rsmi_dev_perf_level_set(device, rsmi_dev_perf_level_t(0)) - if rsmi_ret_ok(ret, device): + if rsmi_ret_ok(ret, device, 'set_perf_level'): printLog(device, 'Successfully reset Performance Level', None) else: printErrLog(device, 'Unable to reset Performance Level') @@ -741,7 +797,67 @@ def resetPerfDeterminism(deviceList): if rsmi_ret_ok(ret, device, 'disable performance determinism'): printLog(device, 'Successfully disabled performance determinism', None) else: - logging.error('GPU[%s]\t\t: Unable to diable performance determinism', device) + logging.error('GPU[%s]\t\t: Unable to disable performance determinism', device) + printLogSpacer() + + +def resetComputePartition(deviceList): + """ Reset Compute Partition to its boot state + + @param deviceList: List of DRM devices (can be a single-item list) + """ + printLogSpacer(" Reset compute partition to its boot state ") + for device in deviceList: + originalPartition = getComputePartition(device) + ret = rocmsmi.rsmi_dev_compute_partition_reset(device) + if rsmi_ret_ok(ret, device, 'reset_compute_partition', silent=True): + resetBootState = getComputePartition(device) + printLog(device, "Successfully reset compute partition (" + + originalPartition + ") to boot state (" + resetBootState + + ")", None) + elif ret == rsmi_status_t.RSMI_STATUS_PERMISSION: + printLog(device, 'Permission denied', None) + elif ret == rsmi_status_t.RSMI_STATUS_NOT_SUPPORTED: + printLog(device, 'Not supported on the given system', None) + else: + rsmi_ret_ok(ret, device, 'reset_compute_partition') + printErrLog(device, 'Failed to reset the compute partition to boot state') + printLogSpacer() + + +def resetNpsMode(deviceList): + """ Reset NPS mode to its boot state + + @param deviceList: List of DRM devices (can be a single-item list) + """ + printLogSpacer(" Reset nps mode to its boot state ") + for device in deviceList: + originalPartition = getMemoryPartition(device) + t1 = multiprocessing.Process(target=showProgressbar, + args=("Resetting NPS mode",13,)) + t1.start() + addExtraLine=True + start=time.time() + ret = rocmsmi.rsmi_dev_nps_mode_reset(device) + stop=time.time() + duration=stop-start + if t1.is_alive(): + t1.terminate() + t1.join() + if duration < float(0.1): # For longer runs, add extra line before output + addExtraLine=False # This is to prevent overriding progress bar + if rsmi_ret_ok(ret, device, 'reset_NPS_mode', silent=True): + resetBootState = getMemoryPartition(device) + printLog(device, "Successfully reset nps mode (" + + originalPartition + ") to boot state (" + + resetBootState + ")", None, addExtraLine) + elif ret == rsmi_status_t.RSMI_STATUS_PERMISSION: + printLog(device, 'Permission denied', None, addExtraLine) + elif ret == rsmi_status_t.RSMI_STATUS_NOT_SUPPORTED: + printLog(device, 'Not supported on the given system', None, addExtraLine) + else: + rsmi_ret_ok(ret, device, 'reset_NPS_mode') + printErrLog(device, 'Failed to reset nps mode to boot state') printLogSpacer() @@ -764,7 +880,7 @@ def setClockRange(deviceList, clkType, minvalue, maxvalue, autoRespond): try: int(minvalue) & int(maxvalue) except ValueError: - printErrLog(device, 'Unable to set %s range' % (clkType)) + printErrLog(None, 'Unable to set %s range' % (clkType)) logging.error('%s or %s is not an integer', minvalue, maxvalue) RETCODE = 1 return @@ -772,11 +888,13 @@ def setClockRange(deviceList, clkType, minvalue, maxvalue, autoRespond): printLogSpacer(' Set Valid %s Range ' % (clkType)) for device in deviceList: ret = rocmsmi.rsmi_dev_clk_range_set(device, int(minvalue), int(maxvalue), rsmi_clk_names_dict[clkType]) - if rsmi_ret_ok(ret, device): + if rsmi_ret_ok(ret, device, silent=True): printLog(device, 'Successfully set %s from %s(MHz) to %s(MHz)' % (clkType, minvalue, maxvalue), None) else: printErrLog(device, 'Unable to set %s from %s(MHz) to %s(MHz)' % (clkType, minvalue, maxvalue)) RETCODE = 1 + if ret == rsmi_status_t.RSMI_STATUS_NOT_SUPPORTED: + printLog(device, 'Setting %s range is not supported for this device.' % (clkType), None) def setVoltageCurve(deviceList, point, clk, volt, autoRespond): @@ -792,16 +910,16 @@ def setVoltageCurve(deviceList, point, clk, volt, autoRespond): global RETCODE value = '%s %s %s' % (point, clk, volt) try: - any(int(item) for item in value) + any(int(item) for item in value.split()) except ValueError: - printLogNoDev('Unable to set Voltage curve') - logging.error('Non-integer characters are present in %s', value) + printErrLog(None, 'Unable to set Voltage curve') + printErrLog(None, 'Non-integer characters are present in %s' %value) RETCODE = 1 return confirmOutOfSpecWarning(autoRespond) for device in deviceList: ret = rocmsmi.rsmi_dev_od_volt_info_set(device, int(point), int(clk), int(volt)) - if rsmi_ret_ok(ret, device): + if rsmi_ret_ok(ret, device, 'set_voltage_curve'): printLog(device, 'Successfully set voltage point %s to %s(MHz) %s(mV)' % (point, clk, volt), None) else: printErrLog(device, 'Unable to set voltage point %s to %s(MHz) %s(mV)' % (point, clk, volt)) @@ -821,11 +939,12 @@ def setPowerPlayTableLevel(deviceList, clkType, point, clk, volt, autoRespond): """ global RETCODE value = '%s %s %s' % (point, clk, volt) + listOfValues = value.split(' ') try: any(int(item) for item in value.split()) except ValueError: - printLogNoDev('Unable to set PowerPlay table level') - logging.error('Non-integer characters are present in %s', value) + printErrLog(None, 'Unable to set PowerPlay table level') + printErrLog(None, 'Non-integer characters are present in %s' %value) RETCODE = 1 return confirmOutOfSpecWarning(autoRespond) @@ -833,7 +952,7 @@ def setPowerPlayTableLevel(deviceList, clkType, point, clk, volt, autoRespond): if clkType == 'sclk': ret = rocmsmi.rsmi_dev_od_clk_info_set(device, rsmi_freq_ind_t(int(point)), int(clk), rsmi_clk_names_dict[clkType]) - if rsmi_ret_ok(ret, device): + if rsmi_ret_ok(ret, device, 'set_power_play_table_level_' + str(clkType)): printLog(device, 'Successfully set voltage point %s to %s(MHz) %s(mV)' % (point, clk, volt), None) else: printErrLog(device, 'Unable to set voltage point %s to %s(MHz) %s(mV)' % (point, clk, volt)) @@ -841,7 +960,7 @@ def setPowerPlayTableLevel(deviceList, clkType, point, clk, volt, autoRespond): elif clkType == 'mclk': ret = rocmsmi.rsmi_dev_od_clk_info_set(device, rsmi_freq_ind_t(int(point)), int(clk), rsmi_clk_names_dict[clkType]) - if rsmi_ret_ok(ret, device): + if rsmi_ret_ok(ret, device, 'set_power_play_table_level_' + str(clkType)): printLog(device, 'Successfully set voltage point %s to %s(MHz) %s(mV)' % (point, clk, volt), None) else: printErrLog(device, 'Unable to set voltage point %s to %s(MHz) %s(mV)' % (point, clk, volt)) @@ -882,14 +1001,15 @@ def setClockOverDrive(deviceList, clktype, value, autoRespond): value = '20' if getPerfLevel(device) != 'MANUAL': ret = rocmsmi.rsmi_dev_perf_level_set(device, rsmi_dev_perf_level_t(3)) - if rsmi_ret_ok(ret, device): + if rsmi_ret_ok(ret, device, 'set_perf_level_manual_' + str(clktype)): printLog(device, 'Performance level set to manual', None) else: printErrLog(device, 'Unable to set performance level to manual') if clktype == 'mclk': fsFile = os.path.join('/sys/class/drm', 'card%d' % (device), 'device', 'pp_mclk_od') if not os.path.isfile(fsFile): - printLog(None, 'Unable to write to sysfs file', None) + printLog(None, 'Unable to write to sysfs file (' + fsFile + + '), file does not exist', None) logging.debug('%s does not exist', fsFile) continue try: @@ -897,14 +1017,14 @@ def setClockOverDrive(deviceList, clktype, value, autoRespond): with open(fsFile, 'w') as fs: fs.write(value + '\n') except (IOError, OSError): - printLog(None, 'Unable to write to sysfs file %s' % fsFile, None) + printLog(None, 'Unable to write to sysfs file %s' %fsFile, None) logging.warning('IO or OS error') RETCODE = 1 continue printLog(device, 'Successfully set %s OverDrive to %s%%' % (clktype, value), None) elif clktype == 'sclk': ret = rocmsmi.rsmi_dev_overdrive_level_set(device, rsmi_dev_perf_level_t(int(value))) - if rsmi_ret_ok(ret, device): + if rsmi_ret_ok(ret, device, 'set_overdrive_level_' + str(clktype)): printLog(device, 'Successfully set %s OverDrive to %s%%' % (clktype, value), None) else: printLog(device, 'Unable to set %s OverDrive to %s%%' % (clktype, value), None) @@ -936,7 +1056,7 @@ def setClocks(deviceList, clktype, clk): int(check_value) except ValueError: printLog(None, 'Unable to set clock level', None) - logging.error('Non-integer characters are present in value %s', value) + logging.error('Non-integer characters are present in value %s', check_value) RETCODE = 1 return # Generate a frequency bitmask from user input value @@ -955,22 +1075,48 @@ def setClocks(deviceList, clktype, clk): # Check if the performance level is manual, if not then set it to manual if getPerfLevel(device).lower() != 'manual': ret = rocmsmi.rsmi_dev_perf_level_set(device, rsmi_dev_perf_level_t(3)) - if rsmi_ret_ok(ret, device): + if rsmi_ret_ok(ret, device, 'set_perf_level_manual'): printLog(device, 'Performance level was set to manual', None) else: printErrLog(device, 'Unable to set performance level to manual') RETCODE = 1 return if clktype != 'pcie': + # Validate frequency bitmask + freq = rsmi_frequencies_t() + ret = rocmsmi.rsmi_dev_gpu_clk_freq_get(device, rsmi_clk_names_dict[clktype], byref(freq)) + if rsmi_ret_ok(ret, device, 'get_gpu_clk_freq_' + str(clktype)) == False: + RETCODE = 1 + return + # The freq_bitmask should be less than 2^(freqs.num_supported) + # For example, num_supported == 3, the max bitmask is 0111 + if freq_bitmask >= (1 << freq.num_supported): + printErrLog(device, 'Invalid clock frequency %s' % hex(freq_bitmask)) + RETCODE = 1 + return + ret = rocmsmi.rsmi_dev_gpu_clk_freq_set(device, rsmi_clk_names_dict[clktype], freq_bitmask) - if rsmi_ret_ok(ret, device): + if rsmi_ret_ok(ret, device, 'set_gpu_clk_freq_' + str(clktype)): printLog(device, 'Successfully set %s bitmask to' % (clktype), hex(freq_bitmask)) else: printErrLog(device, 'Unable to set %s bitmask to: %s' % (clktype, hex(freq_bitmask))) RETCODE = 1 else: + # Validate the bandwidth bitmask + bw = rsmi_pcie_bandwidth_t() + ret = rocmsmi.rsmi_dev_pci_bandwidth_get(device, byref(bw)) + if rsmi_ret_ok(ret, device, 'get_PCIe_bandwidth') == False: + RETCODE = 1 + return + # The freq_bitmask should be less than 2^(bw.transfer_rate.num_supported) + # For example, num_supported == 3, the max bitmask is 0111 + if freq_bitmask >= (1 << bw.transfer_rate.num_supported): + printErrLog(device, 'Invalid PCIe frequency %s' % hex(freq_bitmask)) + RETCODE = 1 + return + ret = rocmsmi.rsmi_dev_pci_bandwidth_set(device, freq_bitmask) - if rsmi_ret_ok(ret, device): + if rsmi_ret_ok(ret, device, 'set_PCIe_bandwidth'): printLog(device, 'Successfully set %s to level bitmask' % (clktype), hex(freq_bitmask)) else: printErrLog(device, 'Unable to set %s bitmask to: %s' % (clktype, hex(freq_bitmask))) @@ -989,13 +1135,13 @@ def setPerfDeterminism(deviceList, clkvalue): try: int(clkvalue) except ValueError: - printErrLog(device, 'Unable to set Performance Determinism') + printErrLog(None, 'Unable to set Performance Determinism') logging.error('%s is not an integer', clkvalue) RETCODE = 1 return for device in deviceList: ret = rocmsmi.rsmi_perf_determinism_mode_set(device, int(clkvalue)) - if rsmi_ret_ok(ret, device): + if rsmi_ret_ok(ret, device, 'set_perf_determinism'): printLog(device, 'Successfully enabled performance determinism and set GFX clock frequency', str(clkvalue)) else: printErrLog(device, 'Unable to set performance determinism and clock frequency to %s' % (str(clkvalue))) @@ -1019,7 +1165,7 @@ def resetGpu(device): RETCODE = 1 return ret = rocmsmi.rsmi_dev_gpu_reset(resetDev) - if rsmi_ret_ok(ret, resetDev): + if rsmi_ret_ok(ret, resetDev, 'reset_gpu'): printLog(resetDev, 'Successfully reset GPU %d' % (resetDev), None) else: printErrLog(resetDev, 'Unable to reset GPU %d' % (resetDev)) @@ -1059,19 +1205,16 @@ def setRas(deviceList, rasAction, rasBlock, rasType): printLog(None, "This is experimental feature, use 'amdgpuras' tool for ras error manipulations for newer vbios") if rasAction not in validRasActions: - printLog(None, 'Unable to perform RAS command %s on block %s for type %s' % (rasAction, rasBlock, rasType), - None) + printLog(None, 'Unable to perform RAS command %s on block %s for type %s' % (rasAction, rasBlock, rasType)) logging.debug('Action %s is not a valid RAS command' % rasAction) return if rasBlock not in validRasBlocks: - printLog(None, 'Unable to perform RAS command %s on block %s for type %s' % (rasAction, rasBlock, rasType), - None) + printLog(None, 'Unable to perform RAS command %s on block %s for type %s' % (rasAction, rasBlock, rasType)) printLog(None, 'Block %s is not a valid RAS block' % rasBlock) return if rasType not in validRasTypes: - printLog(None, 'Unable to perform RAS command %s on block %s for type %s' % (rasAction, rasBlock, rasType), - None) + printLog(None, 'Unable to perform RAS command %s on block %s for type %s' % (rasAction, rasBlock, rasType)) printLog(None, 'Memory error type %s is not a valid RAS memory type' % rasAction) return @@ -1111,14 +1254,13 @@ def setFanSpeed(deviceList, fan): for device in deviceList: if str(fan): fanLevel = c_int64() - sensor_ind = c_uint32(0) last_char = str(fan)[-1] if last_char == '%': fanLevel = int(str(fan)[:-1]) / 100 * 255 else: fanLevel = int(str(fan)) ret = rocmsmi.rsmi_dev_fan_speed_set(device, 0, int(fanLevel)) - if rsmi_ret_ok(ret, device): + if rsmi_ret_ok(ret, device, 'set_fan_speed'): printLog(device, 'Successfully set fan speed to level %s' % (str(int(fanLevel))), None) printLogSpacer() @@ -1137,7 +1279,7 @@ def setPerformanceLevel(deviceList, level): logging.error('Invalid Performance level: %s', level) else: ret = rocmsmi.rsmi_dev_perf_level_set(device, rsmi_dev_perf_level_t(validLevels.index(level))) - if rsmi_ret_ok(ret, device): + if rsmi_ret_ok(ret, device, 'set_perf_level'): printLog(device, 'Performance level set to %s' % (str(level)), None) printLogSpacer() @@ -1196,7 +1338,7 @@ def setPowerOverDrive(deviceList, value, autoRespond): new_power_cap.value = int(value) * 1000000 ret = rocmsmi.rsmi_dev_power_cap_range_get(device, 0, byref(power_cap_max), byref(power_cap_min)) - if rsmi_ret_ok(ret, device) == False: + if rsmi_ret_ok(ret, device, 'get_power_cap_range') == False: printErrLog(device, 'Unable to parse Power OverDrive range') RETCODE = 1 continue @@ -1220,11 +1362,11 @@ def setPowerOverDrive(deviceList, value, autoRespond): specWarningConfirmed = True ret = rocmsmi.rsmi_dev_power_cap_set(device, 0, new_power_cap) - if rsmi_ret_ok(ret, device): + if rsmi_ret_ok(ret, device, 'set_power_cap'): if int(value) == 0: power_cap = c_uint64() ret = rocmsmi.rsmi_dev_power_cap_get(device, 0, byref(power_cap)) - if rsmi_ret_ok(ret, device): + if rsmi_ret_ok(ret, device, 'get_power_cap'): if not PRINT_JSON: printLog(device, 'Successfully reset Power OverDrive to: %sW' % (int(power_cap.value / 1000000)), None) @@ -1255,7 +1397,7 @@ def setProfile(deviceList, profile): for device in deviceList: # Get previous profile ret = rocmsmi.rsmi_dev_power_profile_presets_get(device, 0, byref(status)) - if rsmi_ret_ok(ret, device, 'previous profile'): + if rsmi_ret_ok(ret, device, 'get_power_profile'): previousProfile = profileString(status.current) # Get desired profile desiredProfile = 'UNKNOWN' @@ -1272,10 +1414,10 @@ def setProfile(deviceList, profile): return else: ret = rocmsmi.rsmi_dev_power_profile_set(device, 0, profileString(desiredProfile)) - if rsmi_ret_ok(ret, device, 'set profile'): + if rsmi_ret_ok(ret, device, 'set_power_profile'): # Get current profile ret = rocmsmi.rsmi_dev_power_profile_presets_get(device, 0, byref(status)) - if rsmi_ret_ok(ret, device, 'current profile'): + if rsmi_ret_ok(ret, device, 'get_power_profile_presets'): currentProfile = profileString(status.current) if currentProfile == desiredProfile: printLog(device, 'Successfully set profile to', desiredProfile) @@ -1284,6 +1426,110 @@ def setProfile(deviceList, profile): printLogSpacer() +def setComputePartition(deviceList, computePartitionType): + """ Sets compute partitioning for a list of device + + @param deviceList: List of DRM devices (can be a single-item list) + @param computePartition: Compute Partition type to set as + """ + printLogSpacer(' Set compute partition to %s ' % (str(computePartitionType).upper())) + for device in deviceList: + computePartitionType = computePartitionType.upper() + if computePartitionType not in compute_partition_type_l: + printErrLog(device, 'Invalid compute partition type %s' + '\nValid compute partition types are %s' + % ( computePartitionType.upper(), + (', '.join(map(str, compute_partition_type_l))) )) + return (None, None) + ret = rocmsmi.rsmi_dev_compute_partition_set(device, + rsmi_compute_partition_type_dict[computePartitionType]) + if rsmi_ret_ok(ret, device, 'set_compute_partition', silent=True): + printLog(device, + 'Successfully set compute partition to %s' % (computePartitionType), + None) + elif ret == rsmi_status_t.RSMI_STATUS_PERMISSION: + printLog(device, 'Permission denied', None) + elif ret == rsmi_status_t.RSMI_STATUS_SETTING_UNAVAILABLE: + printLog(device, 'Requested setting (%s) is unavailable for current device' + %computePartitionType, None) + elif ret == rsmi_status_t.RSMI_STATUS_NOT_SUPPORTED: + printLog(device, 'Not supported on the given system', None) + else: + rsmi_ret_ok(ret, device, 'set_compute_partition') + printErrLog(device, 'Failed to retrieve compute partition, even though device supports it.') + printLogSpacer() + + +def progressbar(it, prefix="", size=60, out=sys.stdout): + count = len(it) + def show(j): + x = int(size*j/count) + lock = multiprocessing.Lock() + lock.acquire() + print("{}[{}{}] {}/{} secs remain".format(prefix, u"â–ˆ"*x, "."*(size-x), j, count), + end='\r', file=out, flush=True) + lock.release() + show(0) + for i, item in enumerate(it): + yield item + show(i+1) + lock = multiprocessing.Lock() + lock.acquire() + print("\n", flush=True, file=out) + lock.release() + +def showProgressbar(title="", timeInSeconds=13): + if title != "": + title += ": " + for i in progressbar(range(timeInSeconds), title, 40): + time.sleep(1) + + +def setNPSMode(deviceList, npsMode): + """ Sets nps mode (memory partition) for a list of devices + + @param deviceList: List of DRM devices (can be a single-item list) + @param npsMode: NPS Mode type to set as + """ + printLogSpacer(' Set nps mode to %s ' % (str(npsMode).upper())) + for device in deviceList: + npsMode = npsMode.upper() + if npsMode not in nps_mode_type_l: + printErrLog(device, 'Invalid nps mode type %s' + '\nValid nps mode types are %s' + % ( npsMode.upper(), + (', '.join(map(str, nps_mode_type_l))) )) + return (None, None) + + t1 = multiprocessing.Process(target=showProgressbar, + args=("Updating NPS mode",13,)) + t1.start() + addExtraLine=True + start=time.time() + ret = rocmsmi.rsmi_dev_nps_mode_set(device, + rsmi_nps_mode_type_dict[npsMode]) + stop=time.time() + duration=stop-start + if t1.is_alive(): + t1.terminate() + t1.join() + if duration < float(0.1): # For longer runs, add extra line before output + addExtraLine=False # This is to prevent overriding progress bar + + if rsmi_ret_ok(ret, device, 'set_NPS_mode', silent=True): + printLog(device, + 'Successfully set nps mode to %s' % (npsMode), + None, addExtraLine) + elif ret == rsmi_status_t.RSMI_STATUS_PERMISSION: + printLog(device, 'Permission denied', None, addExtraLine) + elif ret == rsmi_status_t.RSMI_STATUS_NOT_SUPPORTED: + printLog(device, 'Not supported on the given system', None, addExtraLine) + else: + rsmi_ret_ok(ret, device, 'set_NPS_mode') + printErrLog(device, 'Failed to retrieve NPS mode, even though device supports it.') + printLogSpacer() + + def showAllConcise(deviceList): """ Display critical info for all devices in a concise format @@ -1294,7 +1540,7 @@ def showAllConcise(deviceList): print('ERROR: Cannot print JSON/CSV output for concise output') sys.exit(1) printLogSpacer(' Concise Info ') - header = ['GPU', 'Temp', 'AvgPwr', 'SCLK', 'MCLK', 'Fan', 'Perf', 'PwrCap', 'VRAM%', 'GPU%'] + header = ['GPU', 'Temp (DieEdge)', 'AvgPwr', 'SCLK', 'MCLK', 'Fan', 'Perf', 'PwrCap', 'VRAM%', 'GPU%'] head_widths = [len(head) + 2 for head in header] values = {} for device in deviceList: @@ -1323,14 +1569,15 @@ def showAllConcise(deviceList): gpu_busy = str(getGpuUse(device)) + '%' else: gpu_busy = 'Unsupported' - memInfo = getMemInfo(device, 'vram') - if memInfo[0] == None or memInfo[1] == None: - mem_use = 'N/A' - else: - mem_use_pct = '% 3.0f%%' % (100 * (float(memInfo[0]) / float(memInfo[1]))) + vram_used, vram_total = getMemInfo(device, 'vram', True) + mem_use_pct = 0 + if vram_used is None: + mem_use_pct='Unsupported' + if vram_used != None and vram_total != None and float(vram_total) != 0: + mem_use_pct = '% 3.0f%%' % (100 * (float(vram_used) / float(vram_total))) values['card%s' % (str(device))] = [device, temp, avgPwr, sclk, mclk, fan, str(perf).lower(), pwrCap, mem_use_pct, gpu_busy] - val_widths = {} + val_widths = {} for device in deviceList: val_widths[device] = [len(str(val)) + 2 for val in values['card%s' % (str(device))]] max_widths = head_widths @@ -1404,10 +1651,9 @@ def showClocks(deviceList): printLogSpacer(' Supported clock frequencies ') for device in deviceList: for clk_type in sorted(rsmi_clk_names_dict): - freq_list = [] if rocmsmi.rsmi_dev_gpu_clk_freq_get(device, rsmi_clk_names_dict[clk_type], None) == 1: ret = rocmsmi.rsmi_dev_gpu_clk_freq_get(device, rsmi_clk_names_dict[clk_type], byref(freq)) - if rsmi_ret_ok(ret, device, clk_type, True): + if rsmi_ret_ok(ret, device, 'get_clk_freq_' + clk_type, True): printLog(device, 'Supported %s frequencies on GPU%s' % (clk_type, str(device)), None) for x in range(freq.num_supported): fr = '{:>.0f}Mhz'.format(freq.frequency[x] / 1000000) @@ -1421,9 +1667,8 @@ def showClocks(deviceList): printLog(device, '', None) if rocmsmi.rsmi_dev_pci_bandwidth_get(device, None) == 1: ret = rocmsmi.rsmi_dev_pci_bandwidth_get(device, byref(bw)) - if rsmi_ret_ok(ret, device, 'PCIe', True): + if rsmi_ret_ok(ret, device, 'get_PCIe_bandwidth', True): printLog(device, 'Supported %s frequencies on GPU%s' % ('PCIe', str(device)), None) - freq_list = [] for x in range(bw.transfer_rate.num_supported): fr = '{:>.1f}GT/s x{}'.format(bw.transfer_rate.frequency[x] / 1000000000, bw.lanes[x]) if x == bw.transfer_rate.current: @@ -1447,15 +1692,13 @@ def showCurrentClocks(deviceList, clk_defined=None, concise=False): global PRINT_JSON freq = rsmi_frequencies_t() bw = rsmi_pcie_bandwidth_t() - currentString = '' - sortedClocksArray = [] if not concise: printLogSpacer(' Current clock frequencies ') for device in deviceList: if clk_defined: if rocmsmi.rsmi_dev_gpu_clk_freq_get(device, rsmi_clk_names_dict[clk_defined], None) == 1: ret = rocmsmi.rsmi_dev_gpu_clk_freq_get(device, rsmi_clk_names_dict[clk_defined], byref(freq)) - if rsmi_ret_ok(ret, device, clk_defined, True): + if rsmi_ret_ok(ret, device, 'get_gpu_clk_freq_' + str(clk_defined), silent=True): levl = freq.current if levl >= freq.num_supported: printLog(device, '%s current clock frequency not found' % (clk_defined), None) @@ -1471,7 +1714,7 @@ def showCurrentClocks(deviceList, clk_defined=None, concise=False): for clk_type in sorted(rsmi_clk_names_dict): if rocmsmi.rsmi_dev_gpu_clk_freq_get(device, rsmi_clk_names_dict[clk_type], None) == 1: ret = rocmsmi.rsmi_dev_gpu_clk_freq_get(device, rsmi_clk_names_dict[clk_type], byref(freq)) - if rsmi_ret_ok(ret, device, clk_type, True): + if rsmi_ret_ok(ret, device, 'get_clk_freq_' + str(clk_type), True): levl = freq.current if levl >= freq.num_supported: printLog(device, '%s current clock frequency not found' % (clk_type), None) @@ -1487,7 +1730,7 @@ def showCurrentClocks(deviceList, clk_defined=None, concise=False): # pcie clocks if rocmsmi.rsmi_dev_pci_bandwidth_get(device, None) == 1: ret = rocmsmi.rsmi_dev_pci_bandwidth_get(device, byref(bw)) - if rsmi_ret_ok(ret, device, 'PCIe', True): + if rsmi_ret_ok(ret, device, 'get_PCIe_bandwidth', True): current_f = bw.transfer_rate.current if current_f >= bw.transfer_rate.num_supported: printLog(device, 'PCIe current clock frequency not found', None ) @@ -1525,7 +1768,7 @@ def showCurrentFans(deviceList): else: printLog(device, 'Fan Level', str(fanLevel) + ' (%s%%)' % (str(fanSpeed))) ret = rocmsmi.rsmi_dev_fan_rpms_get(device, sensor_ind, byref(rpmSpeed)) - if rsmi_ret_ok(ret, device): + if rsmi_ret_ok(ret, device, 'get_fan_rpms'): printLog(device, 'Fan RPM', rpmSpeed.value) printLogSpacer() @@ -1538,7 +1781,11 @@ def showCurrentTemps(deviceList): printLogSpacer(' Temperature ') for device in deviceList: for sensor in temp_type_lst: - printLog(device, 'Temperature (Sensor %s) (C)' % (sensor), getTemp(device, sensor)) + temp = getTemp(device, sensor) + if temp != 'N/A': + printLog(device, 'Temperature (Sensor %s) (C)' % (sensor), temp) + else: + printInfoLog(device, 'Temperature (Sensor %s) (C)' % (sensor), temp) printLogSpacer() @@ -1557,12 +1804,11 @@ def showFwInfo(deviceList, fwType): firmware_blocks = fwType printLogSpacer(' Firmware Information ') for device in deviceList: - fw_ver_list = [] fw_ver = c_uint64() for fw_name in firmware_blocks: fw_name = fw_name.upper() ret = rocmsmi.rsmi_dev_firmware_version_get(device, fw_block_names_l.index(fw_name), byref(fw_ver)) - if rsmi_ret_ok(ret, device, fw_name): + if rsmi_ret_ok(ret, device, 'get_firmware_version_' + str(fw_name)): # The VCN, VCE, UVD, SOS and ASD firmware's value needs to be in hexadecimal if fw_name in ['VCN', 'VCE', 'UVD', 'SOS', 'ASD']: printLog(device, '%s firmware version' % (fw_name), @@ -1606,14 +1852,17 @@ def showGpusByPid(pidList): return for pid in pidList: ret = rocmsmi.rsmi_compute_process_gpus_get(int(pid), None, byref(num_devices)) - if rsmi_ret_ok(ret, 'PID ' + pid): + if rsmi_ret_ok(ret, metric=('PID ' + pid)): dv_indices = (c_uint32 * num_devices.value)() ret = rocmsmi.rsmi_compute_process_gpus_get(int(pid), dv_indices, byref(num_devices)) - if rsmi_ret_ok(ret): + if rsmi_ret_ok(ret, metric='get_gpu_compute_process'): metricName = 'PID %s is using %s DRM device(s)' % (pid, str(num_devices.value)) - printListLog(metricName, list(dv_indices)) + if (num_devices.value): + printListLog(metricName, list(dv_indices)) + else: + printLog(None, metricName, None) else: print(None, 'Unable to get list of KFD PIDs. A kernel update may be needed', None) printLogSpacer() @@ -1650,7 +1899,7 @@ def getCoarseGrainUtil(device, typeName=None): utilization_counters[i].type = c_int(i) ret = rocmsmi.rsmi_utilization_count_get(device, utilization_counters, length, byref(timestamp)) - if rsmi_ret_ok(ret, device, typeName, True): + if rsmi_ret_ok(ret, device, 'get_utilization_count_'+ str(typeName), True): return utilization_counters return -1 @@ -1671,7 +1920,7 @@ def showGpuUse(deviceList): for ut_counter in util_counters: printLog(device, utilization_counter_name[ut_counter.type], ut_counter.val) else: - printLog(device, 'GFX Activity', 'N/A') + printInfoLog(device, 'GFX Activity', 'N/A') printLogSpacer() @@ -1776,10 +2025,13 @@ def showMemVendor(deviceList): printLogSpacer(' Memory Vendor ') for device in deviceList: ret = rocmsmi.rsmi_dev_vram_vendor_get(device, vendor, 256) - if rsmi_ret_ok(ret, device) and vendor.value.decode(): - printLog(device, 'GPU memory vendor', vendor.value.decode()) - else: - logging.debug('GPU memory vendor missing or not supported') + try: + if rsmi_ret_ok(ret, device, 'get_vram_vendor') and vendor.value.decode(): + printLog(device, 'GPU memory vendor', vendor.value.decode()) + else: + logging.debug('GPU memory vendor missing or not supported') + except UnicodeDecodeError: + printErrLog(device, 'Unable to read GPU memory vendor') printLogSpacer() @@ -1792,26 +2044,23 @@ def showOverDrive(deviceList, odtype): rsmi_od = c_uint32() printLogSpacer(' OverDrive Level ') for device in deviceList: + odStr = '' + od = '' if odtype == 'sclk': odStr = 'GPU' ret = rocmsmi.rsmi_dev_overdrive_level_get(device, byref(rsmi_od)) od = rsmi_od.value - if not rsmi_ret_ok(ret, device): - printErrLog(device, 'Unable to retrieve sclk OverDrive level') + if not rsmi_ret_ok(ret, device, 'get_overdrive_level_' + str(odtype)): + continue elif odtype == 'mclk': odStr = 'GPU Memory' - filePath = os.path.join('/sys/class/drm', 'card%d' % (device), 'device', 'pp_mclk_od') - if filePath: - try: - with open(filePath, 'r') as fileContents: - od = fileContents.read().rstrip('\n') - except: - printErrLog(device, 'Unable to retrieve mclk OverDrive level') - return None + ret = rocmsmi.rsmi_dev_mem_overdrive_level_get(device, byref(rsmi_od)) + od = rsmi_od.value + if not rsmi_ret_ok(ret, device, 'get_mem_overdrive_level_' + str(odtype)): + continue else: printErrLog(device, 'Unable to retrieve OverDrive') - logging.error('Unsupported clock type %s', clktype) - RETCODE = 1 + logging.error('Unsupported clock type %s', odtype) printLog(device, odStr + ' OverDrive value (%)', od) printLogSpacer() @@ -1827,7 +2076,7 @@ def showPcieBw(deviceList): printLogSpacer(' Measured PCIe Bandwidth ') for device in deviceList: ret = rocmsmi.rsmi_dev_pci_throughput_get(device, byref(sent), byref(received), byref(max_pkt_sz)) - if rsmi_ret_ok(ret, device): + if rsmi_ret_ok(ret, device, 'get_PCIe_bandwidth'): # Use 1024.0 to ensure that the result is a float and not integer division bw = ((received.value + sent.value) * max_pkt_sz.value) / 1024.0 / 1024.0 # Use the bwstr below to control precision on the string @@ -1866,11 +2115,15 @@ def showPerformanceLevel(deviceList): printLogSpacer() -def showPids(): +def showPids(verbose): """ Show Information for PIDs created in a KFD (Compute) context """ printLogSpacer(' KFD Processes ') dataArray = [] - dataArray.append(['PID', 'PROCESS NAME', 'GPU(s)', 'VRAM USED', 'SDMA USED', 'CU OCCUPANCY']) + if verbose == "details": + dataArray.append(['PID', 'PROCESS NAME', 'GPU', 'VRAM USED', 'SDMA USED', 'CU OCCUPANCY']) + else: + dataArray.append(['PID', 'PROCESS NAME', 'GPU(s)', 'VRAM USED', 'SDMA USED', 'CU OCCUPANCY']) + pidList = getPidList() if not pidList: printLog(None, 'No KFD PIDs currently running', None) @@ -1884,22 +2137,34 @@ def showPids(): vramUsage = 'UNKNOWN' sdmaUsage = 'UNKNOWN' cuOccupancy = 'UNKNOWN' + dv_indices = (c_uint32 * num_devices.value)() ret = rocmsmi.rsmi_compute_process_gpus_get(int(pid), None, byref(num_devices)) - if rsmi_ret_ok(ret): + if rsmi_ret_ok(ret, metric='get_gpu_compute_process'): dv_indices = (c_uint32 * num_devices.value)() ret = rocmsmi.rsmi_compute_process_gpus_get(int(pid), dv_indices, byref(num_devices)) - if rsmi_ret_ok(ret): + if rsmi_ret_ok(ret, metric='get_gpu_compute_process'): gpuNumber = str(num_devices.value) else: logging.debug('Unable to fetch GPU number by PID') - ret = rocmsmi.rsmi_compute_process_info_by_pid_get(int(pid), byref(proc)) - if rsmi_ret_ok(ret): - vramUsage = proc.vram_usage - sdmaUsage = proc.sdma_usage - cuOccupancy = proc.cu_occupancy + if verbose == "details": + for dv_ind in dv_indices: + ret = rocmsmi.rsmi_compute_process_info_by_device_get(int(pid), dv_ind, byref(proc)) + if rsmi_ret_ok(ret, metric='get_compute_process_info_by_pid'): + vramUsage = proc.vram_usage + sdmaUsage = proc.sdma_usage + cuOccupancy = proc.cu_occupancy + else: + logging.debug('Unable to fetch process info by PID') + dataArray.append([pid, getProcessName(pid), str(gpuNumber), str(vramUsage), str(sdmaUsage), str(cuOccupancy)]) else: - logging.debug('Unable to fetch process info by PID') - dataArray.append([pid, getProcessName(pid), str(gpuNumber), str(vramUsage), str(sdmaUsage), str(cuOccupancy)]) + ret = rocmsmi.rsmi_compute_process_info_by_pid_get(int(pid), byref(proc)) + if rsmi_ret_ok(ret, metric='get_compute_process_info_by_pid'): + vramUsage = proc.vram_usage + sdmaUsage = proc.sdma_usage + cuOccupancy = proc.cu_occupancy + else: + logging.debug('Unable to fetch process info by PID') + dataArray.append([pid, getProcessName(pid), str(gpuNumber), str(vramUsage), str(sdmaUsage), str(cuOccupancy)]) printLog(None, 'KFD process information:', None) print2DArray(dataArray) printLogSpacer() @@ -1938,7 +2203,7 @@ def showPowerPlayTable(deviceList): odvf = rsmi_od_volt_freq_data_t() for device in deviceList: ret = rocmsmi.rsmi_dev_od_volt_info_get(device, byref(odvf)) - if rsmi_ret_ok(ret, device, 'od volt'): + if rsmi_ret_ok(ret, device, 'get_od_volt'): # TODO: Make this more dynamic and less hard-coded if possible printLog(device, 'OD_SCLK:', None) printLog(device, '0: %sMhz' % (int(odvf.curr_sclk_range.lower_bound / 1000000)), None) @@ -1978,19 +2243,29 @@ def showProductName(deviceList): # Retrieve card vendor ret = rocmsmi.rsmi_dev_vendor_name_get(device, vendor, 256) # Only continue if GPU vendor is AMD - if rsmi_ret_ok(ret, device) and isAmdDevice(device): - device_vendor = vendor.value.decode() + if rsmi_ret_ok(ret, device, 'get_vendor_name') and isAmdDevice(device): + try: + device_vendor = vendor.value.decode() + except UnicodeDecodeError: + printErrLog(device, "Unable to read device vendor") + device_vendor = "N/A" # Retrieve the device series ret = rocmsmi.rsmi_dev_name_get(device, series, 256) - if rsmi_ret_ok(ret, device) and series.value.decode(): - device_series = series.value.decode() - printLog(device, 'Card series', '\t\t' + device_series) + if rsmi_ret_ok(ret, device, 'get_name'): + try: + device_series = series.value.decode() + printLog(device, 'Card series', '\t\t' + device_series) + except UnicodeDecodeError: + printErrLog(device, "Unable to read card series") # Retrieve the device model ret = rocmsmi.rsmi_dev_subsystem_name_get(device, model, 256) - if rsmi_ret_ok(ret, device) and model.value.decode(): - device_model = model.value.decode() - # padHexValue is used for applications that expect 4-digit card models - printLog(device, 'Card model', '\t\t' + padHexValue(device_model, 4)) + if rsmi_ret_ok(ret, device, 'get_subsystem_name'): + try: + device_model = model.value.decode() + # padHexValue is used for applications that expect 4-digit card models + printLog(device, 'Card model', '\t\t' + padHexValue(device_model, 4)) + except UnicodeDecodeError: + printErrLog(device, "Unable to read device model") printLog(device, 'Card vendor', '\t\t' + device_vendor) # TODO: Retrieve the SKU using 'rsmi_dev_sku_get' from the LIB # ret = rocmsmi.rsmi_dev_sku_get(device, sku, 256) @@ -1998,10 +2273,15 @@ def showProductName(deviceList): # device_sku = sku.value.decode() # Retrieve the device SKU as a substring from VBIOS ret = rocmsmi.rsmi_dev_vbios_version_get(device, vbios, 256) - if rsmi_ret_ok(ret, device) and vbios.value.decode(): - # Device SKU is just 6 characters after the first occurance of '-' in vbios_version - device_sku = vbios.value.decode().split('-')[1][:6] - printLog(device, 'Card SKU', '\t\t' + device_sku) + if rsmi_ret_ok(ret, device, 'get_vbios_version') and vbios.value.decode(): + # Device SKU is just the characters in between the two '-' in vbios_version + if vbios.value.decode().count('-') == 2 and len(str(vbios.value.decode().split('-')[1])) > 1: + device_sku = vbios.value.decode().split('-')[1] + else: + device_sku = 'unknown' + printLog(device, 'Card SKU', '\t\t' + device_sku) + else: + printErrLog(device, "Unable to decode VBIOS value for device SKU") else: printLog(device, 'Incompatible device.\n' \ 'GPU[%s]\t\t: Expected vendor name: Advanced Micro Devices, Inc. [AMD/ATI]\n' \ @@ -2021,7 +2301,7 @@ def showProfile(deviceList): status = rsmi_power_profile_status_t() for device in deviceList: ret = rocmsmi.rsmi_dev_power_profile_presets_get(device, 0, byref(status)) - if rsmi_ret_ok(ret, device, 'profiles'): + if rsmi_ret_ok(ret, device, 'get_power_profiles', silent=False): binaryMaskString = str(format(status.available_profiles, '07b'))[::-1] bitMaskPosition = 0 profileNumber = 0 @@ -2053,7 +2333,7 @@ def showRange(deviceList, rangeType): odvf = rsmi_od_volt_freq_data_t() for device in deviceList: ret = rocmsmi.rsmi_dev_od_volt_info_get(device, byref(odvf)) - if rsmi_ret_ok(ret, device, 'od volt'): + if rsmi_ret_ok(ret, device, 'get_od_volt', silent=False): if rangeType == 'sclk': printLog(device, 'Valid sclk range: %sMhz - %sMhz' % ( int(odvf.curr_sclk_range.lower_bound / 1000000), int(odvf.curr_sclk_range.upper_bound / 1000000)), None) @@ -2075,8 +2355,6 @@ def showRange(deviceList, rangeType): None) else: printLog(device, 'Unable to display %s range' % (rangeType), None) - else: - printLog(device, 'Unable to display %s range' % (rangeType), None) printLogSpacer() @@ -2093,7 +2371,7 @@ def showRasInfo(deviceList, rasType): for name in rasType: if name.upper() not in rsmi_gpu_block_d: rasType.remove(name) - printErrLog(device, '%s is not a RAS block' % (name)) + printErrLog(None, '%s is not a RAS block' % (name)) rasBlocks = [block.upper() for block in rasType] @@ -2103,7 +2381,7 @@ def showRasInfo(deviceList, rasType): for block in rasBlocks: row = [] ret = rocmsmi.rsmi_dev_ecc_status_get(device, rsmi_gpu_block_d[block], byref(state)) - if rsmi_ret_ok(ret, device, block, True): + if rsmi_ret_ok(ret, device, 'get_ecc_status_' + str(block), True): row.append(block) row.append(rsmi_ras_err_stale_machine[state.value].upper()) # Now add the error count @@ -2114,7 +2392,7 @@ def showRasInfo(deviceList, rasType): row.append(ec.correctable_err) row.append(ec.uncorrectable_err) data.append(row) - printTableLog([' Block', ' Status ', 'uncorrectable err', 'correctable err'], data, device, + printTableLog([' Block', ' Status ', 'Correctable Error', 'Uncorrectable Error'], data, device, 'RAS INFO') # TODO: Use dynamic spacing for column widths printLogSpacer(None, '_') @@ -2159,7 +2437,13 @@ def showSerialNumber(deviceList): for device in deviceList: sn = create_string_buffer(256) ret = rocmsmi.rsmi_dev_serial_number_get(device, sn, 256) - if rsmi_ret_ok(ret, device) and sn.value.decode(): + try: + sn.value.decode() + except UnicodeDecodeError: + printErrLog(device, "FRU Serial Number contains non-alphanumeric characters. FRU is likely corrupted") + continue + + if rsmi_ret_ok(ret, device, 'get_serial_number') and sn.value.decode(): printLog(device, 'Serial Number', sn.value.decode()) else: printLog(device, 'Serial Number', 'N/A') @@ -2175,7 +2459,7 @@ def showUId(deviceList): for device in deviceList: dv_uid = c_uint64() ret = rocmsmi.rsmi_dev_unique_id_get(device, byref(dv_uid)) - if rsmi_ret_ok(ret, device, None, True) and str(hex(dv_uid.value)): + if rsmi_ret_ok(ret, device, 'get_unique_id', True) and str(hex(dv_uid.value)): printLog(device, 'Unique ID', hex(dv_uid.value)) else: printLog(device, 'Unique ID', 'N/A') @@ -2229,15 +2513,15 @@ def showEvents(deviceList, eventTypes): printErrLog(None, 'Ignoring unrecognized event type %s' % (event.replace(',', ''))) if len(eventTypeList) == 0: eventTypeList = notification_type_names - try: print2DArray([['DEVICE\t', 'TIME\t', 'TYPE\t', 'DESCRIPTION']]) # Create a seperate thread for each GPU for device in deviceList: - _thread.start_new_thread(printEventList, (device, 1000, eventTypeList)) - time.sleep(0.25) - except Exception as e: - printErrLog(device, 'Unable to start new thread. %s' % (e)) - return + try: + _thread.start_new_thread(printEventList, (device, 1000, eventTypeList)) + time.sleep(0.25) + except Exception as e: + printErrLog(device, 'Unable to start new thread. %s' % (e)) + return while 1: # Exit condition from user keyboard input of 'q' or 'ctrl + c' getch = _Getch() user_input = getch() @@ -2245,12 +2529,118 @@ def showEvents(deviceList, eventTypes): if user_input == 'q' or user_input == '\x03': for device in deviceList: ret = rocmsmi.rsmi_event_notification_stop(device) - if not rsmi_ret_ok(ret, device): + if not rsmi_ret_ok(ret, device, 'stop_event_notification'): printErrLog(device, 'Unable to end event notifications.') print('\r') break +def printTempGraph(deviceList, delay): + # deviceList must be in ascending order + deviceList.sort() + devices = 0 + # Print an empty line for each device + for device in deviceList: + devices = devices + 1 + for i in range(devices): + printEmptyLine() + originalTerminalWidth = os.get_terminal_size()[0] + while 1: # Exit condition from user keyboard input of 'q' or 'ctrl + c' + terminalWidth = os.get_terminal_size()[0] + printStrings = list() + for device in deviceList: + temp = getTemp(device, 'edge') + if temp == 'N/A': + percentage = 0 + else: + percentage = temp + if percentage >= 100: + percentage = 100 + if percentage < 0: + percentage = 0 + # Get available space based on terminal width + availableSpace = 0 + if terminalWidth >= 20: + availableSpace = terminalWidth - 20 + # Get color based on percentage, with a non-linear scaling + color = getGraphColor(3.16*(percentage**1.5)**(1/2)) + # Get graph length based on percentage and available space + padding = (percentage / float(100)) * availableSpace + if padding > availableSpace: + padding = availableSpace + paddingSpace = color[-1] + for i in range(int(padding)): + paddingSpace += paddingSpace[-1] + remainder = 0 + if availableSpace >= padding: + remainder = availableSpace + 1 - padding + remainderSpace = ' ' * int(remainder) + # TODO: Allow terminal size to be decreased + if terminalWidth < originalTerminalWidth: + print('Terminal size cannot be decreased.\n\r') + return + if type(temp) == str: + tempString = temp + else: + tempString = str(int(temp)) + # Two spare Spaces + tempString = (tempString + '°C').ljust(5) + printStrings.append('\033[2;30;47mGPU[%d] Temp %s|%s%s\x1b[0m%s' % (device, tempString, color, paddingSpace[1:], remainderSpace)) + originalTerminalWidth = terminalWidth + time.sleep((delay / 1000)) + + if terminalWidth >= 20: + # go up and prepare to rewrite the lines + for i in printStrings: + print('\033[A', end='\r') + # print all strings + for i in printStrings: + print(i, end='\r\n') + + +def getGraphColor(percentage): + # Text / Background color mixing (Tested on PuTTY) + colors = ['\033[2;35;45m','\033[2;34;45m','\033[2;35;44m','\033[2;34;44m', + '\033[2;36;44m','\033[2;34;46m','\033[2;36;46m','\033[2;32;46m', + '\033[2;36;42m','\033[2;32;42m','\033[2;33;42m','\033[2;32;43m', + '\033[2;33;43m','\033[2;31;43m','\033[2;33;41m','\033[2;31;41m'] + characters = [' ', 'â–‘', 'â–‘', 'â–’', 'â–’', 'â–‘'] + # Ensure percentage is in range and rounded + if percentage > 99: + percentage = 99 + if percentage < 0: + percentage = 0 + percentage = round(percentage, 0) + # There are a total of 16 distinct colors, with 2 special ascii characters per + # color, for a total of 16*2=32 distinct colors for a gradient. + # Therefore every 100/32=3.125 percent the color gradient will change + stepSize = (100/len(colors))/2 + characterIndex = int((percentage % (len(characters) * stepSize)) / stepSize) + colorIndex = int(percentage / (stepSize * 2)) + returnStr = colors[colorIndex] + characters[characterIndex] + return returnStr + + +def showTempGraph(deviceList): + printLogSpacer(' Temperature Graph ') + # Start a thread for constantly printing + try: + # Create a thread (call print function, devices, delay in ms) + _thread.start_new_thread(printTempGraph, (deviceList, 150)) + except Exception as e: + printErrLog(device, 'Unable to start new thread. %s' % (e)) + # Catch user input for program termination + while 1: # Exit condition from user keyboard input of 'q' or 'ctrl + c' + getch = _Getch() + user_input = getch() + # Catch user input for q or Ctrl + c + if user_input == 'q' or user_input == '\x03': + break + # Reset color to default before exit + print('\033[A\x1b[0m\r') + printLogSpacer() + + def showVersion(deviceList, component): """ Display the software version for the specified component @@ -2273,7 +2663,7 @@ def showVoltage(deviceList): met = rsmi_voltage_metric_t(0) voltage = c_uint64() ret = rocmsmi.rsmi_dev_volt_metric_get(device, vtype, met, byref(voltage)) - if rsmi_ret_ok(ret, device) and str(voltage.value): + if rsmi_ret_ok(ret, device, 'get_volt_metric') and str(voltage.value): printLog(device, 'Voltage (mV)', str(voltage.value)) else: logging.debug('GPU voltage not supported') @@ -2289,13 +2679,11 @@ def showVoltageCurve(deviceList): odvf = rsmi_od_volt_freq_data_t() for device in deviceList: ret = rocmsmi.rsmi_dev_od_volt_info_get(device, byref(odvf)) - if rsmi_ret_ok(ret, device, 'od volt'): + if rsmi_ret_ok(ret, device, 'get_od_volt_info', silent=False): for position in range(3): printLog(device, 'Voltage point %d: %sMhz %smV' % ( position, int(list(odvf.curve.vc_points)[position].frequency / 1000000), int(list(odvf.curve.vc_points)[position].voltage)), None) - else: - printLog(device, 'Voltage Curve is not supported', None) printLogSpacer() @@ -2309,7 +2697,7 @@ def showXgmiErr(deviceList): printLogSpacer('XGMI Error status') xe = rsmi_xgmi_status_t() for device in deviceList: - ret = rocmsmi.rsmi_dev_xgmi_error_status(device, xe) + ret = rocmsmi.rsmi_dev_xgmi_error_status(device, byref(xe)) if rsmi_ret_ok(ret, device, 'xgmi status'): desc = '' if xe.value is None: @@ -2346,7 +2734,7 @@ def showAccessibleTopology(deviceList): for srcdevice in deviceList: for destdevice in deviceList: ret = rocmsmi.rsmi_is_P2P_accessible(srcdevice, destdevice, byref(accessible)) - if rsmi_ret_ok(ret): + if rsmi_ret_ok(ret, metric='is_P2P_accessible'): gpu_links_type[srcdevice][destdevice] = accessible.value else: printErrLog(srcdevice, 'Cannot read link accessibility: Unsupported on this machine') @@ -2385,10 +2773,12 @@ def showWeightTopology(deviceList): continue weight = c_uint64() ret = rocmsmi.rsmi_topo_get_link_weight(srcdevice, destdevice, byref(weight)) - if rsmi_ret_ok(ret): + if rsmi_ret_ok(ret, metric='get_link_weight_topology'): gpu_links_weight[srcdevice][destdevice] = weight else: printErrLog(srcdevice, 'Cannot read Link Weight: Not supported on this machine') + gpu_links_weight[srcdevice][destdevice] = None + if PRINT_JSON: formatMatrixToJSON(deviceList, gpu_links_weight, "(Topology) Weight between DRM devices {} and {}") @@ -2405,6 +2795,8 @@ def showWeightTopology(deviceList): for gpu2 in deviceList: if (gpu1 == gpu2): printTableRow('%-12s', '0') + elif (gpu_links_weight[gpu1][gpu2] == None): + printTableRow('%-12s', 'N/A') else: printTableRow('%-12s', gpu_links_weight[gpu1][gpu2].value) printEmptyLine() @@ -2428,10 +2820,11 @@ def showHopsTopology(deviceList): continue hops = c_uint64() ret = rocmsmi.rsmi_topo_get_link_type(srcdevice, destdevice, byref(hops), byref(linktype)) - if rsmi_ret_ok(ret): + if rsmi_ret_ok(ret, metric='get_link_type_topology'): gpu_links_hops[srcdevice][destdevice] = hops else: printErrLog(srcdevice, 'Cannot read Link Hops: Not supported on this machine') + gpu_links_hops[srcdevice][destdevice] = None if PRINT_JSON: formatMatrixToJSON(deviceList, gpu_links_hops, "(Topology) Hops between DRM devices {} and {}") @@ -2448,6 +2841,8 @@ def showHopsTopology(deviceList): for gpu2 in deviceList: if (gpu1 == gpu2): printTableRow('%-12s', '0') + elif (gpu_links_hops[gpu1][gpu2] == None): + printTableRow('%-12s', 'N/A') else: printTableRow('%-12s', gpu_links_hops[gpu1][gpu2].value) printEmptyLine() @@ -2471,7 +2866,7 @@ def showTypeTopology(deviceList): gpu_links_type[srcdevice][destdevice] = '0' continue ret = rocmsmi.rsmi_topo_get_link_type(srcdevice, destdevice, byref(hops), byref(linktype)) - if rsmi_ret_ok(ret): + if rsmi_ret_ok(ret, metric='get_link_topology_type'): if (linktype.value == 1): gpu_links_type[srcdevice][destdevice] = "PCIE" elif (linktype.value == 2): @@ -2480,6 +2875,8 @@ def showTypeTopology(deviceList): gpu_links_type[srcdevice][destdevice] = "XXXX" else: printErrLog(srcdevice, 'Cannot read Link Type: Not supported on this machine') + gpu_links_type[srcdevice][destdevice] = "XXXX" + if PRINT_JSON: formatMatrixToJSON(deviceList, gpu_links_type, "(Topology) Link type between DRM devices {} and {}") return @@ -2511,13 +2908,13 @@ def showNumaTopology(deviceList): numa_numbers = c_uint32() for device in deviceList: ret = rocmsmi.rsmi_topo_get_numa_node_number(device, byref(numa_numbers)) - if rsmi_ret_ok(ret, device): + if rsmi_ret_ok(ret, device, 'get_numa_node_number'): printLog(device, "(Topology) Numa Node", numa_numbers.value) else: printErrLog(device, "Cannot read Numa Node") ret = rocmsmi.rsmi_topo_numa_affinity_get(device, byref(numa_numbers)) - if rsmi_ret_ok(ret): + if rsmi_ret_ok(ret, metric='get_numa_affinity_topology'): printLog(device, "(Topology) Numa Affinity", numa_numbers.value) else: printErrLog(device, 'Cannot read Numa Affinity') @@ -2560,18 +2957,18 @@ def showNodesBw(deviceList): ret = rocmsmi.rsmi_minmax_bandwidth_get(srcdevice, destdevice, byref(minBW), byref(maxBW)) #verify that link type is xgmi ret2 = rocmsmi.rsmi_topo_get_link_type(srcdevice, destdevice, byref(hops), byref(linktype)) - if rsmi_ret_ok(ret2," {} to {}".format(srcdevice, destdevice), None, True): + if rsmi_ret_ok(ret2," {} to {}".format(srcdevice, destdevice), 'get_link_topology_type', True): if linktype.value != 2: nonXgmi = True silent= True gpu_links_type[srcdevice][destdevice] = "N/A" - if rsmi_ret_ok(ret, " {} to {}".format(srcdevice, destdevice),None,silent): + if rsmi_ret_ok(ret, " {} to {}".format(srcdevice, destdevice), 'get_link_topology_type',silent): gpu_links_type[srcdevice][destdevice] = "{}-{}".format(minBW.value, maxBW.value) else: gpu_links_type[srcdevice][destdevice] = "N/A" if PRINT_JSON: - formatMatrixToJSON(deviceList, "{}-{}".format(minBW.value, maxBW.value), " min-max bandwidth between DRM devices {} and {}".format(srcdevice, destdevice)) + # TODO return printTableRow(None, ' ') for row in deviceList: @@ -2589,6 +2986,43 @@ def showNodesBw(deviceList): if nonXgmi: printLog(None,"Non-xGMI links detected and is currently not supported", None) +def showComputePartition(deviceList): + """ Returns the current compute partitioning for a list of devices + + @param deviceList: List of DRM devices (can be a single-item list) + """ + currentComputePartition = create_string_buffer(256) + printLogSpacer(' Current Compute Partition ') + for device in deviceList: + ret = rocmsmi.rsmi_dev_compute_partition_get(device, currentComputePartition, 256) + if rsmi_ret_ok(ret, device, 'get_compute_partition', silent=True) and currentComputePartition.value.decode(): + printLog(device, 'Compute Partition', currentComputePartition.value.decode()) + elif ret == rsmi_status_t.RSMI_STATUS_NOT_SUPPORTED: + printLog(device, 'Not supported on the given system', None) + else: + rsmi_ret_ok(ret, device, 'get_compute_partition') + printErrLog(device, 'Failed to retrieve compute partition, even though device supports it.') + printLogSpacer() + +def showNPSMode(deviceList): + """ Returns the current NPS mode for a list of devices + + @param deviceList: List of DRM devices (can be a single-item list) + """ + npsMode = create_string_buffer(256) + printLogSpacer(' Current NPS Mode ') + for device in deviceList: + ret = rocmsmi.rsmi_dev_nps_mode_get(device, npsMode, 256) + if rsmi_ret_ok(ret, device, 'get_NPS_mode',silent=True) and npsMode.value.decode(): + printLog(device, 'NPS Mode', npsMode.value.decode()) + elif ret == rsmi_status_t.RSMI_STATUS_NOT_SUPPORTED: + printLog(device, 'Not supported on the given system', None) + else: + rsmi_ret_ok(ret, device, 'get_NPS_mode') + printErrLog(device, 'Failed to retrieve NPS mode, even though device supports it.') + printLogSpacer() + + def checkAmdGpus(deviceList): """ Check if there are any AMD GPUs being queried, return False if there are none @@ -2684,7 +3118,7 @@ def listDevices(): """ Returns a list of GPU devices """ numberOfDevices = c_uint32(0) ret = rocmsmi.rsmi_num_monitor_devices(byref(numberOfDevices)) - if rsmi_ret_ok(ret): + if rsmi_ret_ok(ret, metric='get_num_monitor_devices'): deviceList = list(range(numberOfDevices.value)) return deviceList else: @@ -2762,6 +3196,8 @@ def relaunchAsSudo(): """ if os.geteuid() != 0: os.execvp('sudo', ['sudo'] + sys.argv) + #keeping below, if we want to run sudo with user's env variables + #os.execvp('sudo', ['sudo', '-E'] + sys.argv) def rsmi_ret_ok(my_ret, device=None, metric=None, silent=False): @@ -2772,6 +3208,8 @@ def rsmi_ret_ok(my_ret, device=None, metric=None, silent=False): @param device: DRM device identifier @param my_ret: Return of RSMI call (rocm_smi_lib API) @param metric: Parameter of GPU currently being analyzed + @param silent: Echo verbose error reponse. + True siliences err output, False does not silience err output (default). """ global RETCODE global PRINT_JSON @@ -2783,17 +3221,19 @@ def rsmi_ret_ok(my_ret, device=None, metric=None, silent=False): returnString += '%s GPU[%s]:' % (my_ret, device) if metric is not None: returnString += ' %s: ' % (metric) - returnString += '%s\t' % (err_str.value.decode()) + else: + metric = '' + if err_str.value is not None: + returnString += '%s\t' % (err_str.value.decode()) if not PRINT_JSON: - if silent: - logging.info('%s', returnString) - else: - logging.error('%s', returnString) + logging.debug('%s', returnString) + if not silent: + if my_ret in rsmi_status_verbose_err_out: + printLog(device, metric + ", " + rsmi_status_verbose_err_out[my_ret], None) RETCODE = my_ret return False return True - def save(deviceList, savefilepath): """ Save clock frequencies and fan speeds for a list of devices to a specified file path. @@ -2821,14 +3261,14 @@ def save(deviceList, savefilepath): for clk_type in sorted(rsmi_clk_names_dict): clocks[device] = clocks.get(device, {}) ret = rocmsmi.rsmi_dev_gpu_clk_freq_get(device, rsmi_clk_names_dict[clk_type], byref(freq)) - if rsmi_ret_ok(ret, device, clk_type, True): + if rsmi_ret_ok(ret, device, 'get_gpu_clk_freq_' + str(clk_type), True): clocks[device][clk_type] = str(freq.current) else: clocks[device][clk_type] = '0' fanSpeeds[device] = getFanSpeed(device)[0] od = c_uint32() ret = rocmsmi.rsmi_dev_overdrive_level_get(device, byref(od)) - if rsmi_ret_ok(ret, device): + if rsmi_ret_ok(ret, device, 'get_overdrive_level'): overDriveGpu[device] = str(od.value) else: overDriveGpu[device] = '0' @@ -2836,7 +3276,7 @@ def save(deviceList, savefilepath): overDriveGpuMem[device] = '0' status = rsmi_power_profile_status_t() ret = rocmsmi.rsmi_dev_power_profile_presets_get(device, 0, byref(status)) - if rsmi_ret_ok(ret, device, 'profile'): + if rsmi_ret_ok(ret, device, 'get_profile_presets'): profiles[device] = str(str(bin(status.current))[2:][::-1].index('1') + 1) else: profiles[device] = str('UNKNOWN') @@ -2844,7 +3284,7 @@ def save(deviceList, savefilepath): 'fan': fanSpeeds[device], 'overdrivesclk': overDriveGpu[device], 'overdrivemclk': overDriveGpuMem[device], 'profile': profiles[device], 'perflevel': perfLevels[device]} - printLog(device, 'Current settings successfully saved to', savefilepath) + printLog(None, 'Current settings successfully saved to', savefilepath) with open(savefilepath, 'w') as savefile: json.dump(jsonData, savefile, ensure_ascii=True) printLogSpacer() @@ -2878,6 +3318,7 @@ if __name__ == '__main__': groupDisplayTop.add_argument('-v', '--showvbios', help='Show VBIOS version', action='store_true') groupDisplayTop.add_argument('-e', '--showevents', help='Show event list', metavar='EVENT', type=str, nargs='*') groupDisplayTop.add_argument('--showdriverversion', help='Show kernel driver version', action='store_true') + groupDisplayTop.add_argument('--showtempgraph', help='Show Temperature Graph', action='store_true') groupDisplayTop.add_argument('--showfwinfo', help='Show FW information', metavar='BLOCK', type=str, nargs='*') groupDisplayTop.add_argument('--showmclkrange', help='Show mclk range', action='store_true') groupDisplayTop.add_argument('--showmemvendor', help='Show GPU memory vendor', action='store_true') @@ -2915,7 +3356,8 @@ if __name__ == '__main__': groupDisplay.add_argument('-s', '--showclkfrq', help='Show supported GPU and Memory Clock', action='store_true') groupDisplay.add_argument('--showmeminfo', help='Show Memory usage information for given block(s) TYPE', metavar='TYPE', type=str, nargs='+') - groupDisplay.add_argument('--showpids', help='Show current running KFD PIDs', action='store_true') + groupDisplay.add_argument('--showpids', help='Show current running KFD PIDs (pass details to VERBOSE for detailed information)', + metavar='VERBOSE', const="summary", type=str, nargs='?') groupDisplay.add_argument('--showpidgpus', help='Show GPUs used by specified KFD PIDs (all if no arg given)', nargs='*') groupDisplay.add_argument('--showreplaycount', help='Show PCIe Replay Count', action='store_true') @@ -2933,6 +3375,8 @@ if __name__ == '__main__': groupDisplay.add_argument('--showenergycounter', help='Energy accumulator that stores amount of energy consumed', action='store_true') groupDisplay.add_argument('--shownodesbw', help='Shows the numa nodes ', action='store_true') + groupDisplay.add_argument('--showcomputepartition', help='Shows current compute partitioning ', action='store_true') + groupDisplay.add_argument('--shownpsmode', help='Shows current NPS mode ', action='store_true') groupActionReset.add_argument('-r', '--resetclocks', help='Reset clocks and OverDrive to default', action='store_true') @@ -2942,7 +3386,9 @@ if __name__ == '__main__': help='Set the maximum GPU power back to the device deafult state', action='store_true') groupActionReset.add_argument('--resetxgmierr', help='Reset XGMI error count', action='store_true') - groupAction.add_argument('--resetperfdeterminism', help='Disable performance determinism', action='store_true') + groupActionReset.add_argument('--resetperfdeterminism', help='Disable performance determinism', action='store_true') + groupActionReset.add_argument('--resetcomputepartition', help='Resets to boot compute partition state', action='store_true') + groupActionReset.add_argument('--resetnpsmode', help='Resets to boot NPS mode state', action='store_true') groupAction.add_argument('--setclock', help='Set Clock Frequency Level(s) for specified clock (requires manual Perf level)', metavar=('TYPE','LEVEL'), nargs=2) @@ -2977,6 +3423,12 @@ if __name__ == '__main__': groupAction.add_argument('--setperfdeterminism', help='Set clock frequency limit to get minimal performance variation', type=int, metavar='SCLK', nargs=1) + groupAction.add_argument('--setcomputepartition', help='Set compute partition', + choices=compute_partition_type_l + [x.lower() for x in compute_partition_type_l], + type=str, nargs=1) + groupAction.add_argument('--setnpsmode', help='Set nps mode', + choices=nps_mode_type_l + [x.lower() for x in nps_mode_type_l], + type=str, nargs=1) groupAction.add_argument('--rasenable', help='Enable RAS for specified block and error type', type=str, nargs=2, metavar=('BLOCK', 'ERRTYPE')) groupAction.add_argument('--rasdisable', help='Disable RAS for specified block and error type', type=str, nargs=2, @@ -3014,7 +3466,8 @@ if __name__ == '__main__': or args.resetclocks or args.setprofile or args.resetprofile or args.setoverdrive or args.setmemoverdrive \ or args.setpoweroverdrive or args.resetpoweroverdrive or args.rasenable or args.rasdisable or \ args.rasinject or args.gpureset or args.setperfdeterminism or args.setslevel or args.setmlevel or \ - args.setvc or args.setsrange or args.setmrange or args.setclock: + args.setvc or args.setsrange or args.setmrange or args.setclock or \ + args.setcomputepartition or args.setnpsmode or args.resetcomputepartition or args.resetnpsmode: relaunchAsSudo() # If there is one or more device specified, use that for all commands, otherwise use a @@ -3072,10 +3525,12 @@ if __name__ == '__main__': args.showmemoverdrive = True args.showoverdrive = True args.showperflevel = True - args.showpids = True + args.showpids = "summary" args.showpidgpus = [] args.showreplaycount = True args.showvc = True + args.showcomputepartition = True + args.shownpsmode = True if not PRINT_JSON: args.showprofile = True @@ -3103,6 +3558,8 @@ if __name__ == '__main__': showAllConciseHw(deviceList) if args.showdriverversion: showVersion(deviceList, rsmi_sw_component_t.RSMI_SW_COMP_DRIVER) + if args.showtempgraph: + showTempGraph(deviceList) if args.showid: showId(deviceList) if args.showuniqueid: @@ -3147,8 +3604,8 @@ if __name__ == '__main__': showPcieReplayCount(deviceList) if args.showserial: showSerialNumber(deviceList) - if args.showpids: - showPids() + if args.showpids != None: + showPids(args.showpids) if args.showpidgpus or str(args.showpidgpus) == '[]': showGpusByPid(args.showpidgpus) if args.showclkvolt: @@ -3202,6 +3659,10 @@ if __name__ == '__main__': showVoltageCurve(deviceList) if args.showenergycounter: showEnergy(deviceList) + if args.showcomputepartition: + showComputePartition(deviceList) + if args.shownpsmode: + showNPSMode(deviceList) if args.setclock: setClocks(deviceList, args.setclock[0], [int(args.setclock[1])]) if args.setsclk: @@ -3240,12 +3701,20 @@ if __name__ == '__main__': setClockRange(deviceList, 'mclk', args.setmrange[0], args.setmrange[1], args.autorespond) if args.setperfdeterminism: setPerfDeterminism(deviceList, args.setperfdeterminism[0]) + if args.setcomputepartition: + setComputePartition(deviceList, args.setcomputepartition[0]) + if args.setnpsmode: + setNPSMode(deviceList, args.setnpsmode[0]) if args.resetprofile: resetProfile(deviceList) if args.resetxgmierr: resetXgmiErr(deviceList) if args.resetperfdeterminism: resetPerfDeterminism(deviceList) + if args.resetcomputepartition: + resetComputePartition(deviceList) + if args.resetnpsmode: + resetNpsMode(deviceList) if args.rasenable: setRas(deviceList, 'enable', args.rasenable[0], args.rasenable[1]) if args.rasdisable: @@ -3257,6 +3726,12 @@ if __name__ == '__main__': if args.save: save(deviceList, args.save) + if RETCODE and not PRINT_JSON: + logging.debug(' \t\t One or more commands failed.') + # Set RETCODE value to 0, unless loglevel is None or 'warning' (default) + if args.loglevel is None or getattr(logging, args.loglevel.upper(), logging.WARNING) == logging.WARNING: + RETCODE = 0 + if PRINT_JSON: # Check that we have some actual data to print, instead of the # empty list that we initialized above @@ -3284,8 +3759,6 @@ if __name__ == '__main__': devCsv = formatCsv(deviceList) print(devCsv) - if RETCODE and not PRINT_JSON: - logging.debug(' \t\t One or more commands failed.') printLogSpacer(footerString) rsmi_ret_ok(rocmsmi.rsmi_shut_down()) diff --git a/rocm_smi/python_smi_tools/rsmiBindings.py b/rocm_smi/python_smi_tools/rsmiBindings.py index 090b85c3d8..b6e7f2474d 100644 --- a/rocm_smi/python_smi_tools/rsmiBindings.py +++ b/rocm_smi/python_smi_tools/rsmiBindings.py @@ -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'] diff --git a/rocm_smi/src/rocm_smi.cc b/rocm_smi/src/rocm_smi.cc index 75e92aff2e..ffb89292b3 100755 --- a/rocm_smi/src/rocm_smi.cc +++ b/rocm_smi/src/rocm_smi.cc @@ -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: @@ -45,11 +45,13 @@ #include #include #include -#include +#include +#include #include #include #include #include +#include #include #include @@ -61,6 +63,7 @@ #include #include #include +#include #include "rocm_smi/rocm_smi_common.h" // Should go before rocm_smi.h #include "rocm_smi/rocm_smi.h" @@ -71,8 +74,10 @@ #include "rocm_smi/rocm_smi_counters.h" #include "rocm_smi/rocm_smi_kfd.h" #include "rocm_smi/rocm_smi_io_link.h" - #include "rocm_smi/rocm_smi64Config.h" +#include "rocm_smi/rocm_smi_logger.h" + +using namespace ROCmLogging; static const uint32_t kMaxOverdriveLevel = 20; static const float kEnergyCounterResolution = 15.3f; @@ -369,7 +374,6 @@ static rsmi_status_t get_dev_mon_value(amd::smi::MonitorTypes type, if (dev->monitor() == nullptr) { return RSMI_STATUS_NOT_SUPPORTED; } - std::string val_str; int ret = dev->monitor()->readMonitor(type, sensor_ind, &val_str); @@ -396,7 +400,6 @@ static rsmi_status_t set_dev_mon_value(amd::smi::MonitorTypes type, if (dev->monitor() == nullptr) { return RSMI_STATUS_NOT_SUPPORTED; } - int ret = dev->monitor()->writeMonitor(type, sensor_ind, std::to_string(val)); @@ -420,7 +423,6 @@ static rsmi_status_t get_power_mon_value(amd::smi::PowerMonTypes type, if (dev == nullptr || dev->monitor() == nullptr) { return RSMI_STATUS_NOT_SUPPORTED; } - ret = dev->power_monitor()->readPowerValue(type, val); return amd::smi::ErrnoToRsmiStatus(ret); @@ -526,6 +528,9 @@ rsmi_status_t rsmi_dev_ecc_enabled_get(uint32_t dv_ind, rsmi_status_t ret; std::string feature_line; std::string tmp_str; + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << " | ======= start ======="; + LOG_TRACE(ss); CHK_SUPPORT_NAME_ONLY(enabled_blks) @@ -533,6 +538,10 @@ rsmi_status_t rsmi_dev_ecc_enabled_get(uint32_t dv_ind, ret = get_dev_value_line(amd::smi::kDevErrCntFeatures, dv_ind, &feature_line); if (ret != RSMI_STATUS_SUCCESS) { + ss << __PRETTY_FUNCTION__ << " | ======= end =======" + << ", returning get_dev_value_line() response = " + << amd::smi::getRSMIStatusString(ret); + LOG_ERROR(ss); return ret; } @@ -548,6 +557,11 @@ rsmi_status_t rsmi_dev_ecc_enabled_get(uint32_t dv_ind, *enabled_blks = strtoul(tmp_str.c_str(), nullptr, 16); assert(errno == 0); + ss << __PRETTY_FUNCTION__ << " | ======= end =======" + << ", returning strtoul() response = " + << amd::smi::getRSMIStatusString(amd::smi::ErrnoToRsmiStatus(errno)); + LOG_TRACE(ss); + return amd::smi::ErrnoToRsmiStatus(errno); CATCH } @@ -569,10 +583,17 @@ static_assert(RSMI_RAS_ERR_STATE_LAST == RSMI_RAS_ERR_STATE_ENABLED, rsmi_status_t rsmi_dev_ecc_status_get(uint32_t dv_ind, rsmi_gpu_block_t block, rsmi_ras_err_state_t *state) { TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); CHK_SUPPORT_NAME_ONLY(state) if (!is_power_of_2(block)) { + ss << __PRETTY_FUNCTION__ << " | ======= end =======" + << ", ret was not power of 2 " + << "-> reporting RSMI_STATUS_INVALID_ARGS"; + LOG_ERROR(ss); return RSMI_STATUS_INVALID_ARGS; } rsmi_status_t ret; @@ -583,15 +604,26 @@ rsmi_status_t rsmi_dev_ecc_status_get(uint32_t dv_ind, rsmi_gpu_block_t block, ret = rsmi_dev_ecc_enabled_get(dv_ind, &features_mask); if (ret == RSMI_STATUS_FILE_ERROR) { + ss << __PRETTY_FUNCTION__ << " | ======= end =======" + << ", rsmi_dev_ecc_enabled_get() ret was RSMI_STATUS_FILE_ERROR " + << "-> reporting RSMI_STATUS_NOT_SUPPORTED"; + LOG_ERROR(ss); return RSMI_STATUS_NOT_SUPPORTED; } if (ret != RSMI_STATUS_SUCCESS) { + ss << __PRETTY_FUNCTION__ << " | ======= end =======" + << ", returning rsmi_dev_ecc_enabled_get() response = " + << amd::smi::getRSMIStatusString(ret); + LOG_ERROR(ss); return ret; } *state = (features_mask & block) ? RSMI_RAS_ERR_STATE_ENABLED : RSMI_RAS_ERR_STATE_DISABLED; + ss << __PRETTY_FUNCTION__ << " | ======= end =======" + << ", reporting RSMI_STATUS_SUCCESS"; + LOG_TRACE(ss); return RSMI_STATUS_SUCCESS; CATCH } @@ -601,8 +633,11 @@ rsmi_dev_ecc_count_get(uint32_t dv_ind, rsmi_gpu_block_t block, rsmi_error_count_t *ec) { std::vector val_vec; rsmi_status_t ret; + std::ostringstream ss; TRY + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); CHK_SUPPORT_VAR(ec, block) @@ -637,6 +672,10 @@ rsmi_dev_ecc_count_get(uint32_t dv_ind, rsmi_gpu_block_t block, break; default: + ss << __PRETTY_FUNCTION__ << " | ======= end =======" + << ", default case -> reporting RSMI_STATUS_NOT_SUPPORTED" + << amd::smi::getRSMIStatusString(ret); + LOG_ERROR(ss); return RSMI_STATUS_NOT_SUPPORTED; } @@ -645,9 +684,17 @@ rsmi_dev_ecc_count_get(uint32_t dv_ind, rsmi_gpu_block_t block, ret = GetDevValueVec(type, dv_ind, &val_vec); if (ret == RSMI_STATUS_FILE_ERROR || val_vec.size() != 2) { + ss << __PRETTY_FUNCTION__ << " | ======= end =======" + << ", GetDevValueVec() ret was RSMI_STATUS_FILE_ERROR " + << "-> reporting RSMI_STATUS_NOT_SUPPORTED"; + LOG_ERROR(ss); return RSMI_STATUS_NOT_SUPPORTED; } if (ret != RSMI_STATUS_SUCCESS) { + ss << __PRETTY_FUNCTION__ << " | ======= end =======" + << ", GetDevValueVec() ret was not RSMI_STATUS_SUCCESS" + << " -> reporting " << amd::smi::getRSMIStatusString(ret); + LOG_ERROR(ss); return ret; } @@ -666,6 +713,9 @@ rsmi_dev_ecc_count_get(uint32_t dv_ind, rsmi_gpu_block_t block, assert(junk == "ce:"); fs2 >> ec->correctable_err; + ss << __PRETTY_FUNCTION__ << " | ======= end =======" + << ", reporting " << amd::smi::getRSMIStatusString(ret);; + LOG_TRACE(ss); return ret; CATCH } @@ -673,6 +723,9 @@ rsmi_dev_ecc_count_get(uint32_t dv_ind, rsmi_gpu_block_t block, rsmi_status_t rsmi_dev_pci_id_get(uint32_t dv_ind, uint64_t *bdfid) { TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); GET_DEV_AND_KFDNODE_FROM_INDX CHK_API_SUPPORT_ONLY(bdfid, RSMI_DEFAULT_VARIANT, RSMI_DEFAULT_VARIANT) @@ -695,6 +748,9 @@ rsmi_dev_pci_id_get(uint32_t dv_ind, uint64_t *bdfid) { (*bdfid) &= 0xFFFF; // Clear out the old 16 bit domain *bdfid |= (domain & 0xFFFFFFFF) << 32; + ss << __PRETTY_FUNCTION__ << " | ======= end =======" + << ", reporting RSMI_STATUS_SUCCESS"; + LOG_TRACE(ss); return RSMI_STATUS_SUCCESS; CATCH } @@ -751,32 +807,58 @@ get_id(uint32_t dv_ind, amd::smi::DevInfoTypes typ, uint16_t *id) { rsmi_status_t rsmi_dev_id_get(uint32_t dv_ind, uint16_t *id) { + std::ostringstream ss; + rsmi_status_t ret; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); CHK_SUPPORT_NAME_ONLY(id) - return get_id(dv_ind, amd::smi::kDevDevID, id); + + ret = get_id(dv_ind, amd::smi::kDevDevID, id); + ss << __PRETTY_FUNCTION__ << " | ======= end =======" + << ", reporting " << amd::smi::getRSMIStatusString(ret); + LOG_TRACE(ss); + return ret; } rsmi_status_t rsmi_dev_sku_get(uint32_t dv_ind, uint16_t *id) { TRY + std::ostringstream ss; + rsmi_status_t ret; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); CHK_SUPPORT_NAME_ONLY(id) - return get_id(dv_ind, amd::smi::kDevDevProdNum, id); + ret = get_id(dv_ind, amd::smi::kDevDevProdNum, id); + ss << __PRETTY_FUNCTION__ << " | ======= end =======" + << ", reporting " << amd::smi::getRSMIStatusString(ret); + LOG_TRACE(ss); + return ret; CATCH } rsmi_status_t rsmi_dev_subsystem_id_get(uint32_t dv_ind, uint16_t *id) { + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); CHK_SUPPORT_NAME_ONLY(id) return get_id(dv_ind, amd::smi::kDevSubSysDevID, id); } rsmi_status_t rsmi_dev_vendor_id_get(uint32_t dv_ind, uint16_t *id) { + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); CHK_SUPPORT_NAME_ONLY(id) return get_id(dv_ind, amd::smi::kDevVendorID, id); } rsmi_status_t rsmi_dev_subsystem_vendor_id_get(uint32_t dv_ind, uint16_t *id) { + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); CHK_SUPPORT_NAME_ONLY(id) return get_id(dv_ind, amd::smi::kDevSubSysVendorID, id); } @@ -785,6 +867,9 @@ rsmi_status_t rsmi_dev_perf_level_get(uint32_t dv_ind, rsmi_dev_perf_level_t *perf) { TRY std::string val_str; + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); CHK_SUPPORT_NAME_ONLY(perf) DEVICE_MUTEX @@ -847,6 +932,9 @@ rsmi_status_t rsmi_dev_overdrive_level_get(uint32_t dv_ind, uint32_t *od) { TRY std::string val_str; + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); CHK_SUPPORT_NAME_ONLY(od) DEVICE_MUTEX @@ -875,8 +963,41 @@ rsmi_dev_overdrive_level_get(uint32_t dv_ind, uint32_t *od) { CATCH } +rsmi_status_t +rsmi_dev_mem_overdrive_level_get(uint32_t dv_ind, uint32_t *od) { + TRY + std::string val_str; + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); + CHK_SUPPORT_NAME_ONLY(od) + DEVICE_MUTEX + + rsmi_status_t ret = get_dev_value_str(amd::smi::kDevMemOverDriveLevel, dv_ind, + &val_str); + if (ret != RSMI_STATUS_SUCCESS) { + return ret; + } + + errno = 0; + uint64_t val_ul = strtoul(val_str.c_str(), nullptr, 10); + + if (val_ul > 0xFFFFFFFF) { + return RSMI_STATUS_UNEXPECTED_SIZE; + } + + *od = static_cast(val_ul); + assert(errno == 0); + + return RSMI_STATUS_SUCCESS; + CATCH +} + rsmi_status_t rsmi_dev_overdrive_level_set(int32_t dv_ind, uint32_t od) { + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); if (dv_ind < 0) { return RSMI_STATUS_INVALID_ARGS; } @@ -886,6 +1007,9 @@ rsmi_dev_overdrive_level_set(int32_t dv_ind, uint32_t od) { rsmi_status_t rsmi_dev_overdrive_level_set_v1(uint32_t dv_ind, uint32_t od) { TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); REQUIRE_ROOT_ACCESS if (od > kMaxOverdriveLevel) { @@ -904,12 +1028,18 @@ rsmi_dev_overdrive_level_set_v1(uint32_t dv_ind, uint32_t od) { rsmi_status_t rsmi_dev_perf_level_set(int32_t dv_ind, rsmi_dev_perf_level_t perf_level) { + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); return rsmi_dev_perf_level_set_v1(static_cast(dv_ind), perf_level); } rsmi_status_t rsmi_dev_perf_level_set_v1(uint32_t dv_ind, rsmi_dev_perf_level_t perf_level) { TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); REQUIRE_ROOT_ACCESS if (perf_level > RSMI_DEV_PERF_LEVEL_LAST) { @@ -1192,6 +1322,9 @@ rsmi_status_t rsmi_dev_clk_range_set(uint32_t dv_ind, uint64_t minclkvalue, rsmi_clk_type_t clkType) { TRY rsmi_status_t ret; + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); if (minclkvalue >= maxclkvalue) { return RSMI_STATUS_INVALID_ARGS; @@ -1213,6 +1346,7 @@ rsmi_status_t rsmi_dev_clk_range_set(uint32_t dv_ind, uint64_t minclkvalue, {RSMI_CLK_TYPE_MEM, "m"}, }; DEVICE_MUTEX + assert(clkType == RSMI_CLK_TYPE_SYS || clkType == RSMI_CLK_TYPE_MEM); // Set perf. level to manual so that we can then set the power profile ret = rsmi_dev_perf_level_set_v1(dv_ind, RSMI_DEV_PERF_LEVEL_MANUAL); @@ -1256,6 +1390,9 @@ rsmi_status_t rsmi_dev_od_clk_info_set(uint32_t dv_ind, rsmi_freq_ind_t level, rsmi_clk_type_t clkType) { TRY rsmi_status_t ret; + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); std::string sysvalue; std::map ClkStateMap = { @@ -1311,6 +1448,9 @@ rsmi_status_t rsmi_dev_od_volt_info_set(uint32_t dv_ind, uint32_t vpoint, uint64_t clkvalue, uint64_t voltvalue) { TRY rsmi_status_t ret; + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); DEVICE_MUTEX @@ -1482,6 +1622,9 @@ rsmi_dev_gpu_clk_freq_get(uint32_t dv_ind, rsmi_clk_type_t clk_type, rsmi_frequencies_t *f) { TRY amd::smi::DevInfoTypes dev_type; + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); CHK_SUPPORT_VAR(f, clk_type) @@ -1516,6 +1659,9 @@ rsmi_status_t rsmi_dev_firmware_version_get(uint32_t dv_ind, rsmi_fw_block_t block, uint64_t *fw_version) { TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); CHK_SUPPORT_VAR(fw_version, block) std::string val_str; @@ -1619,6 +1765,9 @@ rsmi_dev_gpu_clk_freq_set(uint32_t dv_ind, rsmi_frequencies_t freqs; TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); REQUIRE_ROOT_ACCESS DEVICE_MUTEX @@ -1695,13 +1844,48 @@ static std::vector pci_name_files = { "/var/lib/pciutils/pci.ids" }; - enum eNameStrType { NAME_STR_VENDOR = 0, NAME_STR_DEVICE, NAME_STR_SUBSYS }; +std::map +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} +}; + +std::map +mapRSMIToStringComputePartitionTypes { + {RSMI_COMPUTE_PARTITION_INVALID, "UNKNOWN"}, + {RSMI_COMPUTE_PARTITION_CPX, "CPX"}, + {RSMI_COMPUTE_PARTITION_SPX, "SPX"}, + {RSMI_COMPUTE_PARTITION_DPX, "DPX"}, + {RSMI_COMPUTE_PARTITION_TPX, "TPX"}, + {RSMI_COMPUTE_PARTITION_QPX, "QPX"} +}; + +std::map +mapRSMIToStringNPSModeTypes { + {RSMI_MEMORY_PARTITION_UNKNOWN, "UNKNOWN"}, + {RSMI_MEMORY_PARTITION_NPS1, "NPS1"}, + {RSMI_MEMORY_PARTITION_NPS2, "NPS2"}, + {RSMI_MEMORY_PARTITION_NPS4, "NPS4"}, + {RSMI_MEMORY_PARTITION_NPS8, "NPS8"} +}; + +std::map +mapStringToNPSModeTypes { + {"NPS1", RSMI_MEMORY_PARTITION_NPS1}, + {"NPS2", RSMI_MEMORY_PARTITION_NPS2}, + {"NPS4", RSMI_MEMORY_PARTITION_NPS4}, + {"NPS8", RSMI_MEMORY_PARTITION_NPS8} +}; + static std::string get_id_name_str_from_line(uint64_t id, std::string ln, std::istringstream *ln_str) { @@ -1791,6 +1975,8 @@ static rsmi_status_t get_dev_name_from_id(uint32_t dv_ind, char *name, uint16_t subsys_vend_id; uint16_t subsys_id; bool found_device_vendor = false; + // to match subsystem, it must match the device id at previous line + bool found_device_id_for_subsys = false; std::string val_str; assert(name != nullptr); @@ -1837,8 +2023,8 @@ static rsmi_status_t get_dev_name_from_id(uint32_t dv_ind, char *name, if (ln[0] == '\t') { if (found_device_vendor) { if (ln[1] == '\t') { - // This is a subsystem line - if (typ == NAME_STR_SUBSYS) { + // The subsystem line, ignore a line if the device id not match + if (typ == NAME_STR_SUBSYS && found_device_id_for_subsys) { val_str = get_id_name_str_from_line(subsys_vend_id, ln, &ln_str); if (val_str.size() > 0) { @@ -1860,6 +2046,12 @@ static rsmi_status_t get_dev_name_from_id(uint32_t dv_ind, char *name, if (val_str.size() > 0) { break; } + } else if (typ == NAME_STR_SUBSYS) { + // match the device id line + val_str = get_id_name_str_from_line(device_id, ln, &ln_str); + if (val_str.size() > 0) { + found_device_id_for_subsys = true; + } } } } else { // ln[0] != '\t'; Vendor line @@ -1925,6 +2117,9 @@ rsmi_dev_name_get(uint32_t dv_ind, char *name, size_t len) { rsmi_status_t ret; TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); CHK_SUPPORT_NAME_ONLY(name) if (len == 0) { @@ -1935,7 +2130,7 @@ rsmi_dev_name_get(uint32_t dv_ind, char *name, size_t len) { ret = get_dev_name_from_file(dv_ind, name, len); - if (ret || name[0] == '\0') { + if (ret || name[0] == '\0' || !isprint(name[0]) ) { ret = get_dev_name_from_id(dv_ind, name, len, NAME_STR_DEVICE); } @@ -1946,6 +2141,9 @@ rsmi_dev_name_get(uint32_t dv_ind, char *name, size_t len) { rsmi_status_t rsmi_dev_brand_get(uint32_t dv_ind, char *brand, uint32_t len) { TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); CHK_SUPPORT_NAME_ONLY(brand) if (len == 0) { return RSMI_STATUS_INVALID_ARGS; @@ -1992,6 +2190,9 @@ rsmi_dev_brand_get(uint32_t dv_ind, char *brand, uint32_t len) { rsmi_status_t rsmi_dev_vram_vendor_get(uint32_t dv_ind, char *brand, uint32_t len) { TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); CHK_SUPPORT_NAME_ONLY(brand) if (len == 0) { @@ -2022,6 +2223,9 @@ rsmi_dev_subsystem_name_get(uint32_t dv_ind, char *name, size_t len) { rsmi_status_t ret; TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); CHK_SUPPORT_NAME_ONLY(name) if (len == 0) { @@ -2040,6 +2244,9 @@ rsmi_dev_drm_render_minor_get(uint32_t dv_ind, uint32_t *minor) { rsmi_status_t ret; TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); CHK_SUPPORT_NAME_ONLY(minor) DEVICE_MUTEX @@ -2053,6 +2260,9 @@ rsmi_dev_vendor_name_get(uint32_t dv_ind, char *name, size_t len) { rsmi_status_t ret; TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); CHK_SUPPORT_NAME_ONLY(name) assert(len > 0); @@ -2069,13 +2279,79 @@ rsmi_dev_vendor_name_get(uint32_t dv_ind, char *name, size_t len) { rsmi_status_t rsmi_dev_pci_bandwidth_get(uint32_t dv_ind, rsmi_pcie_bandwidth_t *b) { + rsmi_status_t ret; TRY - CHK_SUPPORT_NAME_ONLY(b) + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); + GET_DEV_AND_KFDNODE_FROM_INDX + CHK_API_SUPPORT_ONLY((b), RSMI_DEFAULT_VARIANT, RSMI_DEFAULT_VARIANT) DEVICE_MUTEX - - return get_frequencies(amd::smi::kDevPCIEClk, RSMI_CLK_TYPE_PCIE, dv_ind, + ret = get_frequencies(amd::smi::kDevPCIEClk, RSMI_CLK_TYPE_PCIE, dv_ind, &b->transfer_rate, b->lanes); + if (ret == RSMI_STATUS_SUCCESS) { + return ret; + } + + // Only fallback to gpu_metric if connecting via PCIe + if (kfd_node->numa_node_type() != amd::smi::IOLINK_TYPE_PCIEXPRESS) { + return ret; + } + + rsmi_gpu_metrics_t gpu_metrics; + ret = rsmi_dev_gpu_metrics_info_get(dv_ind, &gpu_metrics); + if (ret != RSMI_STATUS_SUCCESS) { + return ret; + } + + // Hardcode based on PCIe specification: https://en.wikipedia.org/wiki/PCI_Express + const uint32_t link_width[] = {1, 2, 4, 8, 12, 16}; + const uint32_t link_speed[] = {25, 50, 80, 160}; // 0.1 Ghz + const uint32_t WIDTH_DATA_LENGTH = sizeof(link_width)/sizeof(uint32_t); + const uint32_t SPEED_DATA_LENGTH = sizeof(link_speed)/sizeof(uint32_t); + + // Calculate the index + int width_index = -1; + int speed_index = -1; + uint32_t cur_index = 0; + for (cur_index = 0; cur_index < WIDTH_DATA_LENGTH; cur_index++) { + if (link_width[cur_index] == gpu_metrics.pcie_link_width) { + width_index = cur_index; + break; + } + } + for (cur_index = 0; + cur_index < SPEED_DATA_LENGTH; cur_index++) { + if (link_speed[cur_index] == gpu_metrics.pcie_link_speed) { + speed_index = cur_index; + break; + } + } + if (width_index == -1 || speed_index == -1) { + return RSMI_STATUS_NOT_SUPPORTED; + } + // Set possible lanes and frequencies + b->transfer_rate.num_supported = WIDTH_DATA_LENGTH * SPEED_DATA_LENGTH; + b->transfer_rate.current = speed_index*WIDTH_DATA_LENGTH + width_index; + for (cur_index = 0; + cur_index < WIDTH_DATA_LENGTH * SPEED_DATA_LENGTH; cur_index++) { + b->transfer_rate.frequency[cur_index] + = link_speed[cur_index/WIDTH_DATA_LENGTH] * 100 * 1000000L; + b->lanes[cur_index] = link_width[cur_index % WIDTH_DATA_LENGTH]; + } + /* + frequency = {2500, 2500, 2500, 2500, 2500, 2500, + 5000, 5000, 5000, 5000, 5000, 5000, + 8000, 8000, 8000, 8000, 8000, 8000, + 16000, 16000, 16000, 16000, 16000, 16000}; // Mhz + lanes = {1, 2, 4, 8, 12, 16, + 1, 2, 4, 8, 12, 16, + 1, 2, 4, 8, 12, 16, + 1, 2, 4, 8, 12, 16 }; // For each frequency + */ + + return RSMI_STATUS_SUCCESS; CATCH } @@ -2086,6 +2362,9 @@ rsmi_dev_pci_bandwidth_set(uint32_t dv_ind, uint64_t bw_bitmask) { rsmi_pcie_bandwidth_t bws; TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); REQUIRE_ROOT_ACCESS DEVICE_MUTEX // Bare Metal only feature @@ -2129,6 +2408,9 @@ rsmi_status_t rsmi_dev_pci_throughput_get(uint32_t dv_ind, uint64_t *sent, uint64_t *received, uint64_t *max_pkt_sz) { TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); rsmi_status_t ret; std::string val_str; @@ -2165,6 +2447,9 @@ rsmi_status_t rsmi_dev_temp_metric_get(uint32_t dv_ind, uint32_t sensor_type, rsmi_temperature_metric_t metric, int64_t *temperature) { TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); rsmi_status_t ret; amd::smi::MonitorTypes mon_type; @@ -2287,6 +2572,9 @@ rsmi_status_t rsmi_dev_volt_metric_get(uint32_t dv_ind, rsmi_voltage_type_t sensor_type, rsmi_voltage_metric_t metric, int64_t *voltage) { TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); rsmi_status_t ret; amd::smi::MonitorTypes mon_type; @@ -2331,8 +2619,13 @@ rsmi_dev_volt_metric_get(uint32_t dv_ind, rsmi_voltage_type_t sensor_type, // getVoltSensorIndex will throw an out of range exception if sensor_type is // not found - uint32_t sensor_index = - m->getVoltSensorIndex(sensor_type); + uint32_t sensor_index; + try { + sensor_index = + m->getVoltSensorIndex(sensor_type); + } catch (...) { + return RSMI_STATUS_NOT_SUPPORTED; + } CHK_API_SUPPORT_ONLY(voltage, metric, sensor_index) ret = get_dev_mon_value(mon_type, dv_ind, sensor_index, voltage); @@ -2344,6 +2637,9 @@ rsmi_dev_volt_metric_get(uint32_t dv_ind, rsmi_voltage_type_t sensor_type, rsmi_status_t rsmi_dev_fan_speed_get(uint32_t dv_ind, uint32_t sensor_ind, int64_t *speed) { TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); rsmi_status_t ret; @@ -2362,6 +2658,9 @@ rsmi_dev_fan_speed_get(uint32_t dv_ind, uint32_t sensor_ind, int64_t *speed) { rsmi_status_t rsmi_dev_fan_rpms_get(uint32_t dv_ind, uint32_t sensor_ind, int64_t *speed) { TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); ++sensor_ind; // fan sysfs files have 1-based indices @@ -2381,6 +2680,9 @@ rsmi_status_t rsmi_dev_fan_reset(uint32_t dv_ind, uint32_t sensor_ind) { TRY rsmi_status_t ret; + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); ++sensor_ind; // fan sysfs files have 1-based indices @@ -2399,6 +2701,9 @@ rsmi_dev_fan_speed_set(uint32_t dv_ind, uint32_t sensor_ind, uint64_t speed) { rsmi_status_t ret; uint64_t max_speed; + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); REQUIRE_ROOT_ACCESS DEVICE_MUTEX @@ -2441,6 +2746,9 @@ rsmi_dev_fan_speed_max_get(uint32_t dv_ind, uint32_t sensor_ind, uint64_t *max_speed) { TRY rsmi_status_t ret; + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); ++sensor_ind; // fan sysfs files have 1-based indices CHK_SUPPORT_SUBVAR_ONLY(max_speed, sensor_ind) DEVICE_MUTEX @@ -2455,6 +2763,9 @@ rsmi_dev_fan_speed_max_get(uint32_t dv_ind, uint32_t sensor_ind, rsmi_status_t rsmi_dev_od_volt_info_get(uint32_t dv_ind, rsmi_od_volt_freq_data_t *odv) { TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); DEVICE_MUTEX CHK_SUPPORT_NAME_ONLY(odv) rsmi_status_t ret = get_od_clk_volt_info(dv_ind, odv); @@ -2466,6 +2777,9 @@ rsmi_dev_od_volt_info_get(uint32_t dv_ind, rsmi_od_volt_freq_data_t *odv) { rsmi_status_t rsmi_dev_gpu_reset(int32_t dv_ind) { TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); REQUIRE_ROOT_ACCESS DEVICE_MUTEX @@ -2482,6 +2796,9 @@ rsmi_dev_gpu_reset(int32_t dv_ind) { rsmi_status_t rsmi_dev_od_volt_curve_regions_get(uint32_t dv_ind, uint32_t *num_regions, rsmi_freq_volt_region_t *buffer) { TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); CHK_SUPPORT_NAME_ONLY((num_regions == nullptr || buffer == nullptr) ? nullptr : num_regions) @@ -2499,6 +2816,9 @@ rsmi_status_t rsmi_dev_od_volt_curve_regions_get(uint32_t dv_ind, rsmi_status_t rsmi_dev_power_max_get(uint32_t dv_ind, uint32_t sensor_ind, uint64_t *power) { TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); (void)sensor_ind; // Not used yet // ++sensor_ind; // power sysfs files have 1-based indices @@ -2516,6 +2836,9 @@ rsmi_dev_power_max_get(uint32_t dv_ind, uint32_t sensor_ind, uint64_t *power) { rsmi_status_t rsmi_dev_power_ave_get(uint32_t dv_ind, uint32_t sensor_ind, uint64_t *power) { TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); ++sensor_ind; // power sysfs files have 1-based indices @@ -2533,6 +2856,9 @@ rsmi_status_t rsmi_dev_energy_count_get(uint32_t dv_ind, uint64_t *power, float *counter_resolution, uint64_t *timestamp) { TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); rsmi_status_t ret; rsmi_gpu_metrics_t gpu_metrics; @@ -2560,6 +2886,9 @@ rsmi_dev_energy_count_get(uint32_t dv_ind, uint64_t *power, rsmi_status_t rsmi_dev_power_cap_default_get(uint32_t dv_ind, uint64_t *default_cap) { TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); uint32_t sensor_ind = 1; // power sysfs files have 1-based indices CHK_SUPPORT_SUBVAR_ONLY(default_cap, sensor_ind) @@ -2576,6 +2905,9 @@ rsmi_dev_power_cap_default_get(uint32_t dv_ind, uint64_t *default_cap) { rsmi_status_t rsmi_dev_power_cap_get(uint32_t dv_ind, uint32_t sensor_ind, uint64_t *cap) { TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); ++sensor_ind; // power sysfs files have 1-based indices CHK_SUPPORT_SUBVAR_ONLY(cap, sensor_ind) @@ -2593,6 +2925,9 @@ rsmi_status_t rsmi_dev_power_cap_range_get(uint32_t dv_ind, uint32_t sensor_ind, uint64_t *max, uint64_t *min) { TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); ++sensor_ind; // power sysfs files have 1-based indices CHK_SUPPORT_SUBVAR_ONLY((min == nullptr || max == nullptr ?nullptr : min), @@ -2615,6 +2950,9 @@ rsmi_dev_power_cap_set(uint32_t dv_ind, uint32_t sensor_ind, uint64_t cap) { TRY rsmi_status_t ret; uint64_t min, max; + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); REQUIRE_ROOT_ACCESS DEVICE_MUTEX @@ -2648,6 +2986,9 @@ rsmi_status_t rsmi_dev_power_profile_presets_get(uint32_t dv_ind, uint32_t reserved, rsmi_power_profile_status_t *status) { TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); (void)reserved; CHK_SUPPORT_NAME_ONLY(status) @@ -2662,6 +3003,9 @@ rsmi_status_t rsmi_dev_power_profile_set(uint32_t dv_ind, uint32_t dummy, rsmi_power_profile_preset_masks_t profile) { TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); REQUIRE_ROOT_ACCESS (void)dummy; @@ -2681,6 +3025,9 @@ rsmi_dev_memory_total_get(uint32_t dv_ind, rsmi_memory_type_t mem_type, TRY rsmi_status_t ret; amd::smi::DevInfoTypes mem_type_file; + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); CHK_SUPPORT_VAR(total, mem_type) @@ -2714,6 +3061,9 @@ rsmi_dev_memory_usage_get(uint32_t dv_ind, rsmi_memory_type_t mem_type, TRY rsmi_status_t ret; amd::smi::DevInfoTypes mem_type_file; + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); CHK_SUPPORT_VAR(used, mem_type) @@ -2746,6 +3096,9 @@ rsmi_status_t rsmi_dev_memory_busy_percent_get(uint32_t dv_ind, uint32_t *busy_percent) { TRY rsmi_status_t ret; + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); CHK_SUPPORT_NAME_ONLY(busy_percent) @@ -2801,71 +3154,89 @@ rsmi_status_string(rsmi_status_t status, const char **status_string) { break; case RSMI_STATUS_OUT_OF_RESOURCES: - *status_string = "Unable to acquire memory or other resource"; + *status_string = "RSMI_STATUS_OUT_OF_RESOURCES: Unable to acquire memory " + "or other resource"; break; case RSMI_STATUS_INTERNAL_EXCEPTION: - *status_string = "An internal exception was caught"; + *status_string = "RSMI_STATUS_INTERNAL_EXCEPTION: An internal exception " + "was caught"; break; case RSMI_STATUS_INPUT_OUT_OF_BOUNDS: - *status_string = "The provided input is out of allowable or safe range"; + *status_string = "RSMI_STATUS_INPUT_OUT_OF_BOUNDS: The provided input is " + "out of allowable or safe range"; break; case RSMI_STATUS_INIT_ERROR: - *status_string = "An error occurred during initialization, during " - "monitor discovery or when when initializing internal data structures"; + *status_string = "RSMI_STATUS_INIT_ERROR: An error occurred during " + "initialization, during monitor discovery or when when " + "initializing internal data structures"; break; case RSMI_STATUS_NOT_YET_IMPLEMENTED: - *status_string = "The called function has not been implemented in this " - "system for this device type"; + *status_string = "RSMI_STATUS_NOT_YET_IMPLEMENTED: The called function " + "has not been implemented in this system for this " + "device type"; break; case RSMI_STATUS_NOT_FOUND: - *status_string = "An item required to complete the call was not found"; + *status_string = "RSMI_STATUS_NOT_FOUND: An item required to complete " + "the call was not found"; break; case RSMI_STATUS_INSUFFICIENT_SIZE: - *status_string = "Not enough resources were available to fully execute" - " the call"; + *status_string = "RSMI_STATUS_INSUFFICIENT_SIZE: Not enough resources " + "were available to fully execute the call"; break; case RSMI_STATUS_INTERRUPT: - *status_string = "An interrupt occurred while executing the function"; + *status_string = "RSMI_STATUS_INTERRUPT: An interrupt occurred while " + "executing the function"; break; case RSMI_STATUS_UNEXPECTED_SIZE: - *status_string = "Data (usually from reading a file) was out of" - " range from what was expected"; + *status_string = "RSMI_STATUS_UNEXPECTED_SIZE: Data (usually from reading" + " a file) was out of range from what was expected"; break; case RSMI_STATUS_NO_DATA: - *status_string = "No data was found (usually from reading a file) " - "where data was expected"; + *status_string = "RSMI_STATUS_NO_DATA: No data was found (usually from " + "reading a file) where data was expected"; break; case RSMI_STATUS_UNEXPECTED_DATA: - *status_string = "Data (usually from reading a file) was not of the " - "type that was expected"; + *status_string = "RSMI_STATUS_UNEXPECTED_DATA: Data (usually from reading" + " a file) was not of the type that was expected"; break; case RSMI_STATUS_BUSY: - *status_string = "A resource or mutex could not be acquired " - "because it is already being used"; + *status_string = "RSMI_STATUS_BUSY: A resource or mutex could not be " + "acquired because it is already being used"; break; case RSMI_STATUS_REFCOUNT_OVERFLOW: - *status_string = "An internal reference counter exceeded INT32_MAX"; + *status_string = "RSMI_STATUS_REFCOUNT_OVERFLOW: An internal reference " + "counter exceeded INT32_MAX"; + break; + + case RSMI_STATUS_SETTING_UNAVAILABLE: + *status_string = "RSMI_STATUS_SETTING_UNAVAILABLE: Requested setting is " + "unavailable for the current device"; + break; + + case RSMI_STATUS_AMDGPU_RESTART_ERR: + *status_string = "RSMI_STATUS_AMDGPU_RESTART_ERR: Could not successfully " + "restart the amdgpu driver"; break; case RSMI_STATUS_UNKNOWN_ERROR: - *status_string = "An unknown error prevented the call from completing" - " successfully"; + *status_string = "RSMI_STATUS_UNKNOWN_ERROR: An unknown error prevented " + "the call from completing successfully"; break; default: - *status_string = "An unknown error occurred"; + *status_string = "RSMI_STATUS_UNKNOWN_ERROR: An unknown error occurred"; return RSMI_STATUS_UNKNOWN_ERROR; } return RSMI_STATUS_SUCCESS; @@ -2876,6 +3247,9 @@ rsmi_status_t rsmi_dev_busy_percent_get(uint32_t dv_ind, uint32_t *busy_percent) { TRY std::string val_str; + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); CHK_SUPPORT_NAME_ONLY(busy_percent) @@ -2946,6 +3320,9 @@ rsmi_utilization_count_get(uint32_t dv_ind, rsmi_status_t rsmi_dev_vbios_version_get(uint32_t dv_ind, char *vbios, uint32_t len) { TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); CHK_SUPPORT_NAME_ONLY(vbios) if (len == 0) { @@ -3042,6 +3419,9 @@ rsmi_version_str_get(rsmi_sw_component_t component, char *ver_str, rsmi_status_t rsmi_dev_serial_number_get(uint32_t dv_ind, char *serial_num, uint32_t len) { + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); CHK_SUPPORT_NAME_ONLY(serial_num) if (len == 0) { return RSMI_STATUS_INVALID_ARGS; @@ -3073,6 +3453,9 @@ rsmi_status_t rsmi_dev_serial_number_get(uint32_t dv_ind, rsmi_status_t rsmi_dev_pci_replay_counter_get(uint32_t dv_ind, uint64_t *counter) { TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); CHK_SUPPORT_NAME_ONLY(counter) rsmi_status_t ret; @@ -3088,6 +3471,9 @@ rsmi_status_t rsmi_dev_unique_id_get(uint32_t dv_ind, uint64_t *unique_id) { TRY rsmi_status_t ret; + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); CHK_SUPPORT_NAME_ONLY(unique_id) @@ -3101,6 +3487,9 @@ rsmi_status_t rsmi_dev_counter_create(uint32_t dv_ind, rsmi_event_type_t type, rsmi_event_handle_t *evnt_handle) { TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); REQUIRE_ROOT_ACCESS // Note we don't need to pass in the variant to CHK_SUPPORT_VAR because @@ -3121,6 +3510,9 @@ rsmi_dev_counter_create(uint32_t dv_ind, rsmi_event_type_t type, rsmi_status_t rsmi_dev_counter_destroy(rsmi_event_handle_t evnt_handle) { TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); if (evnt_handle == 0) { return RSMI_STATUS_INVALID_ARGS; @@ -3241,6 +3633,9 @@ rsmi_counter_available_counters_get(uint32_t dv_ind, rsmi_status_t rsmi_dev_counter_group_supported(uint32_t dv_ind, rsmi_event_group_t group) { TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); DEVICE_MUTEX GET_DEV_FROM_INDX @@ -3302,11 +3697,23 @@ rsmi_compute_process_gpus_get(uint32_t pid, uint32_t *dv_indices, uint32_t i = 0; amd::smi::RocmSMI& smi = amd::smi::RocmSMI::getInstance(); + // filter out the devices not visible to container + auto& nodes = smi.kfd_node_map(); + for (auto nit = gpu_set.begin(); nit != gpu_set.end();) { + uint64_t gpu_id_val = (*nit); + auto kfd_ite = nodes.find(gpu_id_val); + if (kfd_ite == nodes.end()) { + nit = gpu_set.erase(nit); + } else { + nit++; + } + } + if (dv_indices != nullptr) { for (auto it = gpu_set.begin(); i < *num_devices && it != gpu_set.end(); ++it, ++i) { uint64_t gpu_id_val = (*it); - dv_indices[i] = smi.kfd_node_map()[gpu_id_val]->amdgpu_dev_index(); + dv_indices[i] = nodes[gpu_id_val]->amdgpu_dev_index(); } } @@ -3330,6 +3737,9 @@ rsmi_status_t rsmi_dev_memory_reserved_pages_get(uint32_t dv_ind, uint32_t *num_pages, rsmi_retired_page_record_t *records) { TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); rsmi_status_t ret; CHK_SUPPORT_NAME_ONLY(num_pages) @@ -3425,9 +3835,35 @@ rsmi_compute_process_info_by_pid_get(uint32_t pid, CATCH } +rsmi_status_t +rsmi_compute_process_info_by_device_get(uint32_t pid, uint32_t dv_ind, + rsmi_process_info_t *proc) { + TRY + if (proc == nullptr) { + return RSMI_STATUS_INVALID_ARGS; + } + // Check the device and kfdnode exist + GET_DEV_AND_KFDNODE_FROM_INDX + + std::unordered_set gpu_set; + gpu_set.insert(dev->kfd_gpu_id()); + int err = amd::smi::GetProcessInfoForPID(pid, proc, &gpu_set); + + if (err) { + return amd::smi::ErrnoToRsmiStatus(err); + } + + return RSMI_STATUS_SUCCESS; + + CATCH +} + rsmi_status_t rsmi_dev_xgmi_error_status(uint32_t dv_ind, rsmi_xgmi_status_t *status) { TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); CHK_SUPPORT_NAME_ONLY(status) rsmi_status_t ret; @@ -3465,6 +3901,9 @@ rsmi_dev_xgmi_error_status(uint32_t dv_ind, rsmi_xgmi_status_t *status) { rsmi_status_t rsmi_dev_xgmi_error_reset(uint32_t dv_ind) { TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); DEVICE_MUTEX rsmi_status_t ret; @@ -3480,6 +3919,9 @@ rsmi_dev_xgmi_error_reset(uint32_t dv_ind) { rsmi_status_t rsmi_dev_xgmi_hive_id_get(uint32_t dv_ind, uint64_t *hive_id) { TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); if (hive_id == nullptr) { return RSMI_STATUS_INVALID_ARGS; @@ -3532,7 +3974,7 @@ rsmi_topo_get_link_weight(uint32_t dv_ind_src, uint32_t dv_ind_dst, assert(false); // Unexpected IO Link type read status = RSMI_STATUS_NOT_SUPPORTED; } - } else { + } else if (kfd_node->numa_node_type() == amd::smi::IOLINK_TYPE_PCIEXPRESS) { *weight = kfd_node->numa_node_weight(); // from src GPU to it's CPU node uint64_t numa_weight_dst = 0; status = topo_get_numa_node_weight(dv_ind_dst, &numa_weight_dst); @@ -3564,6 +4006,8 @@ rsmi_topo_get_link_weight(uint32_t dv_ind_src, uint32_t dv_ind_dst, assert(false); // Error to read numa node weight status = RSMI_STATUS_INIT_ERROR; } + } else { + status = RSMI_STATUS_NOT_SUPPORTED; } } else { status = RSMI_STATUS_INVALID_ARGS; @@ -3639,7 +4083,7 @@ rsmi_topo_get_link_type(uint32_t dv_ind_src, uint32_t dv_ind_dst, if (ret == 0) { amd::smi::IO_LINK_TYPE io_link_type; ret = kfd_node->get_io_link_type(node_ind_dst, &io_link_type); - if (!ret) { + if (ret == 0) { if (io_link_type == amd::smi::IOLINK_TYPE_XGMI) { *type = RSMI_IOLINK_TYPE_XGMI; *hops = 1; @@ -3648,7 +4092,7 @@ rsmi_topo_get_link_type(uint32_t dv_ind_src, uint32_t dv_ind_dst, assert(false); // Unexpected IO Link type read status = RSMI_STATUS_NOT_SUPPORTED; } - } else { + } else if (kfd_node->numa_node_type() == amd::smi::IOLINK_TYPE_PCIEXPRESS) { uint32_t numa_number_dst; status = topo_get_numa_node_number(dv_ind_dst, &numa_number_dst); if (status == RSMI_STATUS_SUCCESS) { @@ -3664,21 +4108,14 @@ rsmi_topo_get_link_type(uint32_t dv_ind_src, uint32_t dv_ind_dst, else *hops = 4; // More than one CPU hops, hard coded as 4 } - - amd::smi::IO_LINK_TYPE numa_node_type = kfd_node->numa_node_type(); - if (numa_node_type == amd::smi::IOLINK_TYPE_PCIEXPRESS) { - *type = RSMI_IOLINK_TYPE_PCIEXPRESS; - status = RSMI_STATUS_SUCCESS; - } else if (numa_node_type == amd::smi::IOLINK_TYPE_XGMI) { - *type = RSMI_IOLINK_TYPE_XGMI; - status = RSMI_STATUS_SUCCESS; - } else { - status = RSMI_STATUS_INIT_ERROR; - } + *type = RSMI_IOLINK_TYPE_PCIEXPRESS; + status = RSMI_STATUS_SUCCESS; } else { assert(false); // Error to get numa node number status = RSMI_STATUS_INIT_ERROR; } + } else { + status = RSMI_STATUS_NOT_SUPPORTED; } } else { status = RSMI_STATUS_INVALID_ARGS; @@ -3744,6 +4181,331 @@ rsmi_is_P2P_accessible(uint32_t dv_ind_src, uint32_t dv_ind_dst, CATCH } +static rsmi_status_t +get_compute_partition(uint32_t dv_ind, std::string &compute_partition) { + TRY + CHK_SUPPORT_NAME_ONLY(compute_partition.c_str()) + std::string compute_partition_str; + + DEVICE_MUTEX + rsmi_status_t ret = get_dev_value_str(amd::smi::kDevComputePartition, + dv_ind, &compute_partition_str); + if (ret != RSMI_STATUS_SUCCESS) { + return ret; + } + + switch (mapStringToRSMIComputePartitionTypes[compute_partition_str]) { + case RSMI_COMPUTE_PARTITION_INVALID: + // Retrieved an unknown compute partition + return RSMI_STATUS_UNEXPECTED_DATA; + case RSMI_COMPUTE_PARTITION_CPX: + break; + case RSMI_COMPUTE_PARTITION_SPX: + break; + case RSMI_COMPUTE_PARTITION_DPX: + break; + case RSMI_COMPUTE_PARTITION_TPX: + break; + case RSMI_COMPUTE_PARTITION_QPX: + break; + default: + // Retrieved an unknown compute partition + return RSMI_STATUS_UNEXPECTED_DATA; + } + compute_partition = compute_partition_str; + return RSMI_STATUS_SUCCESS; + CATCH +} + +rsmi_status_t +rsmi_dev_compute_partition_get(uint32_t dv_ind, char *compute_partition, + uint32_t len) { + TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); + if ((len == 0) || (compute_partition == nullptr)) { + return RSMI_STATUS_INVALID_ARGS; + } + CHK_SUPPORT_NAME_ONLY(compute_partition) + + std::string returning_compute_partition; + rsmi_status_t ret = get_compute_partition(dv_ind, + returning_compute_partition); + + if (ret != RSMI_STATUS_SUCCESS) { return ret; } + + std::size_t length = returning_compute_partition.copy(compute_partition, len); + compute_partition[length]='\0'; + + if (len < (returning_compute_partition.size() + 1)) { + return RSMI_STATUS_INSUFFICIENT_SIZE; + } + return ret; + CATCH +} + +static rsmi_status_t +is_available_compute_partition(uint32_t dv_ind, + std::string new_compute_partition) { + TRY + DEVICE_MUTEX + std::string availableComputePartitions; + rsmi_status_t ret = + get_dev_value_line(amd::smi::kDevAvailableComputePartition, + dv_ind, &availableComputePartitions); + if (ret != RSMI_STATUS_SUCCESS) { + return ret; + } + + bool isComputePartitionAvailable = + amd::smi::containsString(availableComputePartitions, + new_compute_partition); + return (isComputePartitionAvailable) ? RSMI_STATUS_SUCCESS : + RSMI_STATUS_SETTING_UNAVAILABLE; + CATCH +} + +rsmi_status_t +rsmi_dev_compute_partition_set(uint32_t dv_ind, + rsmi_compute_partition_type_t compute_partition) { + TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); + REQUIRE_ROOT_ACCESS + DEVICE_MUTEX + std::string newComputePartitionStr + = mapRSMIToStringComputePartitionTypes[compute_partition]; + std::string currentComputePartition; + + switch (compute_partition) { + case RSMI_COMPUTE_PARTITION_INVALID: + // Retrieved an unknown compute partition + return RSMI_STATUS_INVALID_ARGS; + case RSMI_COMPUTE_PARTITION_CPX: + break; + case RSMI_COMPUTE_PARTITION_SPX: + break; + case RSMI_COMPUTE_PARTITION_DPX: + break; + case RSMI_COMPUTE_PARTITION_TPX: + break; + case RSMI_COMPUTE_PARTITION_QPX: + break; + default: + return RSMI_STATUS_INVALID_ARGS; + } + + // Confirm what we are trying to set is available, otherwise provide + // RSMI_STATUS_SETTING_UNAVAILABLE + rsmi_status_t available_ret = + is_available_compute_partition(dv_ind, newComputePartitionStr); + if (available_ret != RSMI_STATUS_SUCCESS) { + return available_ret; + } + + // do nothing if compute_partition is the current compute partition + rsmi_status_t ret_get = get_compute_partition(dv_ind, currentComputePartition); + // we can try to set, even if we get unexpected data + if (ret_get != RSMI_STATUS_SUCCESS + && ret_get != RSMI_STATUS_UNEXPECTED_DATA) { + return ret_get; + } + rsmi_compute_partition_type_t currRSMIComputePartition + = mapStringToRSMIComputePartitionTypes[currentComputePartition]; + if (currRSMIComputePartition == compute_partition) { + return RSMI_STATUS_SUCCESS; + } + + GET_DEV_FROM_INDX + int ret = dev->writeDevInfo(amd::smi::kDevComputePartition, + newComputePartitionStr); + return amd::smi::ErrnoToRsmiStatus(ret); + CATCH +} + +static rsmi_status_t get_nps_mode(uint32_t dv_ind, std::string &nps_mode) { + TRY + CHK_SUPPORT_NAME_ONLY(nps_mode.c_str()) + std::string val_str; + + DEVICE_MUTEX + rsmi_status_t ret = get_dev_value_str(amd::smi::kDevMemoryPartition, + dv_ind, &val_str); + + if (ret != RSMI_STATUS_SUCCESS) { + return ret; + } + + switch (mapStringToNPSModeTypes[val_str]) { + case RSMI_MEMORY_PARTITION_UNKNOWN: + // Retrieved an unknown NPS mode + return RSMI_STATUS_UNEXPECTED_DATA; + case RSMI_MEMORY_PARTITION_NPS1: + break; + case RSMI_MEMORY_PARTITION_NPS2: + break; + case RSMI_MEMORY_PARTITION_NPS4: + break; + case RSMI_MEMORY_PARTITION_NPS8: + break; + default: + // Retrieved an unknown NPS mode + return RSMI_STATUS_UNEXPECTED_DATA; + } + nps_mode = val_str; + return RSMI_STATUS_SUCCESS; + CATCH +} + +rsmi_status_t +rsmi_dev_nps_mode_set(uint32_t dv_ind, rsmi_nps_mode_type_t nps_mode) { + TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); + REQUIRE_ROOT_ACCESS + DEVICE_MUTEX + bool isCorrectDevice = false; + char boardName[128]; + boardName[0] = '\0'; + // rsmi_dev_nps_mode_set is only available for for discrete variant, + // others are required to update through bios settings + rsmi_dev_name_get(dv_ind, boardName, 128); + std::string myBoardName = boardName; + if (!myBoardName.empty()) { + std::transform(myBoardName.begin(), myBoardName.end(), myBoardName.begin(), + ::tolower); + if (myBoardName.find("mi") != std::string::npos && + myBoardName.find("00x") != std::string::npos) { + isCorrectDevice = true; + } + } + + if (isCorrectDevice == false) { + return RSMI_STATUS_NOT_SUPPORTED; + } + + std::string newNPSMode + = mapRSMIToStringNPSModeTypes[nps_mode]; + std::string currentNPSMode; + + switch (nps_mode) { + case RSMI_MEMORY_PARTITION_UNKNOWN: + // Retrieved an unknown NPS mode + return RSMI_STATUS_INVALID_ARGS; + case RSMI_MEMORY_PARTITION_NPS1: + break; + case RSMI_MEMORY_PARTITION_NPS2: + break; + case RSMI_MEMORY_PARTITION_NPS4: + break; + case RSMI_MEMORY_PARTITION_NPS8: + break; + default: + return RSMI_STATUS_INVALID_ARGS; + } + + // do nothing if nps_mode is the current NPS mode + rsmi_status_t ret_get = get_nps_mode(dv_ind, currentNPSMode); + // we can try to set, even if we get unexpected data + if (ret_get != RSMI_STATUS_SUCCESS + && ret_get != RSMI_STATUS_UNEXPECTED_DATA) { + return ret_get; + } + rsmi_nps_mode_type_t currRSMINpsMode + = mapStringToNPSModeTypes[currentNPSMode]; + if (currRSMINpsMode == nps_mode) { + return RSMI_STATUS_SUCCESS; + } + + GET_DEV_FROM_INDX + int ret = dev->writeDevInfo(amd::smi::kDevMemoryPartition, newNPSMode); + + if (amd::smi::ErrnoToRsmiStatus(ret) != RSMI_STATUS_SUCCESS) { + return amd::smi::ErrnoToRsmiStatus(ret); + } + + return dev->restartAMDGpuDriver(); + CATCH +} + +rsmi_status_t +rsmi_dev_nps_mode_get(uint32_t dv_ind, char *nps_mode, + uint32_t len) { + TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); + if ((len == 0) || (nps_mode == nullptr)) { + return RSMI_STATUS_INVALID_ARGS; + } + CHK_SUPPORT_NAME_ONLY(nps_mode) + + std::string returning_nps_mode; + rsmi_status_t ret = get_nps_mode(dv_ind, + returning_nps_mode); + + if (ret != RSMI_STATUS_SUCCESS) { return ret; } + + std::size_t length = returning_nps_mode.copy(nps_mode, len); + nps_mode[length]='\0'; + + if (len < (returning_nps_mode.size() + 1)) { + return RSMI_STATUS_INSUFFICIENT_SIZE; + } + return ret; + CATCH +} + +rsmi_status_t rsmi_dev_compute_partition_reset(uint32_t dv_ind) { + TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); + REQUIRE_ROOT_ACCESS + DEVICE_MUTEX + GET_DEV_FROM_INDX + rsmi_status_t ret = RSMI_STATUS_NOT_SUPPORTED; + // read temp file + std::string bootState = + dev->readBootPartitionState(dv_ind); + // Initiate reset + // If bootState is UNKNOWN, we cannot reset - return RSMI_STATUS_NOT_SUPPORTED + // Likely due to device not supporting it + if (bootState != "UNKNOWN") { + rsmi_compute_partition_type_t compute_partition = + mapStringToRSMIComputePartitionTypes[bootState]; + ret = rsmi_dev_compute_partition_set(dv_ind, compute_partition); + } + return ret; + CATCH +} + +rsmi_status_t rsmi_dev_nps_mode_reset(uint32_t dv_ind) { + TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); + REQUIRE_ROOT_ACCESS + DEVICE_MUTEX + GET_DEV_FROM_INDX + rsmi_status_t ret = RSMI_STATUS_NOT_SUPPORTED; + // read temp file + std::string bootState = + dev->readBootPartitionState(dv_ind); + // Initiate reset + // If bootState is UNKNOWN, we cannot reset - return RSMI_STATUS_NOT_SUPPORTED + // Likely due to device not supporting it + if (bootState != "UNKNOWN") { + rsmi_nps_mode_type_t nps_mode = mapStringToNPSModeTypes[bootState]; + ret = rsmi_dev_nps_mode_set(dv_ind, nps_mode); + } + return ret; + CATCH +} + enum iterator_handle_type { FUNC_ITER = 0, VARIANT_ITER, @@ -3754,6 +4516,9 @@ rsmi_status_t rsmi_dev_supported_func_iterator_open(uint32_t dv_ind, rsmi_func_id_iter_handle_t *handle) { TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); GET_DEV_FROM_INDX if (handle == nullptr) { @@ -3796,6 +4561,9 @@ rsmi_dev_supported_variant_iterator_open( rsmi_func_id_iter_handle_t parent_iter, rsmi_func_id_iter_handle_t *var_iter) { TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); if (var_iter == nullptr || parent_iter->id_type == SUBVARIANT_ITER) { return RSMI_STATUS_INVALID_ARGS; @@ -3866,6 +4634,9 @@ rsmi_dev_supported_variant_iterator_open( rsmi_status_t rsmi_dev_supported_func_iterator_close(rsmi_func_id_iter_handle_t *handle) { TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); if (handle == nullptr) { return RSMI_STATUS_INVALID_ARGS; diff --git a/rocm_smi/src/rocm_smi_device.cc b/rocm_smi/src/rocm_smi_device.cc index 67b198ef83..18c96b7f13 100755 --- a/rocm_smi/src/rocm_smi_device.cc +++ b/rocm_smi/src/rocm_smi_device.cc @@ -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 #include #include - #include #include #include + #include #include #include @@ -58,6 +58,7 @@ #include #include #include +#include #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 kDevAttribNameMap = { {kDevPerfLevel, kDevPerfLevelFName}, {kDevOverDriveLevel, kDevOverDriveLevelFName}, + {kDevMemOverDriveLevel, kDevMemOverDriveLevelFName}, {kDevDevProdName, kDevDevProdNameFName}, {kDevDevProdNum, kDevDevProdNumFName}, {kDevDevID, kDevDevIDFName}, @@ -288,6 +298,9 @@ static const std::map kDevAttribNameMap = { {kDevNumaNode, kDevNumaNodeFName}, {kDevGpuMetrics, kDevGpuMetricsFName}, {kDevGpuReset, kDevGpuResetFName}, + {kDevAvailableComputePartition, kDevAvailableComputePartitionFName}, + {kDevComputePartition, kDevComputePartitionFName}, + {kDevMemoryPartition, kDevMemoryPartitionFName}, }; static const std::map kDevPerfLvlMap = { @@ -388,6 +401,7 @@ static const std::map 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 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 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, ®_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 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(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(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(dv_ind); + rsmi_status_t npsRet = storeParameter(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( + 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( + 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 diff --git a/rocm_smi/src/rocm_smi_gpu_metrics.cc b/rocm_smi/src/rocm_smi_gpu_metrics.cc index 801030d6eb..62281dfe4a 100755 --- a/rocm_smi/src/rocm_smi_gpu_metrics.cc +++ b/rocm_smi/src/rocm_smi_gpu_metrics.cc @@ -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 // NOLINT #include #include +#include #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 = {}; diff --git a/rocm_smi/src/rocm_smi_kfd.cc b/rocm_smi/src/rocm_smi_kfd.cc index bf3227f81b..13aed64588 100755 --- a/rocm_smi/src/rocm_smi_kfd.cc +++ b/rocm_smi/src/rocm_smi_kfd.cc @@ -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; } } diff --git a/rocm_smi/src/rocm_smi_logger.cc b/rocm_smi/src/rocm_smi_logger.cc new file mode 100644 index 0000000000..9472e40717 --- /dev/null +++ b/rocm_smi/src/rocm_smi_logger.cc @@ -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 , + * 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=. 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 +#include +#include +#include +#include +#include + +// 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(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 = "; + } + 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 = "; + } + + 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(); +} diff --git a/rocm_smi/src/rocm_smi_main.cc b/rocm_smi/src/rocm_smi_main.cc index 40541d9280..3a5565dbe9 100755 --- a/rocm_smi/src/rocm_smi_main.cc +++ b/rocm_smi/src/rocm_smi_main.cc @@ -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 #include #include +#include #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::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 GetEnvVarUIntegerSets(const char *ev_str) { + std::unordered_set 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(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) ? "" + : 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) + ? "" : 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) + ? "" : 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) + ? "" : env_vars_.path_power_root_override) + << std::endl; + std::cout << __PRETTY_FUNCTION__ << " | env_vars_.debug_inf_loop = " + << ((env_vars_.debug_inf_loop == 0) ? "" + : 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(*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 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); diff --git a/rocm_smi/src/rocm_smi_monitor.cc b/rocm_smi/src/rocm_smi_monitor.cc index 856281053b..82e40ff7f9 100755 --- a/rocm_smi/src/rocm_smi_monitor.cc +++ b/rocm_smi/src/rocm_smi_monitor.cc @@ -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 diff --git a/rocm_smi/src/rocm_smi_utils.cc b/rocm_smi/src/rocm_smi_utils.cc index e372209ef1..e4827216b9 100755 --- a/rocm_smi/src/rocm_smi_utils.cc +++ b/rocm_smi/src/rocm_smi_utils.cc @@ -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 #include #include +#include +#include +#include +#include #include #include +#include #include #include #include #include #include +#include #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 files) { + std::ostringstream ss; + int numberOfFilesFound = static_cast(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 << ""; + } + 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 globFilesExist(const std::string& filePattern) { + std::ostringstream ss; + std::vector 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 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: +// ___ +// - prefix for our application's identifier (see kTmpFilePrefix) +// - name of parameter being stored +// - state at which the stored value captures +// - 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: + // ___ + 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 getListOfAppTmpFiles() { + std::string path = "/tmp"; + DIR *dir; + struct dirent *ent; + std::vector 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 readEntireFile(std::string path) { + std::vector 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 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 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 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 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 getSystemDetails(void) { + struct utsname buf; + bool errorDetected = false; + std::string temp_data; + std::string sysname, nodename, release, version, machine; + std::string domainName = ""; + std::string os_distribution = ""; + + 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 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 diff --git a/src/amd_smi/amd_smi.cc b/src/amd_smi/amd_smi.cc index 0e59fcd964..cecd4ad53e 100644 --- a/src/amd_smi/amd_smi.cc +++ b/src/amd_smi/amd_smi.cc @@ -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(); diff --git a/src/amd_smi/amd_smi_drm.cc b/src/amd_smi/amd_smi_drm.cc index bf626a9641..9f24920377 100644 --- a/src/amd_smi/amd_smi_drm.cc +++ b/src/amd_smi/amd_smi_drm.cc @@ -44,7 +44,6 @@ #include #include #include -#include #include #include #include @@ -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; + std::lock_guard 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; diff --git a/src/amd_smi/amd_smi_gpu_device.cc b/src/amd_smi/amd_smi_gpu_device.cc index 1dab7a267b..9d4a243b6f 100644 --- a/src/amd_smi/amd_smi_gpu_device.cc +++ b/src/amd_smi/amd_smi_gpu_device.cc @@ -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; diff --git a/src/amd_smi/amd_smi_utils.cc b/src/amd_smi/amd_smi_utils.cc index e305eea475..1f9e88b897 100644 --- a/src/amd_smi/amd_smi_utils.cc +++ b/src/amd_smi/amd_smi_utils.cc @@ -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; } diff --git a/tests/amd_smi_test/CMakeLists.txt b/tests/amd_smi_test/CMakeLists.txt index 122adcf29f..d87bdec4c2 100644 --- a/tests/amd_smi_test/CMakeLists.txt +++ b/tests/amd_smi_test/CMakeLists.txt @@ -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}) diff --git a/tests/rocm_smi_test/CMakeLists.txt b/tests/rocm_smi_test/CMakeLists.txt deleted file mode 100755 index 456cb225fe..0000000000 --- a/tests/rocm_smi_test/CMakeLists.txt +++ /dev/null @@ -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) diff --git a/tests/rocm_smi_test/functional/api_support_read.cc b/tests/rocm_smi_test/functional/api_support_read.cc deleted file mode 100755 index 693e978432..0000000000 --- a/tests/rocm_smi_test/functional/api_support_read.cc +++ /dev/null @@ -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 , - * 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 -#include - -#include -#include - -#include -#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) - } - } -} diff --git a/tests/rocm_smi_test/functional/api_support_read.h b/tests/rocm_smi_test/functional/api_support_read.h deleted file mode 100755 index 86ff546a8b..0000000000 --- a/tests/rocm_smi_test/functional/api_support_read.h +++ /dev/null @@ -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 , - * 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_ diff --git a/tests/rocm_smi_test/functional/err_cnt_read.cc b/tests/rocm_smi_test/functional/err_cnt_read.cc deleted file mode 100755 index 1ff1c66df4..0000000000 --- a/tests/rocm_smi_test/functional/err_cnt_read.cc +++ /dev/null @@ -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 , - * 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 -#include - -#include - -#include -#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(b), - &err_state); - CHK_ERR_ASRT(err) - IF_VERB(STANDARD) { - std::cout << "\t**Error Count status for " << - GetBlockNameStr(static_cast(b)) << - " block: " << GetErrStateNameStr(err_state) << std::endl; - } - // Verify api support checking functionality is working - err = rsmi_dev_ecc_status_get(i, static_cast(b), - nullptr); - ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS); - - err = rsmi_dev_ecc_count_get(i, static_cast(b), &ec); - - if (err == RSMI_STATUS_NOT_SUPPORTED) { - IF_VERB(STANDARD) { - std::cout << "\t**Error Count for " << - GetBlockNameStr(static_cast(b)) << - ": Not supported for this device" << std::endl; - } - // Verify api support checking functionality is working - err = rsmi_dev_ecc_count_get(i, static_cast(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(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(b), - nullptr); - ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS); - } - } - } - } -} diff --git a/tests/rocm_smi_test/functional/err_cnt_read.h b/tests/rocm_smi_test/functional/err_cnt_read.h deleted file mode 100755 index 046796c381..0000000000 --- a/tests/rocm_smi_test/functional/err_cnt_read.h +++ /dev/null @@ -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 , - * 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_ diff --git a/tests/rocm_smi_test/functional/evt_notif_read_write.cc b/tests/rocm_smi_test/functional/evt_notif_read_write.cc deleted file mode 100755 index f070466160..0000000000 --- a/tests/rocm_smi_test/functional/evt_notif_read_write.cc +++ /dev/null @@ -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 , - * 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 -#include - -#include - -#include -#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( - static_cast(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); - } -} diff --git a/tests/rocm_smi_test/functional/evt_notif_read_write.h b/tests/rocm_smi_test/functional/evt_notif_read_write.h deleted file mode 100755 index 604bb4f9ea..0000000000 --- a/tests/rocm_smi_test/functional/evt_notif_read_write.h +++ /dev/null @@ -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 , - * 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_ diff --git a/tests/rocm_smi_test/functional/fan_read.cc b/tests/rocm_smi_test/functional/fan_read.cc deleted file mode 100755 index b467538ea2..0000000000 --- a/tests/rocm_smi_test/functional/fan_read.cc +++ /dev/null @@ -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 , - * 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 -#include - -#include - -#include -#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(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); - } - } -} diff --git a/tests/rocm_smi_test/functional/fan_read.h b/tests/rocm_smi_test/functional/fan_read.h deleted file mode 100755 index 20e4bba120..0000000000 --- a/tests/rocm_smi_test/functional/fan_read.h +++ /dev/null @@ -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 , - * 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_ diff --git a/tests/rocm_smi_test/functional/fan_read_write.cc b/tests/rocm_smi_test/functional/fan_read_write.cc deleted file mode 100755 index ae9f79e676..0000000000 --- a/tests/rocm_smi_test/functional/fan_read_write.cc +++ /dev/null @@ -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 , - * 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 -#include - -#include - -#include -#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(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; - } - } -} diff --git a/tests/rocm_smi_test/functional/fan_read_write.h b/tests/rocm_smi_test/functional/fan_read_write.h deleted file mode 100755 index 3964a15e4f..0000000000 --- a/tests/rocm_smi_test/functional/fan_read_write.h +++ /dev/null @@ -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 , - * 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_ diff --git a/tests/rocm_smi_test/functional/frequencies_read.cc b/tests/rocm_smi_test/functional/frequencies_read.cc deleted file mode 100755 index 79226fa7b0..0000000000 --- a/tests/rocm_smi_test/functional/frequencies_read.cc +++ /dev/null @@ -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 , - * 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 -#include - -#include -#include - -#include -#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); - } - } - } - } -} diff --git a/tests/rocm_smi_test/functional/frequencies_read.h b/tests/rocm_smi_test/functional/frequencies_read.h deleted file mode 100755 index 3fadc96db2..0000000000 --- a/tests/rocm_smi_test/functional/frequencies_read.h +++ /dev/null @@ -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 , - * 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_ diff --git a/tests/rocm_smi_test/functional/frequencies_read_write.cc b/tests/rocm_smi_test/functional/frequencies_read_write.cc deleted file mode 100755 index 81a1357b8c..0000000000 --- a/tests/rocm_smi_test/functional/frequencies_read_write.cc +++ /dev/null @@ -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 , - * 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 -#include - -#include -#include -#include -#include -#include - -#include -#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(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(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 - } - } -} diff --git a/tests/rocm_smi_test/functional/frequencies_read_write.h b/tests/rocm_smi_test/functional/frequencies_read_write.h deleted file mode 100755 index c9cce23093..0000000000 --- a/tests/rocm_smi_test/functional/frequencies_read_write.h +++ /dev/null @@ -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 , - * 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_ diff --git a/tests/rocm_smi_test/functional/gpu_busy_read.cc b/tests/rocm_smi_test/functional/gpu_busy_read.cc deleted file mode 100755 index 298b8ea17f..0000000000 --- a/tests/rocm_smi_test/functional/gpu_busy_read.cc +++ /dev/null @@ -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 , - * 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 -#include - -#include -#include - -#include -#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; - } - } - } - } -} diff --git a/tests/rocm_smi_test/functional/gpu_busy_read.h b/tests/rocm_smi_test/functional/gpu_busy_read.h deleted file mode 100755 index 7da865c474..0000000000 --- a/tests/rocm_smi_test/functional/gpu_busy_read.h +++ /dev/null @@ -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 , - * 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_ diff --git a/tests/rocm_smi_test/functional/gpu_metrics_read.cc b/tests/rocm_smi_test/functional/gpu_metrics_read.cc deleted file mode 100644 index 80efe7018a..0000000000 --- a/tests/rocm_smi_test/functional/gpu_metrics_read.cc +++ /dev/null @@ -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 , - * 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 -#include - -#include -#include -#include - -#include -#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); - } -} diff --git a/tests/rocm_smi_test/functional/gpu_metrics_read.h b/tests/rocm_smi_test/functional/gpu_metrics_read.h deleted file mode 100644 index 84139b8647..0000000000 --- a/tests/rocm_smi_test/functional/gpu_metrics_read.h +++ /dev/null @@ -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 , - * 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_ diff --git a/tests/rocm_smi_test/functional/hw_topology_read.cc b/tests/rocm_smi_test/functional/hw_topology_read.cc deleted file mode 100755 index 880dd8d11d..0000000000 --- a/tests/rocm_smi_test/functional/hw_topology_read.cc +++ /dev/null @@ -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 , - * 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 -#include - -#include -#include -#include - -#include -#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> gpu_links(num_devices, - std::vector(num_devices)); - // uint32_t numa_numbers[num_devices]; - std::vector 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; -} diff --git a/tests/rocm_smi_test/functional/hw_topology_read.h b/tests/rocm_smi_test/functional/hw_topology_read.h deleted file mode 100755 index 7291a38f9f..0000000000 --- a/tests/rocm_smi_test/functional/hw_topology_read.h +++ /dev/null @@ -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 , - * 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_ diff --git a/tests/rocm_smi_test/functional/id_info_read.cc b/tests/rocm_smi_test/functional/id_info_read.cc deleted file mode 100755 index 04982c7743..0000000000 --- a/tests/rocm_smi_test/functional/id_info_read.cc +++ /dev/null @@ -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 , - * 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 -#include - -#include -#include - -#include -#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); - } - } -} diff --git a/tests/rocm_smi_test/functional/id_info_read.h b/tests/rocm_smi_test/functional/id_info_read.h deleted file mode 100755 index 28dd028155..0000000000 --- a/tests/rocm_smi_test/functional/id_info_read.h +++ /dev/null @@ -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 , - * 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_ diff --git a/tests/rocm_smi_test/functional/init_shutdown_refcount.cc b/tests/rocm_smi_test/functional/init_shutdown_refcount.cc deleted file mode 100755 index 698c028f64..0000000000 --- a/tests/rocm_smi_test/functional/init_shutdown_refcount.cc +++ /dev/null @@ -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 , - * 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 - -#include -#include -#include // NOLINT -#include -#include // NOLINT - -#include "init_shutdown_refcount.h" -#include -#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; - } -} diff --git a/tests/rocm_smi_test/functional/init_shutdown_refcount.h b/tests/rocm_smi_test/functional/init_shutdown_refcount.h deleted file mode 100755 index 4fe5cc0dd5..0000000000 --- a/tests/rocm_smi_test/functional/init_shutdown_refcount.h +++ /dev/null @@ -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 , - * 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_ diff --git a/tests/rocm_smi_test/functional/mem_page_info_read.cc b/tests/rocm_smi_test/functional/mem_page_info_read.cc deleted file mode 100755 index 46d677f53b..0000000000 --- a/tests/rocm_smi_test/functional/mem_page_info_read.cc +++ /dev/null @@ -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 , - * 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 -#include - -#include -#include - -#include -#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; - } - } -} diff --git a/tests/rocm_smi_test/functional/mem_page_info_read.h b/tests/rocm_smi_test/functional/mem_page_info_read.h deleted file mode 100755 index 926fc907cf..0000000000 --- a/tests/rocm_smi_test/functional/mem_page_info_read.h +++ /dev/null @@ -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 , - * 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_ diff --git a/tests/rocm_smi_test/functional/mem_util_read.cc b/tests/rocm_smi_test/functional/mem_util_read.cc deleted file mode 100755 index e304a98abe..0000000000 --- a/tests/rocm_smi_test/functional/mem_util_read.cc +++ /dev/null @@ -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 , - * 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 -#include - -#include -#include -#include - -#include -#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 - 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(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(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(mem_type)) - << " Calculated Utilization: " << - (static_cast(usage)*100)/total << "% ("<< usage << - "/" << total << ")" << std::endl; - } - } - } - } -} diff --git a/tests/rocm_smi_test/functional/mem_util_read.h b/tests/rocm_smi_test/functional/mem_util_read.h deleted file mode 100755 index 854e3cebef..0000000000 --- a/tests/rocm_smi_test/functional/mem_util_read.h +++ /dev/null @@ -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 , - * 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_ diff --git a/tests/rocm_smi_test/functional/metrics_counter_read.cc b/tests/rocm_smi_test/functional/metrics_counter_read.cc deleted file mode 100644 index 62cafee870..0000000000 --- a/tests/rocm_smi_test/functional/metrics_counter_read.cc +++ /dev/null @@ -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 , - * 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 -#include - -#include -#include -#include - -#include -#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, ×tamp); - 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, ×tamp); - 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 -} diff --git a/tests/rocm_smi_test/functional/metrics_counter_read.h b/tests/rocm_smi_test/functional/metrics_counter_read.h deleted file mode 100644 index 4e0187e6d4..0000000000 --- a/tests/rocm_smi_test/functional/metrics_counter_read.h +++ /dev/null @@ -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 , - * 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_ diff --git a/tests/rocm_smi_test/functional/mutual_exclusion.cc b/tests/rocm_smi_test/functional/mutual_exclusion.cc deleted file mode 100755 index 8e7330cd1c..0000000000 --- a/tests/rocm_smi_test/functional/mutual_exclusion.cc +++ /dev/null @@ -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 , - * 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 -#include - -#include -#include -#include - -#include -#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); - } -} diff --git a/tests/rocm_smi_test/functional/mutual_exclusion.h b/tests/rocm_smi_test/functional/mutual_exclusion.h deleted file mode 100755 index 5a79d5cda7..0000000000 --- a/tests/rocm_smi_test/functional/mutual_exclusion.h +++ /dev/null @@ -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 , - * 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_ diff --git a/tests/rocm_smi_test/functional/overdrive_read.cc b/tests/rocm_smi_test/functional/overdrive_read.cc deleted file mode 100755 index 12469af927..0000000000 --- a/tests/rocm_smi_test/functional/overdrive_read.cc +++ /dev/null @@ -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 , - * 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 -#include - -#include -#include - -#include -#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); - } - } -} diff --git a/tests/rocm_smi_test/functional/overdrive_read.h b/tests/rocm_smi_test/functional/overdrive_read.h deleted file mode 100755 index d143ae7e28..0000000000 --- a/tests/rocm_smi_test/functional/overdrive_read.h +++ /dev/null @@ -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 , - * 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_ diff --git a/tests/rocm_smi_test/functional/overdrive_read_write.cc b/tests/rocm_smi_test/functional/overdrive_read_write.cc deleted file mode 100755 index 830dcc03e9..0000000000 --- a/tests/rocm_smi_test/functional/overdrive_read_write.cc +++ /dev/null @@ -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 , - * 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 -#include - -#include - -#include -#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; - } - } -} diff --git a/tests/rocm_smi_test/functional/overdrive_read_write.h b/tests/rocm_smi_test/functional/overdrive_read_write.h deleted file mode 100755 index 2e128963dd..0000000000 --- a/tests/rocm_smi_test/functional/overdrive_read_write.h +++ /dev/null @@ -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 , - * 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_ diff --git a/tests/rocm_smi_test/functional/pci_read_write.cc b/tests/rocm_smi_test/functional/pci_read_write.cc deleted file mode 100755 index b01b67681f..0000000000 --- a/tests/rocm_smi_test/functional/pci_read_write.cc +++ /dev/null @@ -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 , - * 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 -#include - -#include -#include -#include -#include - -#include -#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(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) - } -} diff --git a/tests/rocm_smi_test/functional/pci_read_write.h b/tests/rocm_smi_test/functional/pci_read_write.h deleted file mode 100755 index 5691424ba4..0000000000 --- a/tests/rocm_smi_test/functional/pci_read_write.h +++ /dev/null @@ -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 , - * 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_ diff --git a/tests/rocm_smi_test/functional/perf_cntr_read_write.cc b/tests/rocm_smi_test/functional/perf_cntr_read_write.cc deleted file mode 100755 index d8c51a7e19..0000000000 --- a/tests/rocm_smi_test/functional/perf_cntr_read_write.cc +++ /dev/null @@ -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 , - * 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 -#include - -#include -#include -#include -#include -#include -#include - -#include -#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 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(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(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(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(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(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(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 evt_handle = - std::shared_ptr( - 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(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(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(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(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"); - } - } -} diff --git a/tests/rocm_smi_test/functional/perf_cntr_read_write.h b/tests/rocm_smi_test/functional/perf_cntr_read_write.h deleted file mode 100755 index bfb3334210..0000000000 --- a/tests/rocm_smi_test/functional/perf_cntr_read_write.h +++ /dev/null @@ -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 , - * 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 - -#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_ diff --git a/tests/rocm_smi_test/functional/perf_determinism.cc b/tests/rocm_smi_test/functional/perf_determinism.cc deleted file mode 100644 index 9488d59a44..0000000000 --- a/tests/rocm_smi_test/functional/perf_determinism.cc +++ /dev/null @@ -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 , - * 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 -#include - -#include -#include -#include -#include -#include - -#include -#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; - } - } -} diff --git a/tests/rocm_smi_test/functional/perf_determinism.h b/tests/rocm_smi_test/functional/perf_determinism.h deleted file mode 100644 index 77c77923c2..0000000000 --- a/tests/rocm_smi_test/functional/perf_determinism.h +++ /dev/null @@ -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 , - * 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_ diff --git a/tests/rocm_smi_test/functional/perf_level_read.cc b/tests/rocm_smi_test/functional/perf_level_read.cc deleted file mode 100755 index 6ffc297ab3..0000000000 --- a/tests/rocm_smi_test/functional/perf_level_read.cc +++ /dev/null @@ -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 , - * 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 -#include - -#include -#include - -#include -#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); - } -} diff --git a/tests/rocm_smi_test/functional/perf_level_read.h b/tests/rocm_smi_test/functional/perf_level_read.h deleted file mode 100755 index ee84f3616f..0000000000 --- a/tests/rocm_smi_test/functional/perf_level_read.h +++ /dev/null @@ -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 , - * 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_ diff --git a/tests/rocm_smi_test/functional/perf_level_read_write.cc b/tests/rocm_smi_test/functional/perf_level_read_write.cc deleted file mode 100755 index 2107f46c8e..0000000000 --- a/tests/rocm_smi_test/functional/perf_level_read_write.cc +++ /dev/null @@ -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 , - * 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 -#include - -#include -#include - -#include -#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(RSMI_DEV_PERF_LEVEL_FIRST); - for (; pfl_i <= static_cast(RSMI_DEV_PERF_LEVEL_LAST); pfl_i++) { - if (pfl_i == static_cast(orig_pfl)) { - continue; - } - - IF_VERB(STANDARD) { - std::cout << "Set Performance Level to " << - GetPerfLevelStr(static_cast(pfl_i)) << - " ..." << std::endl; - } - ret = rsmi_dev_perf_level_set(dv_ind, - static_cast(pfl_i)); - if (ret == RSMI_STATUS_NOT_SUPPORTED) { - std::cout << "\t**" << GetPerfLevelStr(static_cast(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; - } - } -} diff --git a/tests/rocm_smi_test/functional/perf_level_read_write.h b/tests/rocm_smi_test/functional/perf_level_read_write.h deleted file mode 100755 index 06a3651da9..0000000000 --- a/tests/rocm_smi_test/functional/perf_level_read_write.h +++ /dev/null @@ -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 , - * 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_ diff --git a/tests/rocm_smi_test/functional/power_cap_read_write.cc b/tests/rocm_smi_test/functional/power_cap_read_write.cc deleted file mode 100755 index 98e91c9790..0000000000 --- a/tests/rocm_smi_test/functional/power_cap_read_write.cc +++ /dev/null @@ -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 , - * 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 -#include - -#include -#include -#include -#include - -#include -#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; - } - } -} diff --git a/tests/rocm_smi_test/functional/power_cap_read_write.h b/tests/rocm_smi_test/functional/power_cap_read_write.h deleted file mode 100755 index 7ed911b508..0000000000 --- a/tests/rocm_smi_test/functional/power_cap_read_write.h +++ /dev/null @@ -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 , - * 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_ diff --git a/tests/rocm_smi_test/functional/power_read.cc b/tests/rocm_smi_test/functional/power_read.cc deleted file mode 100755 index 07f4ba405f..0000000000 --- a/tests/rocm_smi_test/functional/power_read.cc +++ /dev/null @@ -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 , - * 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 -#include - -#include -#include - -#include -#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" <(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); - } - } - } -} diff --git a/tests/rocm_smi_test/functional/power_read.h b/tests/rocm_smi_test/functional/power_read.h deleted file mode 100755 index 647cfa1881..0000000000 --- a/tests/rocm_smi_test/functional/power_read.h +++ /dev/null @@ -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 , - * 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_ diff --git a/tests/rocm_smi_test/functional/power_read_write.cc b/tests/rocm_smi_test/functional/power_read_write.cc deleted file mode 100755 index c714ed7fb0..0000000000 --- a/tests/rocm_smi_test/functional/power_read_write.cc +++ /dev/null @@ -1,195 +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 , - * 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 -#include - -#include -#include -#include -#include - -#include -#include "rocm_smi/rocm_smi.h" -#include "power_read_write.h" -#include "../test_common.h" - - -TestPowerReadWrite::TestPowerReadWrite() : TestBase() { - set_title("RSMI Power Profiles Read/Write Test"); - set_description("The Power Profiles tests verify that the power profile " - "settings can be read and controlled properly."); -} - -TestPowerReadWrite::~TestPowerReadWrite(void) { -} - -void TestPowerReadWrite::SetUp(void) { - TestBase::SetUp(); - - return; -} - -void TestPowerReadWrite::DisplayTestInfo(void) { - TestBase::DisplayTestInfo(); -} - -void TestPowerReadWrite::DisplayResults(void) const { - TestBase::DisplayResults(); - return; -} - -void TestPowerReadWrite::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 char * -power_profile_string(rsmi_power_profile_preset_masks_t profile) { - switch (profile) { - case RSMI_PWR_PROF_PRST_CUSTOM_MASK: - return "CUSTOM"; - case RSMI_PWR_PROF_PRST_VIDEO_MASK: - return "VIDEO"; - case RSMI_PWR_PROF_PRST_POWER_SAVING_MASK: - return "POWER SAVING"; - case RSMI_PWR_PROF_PRST_COMPUTE_MASK: - return "COMPUTE"; - case RSMI_PWR_PROF_PRST_VR_MASK: - return "VR"; - case RSMI_PWR_PROF_PRST_3D_FULL_SCR_MASK: - return "3D FULL SCREEN"; - case RSMI_PWR_PROF_PRST_BOOTUP_DEFAULT: - return "BOOTUP DEFAULT"; - default: - return "UNKNOWN"; - } -} - -void TestPowerReadWrite::Run(void) { - rsmi_status_t ret; - rsmi_power_profile_status_t status; - - 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_profile_presets_get(dv_ind, 0, &status); - CHK_ERR_ASRT(ret) - - // Verify api support checking functionality is working - ret = rsmi_dev_power_profile_presets_get(dv_ind, 0, nullptr); - ASSERT_EQ(ret, RSMI_STATUS_INVALID_ARGS); - - IF_VERB(STANDARD) { - std::cout << "The available power profiles are:" << std::endl; - uint64_t tmp = 1; - while (tmp <= RSMI_PWR_PROF_PRST_LAST) { - if ((tmp & status.available_profiles) == tmp) { - std::cout << "\t" << - power_profile_string((rsmi_power_profile_preset_masks_t)tmp) << - std::endl; - } - tmp = tmp << 1; - } - std::cout << "The current power profile is: " << - power_profile_string(status.current) << std::endl; - } - - rsmi_power_profile_preset_masks_t orig_profile = status.current; - - // Try setting the profile to a different power profile - rsmi_bit_field_t diff_profiles; - rsmi_power_profile_preset_masks_t new_prof; - diff_profiles = status.available_profiles & (~status.current); - - if (diff_profiles & RSMI_PWR_PROF_PRST_COMPUTE_MASK) { - new_prof = RSMI_PWR_PROF_PRST_COMPUTE_MASK; - } else if (diff_profiles & RSMI_PWR_PROF_PRST_VIDEO_MASK) { - new_prof = RSMI_PWR_PROF_PRST_VIDEO_MASK; - } else if (diff_profiles & RSMI_PWR_PROF_PRST_VR_MASK) { - new_prof = RSMI_PWR_PROF_PRST_VR_MASK; - } else if (diff_profiles & RSMI_PWR_PROF_PRST_POWER_SAVING_MASK) { - new_prof = RSMI_PWR_PROF_PRST_POWER_SAVING_MASK; - } else if (diff_profiles & RSMI_PWR_PROF_PRST_3D_FULL_SCR_MASK) { - new_prof = RSMI_PWR_PROF_PRST_3D_FULL_SCR_MASK; - } else { - std::cout << - "No other non-custom power profiles to set to. Exiting." << std::endl; - return; - } - - ret = rsmi_dev_power_profile_set(dv_ind, 0, new_prof); - CHK_ERR_ASRT(ret) - - rsmi_dev_perf_level_t pfl; - ret = rsmi_dev_perf_level_get(dv_ind, &pfl); - CHK_ERR_ASRT(ret) - ASSERT_EQ(pfl, RSMI_DEV_PERF_LEVEL_MANUAL); - - ret = rsmi_dev_power_profile_presets_get(dv_ind, 0, &status); - CHK_ERR_ASRT(ret) - - ASSERT_EQ(status.current, new_prof); - - ret = rsmi_dev_perf_level_set(dv_ind, RSMI_DEV_PERF_LEVEL_AUTO); - CHK_ERR_ASRT(ret) - - ret = rsmi_dev_perf_level_get(dv_ind, &pfl); - CHK_ERR_ASRT(ret) - ASSERT_EQ(pfl, RSMI_DEV_PERF_LEVEL_AUTO); - - ret = rsmi_dev_power_profile_presets_get(dv_ind, 0, &status); - CHK_ERR_ASRT(ret) - - ASSERT_EQ(status.current, orig_profile); - } -} diff --git a/tests/rocm_smi_test/functional/power_read_write.h b/tests/rocm_smi_test/functional/power_read_write.h deleted file mode 100755 index c54b09854d..0000000000 --- a/tests/rocm_smi_test/functional/power_read_write.h +++ /dev/null @@ -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 , - * 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_WRITE_H_ -#define TESTS_ROCM_SMI_TEST_FUNCTIONAL_POWER_READ_WRITE_H_ - -#include "../test_base.h" - -class TestPowerReadWrite : public TestBase { - public: - TestPowerReadWrite(); - - // @Brief: Destructor for test case of TestPowerReadWrite - virtual ~TestPowerReadWrite(); - - // @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_WRITE_H_ diff --git a/tests/rocm_smi_test/functional/process_info_read.cc b/tests/rocm_smi_test/functional/process_info_read.cc deleted file mode 100755 index 28e905e332..0000000000 --- a/tests/rocm_smi_test/functional/process_info_read.cc +++ /dev/null @@ -1,231 +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 , - * 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 -#include - -#include -#include - -#include -#include "rocm_smi/rocm_smi.h" -#include "process_info_read.h" -#include "../test_common.h" - -TestProcInfoRead::TestProcInfoRead() : TestBase() { - set_title("RSMI Process Info Read Test"); - set_description("This test verifies that process information such as the " - "process ID, PASID, etc. can be read properly."); -} - -TestProcInfoRead::~TestProcInfoRead(void) { -} - -void TestProcInfoRead::SetUp(void) { - TestBase::SetUp(); - - return; -} - -void TestProcInfoRead::DisplayTestInfo(void) { - TestBase::DisplayTestInfo(); -} - -void TestProcInfoRead::DisplayResults(void) const { - TestBase::DisplayResults(); - return; -} - -void TestProcInfoRead::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 dumpProcess(rsmi_process_info_t *p) { - assert(p != nullptr); - std::cout << "\t** ProcessID: " << p->process_id << " "; - std::cout << "PASID: " << p->pasid << " "; - std::cout << std::endl; -} -void TestProcInfoRead::Run(void) { - rsmi_status_t err; - uint32_t num_proc_found; - uint32_t val_ui32; - rsmi_process_info_t *procs = nullptr; - - TestBase::Run(); - if (setup_failed_) { - 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) - - err = rsmi_compute_process_info_get(nullptr, &num_proc_found); - if (err != RSMI_STATUS_SUCCESS) { - if (err == RSMI_STATUS_NOT_SUPPORTED) { - IF_VERB(STANDARD) { - std::cout << "\t**Process info. read: Not supported on this machine" - << std::endl; - return; - } - } else { - CHK_ERR_ASRT(err) - } - } else { - IF_VERB(STANDARD) { - std::cout << "\t** " << std::dec << num_proc_found << - " GPU processes found" << std::endl; - } - } - - if (num_proc_found == 0) { - return; - } - - procs = new rsmi_process_info_t[num_proc_found]; - - val_ui32 = num_proc_found; - err = rsmi_compute_process_info_get(procs, &val_ui32); - if (err != RSMI_STATUS_SUCCESS) { - if (err == RSMI_STATUS_INSUFFICIENT_SIZE) { - IF_VERB(STANDARD) { - std::cout << "\t** " << val_ui32 << - " processes were read, but more became available that were unread." - << std::endl; - for (uint32_t i = 0; i < val_ui32; ++i) { - dumpProcess(&procs[i]); - } - - return; - } - } else { - CHK_ERR_ASRT(err) - } - } else { - IF_VERB(STANDARD) { - std::cout << "\t** Processes currently using GPU: " << std::endl; - for (uint32_t i = 0; i < val_ui32; ++i) { - dumpProcess(&procs[i]); - } - } - } - - // Reset to the number we actually read - num_proc_found = val_ui32; - if (num_proc_found) { - // Allocate the max we expect to get - uint32_t *dev_inds = new uint32_t[num_devices]; - uint32_t amt_allocd = num_devices; - - for (uint32_t j = 0; j < num_proc_found; j++) { - err = rsmi_compute_process_gpus_get(procs[j].process_id, dev_inds, - &amt_allocd); - if (err == RSMI_STATUS_NOT_FOUND) { - std::cout << "\t** Process " << procs[j].process_id << - " is no longer present."; - continue; - } else { - CHK_ERR_ASRT(err); - ASSERT_LE(amt_allocd, num_devices); - } - std::cout << "\t** Process " << procs[j].process_id << - " is using devices with indices: "; - uint32_t i; - if (amt_allocd > 0) { - for (i = 0; i < amt_allocd - 1; ++i) { - std::cout << dev_inds[i] << ", "; - } - std::cout << dev_inds[i]; - } - std::cout << std::endl; - // Reset amt_allocd back to the amount acutally allocated - amt_allocd = num_devices; - } - - delete []dev_inds; - - rsmi_process_info_t proc_info; - for (uint32_t j = 0; j < num_proc_found; j++) { - memset(&proc_info, 0x0, sizeof(rsmi_process_info_t)); - err = rsmi_compute_process_info_by_pid_get(procs[j].process_id, - &proc_info); - if (err == RSMI_STATUS_NOT_FOUND) { - std::cout << - "\t** WARNING: rsmi_compute_process_info_get() found process " << - procs[j].process_id << ", but subsequently, " - "rsmi_compute_process_info_by_pid_get() did not" - " find this same process." << std::endl; - } else { - CHK_ERR_ASRT(err) - ASSERT_EQ(proc_info.process_id, procs[j].process_id); - ASSERT_EQ(proc_info.pasid, procs[j].pasid); - std::cout << "\t** Process ID: " << - procs[j].process_id << " VRAM Usage: " << - proc_info.vram_usage << - " SDMA Usage: " << - proc_info.sdma_usage << - " Compute Unit Usage: " << - proc_info.cu_occupancy << - std::endl; - } - } - } - if (num_proc_found > 1) { - rsmi_process_info_t tmp_proc; - val_ui32 = 1; - err = rsmi_compute_process_info_get(&tmp_proc, &val_ui32); - - if (err != RSMI_STATUS_INSUFFICIENT_SIZE) { - std::cout << "Expected rsmi_compute_process_info_get() to tell us" - " there are more processes available, but instead go return code " << - err << std::endl; - } - } - delete []procs; -} diff --git a/tests/rocm_smi_test/functional/process_info_read.h b/tests/rocm_smi_test/functional/process_info_read.h deleted file mode 100755 index 78b20213ed..0000000000 --- a/tests/rocm_smi_test/functional/process_info_read.h +++ /dev/null @@ -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 , - * 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_PROCESS_INFO_READ_H_ -#define TESTS_ROCM_SMI_TEST_FUNCTIONAL_PROCESS_INFO_READ_H_ - -#include "../test_base.h" - -class TestProcInfoRead : public TestBase { - public: - TestProcInfoRead(); - - // @Brief: Destructor for test case of TestProcInfoRead - virtual ~TestProcInfoRead(); - - // @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_PROCESS_INFO_READ_H_ diff --git a/tests/rocm_smi_test/functional/sys_info_read.cc b/tests/rocm_smi_test/functional/sys_info_read.cc deleted file mode 100755 index 7a08abd4b8..0000000000 --- a/tests/rocm_smi_test/functional/sys_info_read.cc +++ /dev/null @@ -1,205 +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 , - * 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 -#include - -#include -#include - -#include -#include "rocm_smi/rocm_smi.h" -#include "sys_info_read.h" -#include "../test_common.h" -#include "../test_utils.h" - -TestSysInfoRead::TestSysInfoRead() : TestBase() { - set_title("RSMI System Info Read Test"); - set_description("This test verifies that system information such as the " - "BDFID, RSMI version, VBIOS version, etc. can be read properly."); -} - -TestSysInfoRead::~TestSysInfoRead(void) { -} - -void TestSysInfoRead::SetUp(void) { - TestBase::SetUp(); - - return; -} - -void TestSysInfoRead::DisplayTestInfo(void) { - TestBase::DisplayTestInfo(); -} - -void TestSysInfoRead::DisplayResults(void) const { - TestBase::DisplayResults(); - return; -} - -void TestSysInfoRead::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 TestSysInfoRead::Run(void) { - rsmi_status_t err; - uint64_t val_ui64; - uint32_t val_ui32; - char buffer[80]; - rsmi_version_t ver = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, nullptr}; - - 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_vbios_version_get(i, buffer, 80); - - if (err != RSMI_STATUS_SUCCESS) { - if (err == RSMI_STATUS_FILE_ERROR) { - IF_VERB(STANDARD) { - std::cout << "\t**VBIOS read: Not supported on this machine" - << std::endl; - } - // Verify api support checking functionality is working - err = rsmi_dev_vbios_version_get(i, nullptr, 80); - ASSERT_EQ(err, RSMI_STATUS_NOT_SUPPORTED); - } else { - // Verify api support checking functionality is working - err = rsmi_dev_vbios_version_get(i, nullptr, 80); - ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS); - - CHK_ERR_ASRT(err) - } - } else { - IF_VERB(STANDARD) { - std::cout << "\t**VBIOS Version: " << std::hex << buffer << std::endl; - } - } - - err = rsmi_dev_pci_id_get(i, &val_ui64); - 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_topo_numa_affinity_get(i, &val_ui32); - CHK_ERR_ASRT(err) - IF_VERB(STANDARD) { - std::cout << "\t**NUMA NODE: 0x" << std::hex << val_ui32; - std::cout << " (" << std::dec << val_ui32 << ")" << std::endl; - } - // Verify api support checking functionality is working - err = rsmi_topo_numa_affinity_get(i, nullptr); - ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS); - - err = rsmi_dev_unique_id_get(i, &val_ui64); - if (err == RSMI_STATUS_NOT_SUPPORTED) { - std::cout << - "\t**rsmi_dev_unique_id() is not supported" - " on this machine" << std::endl; - // Verify api support checking functionality is working - err = rsmi_dev_unique_id_get(i, nullptr); - ASSERT_EQ(err, RSMI_STATUS_NOT_SUPPORTED); - } else { - if (err == RSMI_STATUS_SUCCESS) { - IF_VERB(STANDARD) { - std::cout << "\t**GPU Unique ID : " << std::hex << val_ui64 << - std::endl; - } - // Verify api support checking functionality is working - err = rsmi_dev_unique_id_get(i, nullptr); - ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS); - } else { - std::cout << "rsmi_dev_unique_id_get() failed with error " << - err << std::endl; - } - } - - err = rsmi_version_get(&ver); - CHK_ERR_ASRT(err) - - ASSERT_TRUE(ver.major != 0xFFFFFFFF && ver.minor != 0xFFFFFFFF && - ver.patch != 0xFFFFFFFF && ver.build != nullptr); - IF_VERB(STANDARD) { - std::cout << "\t**RocM SMI Library version: " << ver.major << "." << - ver.minor << "." << ver.patch << " (" << ver.build << ")" << std::endl; - } - - std::cout << std::setbase(10); - for (int x = RSMI_FW_BLOCK_FIRST; x <= RSMI_FW_BLOCK_LAST; ++x) { - rsmi_fw_block_t block = static_cast(x); - err = rsmi_dev_firmware_version_get(i, block, &val_ui64); - if (err == RSMI_STATUS_NOT_SUPPORTED) { - std::cout << "\t**No FW block " << NameFromFWEnum(block) << - " available on this system" << std::endl; - - // Verify api support checking functionality is working - err = rsmi_dev_firmware_version_get(i, block, nullptr); - ASSERT_EQ(err, RSMI_STATUS_NOT_SUPPORTED); - continue; - } - CHK_ERR_ASRT(err) - IF_VERB(STANDARD) { - std::cout << "\t**FW VERSION for " << NameFromFWEnum(block) << - ": " << val_ui64 << std::endl; - } - // Verify api support checking functionality is working - err = rsmi_dev_firmware_version_get(i, block, nullptr); - ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS); - } - } -} diff --git a/tests/rocm_smi_test/functional/sys_info_read.h b/tests/rocm_smi_test/functional/sys_info_read.h deleted file mode 100755 index 847256a333..0000000000 --- a/tests/rocm_smi_test/functional/sys_info_read.h +++ /dev/null @@ -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 , - * 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_SYS_INFO_READ_H_ -#define TESTS_ROCM_SMI_TEST_FUNCTIONAL_SYS_INFO_READ_H_ - -#include "../test_base.h" - -class TestSysInfoRead : public TestBase { - public: - TestSysInfoRead(); - - // @Brief: Destructor for test case of TestSysInfoRead - virtual ~TestSysInfoRead(); - - // @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_SYS_INFO_READ_H_ diff --git a/tests/rocm_smi_test/functional/temp_read.cc b/tests/rocm_smi_test/functional/temp_read.cc deleted file mode 100755 index ce1d25d9ef..0000000000 --- a/tests/rocm_smi_test/functional/temp_read.cc +++ /dev/null @@ -1,170 +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 , - * 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 -#include - -#include -#include -#include - -#include -#include "rocm_smi/rocm_smi.h" -#include "temp_read.h" -#include "../test_common.h" - - -static const std::map kTempSensorNameMap = { - {RSMI_TEMP_TYPE_MEMORY, "Memory"}, - {RSMI_TEMP_TYPE_JUNCTION, "Junction"}, - {RSMI_TEMP_TYPE_EDGE, "Edge"}, - {RSMI_TEMP_TYPE_HBM_0, "HBM_0"}, - {RSMI_TEMP_TYPE_HBM_1, "HBM_1"}, - {RSMI_TEMP_TYPE_HBM_2, "HBM_2"}, - {RSMI_TEMP_TYPE_HBM_3, "HBM_3"}, -}; -TestTempRead::TestTempRead() : TestBase() { - set_title("RSMI Temp Read Test"); - set_description("The Temperature Read tests verifies that the temperature " - "monitors can be read properly."); -} - -TestTempRead::~TestTempRead(void) { -} - -void TestTempRead::SetUp(void) { - TestBase::SetUp(); - - return; -} - -void TestTempRead::DisplayTestInfo(void) { - TestBase::DisplayTestInfo(); -} - -void TestTempRead::DisplayResults(void) const { - TestBase::DisplayResults(); - return; -} - -void TestTempRead::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 TestTempRead::Run(void) { - rsmi_status_t err; - int64_t val_i64; - - TestBase::Run(); - if (setup_failed_) { - std::cout << "** SetUp Failed for this test. Skipping.**" << std::endl; - return; - } - - uint32_t type; - for (uint32_t x = 0; x < num_iterations(); ++x) { - for (uint32_t i = 0; i < num_monitor_devs(); ++i) { - PrintDeviceHeader(i); - - auto print_temp_metric = [&](rsmi_temperature_metric_t met, - std::string label) { - err = rsmi_dev_temp_metric_get(i, type, met, &val_i64); - - if (err != RSMI_STATUS_SUCCESS) { - if (err == RSMI_STATUS_NOT_SUPPORTED) { - IF_VERB(STANDARD) { - std::cout << "\t**" << label << ": " << - "Not supported on this machine" << std::endl; - } - - // Verify api support checking functionality is working - err = rsmi_dev_temp_metric_get(i, type, met, nullptr); - ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS); - return; - } else { - CHK_ERR_ASRT(err) - } - } - // Verify api support checking functionality is working - err = rsmi_dev_temp_metric_get(i, type, met, nullptr); - ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS); - - IF_VERB(STANDARD) { - std::cout << "\t**" << label << ": " << val_i64/1000 << - "C" << std::endl; - } - }; - for (type = RSMI_TEMP_TYPE_FIRST; type <= RSMI_TEMP_TYPE_LAST; ++type) { - IF_VERB(STANDARD) { - std::cout << "\t** **********" << kTempSensorNameMap.at(type) << - " Temperatures **********" << std::endl; - } - print_temp_metric(RSMI_TEMP_CURRENT, "Current Temp."); - print_temp_metric(RSMI_TEMP_MAX, "Temperature max value"); - print_temp_metric(RSMI_TEMP_MIN, "Temperature min value"); - print_temp_metric(RSMI_TEMP_MAX_HYST, - "Temperature hysteresis value for max limit"); - print_temp_metric(RSMI_TEMP_MIN_HYST, - "Temperature hysteresis value for min limit"); - print_temp_metric(RSMI_TEMP_CRITICAL, "Temperature critical max value"); - print_temp_metric(RSMI_TEMP_CRITICAL_HYST, - "Temperature hysteresis value for critical limit"); - print_temp_metric(RSMI_TEMP_EMERGENCY, - "Temperature emergency max value"); - print_temp_metric(RSMI_TEMP_EMERGENCY_HYST, - "Temperature hysteresis value for emergency limit"); - print_temp_metric(RSMI_TEMP_CRIT_MIN, "Temperature critical min value"); - print_temp_metric(RSMI_TEMP_CRIT_MIN_HYST, - "Temperature hysteresis value for critical min value"); - print_temp_metric(RSMI_TEMP_OFFSET, "Temperature offset"); - print_temp_metric(RSMI_TEMP_LOWEST, "Historical minimum temperature"); - print_temp_metric(RSMI_TEMP_HIGHEST, "Historical maximum temperature"); - } - } - } // x -} diff --git a/tests/rocm_smi_test/functional/temp_read.h b/tests/rocm_smi_test/functional/temp_read.h deleted file mode 100755 index 7dd4d9945c..0000000000 --- a/tests/rocm_smi_test/functional/temp_read.h +++ /dev/null @@ -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 , - * 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_TEMP_READ_H_ -#define TESTS_ROCM_SMI_TEST_FUNCTIONAL_TEMP_READ_H_ - -#include "../test_base.h" - -class TestTempRead : public TestBase { - public: - TestTempRead(); - - // @Brief: Destructor for test case of TestTempRead - virtual ~TestTempRead(); - - // @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_TEMP_READ_H_ diff --git a/tests/rocm_smi_test/functional/version_read.cc b/tests/rocm_smi_test/functional/version_read.cc deleted file mode 100755 index 938b8c41e2..0000000000 --- a/tests/rocm_smi_test/functional/version_read.cc +++ /dev/null @@ -1,126 +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 , - * 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 -#include - -#include -#include - -#include -#include "rocm_smi/rocm_smi.h" -#include "version_read.h" -#include "../test_common.h" - -TestVersionRead::TestVersionRead() : TestBase() { - set_title("RSMI Version Read Test"); - set_description("The Version Read tests verifies that the RSMI library " - "version can be read properly."); -} - -TestVersionRead::~TestVersionRead(void) { -} - -void TestVersionRead::SetUp(void) { - TestBase::SetUp(); - - return; -} - -void TestVersionRead::DisplayTestInfo(void) { - TestBase::DisplayTestInfo(); -} - -void TestVersionRead::DisplayResults(void) const { - TestBase::DisplayResults(); - return; -} - -void TestVersionRead::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 kVerMaxStrLen = 80; - -static const std::map - kComponentNameMap = { - {RSMI_SW_COMP_DRIVER, "Driver Version"}, -}; - -void TestVersionRead::Run(void) { - rsmi_status_t err; - rsmi_version_t ver = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, nullptr}; - - TestBase::Run(); - if (setup_failed_) { - std::cout << "** SetUp Failed for this test. Skipping.**" << std::endl; - return; - } - - err = rsmi_version_get(&ver); - CHK_ERR_ASRT(err) - - ASSERT_TRUE(ver.major != 0xFFFFFFFF && ver.minor != 0xFFFFFFFF && - ver.patch != 0xFFFFFFFF && ver.build != nullptr); - IF_VERB(STANDARD) { - std::cout << "\t**RocM SMI Library version: " << ver.major << "." << - ver.minor << "." << ver.patch << " (" << ver.build << ")" << std::endl; - } - - char ver_str[kVerMaxStrLen]; - - for (uint32_t cmp = RSMI_SW_COMP_FIRST; cmp <= RSMI_SW_COMP_LAST; ++cmp) { - err = rsmi_version_str_get(static_cast(cmp), - ver_str, kVerMaxStrLen); - CHK_ERR_ASRT(err) - - IF_VERB(STANDARD) { - std::cout << "\t**" << kComponentNameMap.at(cmp) << ": " << - ver_str << std::endl; - } - } -} diff --git a/tests/rocm_smi_test/functional/version_read.h b/tests/rocm_smi_test/functional/version_read.h deleted file mode 100755 index 26f9d7f724..0000000000 --- a/tests/rocm_smi_test/functional/version_read.h +++ /dev/null @@ -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 , - * 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_VERSION_READ_H_ -#define TESTS_ROCM_SMI_TEST_FUNCTIONAL_VERSION_READ_H_ - -#include "../test_base.h" - -class TestVersionRead : public TestBase { - public: - TestVersionRead(); - - // @Brief: Destructor for test case of TestVersionRead - virtual ~TestVersionRead(); - - // @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_VERSION_READ_H_ diff --git a/tests/rocm_smi_test/functional/volt_freq_curv_read.cc b/tests/rocm_smi_test/functional/volt_freq_curv_read.cc deleted file mode 100755 index 18cd44d13d..0000000000 --- a/tests/rocm_smi_test/functional/volt_freq_curv_read.cc +++ /dev/null @@ -1,197 +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 , - * 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 -#include - -#include -#include - -#include -#include "rocm_smi/rocm_smi.h" -#include "volt_freq_curv_read.h" -#include "../test_common.h" - -TestVoltCurvRead::TestVoltCurvRead() : TestBase() { - set_title("RSMI Voltage-Frequency Curve Read Test"); - set_description("The Voltage-Frequency Read tests verifies that the voltage" - " frequency curve information can be read properly."); -} - -TestVoltCurvRead::~TestVoltCurvRead(void) { -} - -void TestVoltCurvRead::SetUp(void) { - TestBase::SetUp(); - - return; -} - -void TestVoltCurvRead::DisplayTestInfo(void) { - TestBase::DisplayTestInfo(); -} - -void TestVoltCurvRead::DisplayResults(void) const { - TestBase::DisplayResults(); - return; -} - -void TestVoltCurvRead::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 pt_rng_Mhz(std::string title, rsmi_range *r) { - assert(r != nullptr); - - std::cout << title << std::endl; - std::cout << "\t\t** " << r->lower_bound/1000000 << " to " << - r->upper_bound/1000000 << " MHz" << std::endl; -} - -static void pt_rng_mV(std::string title, rsmi_range *r) { - assert(r != nullptr); - - std::cout << title << std::endl; - std::cout << "\t\t** " << r->lower_bound << " to " << r->upper_bound << - " mV" << std::endl; -} - -static void print_pnt(rsmi_od_vddc_point_t *pt) { - std::cout << "\t\t** Frequency: " << pt->frequency/1000000 << "MHz" << - std::endl; - std::cout << "\t\t** Voltage: " << pt->voltage << "mV" << std::endl; -} -static void pt_vddc_curve(rsmi_od_volt_curve *c) { - assert(c != nullptr); - - for (uint32_t i = 0; i < RSMI_NUM_VOLTAGE_CURVE_POINTS; ++i) { - print_pnt(&c->vc_points[i]); - } -} - -static void print_rsmi_od_volt_freq_data_t(rsmi_od_volt_freq_data_t *odv) { - assert(odv != nullptr); - - std::cout.setf(std::ios::dec, std::ios::basefield); - pt_rng_Mhz("\t\tCurrent SCLK frequency range:", &odv->curr_sclk_range); - pt_rng_Mhz("\t\tCurrent MCLK frequency range:", &odv->curr_mclk_range); - pt_rng_Mhz("\t\tMin/Max Possible SCLK frequency range:", - &odv->sclk_freq_limits); - pt_rng_Mhz("\t\tMin/Max Possible MCLK frequency range:", - &odv->mclk_freq_limits); - - std::cout << "\t\tCurrent Freq/Volt. curve:" << std::endl; - pt_vddc_curve(&odv->curve); - - std::cout << "\tNumber of Freq./Volt. regions: " << - odv->num_regions << std::endl; -} - -static void print_odv_region(rsmi_freq_volt_region_t *region) { - pt_rng_Mhz("\t\tFrequency range:", ®ion->freq_range); - pt_rng_mV("\t\tVoltage range:", ®ion->volt_range); -} - -static void print_rsmi_od_volt_freq_regions(uint32_t num_regions, - rsmi_freq_volt_region_t *regions) { - for (uint32_t i = 0; i < num_regions; ++i) { - std::cout << "\tRegion " << i << ":" << std::endl; - print_odv_region(®ions[i]); - } -} - -void TestVoltCurvRead::Run(void) { - rsmi_status_t err; - rsmi_od_volt_freq_data_t odv; - - 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**rsmi_dev_od_volt_info_get: Not supported on this machine" - << std::endl; - } - // Verify api support checking functionality is working - err = rsmi_dev_od_volt_info_get(i, nullptr); - ASSERT_EQ(err, RSMI_STATUS_NOT_SUPPORTED); - } else { - CHK_ERR_ASRT(err) - // Verify api support checking functionality is working - err = rsmi_dev_od_volt_info_get(i, nullptr); - ASSERT_EQ(err, RSMI_STATUS_NOT_SUPPORTED); - } - - if (err == RSMI_STATUS_SUCCESS) { - std::cout << "\t**Frequency-voltage curve data:" << std::endl; - print_rsmi_od_volt_freq_data_t(&odv); - - rsmi_freq_volt_region_t *regions; - uint32_t num_regions; - regions = new rsmi_freq_volt_region_t[odv.num_regions]; - ASSERT_TRUE(regions != nullptr); - - num_regions = odv.num_regions; - err = rsmi_dev_od_volt_curve_regions_get(i, &num_regions, regions); - CHK_ERR_ASRT(err) - ASSERT_TRUE(num_regions == odv.num_regions); - - std::cout << "\t**Frequency-voltage curve regions:" << std::endl; - print_rsmi_od_volt_freq_regions(num_regions, regions); - - delete []regions; - } - } -} diff --git a/tests/rocm_smi_test/functional/volt_freq_curv_read.h b/tests/rocm_smi_test/functional/volt_freq_curv_read.h deleted file mode 100755 index 34f917dd33..0000000000 --- a/tests/rocm_smi_test/functional/volt_freq_curv_read.h +++ /dev/null @@ -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 , - * 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_VOLT_FREQ_CURV_READ_H_ -#define TESTS_ROCM_SMI_TEST_FUNCTIONAL_VOLT_FREQ_CURV_READ_H_ - -#include "../test_base.h" - -class TestVoltCurvRead : public TestBase { - public: - TestVoltCurvRead(); - - // @Brief: Destructor for test case of TestVoltCurvRead - virtual ~TestVoltCurvRead(); - - // @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_VOLT_FREQ_CURV_READ_H_ diff --git a/tests/rocm_smi_test/functional/volt_read.cc b/tests/rocm_smi_test/functional/volt_read.cc deleted file mode 100644 index ccb6c43a8e..0000000000 --- a/tests/rocm_smi_test/functional/volt_read.cc +++ /dev/null @@ -1,151 +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 , - * 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 -#include - -#include -#include -#include - -#include -#include "rocm_smi/rocm_smi.h" -#include "volt_read.h" -#include "../test_common.h" - - -TestVoltRead::TestVoltRead() : TestBase() { - set_title("RSMI Volt Read Test"); - set_description("The Voltage Read tests verifies that the voltage " - "monitors can be read properly."); -} - -TestVoltRead::~TestVoltRead(void) { -} - -void TestVoltRead::SetUp(void) { - TestBase::SetUp(); - - return; -} - -void TestVoltRead::DisplayTestInfo(void) { - TestBase::DisplayTestInfo(); -} - -void TestVoltRead::DisplayResults(void) const { - TestBase::DisplayResults(); - return; -} - -void TestVoltRead::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 TestVoltRead::Run(void) { - rsmi_status_t err; - int64_t val_i64; - - TestBase::Run(); - if (setup_failed_) { - std::cout << "** SetUp Failed for this test. Skipping.**" << std::endl; - return; - } - - rsmi_voltage_type_t type = RSMI_VOLT_TYPE_VDDGFX; - - for (uint32_t i = 0; i < num_monitor_devs(); ++i) { - PrintDeviceHeader(i); - - auto print_volt_metric = [&](rsmi_voltage_metric_t met, - std::string label) { - err = rsmi_dev_volt_metric_get(i, type, met, &val_i64); - - if (err != RSMI_STATUS_SUCCESS) { - if (err == RSMI_STATUS_NOT_SUPPORTED) { - IF_VERB(STANDARD) { - std::cout << "\t**" << label << ": " << - "Not supported on this machine" << std::endl; - - // Verify api support checking functionality is working - err = rsmi_dev_volt_metric_get(i, type, met, nullptr); - ASSERT_EQ(err, RSMI_STATUS_NOT_SUPPORTED); - return; - } - } else { - CHK_ERR_ASRT(err) - } - } - // Verify api support checking functionality is working - err = rsmi_dev_volt_metric_get(i, type, met, nullptr); - ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS); - - IF_VERB(STANDARD) { - std::cout << "\t**" << label << ": " << val_i64 << - "mV" << std::endl; - } - }; - for (uint32_t i = RSMI_VOLT_TYPE_FIRST; i <= RSMI_VOLT_TYPE_LAST; ++i) { - IF_VERB(STANDARD) { - std::cout << "\t** **********" << - GetVoltSensorNameStr(static_cast(i)) << - " Voltage **********" << std::endl; - } - print_volt_metric(RSMI_VOLT_CURRENT, "Current Voltage"); - print_volt_metric(RSMI_VOLT_MAX, "Voltage max value"); - print_volt_metric(RSMI_VOLT_MIN, "Voltage min value"); - print_volt_metric(RSMI_VOLT_MAX_CRIT, - "Voltage critical max value"); - print_volt_metric(RSMI_VOLT_MIN_CRIT, - "Voltage critical min value"); - print_volt_metric(RSMI_VOLT_AVERAGE, "Voltage critical max value"); - print_volt_metric(RSMI_VOLT_LOWEST, "Historical minimum temperature"); - print_volt_metric(RSMI_VOLT_HIGHEST, "Historical maximum temperature"); - } - } -} diff --git a/tests/rocm_smi_test/functional/volt_read.h b/tests/rocm_smi_test/functional/volt_read.h deleted file mode 100644 index 342e95dd81..0000000000 --- a/tests/rocm_smi_test/functional/volt_read.h +++ /dev/null @@ -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 , - * 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_VOLT_READ_H_ -#define TESTS_ROCM_SMI_TEST_FUNCTIONAL_VOLT_READ_H_ - -#include "../test_base.h" - -class TestVoltRead : public TestBase { - public: - TestVoltRead(); - - // @Brief: Destructor for test case of TestVOltRead - virtual ~TestVoltRead(); - - // @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_VOLT_READ_H_ diff --git a/tests/rocm_smi_test/functional/xgmi_read_write.cc b/tests/rocm_smi_test/functional/xgmi_read_write.cc deleted file mode 100755 index b9002b0112..0000000000 --- a/tests/rocm_smi_test/functional/xgmi_read_write.cc +++ /dev/null @@ -1,154 +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 , - * 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 -#include - -#include - -#include -#include "rocm_smi/rocm_smi.h" -#include "xgmi_read_write.h" -#include "../test_common.h" - -TestXGMIReadWrite::TestXGMIReadWrite() : TestBase() { - set_title("RSMI XGMI Read/Write Test"); - set_description("This test verifies that XGMI error counts can be read" - " properly, and that the count can be reset."); -} - -TestXGMIReadWrite::~TestXGMIReadWrite(void) { -} - -void TestXGMIReadWrite::SetUp(void) { - TestBase::SetUp(); - - return; -} - -void TestXGMIReadWrite::DisplayTestInfo(void) { - TestBase::DisplayTestInfo(); -} - -void TestXGMIReadWrite::DisplayResults(void) const { - TestBase::DisplayResults(); - return; -} - -void TestXGMIReadWrite::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 TestXGMIReadWrite::Run(void) { - rsmi_status_t err; - rsmi_xgmi_status_t err_stat; - uint64_t hive_id; - - 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); - - err = rsmi_dev_xgmi_hive_id_get(dv_ind, &hive_id); - if (err == RSMI_STATUS_NOT_SUPPORTED) { - std::cout << - "\t**rsmi_dev_xgmi_hive_id_get() is not supported" - " on this machine" << std::endl; - // Verify api support checking functionality is working - err = rsmi_dev_xgmi_hive_id_get(dv_ind, nullptr); - ASSERT_EQ(err, RSMI_STATUS_NOT_SUPPORTED); - - continue; - } else { - CHK_ERR_ASRT(err) - IF_VERB(STANDARD) { - std::cout << "\t**XGMI Hive ID : " << std::hex << hive_id << - std::endl; - } - // Verify api support checking functionality is working - err = rsmi_dev_xgmi_hive_id_get(dv_ind, nullptr); - ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS); - } - - err = rsmi_dev_xgmi_error_status(dv_ind, &err_stat); - - if (err == RSMI_STATUS_NOT_SUPPORTED) { - IF_VERB(STANDARD) { - std::cout << "\t**XGMI Error Status: Not supported on this machine" - << std::endl; - } - // Verify api support checking functionality is working - err = rsmi_dev_xgmi_error_status(dv_ind, nullptr); - ASSERT_EQ(err, RSMI_STATUS_NOT_SUPPORTED); - - continue; - } - CHK_ERR_ASRT(err) - IF_VERB(STANDARD) { - std::cout << "\t**XGMI Error Status: " << - static_cast(err_stat) << std::endl; - } - // Verify api support checking functionality is working - err = rsmi_dev_xgmi_error_status(dv_ind, nullptr); - ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS); - - // TODO(cfree) We need to find a way to generate xgmi errors so this - // test won't be meaningless - err = rsmi_dev_xgmi_error_reset(dv_ind); - CHK_ERR_ASRT(err) - IF_VERB(STANDARD) { - std::cout << "\t**Successfully reset XGMI Error Status: " << std::endl; - } - } -} diff --git a/tests/rocm_smi_test/functional/xgmi_read_write.h b/tests/rocm_smi_test/functional/xgmi_read_write.h deleted file mode 100755 index 0aca5496ee..0000000000 --- a/tests/rocm_smi_test/functional/xgmi_read_write.h +++ /dev/null @@ -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 , - * 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_XGMI_READ_WRITE_H_ -#define TESTS_ROCM_SMI_TEST_FUNCTIONAL_XGMI_READ_WRITE_H_ - -#include "../test_base.h" - -class TestXGMIReadWrite : public TestBase { - public: - TestXGMIReadWrite(); - - // @Brief: Destructor for test case of TestXGMIReadWrite - virtual ~TestXGMIReadWrite(); - - // @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_XGMI_READ_WRITE_H_ diff --git a/tests/rocm_smi_test/main.cc b/tests/rocm_smi_test/main.cc deleted file mode 100755 index 4203d573f1..0000000000 --- a/tests/rocm_smi_test/main.cc +++ /dev/null @@ -1,298 +0,0 @@ -/* - * ============================================================================= - * ROC Runtime Conformance Release License - * ============================================================================= - * The University of Illinois/NCSA - * Open Source License (NCSA) - * - * Copyright (c) 2018, 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 , - * 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 -#include -#include -#include - -#include "rocm_smi/rocm_smi.h" -#include -#include "test_common.h" -#include "test_base.h" -#include "functional/fan_read.h" -#include "functional/fan_read_write.h" -#include "functional/temp_read.h" -#include "functional/volt_read.h" -#include "functional/volt_freq_curv_read.h" -#include "functional/perf_level_read.h" -#include "functional/overdrive_read.h" -#include "functional/frequencies_read.h" -#include "functional/sys_info_read.h" -#include "functional/gpu_busy_read.h" -#include "functional/power_read.h" -#include "functional/overdrive_read_write.h" -#include "functional/perf_level_read_write.h" -#include "functional/frequencies_read_write.h" -#include "functional/pci_read_write.h" -#include "functional/power_read_write.h" -#include "functional/power_cap_read_write.h" -#include "functional/version_read.h" -#include "functional/err_cnt_read.h" -#include "functional/mem_util_read.h" -#include "functional/id_info_read.h" -#include "functional/perf_cntr_read_write.h" -#include "functional/process_info_read.h" -#include "functional/xgmi_read_write.h" -#include "functional/mem_page_info_read.h" -#include "functional/api_support_read.h" -#include "functional/mutual_exclusion.h" -#include "functional/evt_notif_read_write.h" -#include "functional/init_shutdown_refcount.h" -#include "functional/hw_topology_read.h" -#include "functional/gpu_metrics_read.h" -#include "functional/metrics_counter_read.h" -#include "functional/perf_determinism.h" - -static RSMITstGlobals *sRSMIGlvalues = nullptr; - -static void SetFlags(TestBase *test) { - assert(sRSMIGlvalues != nullptr); - - test->set_verbosity(sRSMIGlvalues->verbosity); - test->set_dont_fail(sRSMIGlvalues->dont_fail); - test->set_init_options(sRSMIGlvalues->init_options); - test->set_num_iterations(sRSMIGlvalues->num_iterations); -} - -static void RunCustomTestProlog(TestBase *test) { - SetFlags(test); - - if (sRSMIGlvalues->verbosity >= TestBase::VERBOSE_STANDARD) { - test->DisplayTestInfo(); - } - test->SetUp(); - test->Run(); - return; -} -static void RunCustomTestEpilog(TestBase *tst) { - if (sRSMIGlvalues->verbosity >= TestBase::VERBOSE_STANDARD) { - tst->DisplayResults(); - } - tst->Close(); - return; -} - -// If the test case one big test, you should use RunGenericTest() -// to run the test case. OTOH, if the test case consists of multiple -// functions to be run as separate tests, follow this pattern: -// * RunCustomTestProlog(test) // Run() should contain minimal code -// * -// * RunCustomTestEpilog(test) -static void RunGenericTest(TestBase *test) { - RunCustomTestProlog(test); - RunCustomTestEpilog(test); - return; -} - -// TEST ENTRY TEMPLATE: -// TEST(rocrtst, Perf_) { -// ; -// -// // Copy and modify implementation of RunGenericTest() if you need to deviate -// // from the standard pattern implemented there. -// RunGenericTest(&); -// } -TEST(rsmitstReadOnly, TestVersionRead) { - TestVersionRead tst; - RunGenericTest(&tst); -} -TEST(rsmitstReadOnly, FanRead) { - TestFanRead tst; - RunGenericTest(&tst); -} -TEST(rsmitstReadWrite, FanReadWrite) { - TestFanReadWrite tst; - RunGenericTest(&tst); -} -TEST(rsmitstReadOnly, TempRead) { - TestTempRead tst; - RunGenericTest(&tst); -} -TEST(rsmitstReadOnly, VoltRead) { - TestVoltRead tst; - RunGenericTest(&tst); -} -TEST(rsmitstReadOnly, TestVoltCurvRead) { - TestVoltCurvRead tst; - RunGenericTest(&tst); -} -TEST(rsmitstReadOnly, TestPerfLevelRead) { - TestPerfLevelRead tst; - RunGenericTest(&tst); -} -TEST(rsmitstReadWrite, TestPerfLevelReadWrite) { - TestPerfLevelReadWrite tst; - RunGenericTest(&tst); -} -TEST(rsmitstReadOnly, TestOverdriveRead) { - TestOverdriveRead tst; - RunGenericTest(&tst); -} -TEST(rsmitstReadWrite, TestOverdriveReadWrite) { - TestOverdriveReadWrite tst; - RunGenericTest(&tst); -} -TEST(rsmitstReadOnly, TestFrequenciesRead) { - TestFrequenciesRead tst; - RunGenericTest(&tst); -} -TEST(rsmitstReadWrite, TestFrequenciesReadWrite) { - TestFrequenciesReadWrite tst; - RunGenericTest(&tst); -} -TEST(rsmitstReadWrite, TestPciReadWrite) { - TestPciReadWrite tst; - RunGenericTest(&tst); -} -TEST(rsmitstReadOnly, TestSysInfoRead) { - TestSysInfoRead tst; - RunGenericTest(&tst); -} -TEST(rsmitstReadOnly, TestGPUBusyRead) { - TestGPUBusyRead tst; - RunGenericTest(&tst); -} -TEST(rsmitstReadOnly, TestPowerRead) { - TestPowerRead tst; - RunGenericTest(&tst); -} -TEST(rsmitstReadWrite, TestPowerReadWrite) { - TestPowerReadWrite tst; - RunGenericTest(&tst); -} -TEST(rsmitstReadWrite, TestPowerCapReadWrite) { - TestPowerCapReadWrite tst; - RunGenericTest(&tst); -} -TEST(rsmitstReadOnly, TestErrCntRead) { - TestErrCntRead tst; - RunGenericTest(&tst); -} -TEST(rsmitstReadOnly, TestMemUtilRead) { - TestMemUtilRead tst; - RunGenericTest(&tst); -} -TEST(rsmitstReadOnly, TestIdInfoRead) { - TestIdInfoRead tst; - RunGenericTest(&tst); -} -TEST(rsmitstReadWrite, TestPerfCntrReadWrite) { - TestPerfCntrReadWrite tst; - RunGenericTest(&tst); -} -TEST(rsmitstReadOnly, TestProcInfoRead) { - TestProcInfoRead tst; - RunGenericTest(&tst); -} -TEST(rsmitstReadOnly, TestHWTopologyRead) { - TestHWTopologyRead tst; - RunGenericTest(&tst); -} -TEST(rsmitstReadOnly, TestGpuMetricsRead) { - TestGpuMetricsRead tst; - RunGenericTest(&tst); -} -TEST(rsmitstReadOnly, TestMetricsCounterRead) { - TestMetricsCounterRead tst; - RunGenericTest(&tst); -} -TEST(rsmitstReadWrite, TestPerfDeterminism) { - TestPerfDeterminism tst; - RunGenericTest(&tst); -} -TEST(rsmitstReadWrite, TestXGMIReadWrite) { - TestXGMIReadWrite tst; - RunGenericTest(&tst); -} -TEST(rsmitstReadOnly, TestMemPageInfoRead) { - TestMemPageInfoRead tst; - RunGenericTest(&tst); -} -TEST(rsmitstReadOnly, TestAPISupportRead) { - TestAPISupportRead tst; - RunGenericTest(&tst); -} -TEST(rsmitstReadOnly, TestMutualExclusion) { - TestMutualExclusion tst; - SetFlags(&tst); - tst.DisplayTestInfo(); - tst.SetUp(); - tst.Run(); - RunCustomTestEpilog(&tst); -} -TEST(rsmitstReadWrite, TestEvtNotifReadWrite) { - TestEvtNotifReadWrite tst; - RunGenericTest(&tst); -} -TEST(rsmitstReadOnly, TestConcurrentInit) { - TestConcurrentInit tst; - SetFlags(&tst); - tst.DisplayTestInfo(); - // tst.SetUp(); // Avoid extra rsmi_init - tst.Run(); - // RunCustomTestEpilog(&tst); // Avoid extra rsmi_shut_down - tst.DisplayResults(); -} - -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - - RSMITstGlobals settings; - - // Set some default values - settings.verbosity = 1; - settings.monitor_verbosity = 1; - settings.num_iterations = 1; - settings.dont_fail = false; - settings.init_options = 0; - - if (ProcessCmdline(&settings, argc, argv)) { - return 1; - } - - sRSMIGlvalues = &settings; - return RUN_ALL_TESTS(); -} diff --git a/tests/rocm_smi_test/rsmitst.exclude b/tests/rocm_smi_test/rsmitst.exclude deleted file mode 100644 index 3de139d45f..0000000000 --- a/tests/rocm_smi_test/rsmitst.exclude +++ /dev/null @@ -1,66 +0,0 @@ -declare -A FILTER - -# FILTER is meant to be used with a negative gtest filter - -# Designate the tests to be excluded from all test runs first, -# followed by tests that should be excluded by device. - -# Permanent exclusions -# These tests are included for debugging, but are not executed in normal -# execution on any ASIC: -PERMANENT_BLACKLIST_ALL_ASICS= - -# This is the temporary blacklist for all ASICs. This is to be used when a test -# is failing consistently -TEMPORARY_BLACKLIST_ALL_ASICS= - -if [ -z $PERMANENT_BLACKLIST_ALL_ASICS -a -z $TEMPORARY_BLACKLIST_ALL_ASICS ]; then - BLACKLIST_ALL_ASICS= -else - BLACKLIST_ALL_ASICS=\ - "$PERMANENT_BLACKLIST_ALL_ASICS:"\ - "$TEMPORARY_BLACKLIST_ALL_ASICS" -fi - -# Device specific blacklists -FILTER[vega10]=\ -$BLACKLIST_ALL_ASICS - -# SWDEV-207510 -FILTER[vega20]=\ -$BLACKLIST_ALL_ASICS\ -"rsmitstReadOnly.TestFrequenciesRead:"\ -"rsmitstReadOnly.TestProcInfoRead" - -# SWDEV-207510 -FILTER[arcturus]=\ -$BLACKLIST_ALL_ASICS\ -"rsmitstReadOnly.TestFrequenciesRead:"\ -"rsmitstReadWrite.TestFrequenciesReadWrite:"\ -"rsmitstReadOnly.TestProcInfoRead" - -# SWDEV-306889 -FILTER[aldebaran]=\ -$BLACKLIST_ALL_ASICS\ -"rsmitstReadOnly.FanRead:"\ -"rsmitstReadOnly.TestVoltCurvRead:"\ -"rsmitstReadOnly.TestFrequenciesRead:"\ -"rsmitstReadWrite.FanReadWrite:"\ -"rsmitstReadWrite.TestFrequenciesReadWrite:"\ -"rsmitstReadWrite.TestPciReadWrite:"\ -"rsmitstReadWrite.TestPowerReadWrite" - -# SWDEV-319795 -FILTER[sienna_cichlid]=\ -$BLACKLIST_ALL_ASICS\ -"rsmitstReadWrite.TestPerfLevelReadWrite" - -# SWDEV-321166 -FILTER[virtualization]=\ -$BLACKLIST_ALL_ASICS\ -"rsmitstReadOnly.TestOverdriveRead:"\ -"rsmitstReadOnly.TestGPUBusyRead:"\ -"rsmitstReadWrite.FanReadWrite:"\ -"rsmitstReadWrite.TestOverdriveReadWrite:"\ -"rsmitstReadWrite.TestPowerReadWrite:"\ -"rsmitstReadWrite.TestPowerCapReadWrite" \ No newline at end of file diff --git a/tests/rocm_smi_test/test_base.cc b/tests/rocm_smi_test/test_base.cc deleted file mode 100755 index e96e2a7dbf..0000000000 --- a/tests/rocm_smi_test/test_base.cc +++ /dev/null @@ -1,215 +0,0 @@ -/* - * ============================================================================= - * ROC Runtime Conformance Release License - * ============================================================================= - * The University of Illinois/NCSA - * Open Source License (NCSA) - * - * Copyright (c) 2017, 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 , - * 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 - -#include "rocm_smi/rocm_smi.h" -#include "test_base.h" -#include "test_common.h" -#include - -static const int kOutputLineLength = 80; -static const char kLabelDelimiter[] = "####"; -static const char kDescriptionLabel[] = "TEST DESCRIPTION"; -static const char kTitleLabel[] = "TEST NAME"; -static const char kRunLabel[] = "TEST EXECUTION"; -static const char kCloseLabel[] = "TEST CLEAN UP"; -static const char kResultsLabel[] = "TEST RESULTS"; - -// This one is used outside this file -const char kSetupLabel[] = "TEST SETUP"; - -TestBase::TestBase() : setup_failed_(false), description_("") { -} -TestBase::~TestBase() { -} - -void TestBase::MakeHeaderStr(const char *inStr, - std::string *outStr) const { - assert(outStr != nullptr); - assert(inStr != nullptr); - outStr->clear(); - IF_VERB(STANDARD) { - *outStr = kLabelDelimiter; - *outStr += " "; - *outStr += inStr; - *outStr += " "; - *outStr += kLabelDelimiter; - } -} - -void TestBase::SetUp(void) { - SetUp(0); -} - -void TestBase::SetUp(uint64_t init_flags) { - std::string label; - rsmi_status_t err; - - IF_VERB(STANDARD) { - MakeHeaderStr(kSetupLabel, &label); - printf("\n\t%s\n", label.c_str()); - } - - if (init_flags) { - err = rsmi_init(init_flags); - } else { - err = rsmi_init(init_options()); - } - - if (err != RSMI_STATUS_SUCCESS) { - setup_failed_ = true; - } - ASSERT_EQ(err, RSMI_STATUS_SUCCESS); - - err = rsmi_num_monitor_devices(&num_monitor_devs_); - if (err != RSMI_STATUS_SUCCESS) { - setup_failed_ = true; - } - ASSERT_EQ(err, RSMI_STATUS_SUCCESS); - - if (num_monitor_devs_ == 0) { - IF_VERB(STANDARD) { - std::cout << "No monitor devices found on this machine." << std::endl; - std::cout << "No ROCm SMI tests can be run." << std::endl; - } - } - - return; -} - -void TestBase::PrintDeviceHeader(uint32_t dv_ind) { - rsmi_status_t err; - uint16_t val_ui16; - - IF_VERB(STANDARD) { - std::cout << "\t**Device index: " << dv_ind << std::endl; - } - err = rsmi_dev_id_get(dv_ind, &val_ui16); - CHK_ERR_ASRT(err) - IF_VERB(STANDARD) { - std::cout << "\t**Device ID: 0x" << std::hex << val_ui16 << std::endl; - } - char name[128]; - err = rsmi_dev_name_get(dv_ind, name, 128); - CHK_ERR_ASRT(err) - IF_VERB(STANDARD) { - std::cout << "\t**Device name: " << name << std::endl; - } - err = rsmi_dev_vendor_id_get(dv_ind, &val_ui16); - CHK_ERR_ASRT(err) - IF_VERB(STANDARD) { - std::cout << "\t**Device Vendor ID: 0x" << std::hex << val_ui16 << - std::endl; - } - err = rsmi_dev_subsystem_id_get(dv_ind, &val_ui16); - CHK_ERR_ASRT(err) - IF_VERB(STANDARD) { - std::cout << "\t**Subsystem ID: 0x" << std::hex << val_ui16 << std::endl; - } - err = rsmi_dev_subsystem_vendor_id_get(dv_ind, &val_ui16); - CHK_ERR_ASRT(err) - IF_VERB(STANDARD) { - std::cout << "\t**Subsystem Vendor ID: 0x" << std::hex << val_ui16 << - std::endl; - } - std::cout << std::setbase(10); -} -void TestBase::Run(void) { - std::string label; - IF_VERB(STANDARD) { - MakeHeaderStr(kRunLabel, &label); - printf("\n\t%s\n", label.c_str()); - } - ASSERT_TRUE(!setup_failed_); -} - -void TestBase::Close(void) { - std::string label; - IF_VERB(STANDARD) { - MakeHeaderStr(kCloseLabel, &label); - printf("\n\t%s\n", label.c_str()); - } - rsmi_status_t err = rsmi_shut_down(); - ASSERT_EQ(err, RSMI_STATUS_SUCCESS); -} - -void TestBase::DisplayResults(void) const { - std::string label; - IF_VERB(STANDARD) { - MakeHeaderStr(kResultsLabel, &label); - printf("\n\t%s\n", label.c_str()); - } -} - -void TestBase::DisplayTestInfo(void) { - IF_VERB(STANDARD) { - printf("#########################################" - "######################################\n"); - - std::string label; - MakeHeaderStr(kTitleLabel, &label); - printf("\n\t%s\n%s\n", label.c_str(), title().c_str()); - - if (verbosity() >= VERBOSE_STANDARD) { - MakeHeaderStr(kDescriptionLabel, &label); - printf("\n\t%s\n%s\n", label.c_str(), description().c_str()); - } - } -} - -void TestBase::set_description(std::string d) { - int le = kOutputLineLength - 4; - - description_ = d; - size_t endlptr; - - for (size_t i = le; i < description_.size(); i += le) { - endlptr = description_.find_last_of(" ", i); - description_.replace(endlptr, 1, "\n"); - i = endlptr; - } -} - diff --git a/tests/rocm_smi_test/test_base.h b/tests/rocm_smi_test/test_base.h deleted file mode 100755 index d2ced349bc..0000000000 --- a/tests/rocm_smi_test/test_base.h +++ /dev/null @@ -1,153 +0,0 @@ -/* - * ============================================================================= - * ROC Runtime Conformance Release License - * ============================================================================= - * The University of Illinois/NCSA - * Open Source License (NCSA) - * - * Copyright (c) 2018, 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 , - * 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_TEST_BASE_H_ -#define TESTS_ROCM_SMI_TEST_TEST_BASE_H_ - -#include - -class TestBase { - public: - TestBase(void); - - virtual ~TestBase(void); - - enum VerboseLevel {VERBOSE_MIN = 0, VERBOSE_STANDARD, VERBOSE_PROGRESS}; - - // @Brief: Before run the core measure codes, do something to set up - // i.e. init runtime, prepare packet... - // The init_flags option will override any flags set for the whole test - // suite - void SetUp(uint64_t init_flags); - virtual void SetUp(void); - - // @Brief: Core measurement codes executing here - virtual void Run(void); - - // @Brief: Do something clean up - virtual void Close(void); - - // @Brief: Display the results - virtual void DisplayResults(void) const; - - // @Brief: Display information about the test - virtual void DisplayTestInfo(void); - - const std::string & description(void) const {return description_;} - - void set_description(std::string d); - - void set_title(std::string name) { - title_ = name; - } - std::string title(void) const { - return title_; - } - void set_verbosity(uint32_t v) { - verbosity_ = v; - } - uint32_t verbosity(void) const { - return verbosity_; - } - void set_dont_fail(bool f) { - dont_fail_ = f; - } - bool dont_fail(void) const { - return dont_fail_; - } - void set_num_monitor_devs(uint32_t i) { - num_monitor_devs_ = i; - } - uint32_t num_monitor_devs(void) const { - return num_monitor_devs_; - } - void set_init_options(uint64_t x) { - init_options_ = x; - } - uint64_t init_options(void) const { - return init_options_; - } - void set_num_iterations(uint32_t x) { - num_iterations_ = x; - } - uint32_t num_iterations(void) const { - return num_iterations_; - } - - protected: - void MakeHeaderStr(const char *inStr, std::string *outStr) const; - void PrintDeviceHeader(uint32_t dv_ind); - bool setup_failed_; ///< Record that setup failed to return ierr in Run - uint32_t num_monitor_devs_; ///< Number of monitor devices found - - private: - std::string description_; - std::string title_; ///< Displayed title of test - uint32_t verbosity_; ///< How much additional output to produce - bool dont_fail_; ///< Don't quit test on individual failure if true - uint64_t init_options_; ///< rsmi initialization options - uint32_t num_iterations_; -}; - -#define IF_VERB(VB) if (verbosity() && verbosity() >= (TestBase::VERBOSE_##VB)) -#define IF_NVERB(VB) if (verbosity() < (TestBase::VERBOSE_##VB)) - -// Macros to be used within TestBase classes -#define CHK_ERR_ASRT(RET) { \ - if (dont_fail() && ((RET) != RSMI_STATUS_SUCCESS)) { \ - std::cout << std::endl << "\t===> TEST FAILURE." << std::endl; \ - DISPLAY_RSMI_ERR(RET); \ - std::cout << \ - "\t===> Abort is over-ridden due to dont_fail command line option." \ - << std::endl; \ - return; \ - } else { \ - ASSERT_EQ(RSMI_STATUS_SUCCESS, (RET)); \ - } \ -} - -void MakeHeaderStr(const char *inStr, std::string *outStr); -extern const char kSetupLabel[]; - -#endif // TESTS_ROCM_SMI_TEST_TEST_BASE_H_ diff --git a/tests/rocm_smi_test/test_common.cc b/tests/rocm_smi_test/test_common.cc deleted file mode 100755 index c489b70d41..0000000000 --- a/tests/rocm_smi_test/test_common.cc +++ /dev/null @@ -1,314 +0,0 @@ -/* - * ============================================================================= - * ROC Runtime Conformance Release License - * ============================================================================= - * The University of Illinois/NCSA - * Open Source License (NCSA) - * - * Copyright (c) 2017, 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 , - * 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 -#include -#include - -#include -#include -#include - -#include "test_base.h" -#include "test_common.h" -#include "rocm_smi/rocm_smi.h" - -static const std::map - kDevPerfLvlNameMap = { - {RSMI_DEV_PERF_LEVEL_AUTO, "RSMI_DEV_PERF_LEVEL_AUTO"}, - {RSMI_DEV_PERF_LEVEL_LOW, "RSMI_DEV_PERF_LEVEL_LOW"}, - {RSMI_DEV_PERF_LEVEL_HIGH, "RSMI_DEV_PERF_LEVEL_HIGH"}, - {RSMI_DEV_PERF_LEVEL_MANUAL, "RSMI_DEV_PERF_LEVEL_MANUAL"}, - {RSMI_DEV_PERF_LEVEL_STABLE_STD, "RSMI_DEV_PERF_LEVEL_STABLE_STD"}, - {RSMI_DEV_PERF_LEVEL_STABLE_PEAK, "RSMI_DEV_PERF_LEVEL_STABLE_PEAK"}, - {RSMI_DEV_PERF_LEVEL_STABLE_MIN_MCLK, - "RSMI_DEV_PERF_LEVEL_STABLE_MIN_MCLK"}, - {RSMI_DEV_PERF_LEVEL_STABLE_MIN_SCLK, - "RSMI_DEV_PERF_LEVEL_STABLE_MIN_SCLK"}, - {RSMI_DEV_PERF_LEVEL_DETERMINISM, "RSMI_DEV_PERF_LEVEL_DETERMINISM"}, - - {RSMI_DEV_PERF_LEVEL_UNKNOWN, "RSMI_DEV_PERF_LEVEL_UNKNOWN"}, -}; -// If the assert below fails, the map above needs to be updated to match -// rsmi_dev_perf_level_t. -static_assert(RSMI_DEV_PERF_LEVEL_LAST == RSMI_DEV_PERF_LEVEL_DETERMINISM, - "kDevPerfLvlNameMap needs to be updated"); - -static const std::map kBlockNameMap = { - {RSMI_GPU_BLOCK_UMC, "UMC"}, - {RSMI_GPU_BLOCK_SDMA, "SDMA"}, - {RSMI_GPU_BLOCK_GFX, "GFX"}, - {RSMI_GPU_BLOCK_MMHUB, "MMHUB"}, - {RSMI_GPU_BLOCK_ATHUB, "ATHUB"}, - {RSMI_GPU_BLOCK_PCIE_BIF, "PCIE_BIF"}, - {RSMI_GPU_BLOCK_HDP, "HDP"}, - {RSMI_GPU_BLOCK_XGMI_WAFL, "XGMI_WAFL"}, - {RSMI_GPU_BLOCK_DF, "DF"}, - {RSMI_GPU_BLOCK_SMN, "SMN"}, - {RSMI_GPU_BLOCK_SEM, "SEM"}, - {RSMI_GPU_BLOCK_MP0, "MP0"}, - {RSMI_GPU_BLOCK_MP1, "MP1"}, - {RSMI_GPU_BLOCK_FUSE, "FUSE"}, -}; -static_assert(RSMI_GPU_BLOCK_LAST == RSMI_GPU_BLOCK_FUSE, - "kBlockNameMap needs to be updated"); - -static const char * kRasErrStateStrings[] = { - "None", // RSMI_RAS_ERR_STATE_NONE - "Disabled", // RSMI_RAS_ERR_STATE_DISABLED - "Error Unknown", // RSMI_RAS_ERR_STATE_PARITY - "Single, Correctable", // RSMI_RAS_ERR_STATE_SING_C - "Multiple, Uncorrectable", // RSMI_RAS_ERR_STATE_MULT_UC - "Poison", // RSMI_RAS_ERR_STATE_POISON - "Enabled", // RSMI_RAS_ERR_STATE_ENABLED -}; -static_assert( - sizeof(kRasErrStateStrings)/sizeof(char *) == (RSMI_RAS_ERR_STATE_LAST + 1), - "kErrStateNameMap needs to be updated"); - - -static const std::map kErrStateNameMap = { - {RSMI_RAS_ERR_STATE_NONE, - kRasErrStateStrings[RSMI_RAS_ERR_STATE_NONE]}, - {RSMI_RAS_ERR_STATE_DISABLED, - kRasErrStateStrings[RSMI_RAS_ERR_STATE_DISABLED]}, - {RSMI_RAS_ERR_STATE_PARITY, - kRasErrStateStrings[RSMI_RAS_ERR_STATE_PARITY]}, - {RSMI_RAS_ERR_STATE_SING_C, - kRasErrStateStrings[RSMI_RAS_ERR_STATE_SING_C]}, - {RSMI_RAS_ERR_STATE_MULT_UC, - kRasErrStateStrings[RSMI_RAS_ERR_STATE_MULT_UC]}, - {RSMI_RAS_ERR_STATE_POISON, - kRasErrStateStrings[RSMI_RAS_ERR_STATE_POISON]}, - {RSMI_RAS_ERR_STATE_ENABLED, - kRasErrStateStrings[RSMI_RAS_ERR_STATE_ENABLED]}, -}; -static_assert(RSMI_RAS_ERR_STATE_LAST == RSMI_RAS_ERR_STATE_ENABLED, - "kErrStateNameMap needs to be updated"); - -static const struct option long_options[] = { - {"iterations", required_argument, nullptr, 'i'}, - {"verbose", required_argument, nullptr, 'v'}, - {"monitor_verbose", required_argument, nullptr, 'm'}, - {"dont_fail", no_argument, nullptr, 'f'}, - {"rsmitst_help", no_argument, nullptr, 'r'}, - - {nullptr, 0, nullptr, 0} -}; -static const char* short_options = "i:v:m:fr"; - -static const std::map kVoltSensorNameMap = { - {RSMI_VOLT_TYPE_VDDGFX, "Vddgfx"}, -}; - -static void PrintHelp(void) { - std::cout << - "Optional rsmitst Arguments:\n" - "--dont_fail, -f if set, don't fail test when individual test fails; " - "default is to fail when an individual test fails\n" - "--rsmitst_help, -r print this help message\n" - "--verbosity, -v \n" - " Verbosity levels:\n" - " 0 -- minimal; just summary information\n" - " 1 -- intermediate; show intermediate values such as intermediate " - "perf. data\n" - " 2 -- progress; show progress displays\n" - " >= 3 -- more debug output\n"; -} - -uint32_t ProcessCmdline(RSMITstGlobals* test, int arg_cnt, char** arg_list) { - int a; - int ind = -1; - - assert(test != nullptr); - - while (true) { - a = getopt_long(arg_cnt, arg_list, short_options, long_options, &ind); - - if (a == -1) { - break; - } - - switch (a) { - case 'i': - test->num_iterations = std::stoi(optarg); - break; - - case 'v': - test->verbosity = std::stoi(optarg); - break; - - case 'm': - test->monitor_verbosity = std::stoi(optarg); - break; - - case 'r': - PrintHelp(); - return 1; - - case 'f': - test->dont_fail = true; - break; - - default: - std::cout << "Unknown command line option: \"" << a << - "\". Ignoring..." << std::endl; - PrintHelp(); - return 0; - } - } - return 0; -} - -const char *GetPerfLevelStr(rsmi_dev_perf_level_t lvl) { - return kDevPerfLvlNameMap.at(lvl); -} -const char *GetBlockNameStr(rsmi_gpu_block_t id) { - return kBlockNameMap.at(id); -} -const char *GetErrStateNameStr(rsmi_ras_err_state_t st) { - return kErrStateNameMap.at(st); -} -const std::string GetVoltSensorNameStr(rsmi_voltage_type_t st) { - return kVoltSensorNameMap.at(st); -} -const char *FreqEnumToStr(rsmi_clk_type rsmi_clk) { - static_assert(RSMI_CLK_TYPE_LAST == RSMI_CLK_TYPE_MEM, - "FreqEnumToStr() needs to be updated"); - switch (rsmi_clk) { - case RSMI_CLK_TYPE_SYS: return "System clock"; - case RSMI_CLK_TYPE_DF: return "Data Fabric clock"; - case RSMI_CLK_TYPE_DCEF: return "Display Controller Engine clock"; - case RSMI_CLK_TYPE_SOC: return "SOC clock"; - case RSMI_CLK_TYPE_MEM: return "Memory clock"; - default: return "Invalid Clock ID"; - } -} - -#if ENABLE_SMI -void DumpMonitorInfo(const TestBase *test) { - int ret = 0; - uint32_t value; - uint32_t value2; - std::string val_str; - std::vector val_vec; - - assert(test != nullptr); - assert(test->monitor_devices() != nullptr && - "Make sure to call test->set_monitor_devices()"); - auto print_attr_label = - [&](std::string attrib) -> bool { - std::cout << "\t** " << attrib; - if (ret == -1) { - std::cout << "not available" << std::endl; - return false; - } - return true; - }; - - auto delim = "\t***********************************"; - - std::cout << "\t***** Hardware monitor values *****" << std::endl; - std::cout << delim << std::endl; - std::cout.setf(std::ios::dec, std::ios::basefield); - for (auto dev : *test->monitor_devices()) { - auto print_vector = - [&](amd::smi::DevInfoTypes type, std::string label) { - ret = dev->readDevInfo(type, &val_vec); - if (print_attr_label(label)) { - for (auto vs : val_vec) { - std::cout << "\t** " << vs << std::endl; - } - val_vec.clear(); - } - }; - auto print_val_str = - [&](amd::smi::DevInfoTypes type, std::string label) { - ret = dev->readDevInfo(type, &val_str); - - std::cout << "\t** " << label; - if (ret == -1) { - std::cout << "not available"; - } else { - std::cout << val_str; - } - std::cout << std:: endl; - }; - - print_val_str(amd::smi::kDevDevID, "Device ID: "); - print_val_str(amd::smi::kDevPerfLevel, "Performance Level: "); - print_val_str(amd::smi::kDevOverDriveLevel, "OverDrive Level: "); - print_vector(amd::smi::kDevGPUMClk, - "Supported GPU Memory clock frequencies:\n"); - print_vector(amd::smi::kDevGPUSClk, - "Supported GPU clock frequencies:\n"); - - if (dev->monitor() != nullptr) { - ret = dev->monitor()->readMonitor(amd::smi::kMonName, &val_str); - if (print_attr_label("Monitor name: ")) { - std::cout << val_str << std::endl; - } - - ret = dev->monitor()->readMonitor(amd::smi::kMonTemp, &value); - if (print_attr_label("Temperature: ")) { - std::cout << static_cast(value)/1000.0 << "C" << std::endl; - } - - std::cout.setf(std::ios::dec, std::ios::basefield); - - ret = dev->monitor()->readMonitor(amd::smi::kMonMaxFanSpeed, &value); - if (ret == 0) { - ret = dev->monitor()->readMonitor(amd::smi::kMonFanSpeed, &value2); - } - if (print_attr_label("Current Fan Speed: ")) { - std::cout << value2/static_cast(value) * 100 << "% (" << - value2 << "/" << value << ")" << std::endl; - } - } - std::cout << "\t=======" << std::endl; - } - std::cout << delim << std::endl; -} -#endif diff --git a/tests/rocm_smi_test/test_common.h b/tests/rocm_smi_test/test_common.h deleted file mode 100755 index e601fb0e8e..0000000000 --- a/tests/rocm_smi_test/test_common.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * ============================================================================= - * ROC Runtime Conformance Release License - * ============================================================================= - * The University of Illinois/NCSA - * Open Source License (NCSA) - * - * Copyright (c) 2018, 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 , - * 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_TEST_COMMON_H_ -#define TESTS_ROCM_SMI_TEST_TEST_COMMON_H_ - -#include -#include -#include - -#include "rocm_smi/rocm_smi.h" - -struct RSMITstGlobals { - uint32_t verbosity; - uint32_t monitor_verbosity; - uint32_t num_iterations; - uint64_t init_options; - bool dont_fail; -}; - -uint32_t ProcessCmdline(RSMITstGlobals* test, int arg_cnt, char** arg_list); - -void PrintTestHeader(uint32_t dv_ind); -const char *GetPerfLevelStr(rsmi_dev_perf_level_t lvl); -const char *GetBlockNameStr(rsmi_gpu_block_t id); -const char *GetErrStateNameStr(rsmi_ras_err_state_t st); -const char *FreqEnumToStr(rsmi_clk_type rsmi_clk); -const std::string GetVoltSensorNameStr(rsmi_voltage_type_t st); - -#if ENABLE_SMI -void DumpMonitorInfo(const TestBase *test); -#endif - -#define DISPLAY_RSMI_ERR(RET) { \ - if (RET != RSMI_STATUS_SUCCESS) { \ - const char *err_str; \ - std::cout << "\t===> ERROR: RSMI call returned " << (RET) << std::endl; \ - rsmi_status_string((RET), &err_str); \ - std::cout << "\t===> (" << err_str << ")" << std::endl; \ - std::cout << "\t===> at " << __FILE__ << ":" << std::dec << __LINE__ << \ - std::endl; \ - } \ -} - -#define CHK_ERR_RET(RET) { \ - DISPLAY_RSMI_ERR(RET) \ - if ((RET) != RSMI_STATUS_SUCCESS) { \ - return (RET); \ - } \ -} -#define CHK_RSMI_PERM_ERR(RET) { \ - if (RET == RSMI_STATUS_PERMISSION) { \ - std::cout << "This command requires root access." << std::endl; \ - } else { \ - DISPLAY_RSMI_ERR(RET) \ - } \ -} - -#endif // TESTS_ROCM_SMI_TEST_TEST_COMMON_H_ diff --git a/tests/rocm_smi_test/test_utils.cc b/tests/rocm_smi_test/test_utils.cc deleted file mode 100755 index aeda744dd9..0000000000 --- a/tests/rocm_smi_test/test_utils.cc +++ /dev/null @@ -1,90 +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 , - * 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 - -#include "rocm_smi/rocm_smi.h" -#include "test_utils.h" - -static const std::map kDevFWNameMap = { - {RSMI_FW_BLOCK_ASD, "asd"}, - {RSMI_FW_BLOCK_CE, "ce"}, - {RSMI_FW_BLOCK_DMCU, "dmcu"}, - {RSMI_FW_BLOCK_MC, "mc"}, - {RSMI_FW_BLOCK_ME, "me"}, - {RSMI_FW_BLOCK_MEC, "mec"}, - {RSMI_FW_BLOCK_MEC2, "mec2"}, - {RSMI_FW_BLOCK_PFP, "pfp"}, - {RSMI_FW_BLOCK_RLC, "rlc"}, - {RSMI_FW_BLOCK_RLC_SRLC, "rlc_srlc"}, - {RSMI_FW_BLOCK_RLC_SRLG, "rlc_srlg"}, - {RSMI_FW_BLOCK_RLC_SRLS, "rlc_srls"}, - {RSMI_FW_BLOCK_SDMA, "sdma"}, - {RSMI_FW_BLOCK_SDMA2, "sdma2"}, - {RSMI_FW_BLOCK_SMC, "smc"}, - {RSMI_FW_BLOCK_SOS, "sos"}, - {RSMI_FW_BLOCK_TA_RAS, "ta_ras"}, - {RSMI_FW_BLOCK_TA_XGMI, "ta_xgmi"}, - {RSMI_FW_BLOCK_UVD, "uvd"}, - {RSMI_FW_BLOCK_VCE, "vce"}, - {RSMI_FW_BLOCK_VCN, "vcn"}, -}; - -const char * -NameFromFWEnum(rsmi_fw_block_t blk) { - return kDevFWNameMap.at(blk); -} - -static const std::map - kEvtNotifEvntNameMap = { - {RSMI_EVT_NOTIF_VMFAULT, "RSMI_EVT_NOTIF_VMFAULT"}, - {RSMI_EVT_NOTIF_THERMAL_THROTTLE, "RSMI_EVT_NOTIF_THERMAL_THROTTLE"}, - {RSMI_EVT_NOTIF_GPU_PRE_RESET, "RSMI_EVT_NOTIF_GPU_PRE_RESET"}, - {RSMI_EVT_NOTIF_GPU_POST_RESET, "RSMI_EVT_NOTIF_GPU_POST_RESET"}, -}; -const char * -NameFromEvtNotifType(rsmi_evt_notification_type_t evt) { - return kEvtNotifEvntNameMap.at(evt); -} diff --git a/tests/rocm_smi_test/test_utils.h b/tests/rocm_smi_test/test_utils.h deleted file mode 100755 index 28185a1307..0000000000 --- a/tests/rocm_smi_test/test_utils.h +++ /dev/null @@ -1,56 +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 , - * 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_TEST_UTILS_H_ -#define TESTS_ROCM_SMI_TEST_TEST_UTILS_H_ - -#include "rocm_smi/rocm_smi.h" - -const char * -NameFromFWEnum(rsmi_fw_block_t blk); -const char * -NameFromEvtNotifType(rsmi_evt_notification_type_t evt); - -#endif // TESTS_ROCM_SMI_TEST_TEST_UTILS_H_ diff --git a/third_party/shared_mutex/shared_mutex.cc b/third_party/shared_mutex/shared_mutex.cc index 55fac1f5b5..b1b8dade38 100755 --- a/third_party/shared_mutex/shared_mutex.cc +++ b/third_party/shared_mutex/shared_mutex.cc @@ -1,5 +1,5 @@ /* -Modifications Copyright © 2019 – 2020 Advanced Micro Devices, Inc. All Rights +Modifications Copyright 2019 - 2022 Advanced Micro Devices, Inc. All Rights Reserved. Copyright (c) 2018 Oleg Yamnikov @@ -34,9 +34,51 @@ THE SOFTWARE. #include // clock_gettime #include +#include +#include +#include +#include +#include + #include "rocm_smi/rocm_smi_exception.h" -shared_mutex_t shared_mutex_init(const char *name, mode_t mode) { +// find which processes are using the file by searching /proc/*/fd +static std::vector lsof(const char* filename) { + struct dirent *entry = nullptr; + DIR *dp = nullptr; + std::vector process_id; + + dp = opendir("/proc"); + if (dp != nullptr) { + while ((entry = readdir(dp))) { + std::string id(entry->d_name); + // the process id should be a number + if (std::all_of(id.begin(), id.end(), ::isdigit)) { + process_id.push_back(entry->d_name); + } + } + closedir(dp); + } + + std::vector matched_process; + for (unsigned int i=0; i < process_id.size(); i++) { + std::string folder_name("/proc/"); + folder_name += process_id[i]+"/fd/"; + dp = opendir(folder_name.c_str()); + if (dp == nullptr) continue; + while ((entry = readdir(dp))) { + std::string p(folder_name+entry->d_name); + char buf[512]; + memset(buf, 0, 512); + if (readlink(p.c_str(), buf, sizeof(buf)-1) < 0) continue; + if (!strcmp(filename, buf)) matched_process.push_back(process_id[i]); + } + closedir(dp); + } + return matched_process; +} + +shared_mutex_t shared_mutex_init(const char *name, mode_t mode, bool retried) { shared_mutex_t mutex = {NULL, 0, NULL, 0}; errno = 0; @@ -110,6 +152,20 @@ shared_mutex_t shared_mutex_init(const char *name, mode_t mode) { } else if (ret || (mutex.created == 0 && reinterpret_cast(addr)->ptr == NULL)) { // Something is out of sync. + + // When process crash before unlock the mutex, the mutex is in bad status. + // reset the mutex if no process is using it, and then retry lock + if (!retried) { + std::vector ids = lsof(name); + if (ids.size() == 0) { // no process is using it + memset(mutex_ptr, 0, sizeof(pthread_mutex_t)); + // Set mutex.created == 1 so that it can be initialized latter. + mutex.created = 1; + free(mutex.name); + return shared_mutex_init(name, mode, true); + } + } + fprintf(stderr, "pthread_mutex_timedlock() returned %d\n", ret); perror("Failed to initialize RSMI device mutex after 5 seconds. Previous " "execution may not have shutdown cleanly. To fix problem, stop all " diff --git a/third_party/shared_mutex/shared_mutex.h b/third_party/shared_mutex/shared_mutex.h index 7fc5ce845e..d04d1d0984 100755 --- a/third_party/shared_mutex/shared_mutex.h +++ b/third_party/shared_mutex/shared_mutex.h @@ -61,7 +61,7 @@ typedef struct shared_mutex_t { // There is no workaround currently, except to run first // initialization only before multi-threaded or multi-process // functionality. -shared_mutex_t shared_mutex_init(const char *name, mode_t mode); +shared_mutex_t shared_mutex_init(const char *name, mode_t mode, bool retried=false); // Close access to the shared mutex and free all the resources, // used by the structure.