From 1dd2942136ca1234c5b00b226571401a04b56e05 Mon Sep 17 00:00:00 2001 From: Maisam Arif Date: Tue, 10 Oct 2023 20:42:52 -0500 Subject: [PATCH 01/27] Added static --cache to cli tool Change-Id: I494d29aba7915a0b8815036977b2636a2da5264e Signed-off-by: Maisam Arif [ROCm/amdsmi commit: 66eb3de5e42fa9176aaf05e7a288d5b243edc1bb] --- projects/amdsmi/amdsmi_cli/README.md | 1 + projects/amdsmi/amdsmi_cli/amdsmi_commands.py | 23 ++++-- projects/amdsmi/amdsmi_cli/amdsmi_parser.py | 6 +- projects/amdsmi/py-interface/README.md | 79 +++++++++++++++++++ projects/amdsmi/py-interface/__init__.py | 1 + .../amdsmi/py-interface/amdsmi_interface.py | 24 ++++++ 6 files changed, 127 insertions(+), 7 deletions(-) diff --git a/projects/amdsmi/amdsmi_cli/README.md b/projects/amdsmi/amdsmi_cli/README.md index ccc75b416a..7032b74d0c 100644 --- a/projects/amdsmi/amdsmi_cli/README.md +++ b/projects/amdsmi/amdsmi_cli/README.md @@ -176,6 +176,7 @@ Static Arguments: -d, --driver Displays driver version -r, --ras Displays RAS features information -v, --vram All vram information + -c, --cache All cache information -B, --board All board information -l, --limit All limit metric values (i.e. power and thermal limits) -u, --numa All numa node information diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_commands.py b/projects/amdsmi/amdsmi_cli/amdsmi_commands.py index b598a15d5c..3d1cb78bf7 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_commands.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_commands.py @@ -131,7 +131,7 @@ class AMDSMICommands(): def static(self, args, multiple_devices=False, gpu=None, asic=None, bus=None, vbios=None, limit=None, driver=None, - ras=None, board=None, numa=None, vram=None): + ras=None, board=None, numa=None, vram=None, cache=None): """Get Static information for target gpu Args: @@ -147,6 +147,7 @@ class AMDSMICommands(): board (bool, optional): Value override for args.board. Defaults to None. numa (bool, optional): Value override for args.numa. Defaults to None. vram (bool, optional): Value override for args.vram. Defaults to None. + cache (bool, optional): Value override for args.cache. Defaults to None. Raises: IndexError: Index error if gpu list is empty @@ -171,6 +172,8 @@ class AMDSMICommands(): args.driver = driver if vram: args.vram = vram + if cache: + args.cache = cache if self.helpers.is_linux() and self.helpers.is_baremetal(): if ras: args.ras = ras @@ -189,11 +192,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.board, args.ras, args.driver, args.numa, args.vram]): - args.asic = args.bus = args.vbios = args.limit = args.board = args.ras = args.driver = args.numa = args.vram = self.all_arguments = True + if not any([args.asic, args.bus, args.vbios, args.limit, args.board, args.ras, args.driver, args.numa, args.vram, args.cache]): + args.asic = args.bus = args.vbios = args.limit = args.board = args.ras = args.driver = args.numa = args.vram = args.cache = self.all_arguments = True if self.helpers.is_linux() and self.helpers.is_virtual_os(): - if not any([args.asic, args.bus, args.vbios, args.board, args.driver, args.vram]): - args.asic = args.bus = args.vbios = args.board = args.driver = args.vram = self.all_arguments = True + if not any([args.asic, args.bus, args.vbios, args.board, args.driver, args.vram, args.cache]): + args.asic = args.bus = args.vbios = args.board = args.driver = args.vram = args.cache = self.all_arguments = True static_dict = {} @@ -434,7 +437,17 @@ class AMDSMICommands(): logging.debug("Failed to get vram info for gpu %s | %s", gpu_id, e.get_error_info()) static_dict['vram'] = vram_info + if args.cache: + try: + cache_info = amdsmi_interface.amdsmi_get_gpu_cache_info(args.gpu) + if self.logger.is_human_readable_format(): + for _ , cache_values in cache_info.items(): + cache_values['cache_size'] = f"{cache_values['cache_size']} KB" + except amdsmi_exception.AmdSmiLibraryException as e: + cache_info = "N/A" + logging.debug("Failed to get cache info for gpu %s | %s", gpu_id, e.get_error_info()) + static_dict['cache'] = cache_info if self.helpers.is_hypervisor() or self.helpers.is_baremetal(): if args.ras: ras_dict = {"eeprom_version": "N/A", diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_parser.py b/projects/amdsmi/amdsmi_cli/amdsmi_parser.py index 85fda61d6f..1d737e0a5f 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_parser.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_parser.py @@ -293,11 +293,12 @@ 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" + vram_help = "All vram information" + cache_help = "All cache information" + board_help = "All board information" # Options arguments help text for Hypervisors and Baremetal ras_help = "Displays RAS features information" - vram_help = "All vram information" - board_help = "All board information" # Linux Baremetal only numa_help = "All numa node information" # Linux Baremetal only # Options arguments help text for Hypervisors @@ -321,6 +322,7 @@ class AMDSMIParser(argparse.ArgumentParser): 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('-v', '--vram', action='store_true', required=False, help=vram_help) + static_parser.add_argument('-c', '--cache', action='store_true', required=False, help=cache_help) static_parser.add_argument('-B', '--board', action='store_true', required=False, help=board_help) # Options to display on Hypervisors and Baremetal diff --git a/projects/amdsmi/py-interface/README.md b/projects/amdsmi/py-interface/README.md index 8147ba1b6d..c57b63074c 100644 --- a/projects/amdsmi/py-interface/README.md +++ b/projects/amdsmi/py-interface/README.md @@ -424,6 +424,85 @@ except AmdSmiException as e: print(e) ``` +### amdsmi_get_gpu_vram_info + +Description: Returns dictionary of vram information for the given GPU. + +Input parameters: + +* `processor_handle` device which to query + +Output: Dictionary with fields + +Field | Description +---|--- +`vram_type` | vram type +`vram_vendor` | vram vendor +`vram_size_mb` | vram size in mb + +Exceptions that can be thrown by `amdsmi_get_gpu_vram_info` function: + +* `AmdSmiLibraryException` +* `AmdSmiRetryException` +* `AmdSmiParameterException` + +Example: + +```python +try: + devices = amdsmi_get_processor_handles() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + vram_info = amdsmi_get_gpu_vram_info(device) + print(vram_info['vram_type']) + print(vram_info['vram_vendor']) + print(vram_info['vram_size_mb']) +except AmdSmiException as e: + print(e) +``` + +### amdsmi_get_gpu_cache_info + +Description: Returns dictionary of cache information for the given GPU. + +Input parameters: + +* `processor_handle` device which to query + +Output: Dictionary of Dictionaries containing cache information + +Field | Description +---|--- +`cache #` | upt 10 caches will be available +`cache_size` | size of cache in KB +`cache_level` | level of cache + +Exceptions that can be thrown by `amdsmi_get_gpu_cache_info` function: + +* `AmdSmiLibraryException` +* `AmdSmiRetryException` +* `AmdSmiParameterException` + +Example: + +```python +try: + devices = amdsmi_get_processor_handles() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + cache_info = amdsmi_get_gpu_cache_info(device) + for cache_index, cache_values in cache_info.items(): + print(cache_index) + print(cache_values['cache_size']) + print(cache_values['cache_level']) +except AmdSmiException as e: + print(e) +``` + ### amdsmi_get_gpu_vbios_info Description: Returns the static information for the VBIOS on the device. diff --git a/projects/amdsmi/py-interface/__init__.py b/projects/amdsmi/py-interface/__init__.py index 22a13f7c95..d0b7bc417a 100644 --- a/projects/amdsmi/py-interface/__init__.py +++ b/projects/amdsmi/py-interface/__init__.py @@ -40,6 +40,7 @@ from .amdsmi_interface import amdsmi_get_gpu_driver_info from .amdsmi_interface import amdsmi_get_gpu_asic_info from .amdsmi_interface import amdsmi_get_power_cap_info from .amdsmi_interface import amdsmi_get_gpu_vram_info +from .amdsmi_interface import amdsmi_get_gpu_cache_info # # Microcode and VBIOS Information from .amdsmi_interface import amdsmi_get_gpu_vbios_info diff --git a/projects/amdsmi/py-interface/amdsmi_interface.py b/projects/amdsmi/py-interface/amdsmi_interface.py index 98907c2708..425ced72e7 100644 --- a/projects/amdsmi/py-interface/amdsmi_interface.py +++ b/projects/amdsmi/py-interface/amdsmi_interface.py @@ -691,6 +691,30 @@ def amdsmi_get_gpu_vram_info( } +def amdsmi_get_gpu_cache_info( + processor_handle: amdsmi_wrapper.amdsmi_processor_handle, +) -> Dict[str, Any]: + if not isinstance(processor_handle, amdsmi_wrapper.amdsmi_processor_handle): + raise AmdSmiParameterException( + processor_handle, amdsmi_wrapper.amdsmi_processor_handle + ) + + cache_info = amdsmi_wrapper.amdsmi_gpu_cache_info_t() + _check_res( + amdsmi_wrapper.amdsmi_get_gpu_cache_info( + processor_handle, ctypes.byref(cache_info)) + ) + + cache_info_dict = {} + for cache_index in range(cache_info.num_cache_types): + cache_size = cache_info.cache[cache_index].cache_size_kb + cache_level = cache_info.cache[cache_index].cache_level + cache_info_dict[f"cache {cache_index}"] = {"cache_size": cache_size, + "cache_level": cache_level} + + return cache_info_dict + + def amdsmi_get_gpu_vbios_info( processor_handle: amdsmi_wrapper.amdsmi_processor_handle, ) -> Dict[str, Any]: From f7cb43462e38f0af8a70846771c4194640aa53ea Mon Sep 17 00:00:00 2001 From: "Galantsev, Dmitrii" Date: Wed, 11 Oct 2023 21:54:09 -0500 Subject: [PATCH 02/27] Add wrapper generator Change-Id: I34a191acfefbef2e40d0242eb121ba9af55cb9de Signed-off-by: Galantsev, Dmitrii [ROCm/amdsmi commit: c94036de219697b3c40d45d80584f0d96b59519e] --- projects/amdsmi/README.md | 15 +++---- projects/amdsmi/py-interface/CMakeLists.txt | 9 ++-- projects/amdsmi/py-interface/Dockerfile | 43 +++++++++++++++++++ .../amdsmi/py-interface/amdsmi_wrapper.py | 2 +- projects/amdsmi/update_wrapper.sh | 36 ++++++++++++++++ 5 files changed, 92 insertions(+), 13 deletions(-) create mode 100644 projects/amdsmi/py-interface/Dockerfile create mode 100755 projects/amdsmi/update_wrapper.sh diff --git a/projects/amdsmi/README.md b/projects/amdsmi/README.md index 7de1330296..3e78fb9321 100755 --- a/projects/amdsmi/README.md +++ b/projects/amdsmi/README.md @@ -118,7 +118,7 @@ To build the documentation locally, run the commands below: ``` bash cd docs -pip3 install -r sphinx/requirements.txt +python3 -m pip install -r sphinx/requirements.txt python3 -m sphinx -T -E -b html -d _build/doctrees -D language=en . _build/html ``` @@ -203,15 +203,14 @@ The python wrapper (binding) is an auto-generated file `py-interface/amdsmi_wrap Wrapper should be re-generated on each C++ API change, by doing: ```bash -cmake .. -DBUILD_WRAPPER=on -make python_wrapper # or simply 'make' +./update_wrapper.sh ``` After this command, the file in `py-interface/amdsmi_wrapper.py` will be automatically updated on each compile. -Note: To be able to re-generate python wrapper you need several tools installed on your system: clang-14, clang-format, libclang-dev, and ***python3.7 or newer***. +Note: To be able to re-generate python wrapper you need **docker** installed. -Note: python_wrapper is NOT automatically re-generated. You must run `cmake` with `-DBUILD_WRAPPER=on` argument. +Note: python_wrapper is NOT automatically re-generated. You must run `./update_wrapper.sh`. ## Building AMD SMI @@ -219,14 +218,14 @@ Note: python_wrapper is NOT automatically re-generated. You must run `cmake` wit In order to build the AMD SMI library, the following components are required. Note that the software versions listed are what was used in development. Earlier versions are not guaranteed to work: -* CMake (v3.11.0) - `pip3 install cmake` +* CMake (v3.14.0) - `python3 -m pip install cmake` * g++ (5.4.0) In order to build the AMD SMI python package, the following components are required: * clang (14.0 or above) -* python (3.6 or above) -* virtualenv - `pip3 install virtualenv` +* python (3.7 or above) +* virtualenv - `python3 -m pip install virtualenv` In order to build the latest documentation, the following are required: diff --git a/projects/amdsmi/py-interface/CMakeLists.txt b/projects/amdsmi/py-interface/CMakeLists.txt index dc1d498103..4582776ecc 100644 --- a/projects/amdsmi/py-interface/CMakeLists.txt +++ b/projects/amdsmi/py-interface/CMakeLists.txt @@ -1,8 +1,9 @@ # Generate py-interface and package targets -# CLANG installed must be 14.0 or above -set(clang_ver 14.0) -set(ctypeslib_ver 2.3.2) +# CLANG installed must be 16.0 or above +set(clang_ver 16.0) +set(clang_ver_py 16.0.1) +set(ctypeslib_ver_py 2.3.4) set(PY_BUILD_DIR "python_package") # amdsmi part of this string is the directory containing all python files @@ -52,7 +53,7 @@ else() endif() add_custom_target( python_pre_reqs - COMMAND ${Python3_EXECUTABLE} -m pip install ${Python3_BREAK_SYSTEM_PACKAGES} clang==${clang_ver} ctypeslib2==${ctypeslib_ver}) + COMMAND ${Python3_EXECUTABLE} -m pip install ${Python3_BREAK_SYSTEM_PACKAGES} clang==${clang_ver_py} ctypeslib2==${ctypeslib_ver_py}) # generate new wrapper configure_file(${PROJECT_SOURCE_DIR}/tools/generator.py generator.py @ONLY COPYONLY) add_custom_command( diff --git a/projects/amdsmi/py-interface/Dockerfile b/projects/amdsmi/py-interface/Dockerfile new file mode 100644 index 0000000000..5218f76946 --- /dev/null +++ b/projects/amdsmi/py-interface/Dockerfile @@ -0,0 +1,43 @@ +FROM ubuntu:latest + +# do not prompt in apt +# https://github.com/moby/moby/issues/4032#issuecomment-163689851 +ARG DEBIAN_FRONTEND=noninteractive +ARG DEBCONF_NONINTERACTIVE_SEEN=true + +# set timezone +ENV TZ="America/Chicago" +RUN ln -snf /usr/share/zoneinfo/${TZ} /etc/localtime && echo ${TZ} > /etc/timezone + +RUN apt update --yes \ + && apt install --yes \ + build-essential \ + cmake \ + gnupg \ + libdrm-dev \ + libpython3-dev \ + lsb-release \ + pkg-config \ + pkg-config \ + python3-pip \ + software-properties-common \ + wget \ + && apt clean \ + && rm -rf /var/cache/apt/ /var/lib/apt/lists/* + +WORKDIR /var/tmp +RUN TEMPDIR=$(mktemp -d) \ + && cd $TEMPDIR \ + && wget https://apt.llvm.org/llvm.sh && chmod +x llvm.sh \ + && ./llvm.sh 16 \ + && update-alternatives --install /usr/bin/clang clang $(which clang-16) 91 --slave /usr/bin/clang++ clang++ $(which clang++-16) \ + && python3 -m pip install --no-cache-dir clang==16.0.1 ctypeslib2==2.3.4 -U \ + && rm -rf $TEMPDIR + +WORKDIR /src +CMD cp -r /src /tmp/src \ + && cd /tmp/src \ + && rm -rf build .cache \ + && cmake -B build -DBUILD_WRAPPER=ON \ + && make -C build -j $(nproc) \ + && cp /tmp/src/py-interface/amdsmi_wrapper.py /src/py-interface/amdsmi_wrapper.py diff --git a/projects/amdsmi/py-interface/amdsmi_wrapper.py b/projects/amdsmi/py-interface/amdsmi_wrapper.py index 1e48cf7636..883ffd5b7f 100644 --- a/projects/amdsmi/py-interface/amdsmi_wrapper.py +++ b/projects/amdsmi/py-interface/amdsmi_wrapper.py @@ -23,7 +23,7 @@ import os # -*- coding: utf-8 -*- # -# TARGET arch is: ['-I/usr/lib64/clang/17/include'] +# TARGET arch is: ['-I/usr/lib/llvm-16/lib/clang/16/include'] # WORD_SIZE is: 8 # POINTER_SIZE is: 8 # LONGDOUBLE_SIZE is: 16 diff --git a/projects/amdsmi/update_wrapper.sh b/projects/amdsmi/update_wrapper.sh new file mode 100755 index 0000000000..d7bc4da8e8 --- /dev/null +++ b/projects/amdsmi/update_wrapper.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash + +# this program generates py-interface/amdsmi_wrapper.py + +set -eu + +# get current dir +DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) + +# override by calling this script with: +# DOCKER_NAME=yourdockername ./update_wrapper.sh +DOCKER_NAME="${DOCKER_NAME:-dmitriigalantsev/amdsmi_wrapper_updater}" + +command -v docker &>/dev/null || { + echo "Please install docker!" >&2 + exit 1 +} + +does_image_exist () { + docker images | grep -q "$DOCKER_NAME" +} + +if ! does_image_exist; then + # if you prefer to not generate it yourself: + # pull from https://hub.docker.com/r/dmitriigalantsev/amdsmi_wrapper_updater + # using the following command: + # docker pull dmitriigalantsev/amdsmi_wrapper_updater + echo "No docker image found! Generating one" + # set to 0 because it's compatible with more systems + DOCKER_BUILDKIT="${DOCKER_BUILDKIT:0}" docker build "$DIR/py-interface" -t "$DOCKER_NAME":latest +fi + +docker run --rm -ti --volume "$DIR":/src:rw "$DOCKER_NAME":latest + +echo -e "Generated new wrapper! +[$DIR/py-interface/amdsmi_wrapper.py]" From f29d776cf6cbe4ee0585706b604c898409502761 Mon Sep 17 00:00:00 2001 From: "Galantsev, Dmitrii" Date: Thu, 12 Oct 2023 11:26:01 -0500 Subject: [PATCH 03/27] CMAKE - Fix amdsmi lib version This allows for lib version to change before: libamd_smi.so.1.0 after: libamd_smi.so.23.4 Change-Id: Iaba991afac4e625d11df2bacdf6287c6f8bf5383 Signed-off-by: Galantsev, Dmitrii [ROCm/amdsmi commit: 69c35a4cff5bb8c2e0157f5b34edce494fb04258] --- projects/amdsmi/src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/amdsmi/src/CMakeLists.txt b/projects/amdsmi/src/CMakeLists.txt index 8b3891eb34..956bb98fec 100644 --- a/projects/amdsmi/src/CMakeLists.txt +++ b/projects/amdsmi/src/CMakeLists.txt @@ -21,7 +21,7 @@ message("--------Proj Src Dir: " ${PROJECT_SOURCE_DIR}) include(utils) ################# Determine the library version ######################### -set(SO_VERSION_GIT_TAG_PREFIX "amd_smi_so_ver") +set(SO_VERSION_GIT_TAG_PREFIX "amdsmi_so_ver") set(SRC_DIR "amd_smi") set(INC_DIR "${PROJECT_SOURCE_DIR}/include/amd_smi") From f6c46e97ee69817185216f3ef6e42eb0628f2f42 Mon Sep 17 00:00:00 2001 From: "Galantsev, Dmitrii" Date: Thu, 12 Oct 2023 21:27:55 -0500 Subject: [PATCH 04/27] TESTS - Skip XGMI test Change-Id: Idd9f505f36fac4a670e5129f835aa051b5c4c9fa Signed-off-by: Galantsev, Dmitrii [ROCm/amdsmi commit: 2a7589a0656c69a7cc03eb5d064caf42b475bfea] --- .../amdsmi/tests/rocm_smi_test/functional/xgmi_read_write.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/projects/amdsmi/tests/rocm_smi_test/functional/xgmi_read_write.cc b/projects/amdsmi/tests/rocm_smi_test/functional/xgmi_read_write.cc index c85de42cf4..d008947110 100755 --- a/projects/amdsmi/tests/rocm_smi_test/functional/xgmi_read_write.cc +++ b/projects/amdsmi/tests/rocm_smi_test/functional/xgmi_read_write.cc @@ -85,6 +85,7 @@ void TestXGMIReadWrite::Close() { void TestXGMIReadWrite::Run(void) { + GTEST_SKIP_("Temporarily disabled"); rsmi_status_t err; rsmi_xgmi_status_t err_stat; uint64_t hive_id; From b9073f2bf7c7068519ca9e44f28b810268161a91 Mon Sep 17 00:00:00 2001 From: "Bill(Shuzhou) Liu" Date: Tue, 10 Oct 2023 10:11:16 -0500 Subject: [PATCH 05/27] Add new API for RAS related information The API to get the EEPROM version and ECC schema. Change-Id: Iee6b3c555541a33bf16bf9ac1fd60100dfff5643 [ROCm/amdsmi commit: d92d4e4b38eb1c30441d9effbe11f6d854bba97a] --- .../amdsmi/example/amd_smi_nodrm_example.cc | 10 +++ projects/amdsmi/include/amd_smi/amdsmi.h | 24 +++++++ .../rocm_smi/include/rocm_smi/rocm_smi.h | 37 ++++++++++ .../include/rocm_smi/rocm_smi_device.h | 2 + projects/amdsmi/rocm_smi/src/rocm_smi.cc | 67 +++++++++++++++++++ .../amdsmi/rocm_smi/src/rocm_smi_device.cc | 8 +++ projects/amdsmi/rocm_smi/src/rocm_smi_main.cc | 2 + projects/amdsmi/src/amd_smi/amd_smi.cc | 28 ++++++++ 8 files changed, 178 insertions(+) diff --git a/projects/amdsmi/example/amd_smi_nodrm_example.cc b/projects/amdsmi/example/amd_smi_nodrm_example.cc index ec02ec53d8..3b4adce76a 100644 --- a/projects/amdsmi/example/amd_smi_nodrm_example.cc +++ b/projects/amdsmi/example/amd_smi_nodrm_example.cc @@ -122,6 +122,16 @@ int main() { return AMDSMI_STATUS_NOT_SUPPORTED; } + amdsmi_ras_feature_t ras_feature; + ret = amdsmi_get_gpu_ras_feature_info( + processor_handles[j] ,&ras_feature); + if (ret != AMDSMI_STATUS_NOT_SUPPORTED) { + CHK_AMDSMI_RET(ret) + printf("\tras_feature: version: %x, schema: %x\n", + ras_feature.ras_eeprom_version, ras_feature.ecc_correction_schema_flag); + } + + amdsmi_bdf_t bdf = {}; ret = amdsmi_get_gpu_device_bdf(processor_handles[j], &bdf); CHK_AMDSMI_RET(ret) diff --git a/projects/amdsmi/include/amd_smi/amdsmi.h b/projects/amdsmi/include/amd_smi/amdsmi.h index 5546bc46c7..6de6ba028f 100644 --- a/projects/amdsmi/include/amd_smi/amdsmi.h +++ b/projects/amdsmi/include/amd_smi/amdsmi.h @@ -1163,6 +1163,16 @@ typedef struct { /// @endcond } amdsmi_gpu_metrics_t; +/** + * @brief This structure holds ras feature + */ +typedef struct { + uint32_t ras_eeprom_version; + // PARITY error(bit 0), Single Bit correctable (bit1), + // Double bit error detection (bit2), Poison (bit 3). + uint32_t ecc_correction_schema_flag; //!< ecc_correction_schema mask +} amdsmi_ras_feature_t; + /** * @brief This structure holds error counts. */ @@ -2004,6 +2014,20 @@ amdsmi_get_gpu_memory_usage(amdsmi_processor_handle processor_handle, amdsmi_mem amdsmi_status_t amdsmi_get_gpu_bad_page_info(amdsmi_processor_handle processor_handle, uint32_t *num_pages, amdsmi_retired_page_record_t *info); +/** + * @brief Returns RAS features info. + * + * @param[in] processor_handle Device handle which to query + * + * @param[out] ras_feature RAS features that are currently enabled and supported on + * the processor. Must be allocated by user. + * + * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail + */ +amdsmi_status_t amdsmi_get_gpu_ras_feature_info( + amdsmi_processor_handle processor_handle, amdsmi_ras_feature_t *ras_feature); + + /** * @brief Returns if RAS features are enabled or disabled for given block. It is not * supported on virtual machine guest diff --git a/projects/amdsmi/rocm_smi/include/rocm_smi/rocm_smi.h b/projects/amdsmi/rocm_smi/include/rocm_smi/rocm_smi.h index 3e2735f870..67607fa186 100755 --- a/projects/amdsmi/rocm_smi/include/rocm_smi/rocm_smi.h +++ b/projects/amdsmi/rocm_smi/include/rocm_smi/rocm_smi.h @@ -1059,6 +1059,16 @@ typedef struct { uint64_t uncorrectable_err; //!< Accumulated uncorrectable errors } rsmi_error_count_t; +/** + * @brief This structure holds ras feature + */ +typedef struct { + uint32_t ras_eeprom_version; + // PARITY error(bit 0), Single Bit correctable (bit1), + // Double bit error detection (bit2), Poison (bit 3). + uint32_t ecc_correction_schema_flag; //!< ecc_correction_schema mask +} rsmi_ras_feature_info_t; + /** * @brief This structure contains information specific to a process. */ @@ -3279,6 +3289,33 @@ rsmi_status_t rsmi_dev_ecc_enabled_get(uint32_t dv_ind, */ rsmi_status_t rsmi_dev_ecc_status_get(uint32_t dv_ind, rsmi_gpu_block_t block, rsmi_ras_err_state_t *state); + + +/** + * @brief Returns RAS features info. + * + * @details Given a device index @p dv_ind, and + * a pointer to an ::rsmi_ras_feature_info_t @p ras_feature, this function will write + * the ras feature info to memory pointed to by @p ras_feature. + * + * @param[in] dv_ind a device index + * + * @param[inout] ras_feature A pointer to an ::rsmi_ras_feature_info_t to which the + * RAS info should 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_ras_feature_info_get( + uint32_t dv_ind, rsmi_ras_feature_info_t *ras_feature); + + /** * @brief Get a description of a provided RSMI error status * diff --git a/projects/amdsmi/rocm_smi/include/rocm_smi/rocm_smi_device.h b/projects/amdsmi/rocm_smi/include/rocm_smi/rocm_smi_device.h index 6aedfb0c1a..c728326691 100755 --- a/projects/amdsmi/rocm_smi/include/rocm_smi/rocm_smi_device.h +++ b/projects/amdsmi/rocm_smi/include/rocm_smi/rocm_smi_device.h @@ -129,6 +129,8 @@ enum DevInfoTypes { kDevErrCntPCIEBIF, kDevErrCntHDP, kDevErrCntXGMIWAFL, + kDevErrTableVersion, + kDevErrRASSchema, kDevErrCntFeatures, kDevMemTotGTT, kDevMemTotVisVRAM, diff --git a/projects/amdsmi/rocm_smi/src/rocm_smi.cc b/projects/amdsmi/rocm_smi/src/rocm_smi.cc index 521c615016..6fe0c41d26 100755 --- a/projects/amdsmi/rocm_smi/src/rocm_smi.cc +++ b/projects/amdsmi/rocm_smi/src/rocm_smi.cc @@ -849,6 +849,73 @@ get_id(uint32_t dv_ind, amd::smi::DevInfoTypes typ, uint16_t *id) { CATCH } +rsmi_status_t rsmi_ras_feature_info_get( + uint32_t dv_ind, rsmi_ras_feature_info_t *ras_feature) { + TRY + 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(ras_feature) + + DEVICE_MUTEX + + ret = get_dev_value_line(amd::smi::kDevErrTableVersion, + 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; + } + + // table version: 0x10000 + const char* version_key = "table version: "; + if (feature_line.rfind(version_key, 0) == 0) { + errno = 0; + auto eeprom_version = strtoul( + feature_line.substr(strlen(version_key)).c_str(), nullptr, 16); + if (errno == 0) { + ras_feature->ras_eeprom_version = eeprom_version; + } else { + return RSMI_STATUS_NOT_SUPPORTED; + } + } else { + return RSMI_STATUS_NOT_SUPPORTED; + } + + ret = get_dev_value_line(amd::smi::kDevErrRASSchema, + 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; + } + // schema: 0xf + const char* schema_key = "schema: "; + if (feature_line.rfind(schema_key, 0) == 0) { + errno = 0; + auto schema = strtoul( + feature_line.substr(strlen(schema_key)).c_str(), nullptr, 16); + if (errno == 0) { + ras_feature->ecc_correction_schema_flag = schema; + } else { + return RSMI_STATUS_NOT_SUPPORTED; + } + } else { + return RSMI_STATUS_NOT_SUPPORTED; + } + + return RSMI_STATUS_SUCCESS; + CATCH +} + rsmi_status_t rsmi_dev_id_get(uint32_t dv_ind, uint16_t *id) { std::ostringstream ss; diff --git a/projects/amdsmi/rocm_smi/src/rocm_smi_device.cc b/projects/amdsmi/rocm_smi/src/rocm_smi_device.cc index 85aebef6f4..61fd9a3885 100755 --- a/projects/amdsmi/rocm_smi/src/rocm_smi_device.cc +++ b/projects/amdsmi/rocm_smi/src/rocm_smi_device.cc @@ -112,6 +112,8 @@ static const char *kDevErrCntPCIEBIFFName = "ras/pcie_bif_err_count"; static const char *kDevErrCntHDPFName = "ras/hdp_err_count"; static const char *kDevErrCntXGMIWAFLFName = "ras/xgmi_wafl_err_count"; static const char *kDevErrCntFeaturesFName = "ras/features"; +static const char *kDevErrRASSchemaFName = "ras/schema"; +static const char *kDevErrTableVersionFName = "ras/version"; static const char *kDevMemPageBadFName = "ras/gpu_vram_bad_pages"; static const char *kDevMemTotGTTFName = "mem_info_gtt_total"; static const char *kDevMemTotVisVRAMFName = "mem_info_vis_vram_total"; @@ -269,6 +271,8 @@ static const std::map kDevAttribNameMap = { {kDevErrCntHDP, kDevErrCntHDPFName}, {kDevErrCntXGMIWAFL, kDevErrCntXGMIWAFLFName}, {kDevErrCntFeatures, kDevErrCntFeaturesFName}, + {kDevErrTableVersion, kDevErrTableVersionFName}, + {kDevErrRASSchema, kDevErrRASSchemaFName}, {kDevMemTotGTT, kDevMemTotGTTFName}, {kDevMemTotVisVRAM, kDevMemTotVisVRAMFName}, {kDevMemBusyPercent, kDevMemBusyPercentFName}, @@ -432,6 +436,8 @@ static const std::map kDevFuncDependsMap = { {"rsmi_dev_od_volt_curve_regions_get", {{kDevPowerODVoltageFName}, {}}}, {"rsmi_dev_ecc_enabled_get", {{kDevErrCntFeaturesFName}, {}}}, {"rsmi_dev_ecc_status_get", {{kDevErrCntFeaturesFName}, {}}}, + {"rsmi_ras_feature_info_get", {{kDevErrRASSchemaFName, + kDevErrTableVersionFName}, {}}}, {"rsmi_dev_counter_group_supported", {{}, {}}}, {"rsmi_dev_counter_create", {{}, {}}}, {"rsmi_dev_xgmi_error_status", {{kDevXGMIErrorFName}, {}}}, @@ -933,6 +939,8 @@ int Device::readDevInfo(DevInfoTypes type, uint64_t *val) { case kDevPCieVendorID: case kDevErrCntFeatures: case kDevXGMIPhysicalID: + case kDevErrRASSchema: + case kDevErrTableVersion: ret = readDevInfoStr(type, &tempStr); RET_IF_NONZERO(ret); diff --git a/projects/amdsmi/rocm_smi/src/rocm_smi_main.cc b/projects/amdsmi/rocm_smi/src/rocm_smi_main.cc index 3b7293cd49..0a07449b8b 100755 --- a/projects/amdsmi/rocm_smi/src/rocm_smi_main.cc +++ b/projects/amdsmi/rocm_smi/src/rocm_smi_main.cc @@ -112,6 +112,8 @@ amd::smi::RocmSMI::devInfoTypesStrings = { {amd::smi::kDevErrCntHDP, amdSMI + "kDevErrCntHDP"}, {amd::smi::kDevErrCntXGMIWAFL, amdSMI + "kDevErrCntXGMIWAFL"}, {amd::smi::kDevErrCntFeatures, amdSMI + "kDevErrCntFeatures"}, + {amd::smi::kDevErrRASSchema, amdSMI + "kDevErrRASSchema"}, + {amd::smi::kDevErrTableVersion, amdSMI + "kDevErrTableVersion"}, {amd::smi::kDevMemTotGTT, amdSMI + "kDevMemTotGTT"}, {amd::smi::kDevMemTotVisVRAM, amdSMI + "kDevMemTotVisVRAM"}, {amd::smi::kDevMemTotVRAM, amdSMI + "kDevMemTotVRAM"}, diff --git a/projects/amdsmi/src/amd_smi/amd_smi.cc b/projects/amdsmi/src/amd_smi/amd_smi.cc index ff5988c126..1d1bae6231 100644 --- a/projects/amdsmi/src/amd_smi/amd_smi.cc +++ b/projects/amdsmi/src/amd_smi/amd_smi.cc @@ -1600,6 +1600,34 @@ amdsmi_get_gpu_bad_page_info(amdsmi_processor_handle processor_handle, uint32_t return AMDSMI_STATUS_SUCCESS; } +amdsmi_status_t amdsmi_get_gpu_ras_feature_info( + amdsmi_processor_handle processor_handle, amdsmi_ras_feature_t *ras_feature) { + AMDSMI_CHECK_INIT(); + + if (ras_feature == nullptr) { + return AMDSMI_STATUS_INVAL; + } + + amd::smi::AMDSmiGPUDevice* gpu_device = nullptr; + amdsmi_status_t r = get_gpu_device_from_handle(processor_handle, + &gpu_device); + if (r != AMDSMI_STATUS_SUCCESS) + return r; + + rsmi_ras_feature_info_t rsmi_ras_feature; + r = rsmi_wrapper(rsmi_ras_feature_info_get, processor_handle, + &rsmi_ras_feature); + + if (r != AMDSMI_STATUS_SUCCESS) + return r; + + ras_feature->ecc_correction_schema_flag + = rsmi_ras_feature.ecc_correction_schema_flag; + ras_feature->ras_eeprom_version = rsmi_ras_feature.ras_eeprom_version; + + return AMDSMI_STATUS_SUCCESS; +} + amdsmi_status_t amdsmi_get_gpu_total_ecc_count(amdsmi_processor_handle processor_handle, amdsmi_error_count_t *ec) { AMDSMI_CHECK_INIT(); From 1c23b45a3899dea35fd6be3a3f8eca1f57f97ad0 Mon Sep 17 00:00:00 2001 From: Maisam Arif Date: Thu, 12 Oct 2023 17:45:48 -0500 Subject: [PATCH 06/27] Updated interface & wrapper to work with ras_feature Change-Id: Iadd8c5e736f4dad2662dda2c9587454f00197474 Signed-off-by: Maisam Arif [ROCm/amdsmi commit: f0e6f34bfe97e847c7388b9b69cde2a393c33d27] --- .../amdsmi/py-interface/amdsmi_interface.py | 22 +++++++++++++------ .../amdsmi/py-interface/amdsmi_wrapper.py | 18 +++++++++++++-- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/projects/amdsmi/py-interface/amdsmi_interface.py b/projects/amdsmi/py-interface/amdsmi_interface.py index 425ced72e7..01ce67a793 100644 --- a/projects/amdsmi/py-interface/amdsmi_interface.py +++ b/projects/amdsmi/py-interface/amdsmi_interface.py @@ -863,14 +863,22 @@ def amdsmi_get_gpu_ras_feature_info( raise AmdSmiParameterException( processor_handle, amdsmi_wrapper.amdsmi_processor_handle ) - # Dummy data waiting on population - ras_info = {"eeprom_version": "N/A", - "parity_schema" : "N/A", - "single_bit_schema" : "N/A", - "double_bit_schema" : "N/A", - "poison_schema" : "N/A"} - return ras_info + ras_feature = amdsmi_wrapper.amdsmi_ras_feature_t() + + _check_res( + amdsmi_wrapper.amdsmi_get_gpu_ras_feature_info( + processor_handle, ctypes.byref(ras_feature) + ) + ) + + return { + "eeprom_version": ras_feature.ras_eeprom_version, + "parity_schema" : bool(ras_feature.ecc_correction_schema_flags & 1), + "single_bit_schema" : bool(ras_feature.ecc_correction_schema_flags & 2), + "double_bit_schema" : bool(ras_feature.ecc_correction_schema_flags & 4), + "poison_schema" : bool(ras_feature.ecc_correction_schema_flags & 8) + } def amdsmi_get_gpu_ras_block_features_enabled( diff --git a/projects/amdsmi/py-interface/amdsmi_wrapper.py b/projects/amdsmi/py-interface/amdsmi_wrapper.py index 883ffd5b7f..af8edfe8a0 100644 --- a/projects/amdsmi/py-interface/amdsmi_wrapper.py +++ b/projects/amdsmi/py-interface/amdsmi_wrapper.py @@ -1447,6 +1447,17 @@ struct_amdsmi_gpu_metrics_t._fields_ = [ ] amdsmi_gpu_metrics_t = struct_amdsmi_gpu_metrics_t + +class struct_amdsmi_ras_feature_t(Structure): + pass + +struct_amdsmi_ras_feature_t._pack_ = 1 # source:False +struct_amdsmi_ras_feature_t._fields_ = [ + ('ras_eeprom_version', ctypes.c_uint32), + ('ecc_correction_schema_flag', ctypes.c_uint32), +] + +amdsmi_ras_feature_t = struct_amdsmi_ras_feature_t class struct_amdsmi_error_count_t(Structure): pass @@ -1637,6 +1648,9 @@ amdsmi_get_gpu_od_volt_info.argtypes = [amdsmi_processor_handle, ctypes.POINTER( amdsmi_get_gpu_metrics_info = _libraries['libamd_smi.so'].amdsmi_get_gpu_metrics_info amdsmi_get_gpu_metrics_info.restype = amdsmi_status_t amdsmi_get_gpu_metrics_info.argtypes = [amdsmi_processor_handle, ctypes.POINTER(struct_amdsmi_gpu_metrics_t)] +amdsmi_get_gpu_ras_feature_info = _libraries['libamd_smi.so'].amdsmi_get_gpu_ras_feature_info +amdsmi_get_gpu_ras_feature_info.restype = amdsmi_status_t +amdsmi_get_gpu_ras_feature_info.argtypes = [amdsmi_processor_handle, ctypes.POINTER(struct_amdsmi_ras_feature_t)] amdsmi_set_gpu_clk_range = _libraries['libamd_smi.so'].amdsmi_set_gpu_clk_range amdsmi_set_gpu_clk_range.restype = amdsmi_status_t amdsmi_set_gpu_clk_range.argtypes = [amdsmi_processor_handle, uint64_t, uint64_t, amdsmi_clk_type_t] @@ -1972,7 +1986,7 @@ __all__ = \ 'amdsmi_get_gpu_fan_speed', 'amdsmi_get_gpu_fan_speed_max', 'amdsmi_get_gpu_id', 'amdsmi_get_gpu_memory_reserved_pages', 'amdsmi_get_gpu_memory_total', 'amdsmi_get_gpu_memory_usage', - 'amdsmi_get_gpu_metrics_info', + 'amdsmi_get_gpu_metrics_info', 'amdsmi_get_gpu_ras_feature_info', 'amdsmi_get_gpu_od_volt_curve_regions', 'amdsmi_get_gpu_od_volt_info', 'amdsmi_get_gpu_overdrive_level', 'amdsmi_get_gpu_pci_bandwidth', @@ -2029,7 +2043,7 @@ __all__ = \ 'amdsmi_temperature_metric_t', 'amdsmi_temperature_type_t', 'amdsmi_topo_get_link_type', 'amdsmi_topo_get_link_weight', 'amdsmi_topo_get_numa_node_number', - 'amdsmi_utilization_counter_t', + 'amdsmi_utilization_counter_t', 'struct_amdsmi_ras_feature_t', 'amdsmi_utilization_counter_type_t', 'amdsmi_vbios_info_t', 'amdsmi_version_t', 'amdsmi_voltage_metric_t', 'amdsmi_voltage_type_t', 'amdsmi_vram_info_t', From 06d453c54ebdf6e08eb863c7431901efd375bbc7 Mon Sep 17 00:00:00 2001 From: Maisam Arif Date: Fri, 13 Oct 2023 01:19:40 -0500 Subject: [PATCH 07/27] Updated wrapper generation Signed-off-by: Maisam Arif Change-Id: I2af5704ce62c7d58a13cbc51dcca92f3d35fc07a [ROCm/amdsmi commit: d72f9cca1beb9fc22fe8203e3e0d05237165c97f] --- .../amdsmi/py-interface/amdsmi_wrapper.py | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/projects/amdsmi/py-interface/amdsmi_wrapper.py b/projects/amdsmi/py-interface/amdsmi_wrapper.py index af8edfe8a0..0b702ace1b 100644 --- a/projects/amdsmi/py-interface/amdsmi_wrapper.py +++ b/projects/amdsmi/py-interface/amdsmi_wrapper.py @@ -1447,7 +1447,6 @@ struct_amdsmi_gpu_metrics_t._fields_ = [ ] amdsmi_gpu_metrics_t = struct_amdsmi_gpu_metrics_t - class struct_amdsmi_ras_feature_t(Structure): pass @@ -1588,6 +1587,9 @@ amdsmi_get_gpu_memory_usage.argtypes = [amdsmi_processor_handle, amdsmi_memory_t amdsmi_get_gpu_bad_page_info = _libraries['libamd_smi.so'].amdsmi_get_gpu_bad_page_info amdsmi_get_gpu_bad_page_info.restype = amdsmi_status_t amdsmi_get_gpu_bad_page_info.argtypes = [amdsmi_processor_handle, ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(struct_amdsmi_retired_page_record_t)] +amdsmi_get_gpu_ras_feature_info = _libraries['libamd_smi.so'].amdsmi_get_gpu_ras_feature_info +amdsmi_get_gpu_ras_feature_info.restype = amdsmi_status_t +amdsmi_get_gpu_ras_feature_info.argtypes = [amdsmi_processor_handle, ctypes.POINTER(struct_amdsmi_ras_feature_t)] amdsmi_get_gpu_ras_block_features_enabled = _libraries['libamd_smi.so'].amdsmi_get_gpu_ras_block_features_enabled amdsmi_get_gpu_ras_block_features_enabled.restype = amdsmi_status_t amdsmi_get_gpu_ras_block_features_enabled.argtypes = [amdsmi_processor_handle, amdsmi_gpu_block_t, ctypes.POINTER(amdsmi_ras_err_state_t)] @@ -1648,9 +1650,6 @@ amdsmi_get_gpu_od_volt_info.argtypes = [amdsmi_processor_handle, ctypes.POINTER( amdsmi_get_gpu_metrics_info = _libraries['libamd_smi.so'].amdsmi_get_gpu_metrics_info amdsmi_get_gpu_metrics_info.restype = amdsmi_status_t amdsmi_get_gpu_metrics_info.argtypes = [amdsmi_processor_handle, ctypes.POINTER(struct_amdsmi_gpu_metrics_t)] -amdsmi_get_gpu_ras_feature_info = _libraries['libamd_smi.so'].amdsmi_get_gpu_ras_feature_info -amdsmi_get_gpu_ras_feature_info.restype = amdsmi_status_t -amdsmi_get_gpu_ras_feature_info.argtypes = [amdsmi_processor_handle, ctypes.POINTER(struct_amdsmi_ras_feature_t)] amdsmi_set_gpu_clk_range = _libraries['libamd_smi.so'].amdsmi_set_gpu_clk_range amdsmi_set_gpu_clk_range.restype = amdsmi_status_t amdsmi_set_gpu_clk_range.argtypes = [amdsmi_processor_handle, uint64_t, uint64_t, amdsmi_clk_type_t] @@ -1986,7 +1985,7 @@ __all__ = \ 'amdsmi_get_gpu_fan_speed', 'amdsmi_get_gpu_fan_speed_max', 'amdsmi_get_gpu_id', 'amdsmi_get_gpu_memory_reserved_pages', 'amdsmi_get_gpu_memory_total', 'amdsmi_get_gpu_memory_usage', - 'amdsmi_get_gpu_metrics_info', 'amdsmi_get_gpu_ras_feature_info', + 'amdsmi_get_gpu_metrics_info', 'amdsmi_get_gpu_od_volt_curve_regions', 'amdsmi_get_gpu_od_volt_info', 'amdsmi_get_gpu_overdrive_level', 'amdsmi_get_gpu_pci_bandwidth', @@ -1995,8 +1994,8 @@ __all__ = \ 'amdsmi_get_gpu_power_profile_presets', 'amdsmi_get_gpu_process_info', 'amdsmi_get_gpu_process_list', 'amdsmi_get_gpu_ras_block_features_enabled', - 'amdsmi_get_gpu_revision', 'amdsmi_get_gpu_subsystem_id', - 'amdsmi_get_gpu_subsystem_name', + 'amdsmi_get_gpu_ras_feature_info', 'amdsmi_get_gpu_revision', + 'amdsmi_get_gpu_subsystem_id', 'amdsmi_get_gpu_subsystem_name', 'amdsmi_get_gpu_topo_numa_affinity', 'amdsmi_get_gpu_total_ecc_count', 'amdsmi_get_gpu_vbios_info', 'amdsmi_get_gpu_vendor_name', 'amdsmi_get_gpu_volt_metric', @@ -2027,7 +2026,8 @@ __all__ = \ 'amdsmi_power_profile_status_t', 'amdsmi_power_type_t', 'amdsmi_proc_info_t', 'amdsmi_process_handle_t', 'amdsmi_process_info_t', 'amdsmi_processor_handle', - 'amdsmi_range_t', 'amdsmi_ras_err_state_t', 'amdsmi_reset_gpu', + 'amdsmi_range_t', 'amdsmi_ras_err_state_t', + 'amdsmi_ras_feature_t', 'amdsmi_reset_gpu', 'amdsmi_reset_gpu_fan', 'amdsmi_reset_gpu_xgmi_error', 'amdsmi_retired_page_record_t', 'amdsmi_set_clk_freq', 'amdsmi_set_gpu_clk_range', @@ -2043,7 +2043,7 @@ __all__ = \ 'amdsmi_temperature_metric_t', 'amdsmi_temperature_type_t', 'amdsmi_topo_get_link_type', 'amdsmi_topo_get_link_weight', 'amdsmi_topo_get_numa_node_number', - 'amdsmi_utilization_counter_t', 'struct_amdsmi_ras_feature_t', + 'amdsmi_utilization_counter_t', 'amdsmi_utilization_counter_type_t', 'amdsmi_vbios_info_t', 'amdsmi_version_t', 'amdsmi_voltage_metric_t', 'amdsmi_voltage_type_t', 'amdsmi_vram_info_t', @@ -2064,7 +2064,8 @@ __all__ = \ 'struct_amdsmi_power_cap_info_t', 'struct_amdsmi_power_info_t', 'struct_amdsmi_power_profile_status_t', 'struct_amdsmi_proc_info_t', 'struct_amdsmi_process_info_t', - 'struct_amdsmi_range_t', 'struct_amdsmi_retired_page_record_t', + 'struct_amdsmi_range_t', 'struct_amdsmi_ras_feature_t', + 'struct_amdsmi_retired_page_record_t', 'struct_amdsmi_utilization_counter_t', 'struct_amdsmi_vbios_info_t', 'struct_amdsmi_version_t', 'struct_amdsmi_vram_info_t', 'struct_amdsmi_vram_usage_t', From 6cee8730b1a025502d8483f0624958a90165d2fb Mon Sep 17 00:00:00 2001 From: Maisam Arif Date: Thu, 12 Oct 2023 16:44:07 -0500 Subject: [PATCH 08/27] Add yaml as dependency for Ubuntu Signed-off-by: Maisam Arif Change-Id: Ie3da877522acbf320feac4d9d34fb9344d40f339 [ROCm/amdsmi commit: de892bab691e6cfca47775a59f6a1a632e3668c1] --- projects/amdsmi/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/amdsmi/CMakeLists.txt b/projects/amdsmi/CMakeLists.txt index c4b9421130..359c24bdef 100755 --- a/projects/amdsmi/CMakeLists.txt +++ b/projects/amdsmi/CMakeLists.txt @@ -229,7 +229,7 @@ endif() #Debian package specific variables set(CPACK_DEBIAN_PACKAGE_PROVIDES "amd-smi") -set(CPACK_DEBIAN_PACKAGE_RECOMMENDS "sudo, libdrm-dev") +set(CPACK_DEBIAN_PACKAGE_RECOMMENDS "sudo, libdrm-dev, python3-yaml") set(CPACK_DEBIAN_ASAN_PACKAGE_RECOMMENDS ${CPACK_DEBIAN_PACKAGE_RECOMMENDS}) set(CPACK_DEBIAN_DEV_PACKAGE_RECOMMENDS ${CPACK_DEBIAN_PACKAGE_RECOMMENDS}) set(CPACK_DEBIAN_ASAN_PACKAGE_PROVIDES "${AMD_SMI_PACKAGE}-asan") From 8beb9381886142649e9a508ccede3d19d0d4d433 Mon Sep 17 00:00:00 2001 From: Deepak Mewar Date: Tue, 10 Oct 2023 06:18:05 -0400 Subject: [PATCH 09/27] build issue fix with sample test code Change-Id: I03890879253f1be74311cf613a9baad55d197f75 [ROCm/amdsmi commit: 1f0f5ab63fd97931198818c4781209134ab61907] --- projects/amdsmi/example/amdsmi_esmi_intg_example.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/projects/amdsmi/example/amdsmi_esmi_intg_example.cc b/projects/amdsmi/example/amdsmi_esmi_intg_example.cc index 28d4784121..f213b8a8f9 100644 --- a/projects/amdsmi/example/amdsmi_esmi_intg_example.cc +++ b/projects/amdsmi/example/amdsmi_esmi_intg_example.cc @@ -436,15 +436,15 @@ int main(int argc, char **argv) { cout<<"\n-------------------------------------------------\n"; - amdsmi_dimm_power_t pow; + amdsmi_dimm_power_t p; cout<<"\n| Socket DIMM power consumption\t\t |\n"; - ret = amdsmi_get_cpu_dimm_power_consumption(sockets[i], i, dimm_addr, &pow); + ret = amdsmi_get_cpu_dimm_power_consumption(sockets[i], i, dimm_addr, &p); CHK_AMDSMI_RET(ret) if(ret) { - cout<<"\n| Power(mWatts)\t\t |"< Date: Fri, 13 Oct 2023 06:32:34 -0500 Subject: [PATCH 10/27] Fixed spacing in amd-smi tool output Signed-off-by: Maisam Arif Change-Id: I83cb040b81a4d3653417ba7399160eb81e95ce33 [ROCm/amdsmi commit: c7726bde3d3054d9fdf8575e26f21104d5e2589e] --- projects/amdsmi/amdsmi_cli/amdsmi_parser.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_parser.py b/projects/amdsmi/amdsmi_cli/amdsmi_parser.py index 1d737e0a5f..97c3a53573 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_parser.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_parser.py @@ -33,6 +33,19 @@ from amdsmi_helpers import AMDSMIHelpers import amdsmi_cli_exceptions +# Custom Help Formatter for increasing the action max length +class SubparserHelpFormatter(argparse.HelpFormatter): + def __init__(self, prog, + indent_increment=2, + max_help_position=24, + width=90): + super().__init__(prog, + indent_increment=indent_increment, + max_help_position=max_help_position, + width=width) + self._action_max_length = 20 + + class AMDSMIParser(argparse.ArgumentParser): """Unified Parser for AMDSMI CLI. This parser doesn't access amdsmi's lib directly,but via AMDSMIHelpers, @@ -56,9 +69,7 @@ class AMDSMIParser(argparse.ArgumentParser): # Adjust argument parser options super().__init__( - formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, - max_help_position=80, - width=90), + formatter_class= lambda prog: SubparserHelpFormatter(prog), description=f"AMD System Management Interface | {version_string} | {platform_string}", add_help=True, prog=program_name) From fad0af9ba2e0e1470b95e362abf943dbab856c22 Mon Sep 17 00:00:00 2001 From: Deepak Mewar Date: Wed, 11 Oct 2023 06:07:02 -0400 Subject: [PATCH 11/27] esmi: remove energy reporting, fix errors from clang compiler Clang compiler reporting errors while generating python wrappers for esmi lib Change-Id: I62352aba3b87f9a6b044c97af6b9fd649612b622 [ROCm/amdsmi commit: ee890c50605d9996343136cfbfa8709721246a7b] --- .../example/amdsmi_esmi_intg_example.cc | 47 +------------------ projects/amdsmi/include/amd_smi/amdsmi.h | 11 ++++- projects/amdsmi/src/amd_smi/amd_smi.cc | 4 +- 3 files changed, 14 insertions(+), 48 deletions(-) diff --git a/projects/amdsmi/example/amdsmi_esmi_intg_example.cc b/projects/amdsmi/example/amdsmi_esmi_intg_example.cc index f213b8a8f9..a17554b3e6 100644 --- a/projects/amdsmi/example/amdsmi_esmi_intg_example.cc +++ b/projects/amdsmi/example/amdsmi_esmi_intg_example.cc @@ -135,24 +135,6 @@ int main(int argc, char **argv) { uint32_t err_bits = 0; uint64_t pkg_input; - cout<<"\n-------------------------------------------------"; - cout<<"\n| Sensor Name\t\t\t |"; - for (uint32_t i = 0; i < socket_count; i++) { - cout<(pkg_input)/1000000000<<"\t|"; - } else { - err_bits |= 1 << ret; - cout<<" NA (Err:" <(core_input)/1000000<<" Joules\t\t|\n"; - cout<<"-------------------------------------------------\n"; - - core_input = 0; - cout<<"\n| CPU energies in Joules:\t\t\t\t\t\t\t\t\t|"; - for (uint32_t j = 0; j < core_count; j++) { - ret = amdsmi_get_cpu_core_energy(processor_handles[j], j, &core_input); - CHK_AMDSMI_RET(ret) - if(!(j % 8)) { - if(j < 10) - cout<<"\n| cpu [0"<(core_input)/1000000<<" "; - if (j % 8 == 7) - cout<<"\t|"; - } - cout<<"\n-------------------------------------------------\n"; - uint32_t c_clk = 0; ret = amdsmi_get_cpu_core_current_freq_limit(processor_handles[i], i, &c_clk); CHK_AMDSMI_RET(ret) @@ -597,7 +554,7 @@ int main(int argc, char **argv) { uint32_t bw; char *link = "P0"; io_link.link_name = link; - io_link.bw_type = static_cast(1) ; + io_link.bw_type = static_cast(1) ; ret = amdsmi_get_cpu_current_io_bandwidth(sockets[i], i, io_link, &bw); CHK_AMDSMI_RET(ret) @@ -614,7 +571,7 @@ int main(int argc, char **argv) { char *link1 = "P0"; int bw_ind = 1; xgmi_link.link_name = link1; - xgmi_link.bw_type = static_cast(1<(1<(io_link.bw_type); *io_bw = bw; return AMDSMI_STATUS_SUCCESS; @@ -2852,7 +2852,7 @@ amdsmi_status_t amdsmi_get_cpu_current_xgmi_bw(amdsmi_cpusocket_handle socket_ha return status; link.link_name = io_link.link_name; - link.bw_type= io_link.bw_type; + link.bw_type= static_cast(io_link.bw_type); *xgmi_bw = bw; return AMDSMI_STATUS_SUCCESS; From d1450bbbcc505dbecba9634d988970b9bf42ac31 Mon Sep 17 00:00:00 2001 From: Charis Poag Date: Thu, 12 Oct 2023 10:54:46 -0500 Subject: [PATCH 12/27] bdfid fix for partition & xgmi nodes * Updates: - [API] After discovering all amd gpus, we now properly map correct bdf (xgmi nodes). Especially important for partition changes - aka secondary nodes. - [API] While adding new secondary nodes we now have better grouping -> due to resorting based on kfd properties list & matching to primary uniqueid - [API] All secondary nodes are now AddToDeviceList with correct bdf (location id), provided by kfd - [API] Modified AddToDeviceList(..., uint64_t bdfid): providing an optional field - bdfid. This allows working around primary pcie cards with xgmi nodes - [API] Utils - cpplint minor fixes - [Example] Removed all endl references w/ newline, fixed spacing, and some incorrect values displaying as hex (needed dec representation) - [API] kfd node functions - now print full path of file for trace logs - [Tests] power_read.cc: Added in generic power test to confirm guaranteeing specific return values Change-Id: I143474e8d64c4915a966e789be6bcea4fa7f4472 Signed-off-by: Charis Poag [ROCm/amdsmi commit: 6f1afd2678139dd1b6421a81b225f0c32da574b0] --- .../amdsmi/include/rocm_smi/rocm_smi_main.h | 2 +- .../rocm_smi/example/rocm_smi_example.cc | 23 ++-- projects/amdsmi/src/rocm_smi_kfd.cc | 10 ++ projects/amdsmi/src/rocm_smi_main.cc | 127 +++++++++++++++--- projects/amdsmi/src/rocm_smi_utils.cc | 6 +- .../rocm_smi_test/functional/power_read.cc | 2 + 6 files changed, 137 insertions(+), 33 deletions(-) diff --git a/projects/amdsmi/include/rocm_smi/rocm_smi_main.h b/projects/amdsmi/include/rocm_smi/rocm_smi_main.h index 8b60324988..1cd2ec343f 100755 --- a/projects/amdsmi/include/rocm_smi/rocm_smi_main.h +++ b/projects/amdsmi/include/rocm_smi/rocm_smi_main.h @@ -128,7 +128,7 @@ class RocmSMI { std::map, std::shared_ptr> io_link_map_; std::map dev_ind_to_node_ind_map_; - void AddToDeviceList(std::string dev_name); + void AddToDeviceList(std::string dev_name, uint64_t bdfid = 0); void GetEnvVariables(void); std::shared_ptr FindMonitor(std::string monitor_path); diff --git a/projects/amdsmi/rocm_smi/example/rocm_smi_example.cc b/projects/amdsmi/rocm_smi/example/rocm_smi_example.cc index a2df8e66ee..fa01b42978 100755 --- a/projects/amdsmi/rocm_smi/example/rocm_smi_example.cc +++ b/projects/amdsmi/rocm_smi/example/rocm_smi_example.cc @@ -58,8 +58,8 @@ #define PRINT_RSMI_ERR(RET) { \ if (RET != RSMI_STATUS_SUCCESS) { \ std::cout << "[ERROR] RSMI call returned " << (RET) \ - << " at line " << __LINE__ << std::endl; \ - std::cout << amd::smi::getRSMIStatusString(RET) << std::endl; \ + << " at line " << __LINE__ << "\n"; \ + std::cout << amd::smi::getRSMIStatusString(RET) << "\n"; \ } \ } @@ -718,7 +718,7 @@ int main() { rsmi_num_monitor_devices(&num_monitor_devs); for (uint32_t i = 0; i < num_monitor_devs; ++i) { - std::cout << "\t**Device #: " << std::dec << i << std::endl; + std::cout << "\t**Device #: " << std::dec << i << "\n"; ret = rsmi_dev_id_get(i, &val_ui16); CHK_RSMI_RET_I(ret) std::cout << "\t**Device ID: 0x" << std::hex << val_ui16 << "\n"; @@ -765,8 +765,9 @@ int main() { uint64_t max_bandwidth = 0; ret = rsmi_minmax_bandwidth_get(0, i, &min_bandwidth, &max_bandwidth); CHK_RSMI_NOT_SUPPORTED_OR_UNEXPECTED_DATA_RET(ret) - std::cout << "\nMinimum Bandwidth: " << min_bandwidth - << "\nMaximum Bandwidth: " << max_bandwidth; + std::cout << "\n\t**\tMinimum Bandwidth: " << std::dec << min_bandwidth + << "\n\t**\tMaximum Bandwidth: " << std::dec + << max_bandwidth << "\n"; } else { std::cout << "Not Supported\n"; } @@ -813,7 +814,7 @@ int main() { ret = rsmi_dev_temp_metric_get(i, RSMI_TEMP_TYPE_EDGE, rsmi_temperature_metric_t::RSMI_TEMP_CURRENT, &val_i64); if (ret == RSMI_STATUS_SUCCESS) { - std::cout << val_i64/1000 << "C" << "\n"; + std::cout << std::dec << val_i64/1000 << " C" << "\n"; } CHK_RSMI_NOT_SUPPORTED_RET(ret) @@ -821,7 +822,7 @@ int main() { ret = rsmi_dev_temp_metric_get(i, RSMI_TEMP_TYPE_JUNCTION, rsmi_temperature_metric_t::RSMI_TEMP_CURRENT, &val_i64); if (ret == RSMI_STATUS_SUCCESS) { - std::cout << (val_i64 / 1000) << "C" << std::endl; + std::cout << std::dec << (val_i64 / 1000) << " C" << "\n"; } CHK_RSMI_NOT_SUPPORTED_RET(ret) @@ -869,14 +870,14 @@ int main() { std::cout << "\t**Average Power Usage: "; ret = rsmi_dev_power_ave_get(i, 0, &val_ui64); if (ret == RSMI_STATUS_SUCCESS) { - std::cout << convert_mw_to_w(val_ui64) << " W" << std::endl; + std::cout << convert_mw_to_w(val_ui64) << " W" << "\n"; } CHK_RSMI_NOT_SUPPORTED_RET(ret) std::cout << "\t**Current Socket Power Usage: "; ret = rsmi_dev_current_socket_power_get(i, &val_ui64); if (ret == RSMI_STATUS_SUCCESS) { - std::cout << convert_mw_to_w(val_ui64) << " W" << std::endl; + std::cout << convert_mw_to_w(val_ui64) << " W" << "\n"; } CHK_RSMI_NOT_SUPPORTED_RET(ret) @@ -884,7 +885,7 @@ int main() { ret = rsmi_dev_power_get(i, &val_ui64, &power_type); if (ret == RSMI_STATUS_SUCCESS) { std::cout << "[" << amd::smi::power_type_string(power_type) << "] " - << convert_mw_to_w(val_ui64) << " W" << std::endl; + << convert_mw_to_w(val_ui64) << " W" << "\n"; } CHK_RSMI_NOT_SUPPORTED_RET(ret) std::cout << "\t=======" << "\n"; @@ -897,7 +898,7 @@ int main() { return 0; } - for (uint32_t i = 0; i< num_monitor_devs; ++i) { + for (uint32_t i = 0; i < num_monitor_devs; ++i) { ret = test_set_overdrive(i); CHK_AND_PRINT_RSMI_ERR_RET(ret) diff --git a/projects/amdsmi/src/rocm_smi_kfd.cc b/projects/amdsmi/src/rocm_smi_kfd.cc index 9b7e0e5eaa..40984b430b 100755 --- a/projects/amdsmi/src/rocm_smi_kfd.cc +++ b/projects/amdsmi/src/rocm_smi_kfd.cc @@ -890,9 +890,12 @@ int KFDNode::get_used_memory(uint64_t* used) { int read_node_properties(uint32_t node, std::string property_name, uint64_t *val) { std::ostringstream ss; + std::string propertiesFullPath = "/sys/class/kfd/kfd/topology/nodes/" + + std::to_string(node) + "/properties"; int retVal = EINVAL; if (property_name.empty() || val == nullptr) { ss << __PRETTY_FUNCTION__ + << " | File: " << propertiesFullPath << " | Issue: Could not read node #" << std::to_string(node) << ", property_name is empty or *val is nullptr " << " | return = " << std::to_string(retVal) @@ -905,6 +908,7 @@ int read_node_properties(uint32_t node, std::string property_name, if (KFDNodeSupported(node)) { retVal = myNode->get_property_value(property_name, val); ss << __PRETTY_FUNCTION__ + << " | File: " << propertiesFullPath << " | Successfully read node #" << std::to_string(node) << " for property_name = " << property_name << " | Data (" << property_name << ") * val = " @@ -915,6 +919,7 @@ int read_node_properties(uint32_t node, std::string property_name, } else { retVal = 1; ss << __PRETTY_FUNCTION__ + << " | File: " << propertiesFullPath << " | Issue: Could not read node #" << std::to_string(node) << ", KFD node was an unsupported node." << " | return = " << std::to_string(retVal) @@ -927,9 +932,12 @@ int read_node_properties(uint32_t node, std::string property_name, // /sys/class/kfd/kfd/topology/nodes/*/gpu_id int get_gpu_id(uint32_t node, uint64_t *gpu_id) { std::ostringstream ss; + std::string gpu_id_FullPath = "/sys/class/kfd/kfd/topology/nodes/" + + std::to_string(node) + "/gpu_id"; int retVal = EINVAL; if (gpu_id == nullptr) { ss << __PRETTY_FUNCTION__ + << " | File: " << gpu_id_FullPath << " | Issue: Could not read node #" << std::to_string(node) << ", gpu_id is a nullptr " << " | return = " << std::to_string(retVal) @@ -942,6 +950,7 @@ int get_gpu_id(uint32_t node, uint64_t *gpu_id) { if (KFDNodeSupported(node)) { retVal = ReadKFDGpuId(node, gpu_id); ss << __PRETTY_FUNCTION__ + << " | File: " << gpu_id_FullPath << " | Successfully read node #" << std::to_string(node) << " for gpu_id" << " | Data (gpu_id) *gpu_id = " @@ -952,6 +961,7 @@ int get_gpu_id(uint32_t node, uint64_t *gpu_id) { } else { retVal = 1; ss << __PRETTY_FUNCTION__ + << " | File: " << gpu_id_FullPath << " | Issue: Could not read node #" << std::to_string(node) << ", KFD node was an unsupported node." << " | return = " << std::to_string(retVal) diff --git a/projects/amdsmi/src/rocm_smi_main.cc b/projects/amdsmi/src/rocm_smi_main.cc index 05851a88e6..3647f8e35d 100755 --- a/projects/amdsmi/src/rocm_smi_main.cc +++ b/projects/amdsmi/src/rocm_smi_main.cc @@ -312,6 +312,7 @@ RocmSMI::Initialize(uint64_t flags) { auto i = 0; uint32_t ret; int i_ret; + std::ostringstream ss; LOG_ALWAYS("=============== ROCM SMI initialize ================"); ROCmLogging::Logger::getInstance()->enableAllLogLevels(); @@ -355,9 +356,32 @@ RocmSMI::Initialize(uint64_t flags) { if (ConstructBDFID(device->path(), &bdfid) != 0) { std::cerr << "Failed to construct BDFID." << std::endl; ret = 1; + } else if (device->bdfid() != UINT64_MAX && device->bdfid() != bdfid) { + // handles secondary partitions - compute partition feature nodes + ss << __PRETTY_FUNCTION__ + << " | [before] device->path() = " << device->path() + << "\n | bdfid = " << bdfid + << "\n | device->bdfid() = " << device->bdfid() + << "\n | (xgmi node) setting to setting " + << "device->set_bdfid(device->bdfid())"; + LOG_TRACE(ss); + device->set_bdfid(device->bdfid()); } else { + // legacy & pcie card updates + ss << __PRETTY_FUNCTION__ + << " | [before] device->path() = " << device->path() + << "\n | bdfid = " << bdfid + << "\n | device->bdfid() = " << device->bdfid() + << "\n | (legacy/pcie card) setting device->set_bdfid(bdfid)"; + LOG_TRACE(ss); device->set_bdfid(bdfid); } + ss << __PRETTY_FUNCTION__ + << " | [after] device->path() = " << device->path() + << "\n | bdfid = " << bdfid + << "\n | device->bdfid() = " << device->bdfid() + << "\n | final update: device->bdfid() holds correct device bdf"; + LOG_TRACE(ss); } if (ret != 0) { throw amd::smi::rsmi_exception(RSMI_INITIALIZATION_ERROR, @@ -386,7 +410,6 @@ RocmSMI::Initialize(uint64_t flags) { // Remove any drm nodes that don't have a corresponding readable kfd node. // kfd nodes will not be added if their properties file is not readable. - std::ostringstream ss; auto dev_iter = devices_.begin(); while (dev_iter != devices_.end()) { uint64_t bdfid = (*dev_iter)->bdfid(); @@ -665,8 +688,8 @@ RocmSMI::FindMonitor(std::string monitor_path) { return m; } -void -RocmSMI::AddToDeviceList(std::string dev_name) { + +void RocmSMI::AddToDeviceList(std::string dev_name, uint64_t bdfid) { std::ostringstream ss; ss << __PRETTY_FUNCTION__ << " | ======= start ======="; LOG_TRACE(ss); @@ -684,10 +707,15 @@ RocmSMI::AddToDeviceList(std::string dev_name) { dev->set_drm_render_minor(GetDrmRenderMinor(dev_path)); dev->set_card_index(card_indx); GetSupportedEventGroups(card_indx, dev->supported_event_groups()); + if (bdfid != 0) { + dev->set_bdfid(bdfid); + } devices_.push_back(dev); - ss << __PRETTY_FUNCTION__ << " | Adding to device list dev_name = " - << dev_name << " | path = " << dev_path + ss << __PRETTY_FUNCTION__ + << " | Adding to device list dev_name = " << dev_name + << " | path = " << dev_path + << " | bdfid = " << bdfid << " | card index = " << std::to_string(card_indx) << " | "; LOG_DEBUG(ss); } @@ -768,19 +796,24 @@ uint32_t RocmSMI::DiscoverAmdgpuDevices(void) { uint32_t s_node_id = 0; uint64_t s_gpu_id = 0; uint64_t s_unique_id = 0; + uint64_t s_location_id = 0; }; - // allSystemNodes[key = unique_id] => {node_id, gpu_id, unique_id} + // allSystemNodes[key = unique_id] => {node_id, gpu_id, unique_id, + // location_id} std::multimap allSystemNodes; uint32_t node_id = 0; while (true) { - uint64_t gpu_id = 0, unique_id = 0; + uint64_t gpu_id = 0, unique_id = 0, location_id = 0; int ret_gpu_id = get_gpu_id(node_id, &gpu_id); int ret_unique_id = read_node_properties(node_id, "unique_id", &unique_id); - if (ret_gpu_id == 0 || ret_unique_id == 0) { + int ret_loc_id = + read_node_properties(node_id, "location_id", &location_id); + if (ret_gpu_id == 0 || ret_unique_id == 0 || ret_loc_id == 0) { systemNode myNode; myNode.s_node_id = node_id; myNode.s_gpu_id = gpu_id; myNode.s_unique_id = unique_id; + myNode.s_location_id = location_id; if (gpu_id != 0) { // only add gpu nodes, 0 = CPU allSystemNodes.emplace(unique_id, myNode); } @@ -795,6 +828,7 @@ uint32_t RocmSMI::DiscoverAmdgpuDevices(void) { ss << "\n[node_id = " << std::to_string(i.second.s_node_id) << "; gpu_id = " << std::to_string(i.second.s_gpu_id) << "; unique_id = " << std::to_string(i.second.s_unique_id) + << "; location_id = " << std::to_string(i.second.s_location_id) << "], "; } ss << "}"; @@ -807,6 +841,14 @@ uint32_t RocmSMI::DiscoverAmdgpuDevices(void) { path += "/card"; path += std::to_string(cardId); uint64_t primary_unique_id = 0; + uint64_t device_uuid = 0; + bool doesDeviceSupportPartitions = false; + // get current partition + int kSize = 256; + char computePartition[kSize]; + std::string strCompPartition = "UNKNOWN"; + uint32_t numMonDevices = 0; + rsmi_num_monitor_devices(&numMonDevices); // each identified gpu card node is a primary node for // potential matching unique ids @@ -814,7 +856,25 @@ uint32_t RocmSMI::DiscoverAmdgpuDevices(void) { (init_options_ & RSMI_INIT_FLAG_ALL_GPUS)) { std::string d_name = "card"; d_name += std::to_string(cardId); - AddToDeviceList(d_name); + uint32_t numMonDevices = 0; + rsmi_num_monitor_devices(&numMonDevices); + if (rsmi_dev_compute_partition_get(cardAdded, computePartition, kSize) + == RSMI_STATUS_SUCCESS) { + strCompPartition = computePartition; + doesDeviceSupportPartitions = true; + } + rsmi_status_t ret_unique_id = + rsmi_dev_unique_id_get(cardAdded, &device_uuid); + auto temp_numb_nodes = allSystemNodes.count(device_uuid); + auto primaryBdfId = + allSystemNodes.lower_bound(device_uuid)->second.s_location_id; + if (doesDeviceSupportPartitions && temp_numb_nodes > 1 + && ret_unique_id == RSMI_STATUS_SUCCESS) { + // helps identify xgmi nodes (secondary nodes) easier + AddToDeviceList(d_name, primaryBdfId); + } else { + AddToDeviceList(d_name, UINT64_MAX); + } ss << __PRETTY_FUNCTION__ << " | Ordered system nodes seen in lookup = {"; @@ -822,12 +882,14 @@ uint32_t RocmSMI::DiscoverAmdgpuDevices(void) { ss << "\n[node_id = " << std::to_string(i.second.s_node_id) << "; gpu_id = " << std::to_string(i.second.s_gpu_id) << "; unique_id = " << std::to_string(i.second.s_unique_id) + << "; location_id = " << std::to_string(i.second.s_location_id) << "], "; } ss << "}"; LOG_DEBUG(ss); uint64_t temp_primary_unique_id = 0; + uint64_t primary_location_id = 0; if (allSystemNodes.empty()) { cardAdded++; ss << __PRETTY_FUNCTION__ @@ -837,16 +899,11 @@ uint32_t RocmSMI::DiscoverAmdgpuDevices(void) { } // get current partition - const int kSize = 256; - char computePartition[kSize]; - std::string strCompPartition = "UNKNOWN"; - uint32_t numMonDevices = 0; rsmi_num_monitor_devices(&numMonDevices); if (rsmi_dev_compute_partition_get(cardAdded, computePartition, kSize) == RSMI_STATUS_SUCCESS) { strCompPartition = computePartition; } - uint64_t device_uuid = 0; if (rsmi_dev_unique_id_get(cardAdded, &device_uuid) != RSMI_STATUS_SUCCESS) { cardAdded++; @@ -860,7 +917,7 @@ uint32_t RocmSMI::DiscoverAmdgpuDevices(void) { temp_primary_unique_id = allSystemNodes.find(device_uuid)->second.s_unique_id; - auto temp_numb_nodes = allSystemNodes.count(temp_primary_unique_id); + temp_numb_nodes = allSystemNodes.count(temp_primary_unique_id); ss << __PRETTY_FUNCTION__ << " | device/node id (cardId) = " << std::to_string(cardId) @@ -892,12 +949,46 @@ uint32_t RocmSMI::DiscoverAmdgpuDevices(void) { LOG_DEBUG(ss); while (numb_nodes > 1) { std::string secNode = "card"; - secNode += std::to_string(cardId); // add the primary node id - AddToDeviceList(secNode); + secNode += std::to_string(cardId); // maps the primary node card to + // secondary - allows get/sets + auto it = allSystemNodes.lower_bound(device_uuid); + auto it_end = allSystemNodes.upper_bound(device_uuid); + if (numb_nodes == temp_numb_nodes) { + auto removalNodeId = it->second.s_node_id; + auto removalGpuId = it->second.s_gpu_id; + auto removalUniqueId = it->second.s_unique_id; + auto removalLocId = it->second.s_location_id; + auto nodesErased = 1; + primary_location_id = removalLocId; + allSystemNodes.erase(it++); + ss << __PRETTY_FUNCTION__ + << "\nPRIMARY --> num_nodes == temp_numb_nodes; ERASING " + << std::to_string(nodesErased) << " node -> [node_id = " + << std::to_string(removalNodeId) + << "; gpu_id = " << std::to_string(removalGpuId) + << "; unique_id = " << std::to_string(removalUniqueId) + << "; location_id = " << std::to_string(removalLocId) + << "]"; + LOG_DEBUG(ss); + } + if (it == it_end) { + break; + } + auto myBdfId = it->second.s_location_id; + AddToDeviceList(secNode, myBdfId); + ss << __PRETTY_FUNCTION__ + << "\nSECONDARY --> After adding new node; ERASING -> [node_id = " + << std::to_string(it->second.s_node_id) + << "; gpu_id = " << std::to_string(it->second.s_gpu_id) + << "; unique_id = " << std::to_string(it->second.s_unique_id) + << "; location_id = " << std::to_string(it->second.s_location_id) + << "]"; + LOG_DEBUG(ss); + allSystemNodes.erase(it++); numb_nodes--; cardAdded++; } - // remove already added nodes associated with current card + // remove any remaining nodes associated with current card auto erasedNodes = allSystemNodes.erase(primary_unique_id); ss << __PRETTY_FUNCTION__ << " | After finding primary_unique_id = " << std::to_string(primary_unique_id) << " erased " diff --git a/projects/amdsmi/src/rocm_smi_utils.cc b/projects/amdsmi/src/rocm_smi_utils.cc index db11f0645c..3d74c7e7f1 100755 --- a/projects/amdsmi/src/rocm_smi_utils.cc +++ b/projects/amdsmi/src/rocm_smi_utils.cc @@ -520,7 +520,7 @@ std::vector readEntireFile(std::string path) { void displayAppTmpFilesContent() { std::vector tmpFiles = getListOfAppTmpFiles(); if (!tmpFiles.empty()) { - for (auto &x: tmpFiles) { + for (auto &x : tmpFiles) { std::string out = readFile(x); std::cout << __PRETTY_FUNCTION__ << " | Temporary file: " << x << "; Contained content: " << out << std::endl; @@ -539,7 +539,7 @@ std::string debugVectorContent(std::vector v) { for (auto it=v.begin(); it < v.end(); it++) { ss << *it; auto temp_it = it; - if(++temp_it != v.end()) { + if (++temp_it != v.end()) { ss << ", "; } } @@ -557,7 +557,7 @@ std::string displayAllDevicePaths(std::vector> v) { for (auto it=v.begin(); it < v.end(); it++) { ss << (*it)->path(); auto temp_it = it; - if(++temp_it != v.end()) { + if (++temp_it != v.end()) { ss << ", "; } } diff --git a/projects/amdsmi/tests/rocm_smi_test/functional/power_read.cc b/projects/amdsmi/tests/rocm_smi_test/functional/power_read.cc index f379fd48c8..e5c636b0b8 100755 --- a/projects/amdsmi/tests/rocm_smi_test/functional/power_read.cc +++ b/projects/amdsmi/tests/rocm_smi_test/functional/power_read.cc @@ -167,6 +167,8 @@ void TestPowerRead::Run(void) { err = rsmi_dev_power_get(i, &val_ui64, &type); ASSERT_TRUE(err == RSMI_STATUS_SUCCESS || err == RSMI_STATUS_NOT_SUPPORTED); + ASSERT_TRUE(type == RSMI_AVERAGE_POWER || type == RSMI_CURRENT_POWER + || type == RSMI_INVALID_POWER); if (err == RSMI_STATUS_NOT_SUPPORTED) { std::cout << From e77abc0a1d45305ed5db181a4f233c160d1e0059 Mon Sep 17 00:00:00 2001 From: Maisam Arif Date: Fri, 13 Oct 2023 01:41:14 -0500 Subject: [PATCH 13/27] Added memory & compute partitions to amd-smi lib Signed-off-by: Maisam Arif Change-Id: If3acea6ad281298f1f05785b2e6d8e70fae8d89b [ROCm/amdsmi commit: 1f8d9cb9efdbbb05dabf50fec974e8fd7d12a208] --- projects/amdsmi/include/amd_smi/amdsmi.h | 302 +++++++++++++++--- projects/amdsmi/py-interface/README.md | 187 +++++++++++ .../amdsmi/py-interface/amdsmi_interface.py | 109 +++++++ .../amdsmi/py-interface/amdsmi_wrapper.py | 105 ++++-- .../rocm_smi/include/rocm_smi/rocm_smi.h | 26 +- projects/amdsmi/src/amd_smi/amd_smi.cc | 46 +++ 6 files changed, 703 insertions(+), 72 deletions(-) diff --git a/projects/amdsmi/include/amd_smi/amdsmi.h b/projects/amdsmi/include/amd_smi/amdsmi.h index d35b8621b6..4199547127 100644 --- a/projects/amdsmi/include/amd_smi/amdsmi.h +++ b/projects/amdsmi/include/amd_smi/amdsmi.h @@ -221,6 +221,45 @@ typedef enum { CLK_TYPE__MAX = CLK_TYPE_DCLK1 } amdsmi_clk_type_t; +/** + * @brief Compute Partition. This enum is used to identify + * various compute partitioning settings. + */ +typedef enum { + COMPUTE_PARTITION_INVALID = 0, + COMPUTE_PARTITION_CPX, //!< Core mode (CPX)- Per-chip XCC with + //!< shared memory + COMPUTE_PARTITION_SPX, //!< Single GPU mode (SPX)- All XCCs work + //!< together with shared memory + COMPUTE_PARTITION_DPX, //!< Dual GPU mode (DPX)- Half XCCs work + //!< together with shared memory + COMPUTE_PARTITION_TPX, //!< Triple GPU mode (TPX)- One-third XCCs + //!< work together with shared memory + COMPUTE_PARTITION_QPX //!< Quad GPU mode (QPX)- Quarter XCCs + //!< work together with shared memory +} amdsmi_compute_partition_type_t; + +/** + * @brief Memory Partitions. This enum is used to identify various + * memory partition types. + */ +typedef enum { + MEMORY_PARTITION_UNKNOWN = 0, + MEMORY_PARTITION_NPS1, //!< NPS1 - All CCD & XCD data is interleaved + //!< accross all 8 HBM stacks (all stacks/1). + MEMORY_PARTITION_NPS2, //!< NPS2 - 2 sets of CCDs or 4 XCD interleaved + //!< accross the 4 HBM stacks per AID pair + //!< (8 stacks/2). + MEMORY_PARTITION_NPS4, //!< NPS4 - Each XCD data is interleaved accross + //!< accross 2 (or single) HBM stacks + //!< (8 stacks/8 or 8 stacks/4). + 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). +} amdsmi_memory_partition_type_t; + /** * @brief This enumeration is used to indicate from which part of the device a * temperature reading should be obtained. @@ -1525,7 +1564,8 @@ amdsmi_status_t amdsmi_get_processor_type(amdsmi_processor_handle processor_hand * * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ -amdsmi_status_t amdsmi_get_processor_handle_from_bdf(amdsmi_bdf_t bdf, amdsmi_processor_handle* processor_handle); +amdsmi_status_t amdsmi_get_processor_handle_from_bdf(amdsmi_bdf_t bdf, + amdsmi_processor_handle* processor_handle); /** @} End DiscQueries */ @@ -1715,7 +1755,8 @@ amdsmi_get_gpu_subsystem_name(amdsmi_processor_handle processor_handle, char *na * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ amdsmi_status_t -amdsmi_get_gpu_pci_bandwidth(amdsmi_processor_handle processor_handle, amdsmi_pcie_bandwidth_t *bandwidth); +amdsmi_get_gpu_pci_bandwidth(amdsmi_processor_handle processor_handle, + amdsmi_pcie_bandwidth_t *bandwidth); /** * @brief Get the unique PCI device identifier associated for a device @@ -1770,7 +1811,8 @@ amdsmi_status_t amdsmi_get_gpu_bdf_id(amdsmi_processor_handle processor_handle, * * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ -amdsmi_status_t amdsmi_get_gpu_topo_numa_affinity(amdsmi_processor_handle processor_handle, int32_t *numa_node); +amdsmi_status_t amdsmi_get_gpu_topo_numa_affinity(amdsmi_processor_handle processor_handle, + int32_t *numa_node); /** * @brief Get PCIe traffic information. It is not supported on virtual machine guest @@ -1816,7 +1858,7 @@ amdsmi_status_t amdsmi_get_gpu_pci_throughput(amdsmi_processor_handle processor_ * * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ -amdsmi_status_t amdsmi_get_gpu_pci_replay_counter(amdsmi_processor_handle processor_handle, +amdsmi_status_t amdsmi_get_gpu_pci_replay_counter(amdsmi_processor_handle processor_handle, uint64_t *counter); /** @} End PCIeQuer */ @@ -1857,7 +1899,8 @@ amdsmi_status_t amdsmi_get_gpu_pci_replay_counter(amdsmi_processor_handle proce * * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ -amdsmi_status_t amdsmi_set_gpu_pci_bandwidth(amdsmi_processor_handle processor_handle, uint64_t bw_bitmask); +amdsmi_status_t amdsmi_set_gpu_pci_bandwidth(amdsmi_processor_handle processor_handle, + uint64_t bw_bitmask); /** @} End PCIeCont */ @@ -2021,7 +2064,8 @@ amdsmi_get_gpu_memory_usage(amdsmi_processor_handle processor_handle, amdsmi_mem * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ amdsmi_status_t -amdsmi_get_gpu_bad_page_info(amdsmi_processor_handle processor_handle, uint32_t *num_pages, amdsmi_retired_page_record_t *info); +amdsmi_get_gpu_bad_page_info(amdsmi_processor_handle processor_handle, uint32_t *num_pages, + amdsmi_retired_page_record_t *info); /** * @brief Returns RAS features info. @@ -2059,8 +2103,9 @@ amdsmi_status_t amdsmi_get_gpu_ras_feature_info( * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ amdsmi_status_t -amdsmi_get_gpu_ras_block_features_enabled(amdsmi_processor_handle processor_handle, amdsmi_gpu_block_t block, - amdsmi_ras_err_state_t *state); +amdsmi_get_gpu_ras_block_features_enabled(amdsmi_processor_handle processor_handle, + amdsmi_gpu_block_t block, + amdsmi_ras_err_state_t *state); /** * @brief Get information about reserved ("retired") memory pages. It is not supported on @@ -2094,8 +2139,9 @@ amdsmi_get_gpu_ras_block_features_enabled(amdsmi_processor_handle processor_hand * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ amdsmi_status_t -amdsmi_get_gpu_memory_reserved_pages(amdsmi_processor_handle processor_handle, uint32_t *num_pages, - amdsmi_retired_page_record_t *records); +amdsmi_get_gpu_memory_reserved_pages(amdsmi_processor_handle processor_handle, + uint32_t *num_pages, + amdsmi_retired_page_record_t *records); /** @} End MemQuer */ @@ -2127,8 +2173,8 @@ amdsmi_get_gpu_memory_reserved_pages(amdsmi_processor_handle processor_handle, u * * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ -amdsmi_status_t amdsmi_get_gpu_fan_rpms(amdsmi_processor_handle processor_handle, uint32_t sensor_ind, - int64_t *speed); +amdsmi_status_t amdsmi_get_gpu_fan_rpms(amdsmi_processor_handle processor_handle, + uint32_t sensor_ind, int64_t *speed); /** * @brief Get the fan speed for the specified device as a value relative to @@ -2208,7 +2254,7 @@ amdsmi_status_t amdsmi_get_gpu_fan_speed_max(amdsmi_processor_handle processor_h * * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ -amdsmi_status_t amdsmi_get_temp_metric(amdsmi_processor_handle processor_handle, +amdsmi_status_t amdsmi_get_temp_metric(amdsmi_processor_handle processor_handle, amdsmi_temperature_type_t sensor_type, amdsmi_temperature_metric_t metric, int64_t *temperature); @@ -2252,7 +2298,7 @@ amdsmi_status_t amdsmi_get_gpu_cache_info( * * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ -amdsmi_status_t amdsmi_get_gpu_volt_metric(amdsmi_processor_handle processor_handle, +amdsmi_status_t amdsmi_get_gpu_volt_metric(amdsmi_processor_handle processor_handle, amdsmi_voltage_type_t sensor_type, amdsmi_voltage_metric_t metric, int64_t *voltage); @@ -2354,7 +2400,8 @@ amdsmi_get_utilization_count(amdsmi_processor_handle processor_handle, * * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ -amdsmi_status_t amdsmi_get_pcie_link_status(amdsmi_processor_handle processor_handle, amdsmi_pcie_info_t *info); +amdsmi_status_t amdsmi_get_pcie_link_status(amdsmi_processor_handle processor_handle, + amdsmi_pcie_info_t *info); /** * @brief Get max PCIe capabilities of the device with provided processor handle. @@ -2368,7 +2415,8 @@ amdsmi_status_t amdsmi_get_pcie_link_status(amdsmi_processor_handle processor_ha * * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ -amdsmi_status_t amdsmi_get_pcie_link_caps(amdsmi_processor_handle processor_handle, amdsmi_pcie_info_t *info); +amdsmi_status_t amdsmi_get_pcie_link_caps(amdsmi_processor_handle processor_handle, + amdsmi_pcie_info_t *info); /** * @brief Get the performance level of the device. It is not supported on virtual @@ -2433,7 +2481,8 @@ amdsmi_set_gpu_perf_determinism_mode(amdsmi_processor_handle processor_handle, u * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ -amdsmi_status_t amdsmi_get_gpu_overdrive_level(amdsmi_processor_handle processor_handle, uint32_t *od); +amdsmi_status_t amdsmi_get_gpu_overdrive_level(amdsmi_processor_handle processor_handle, + uint32_t *od); /** * @brief Get the list of possible system clock speeds of device for a @@ -2454,7 +2503,7 @@ amdsmi_status_t amdsmi_get_gpu_overdrive_level(amdsmi_processor_handle processor * * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ -amdsmi_status_t amdsmi_get_clk_freq(amdsmi_processor_handle processor_handle, +amdsmi_status_t amdsmi_get_clk_freq(amdsmi_processor_handle processor_handle, amdsmi_clk_type_t clk_type, amdsmi_frequencies_t *f); /** @@ -2487,7 +2536,7 @@ amdsmi_status_t amdsmi_reset_gpu(amdsmi_processor_handle processor_handle); * * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ -amdsmi_status_t amdsmi_get_gpu_od_volt_info(amdsmi_processor_handle processor_handle, +amdsmi_status_t amdsmi_get_gpu_od_volt_info(amdsmi_processor_handle processor_handle, amdsmi_od_volt_freq_data_t *odv); /** @@ -2508,7 +2557,7 @@ amdsmi_status_t amdsmi_get_gpu_od_volt_info(amdsmi_processor_handle processor_h * * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ -amdsmi_status_t amdsmi_get_gpu_metrics_info(amdsmi_processor_handle processor_handle, +amdsmi_status_t amdsmi_get_gpu_metrics_info(amdsmi_processor_handle processor_handle, amdsmi_gpu_metrics_t *pgpu_metrics); /** @@ -2531,9 +2580,10 @@ amdsmi_status_t amdsmi_get_gpu_metrics_info(amdsmi_processor_handle processor_h * * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ -amdsmi_status_t amdsmi_set_gpu_clk_range(amdsmi_processor_handle processor_handle, uint64_t minclkvalue, - uint64_t maxclkvalue, - amdsmi_clk_type_t clkType); +amdsmi_status_t amdsmi_set_gpu_clk_range(amdsmi_processor_handle processor_handle, + uint64_t minclkvalue, + uint64_t maxclkvalue, + amdsmi_clk_type_t clkType); /** * @brief This function sets the clock frequency information. It is not supported on @@ -2555,9 +2605,10 @@ amdsmi_status_t amdsmi_set_gpu_clk_range(amdsmi_processor_handle processor_handl * * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ -amdsmi_status_t amdsmi_set_gpu_od_clk_info(amdsmi_processor_handle processor_handle, amdsmi_freq_ind_t level, - uint64_t clkvalue, - amdsmi_clk_type_t clkType); +amdsmi_status_t amdsmi_set_gpu_od_clk_info(amdsmi_processor_handle processor_handle, + amdsmi_freq_ind_t level, + uint64_t clkvalue, + amdsmi_clk_type_t clkType); /** * @brief This function sets 1 of the 3 voltage curve points. It is not supported @@ -2578,8 +2629,10 @@ amdsmi_status_t amdsmi_set_gpu_od_clk_info(amdsmi_processor_handle processor_ha * * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ -amdsmi_status_t amdsmi_set_gpu_od_volt_info(amdsmi_processor_handle processor_handle, uint32_t vpoint, - uint64_t clkvalue, uint64_t voltvalue); +amdsmi_status_t amdsmi_set_gpu_od_volt_info(amdsmi_processor_handle processor_handle, + uint32_t vpoint, + uint64_t clkvalue, + uint64_t voltvalue); /** * @brief This function will retrieve the current valid regions in the @@ -2616,7 +2669,7 @@ amdsmi_status_t amdsmi_set_gpu_od_volt_info(amdsmi_processor_handle processor_h * * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ -amdsmi_status_t amdsmi_get_gpu_od_volt_curve_regions(amdsmi_processor_handle processor_handle, +amdsmi_status_t amdsmi_get_gpu_od_volt_curve_regions(amdsmi_processor_handle processor_handle, uint32_t *num_regions, amdsmi_freq_volt_region_t *buffer); /** @@ -2720,7 +2773,7 @@ amdsmi_status_t * * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ -amdsmi_status_t amdsmi_set_gpu_overdrive_level(amdsmi_processor_handle processor_handle, uint32_t od); +amdsmi_status_t amdsmi_set_gpu_overdrive_level(amdsmi_processor_handle processor_handle, uint32_t od); /** * @brief Control the set of allowed frequencies that can be used for the @@ -2754,7 +2807,7 @@ amdsmi_status_t amdsmi_set_gpu_overdrive_level(amdsmi_processor_handle processo * * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ -amdsmi_status_t amdsmi_set_clk_freq(amdsmi_processor_handle processor_handle, +amdsmi_status_t amdsmi_set_clk_freq(amdsmi_processor_handle processor_handle, amdsmi_clk_type_t clk_type, uint64_t freq_bitmask); /** @} End PerfCont */ @@ -2811,7 +2864,7 @@ amdsmi_get_lib_version(amdsmi_version_t *version); * * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ -amdsmi_status_t amdsmi_get_gpu_ecc_count(amdsmi_processor_handle processor_handle, +amdsmi_status_t amdsmi_get_gpu_ecc_count(amdsmi_processor_handle processor_handle, amdsmi_gpu_block_t block, amdsmi_error_count_t *ec); /** @@ -2838,7 +2891,7 @@ amdsmi_status_t amdsmi_get_gpu_ecc_count(amdsmi_processor_handle processor_hand * * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ -amdsmi_status_t amdsmi_get_gpu_ecc_enabled(amdsmi_processor_handle processor_handle, +amdsmi_status_t amdsmi_get_gpu_ecc_enabled(amdsmi_processor_handle processor_handle, uint64_t *enabled_blocks); /** @@ -2863,7 +2916,8 @@ amdsmi_status_t amdsmi_get_gpu_ecc_enabled(amdsmi_processor_handle processor_ha * * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ -amdsmi_status_t amdsmi_get_gpu_ecc_status(amdsmi_processor_handle processor_handle, amdsmi_gpu_block_t block, +amdsmi_status_t amdsmi_get_gpu_ecc_status(amdsmi_processor_handle processor_handle, + amdsmi_gpu_block_t block, amdsmi_ras_err_state_t *state); /** @@ -3317,8 +3371,10 @@ amdsmi_topo_get_link_weight(amdsmi_processor_handle processor_handle_src, amdsmi * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ amdsmi_status_t - amdsmi_get_minmax_bandwidth_between_processors(amdsmi_processor_handle processor_handle_src, amdsmi_processor_handle processor_handle_dst, - uint64_t *min_bandwidth, uint64_t *max_bandwidth); + amdsmi_get_minmax_bandwidth_between_processors(amdsmi_processor_handle processor_handle_src, + amdsmi_processor_handle processor_handle_dst, + uint64_t *min_bandwidth, + uint64_t *max_bandwidth); /** * @brief Retrieve the hops and the connection type between 2 GPUs @@ -3366,11 +3422,181 @@ amdsmi_topo_get_link_type(amdsmi_processor_handle processor_handle_src, * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ amdsmi_status_t -amdsmi_is_P2P_accessible(amdsmi_processor_handle processor_handle_src, amdsmi_processor_handle processor_handle_dst, - bool *accessible); +amdsmi_is_P2P_accessible(amdsmi_processor_handle processor_handle_src, + amdsmi_processor_handle processor_handle_dst, + bool *accessible); /** @} End HWTopo */ +/*****************************************************************************/ +/** @defgroup compute_partition 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 ::AMDSMI_STATUS_SUCCESS call was successful + * @retval ::AMDSMI_STATUS_INVALID_ARGS the provided arguments are not valid + * @retval ::AMDSMI_STATUS_UNEXPECTED_DATA data provided to function is not valid + * @retval ::AMDSMI_STATUS_NOT_SUPPORTED installed software or hardware does not + * support this function + * @retval ::AMDSMI_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. + * + */ +amdsmi_status_t +amdsmi_dev_compute_partition_get(amdsmi_processor_handle processor_handle, + 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 ::amdsmi_compute_partition_type_t, + * define what the selected device's compute partition setting should be + * updated to. + * + * @retval ::AMDSMI_STATUS_SUCCESS call was successful + * @retval ::AMDSMI_STATUS_PERMISSION function requires root access + * @retval ::AMDSMI_STATUS_INVALID_ARGS the provided arguments are not valid + * @retval ::AMDSMI_STATUS_SETTING_UNAVAILABLE the provided setting is + * unavailable for current device + * @retval ::AMDSMI_STATUS_NOT_SUPPORTED installed software or hardware does not + * support this function + * + */ +amdsmi_status_t +amdsmi_dev_compute_partition_set(amdsmi_processor_handle processor_handle, + amdsmi_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 ::AMDSMI_STATUS_SUCCESS call was successful + * @retval ::AMDSMI_STATUS_PERMISSION function requires root access + * @retval ::AMDSMI_STATUS_NOT_SUPPORTED installed software or hardware does not + * support this function + * + */ +amdsmi_status_t amdsmi_dev_compute_partition_reset(amdsmi_processor_handle processor_handle); + +/** @} */ // end of compute_partition + +/*****************************************************************************/ +/** @defgroup memory_partition Memory Partition Functions + * These functions are used to query and set the device's current memory + * partition. + * @{ + */ + +/** + * @brief Retrieves the current memory partition for a desired device + * + * @details + * Given a device index @p dv_ind and a string @p memory_partition , + * and uint32 @p len , this function will attempt to obtain the device's + * memory partition string. Upon successful retreival, the obtained device's + * memory partition string shall be stored in the passed @p memory_partition + * char string variable. + * + * @param[in] dv_ind a device index + * + * @param[inout] memory_partition a pointer to a char string variable, + * which the device's memory partition will be written to. + * + * @param[in] len the length of the caller provided buffer @p memory_partition , + * suggested length is 5 or greater. + * + * @retval ::AMDSMI_STATUS_SUCCESS call was successful + * @retval ::AMDSMI_STATUS_INVALID_ARGS the provided arguments are not valid + * @retval ::AMDSMI_STATUS_UNEXPECTED_DATA data provided to function is not valid + * @retval ::AMDSMI_STATUS_NOT_SUPPORTED installed software or hardware does not + * support this function + * @retval ::AMDSMI_STATUS_INSUFFICIENT_SIZE is returned if @p len bytes is not + * large enough to hold the entire memory partition value. In this case, + * only @p len bytes will be written. + * + */ +amdsmi_status_t +amdsmi_dev_memory_partition_get(amdsmi_processor_handle processor_handle, + char *memory_partition, uint32_t len); + +/** + * @brief Modifies a selected device's current memory partition setting. + * + * @details Given a device index @p dv_ind and a type of memory partition + * @p memory_partition, this function will attempt to update the selected + * device's memory partition setting. + * + * @param[in] dv_ind a device index + * + * @param[in] memory_partition using enum ::amdsmi_memory_partition_type_t, + * define what the selected device's current mode setting should be updated to. + * + * @retval ::AMDSMI_STATUS_SUCCESS call was successful + * @retval ::AMDSMI_STATUS_PERMISSION function requires root access + * @retval ::AMDSMI_STATUS_INVALID_ARGS the provided arguments are not valid + * @retval ::AMDSMI_STATUS_NOT_SUPPORTED installed software or hardware does not + * support this function + * @retval ::AMDSMI_STATUS_AMDGPU_RESTART_ERR could not successfully restart + * the amdgpu driver + * + */ +amdsmi_status_t +amdsmi_dev_memory_partition_set(amdsmi_processor_handle processor_handle, + amdsmi_memory_partition_type_t memory_partition); + +/** + * @brief Reverts a selected device's memory partition setting back to its + * boot state. + * + * @details Given a device index @p dv_ind , this function will attempt to + * revert its current memory partition setting back to its boot state. + * + * @param[in] dv_ind a device index + * + * @retval ::AMDSMI_STATUS_SUCCESS call was successful + * @retval ::AMDSMI_STATUS_PERMISSION function requires root access + * @retval ::AMDSMI_STATUS_NOT_SUPPORTED installed software or hardware does not + * support this function + * @retval ::AMDSMI_STATUS_AMDGPU_RESTART_ERR could not successfully restart + * the amdgpu driver + * + */ +amdsmi_status_t amdsmi_dev_memory_partition_reset(amdsmi_processor_handle processor_handle); + +/** @} */ // end of memory_partition + /*****************************************************************************/ /** @defgroup EvntNotif Event Notification Functions * These functions are used to configure for and get asynchronous event diff --git a/projects/amdsmi/py-interface/README.md b/projects/amdsmi/py-interface/README.md index c57b63074c..25845075c1 100644 --- a/projects/amdsmi/py-interface/README.md +++ b/projects/amdsmi/py-interface/README.md @@ -3268,6 +3268,193 @@ except AmdSmiException as e: print(e) ``` + +### amdsmi_dev_compute_partition_get + +Description: Get the compute partition from the given GPU + +Input parameters: + +* `processor_handle` the device handle + +Output: String of the partition type + +Exceptions that can be thrown by `amdsmi_dev_compute_partition_get` function: + +* `AmdSmiLibraryException` +* `AmdSmiRetryException` +* `AmdSmiParameterException` + +Example: + +```python +try: + devices = amdsmi_get_processor_handles() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + compute_partition_type = amdsmi_dev_compute_partition_get(device) + print(compute_partition_type) +except AmdSmiException as e: + print(e) +``` + +### amdsmi_dev_compute_partition_set + +Description: Set the compute partition to the given GPU + +Input parameters: + +* `processor_handle` the device handle +* `compute_partition` the type of compute_partition to set + +Output: String of the partition type + +Exceptions that can be thrown by `amdsmi_dev_compute_partition_set` function: + +* `AmdSmiLibraryException` +* `AmdSmiRetryException` +* `AmdSmiParameterException` + +Example: + +```python +try: + compute_partition = AmdSmiComputePartitionType.SPX + devices = amdsmi_get_processor_handles() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + amdsmi_dev_compute_partition_set(device, compute_partition) +except AmdSmiException as e: + print(e) +``` + +### amdsmi_dev_compute_partition_reset + +Description: Reset the compute partitioning on the given GPU + +Input parameters: + +* `processor_handle` the device handle + +Output: String of the partition type + +Exceptions that can be thrown by `amdsmi_dev_compute_partition_reset` function: + +* `AmdSmiLibraryException` +* `AmdSmiRetryException` +* `AmdSmiParameterException` + +Example: + +```python +try: + devices = amdsmi_get_processor_handles() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + amdsmi_dev_compute_partition_reset(device) +except AmdSmiException as e: + print(e) +``` + +### amdsmi_dev_memory_partition_get + +Description: Get the memory partition from the given GPU + +Input parameters: + +* `processor_handle` the device handle + +Output: String of the partition type + +Exceptions that can be thrown by `amdsmi_dev_memory_partition_get` function: + +* `AmdSmiLibraryException` +* `AmdSmiRetryException` +* `AmdSmiParameterException` + +Example: + +```python +try: + devices = amdsmi_get_processor_handles() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + memory_partition_type = amdsmi_dev_memory_partition_get(device) + print(memory_partition_type) +except AmdSmiException as e: + print(e) +``` + +### amdsmi_dev_memory_partition_set + +Description: Set the memory partition to the given GPU + +Input parameters: + +* `processor_handle` the device handle +* `memory_partition` the type of memory_partition to set + +Output: String of the partition type + +Exceptions that can be thrown by `amdsmi_dev_memory_partition_set` function: + +* `AmdSmiLibraryException` +* `AmdSmiRetryException` +* `AmdSmiParameterException` + +Example: + +```python +try: + memory_partition = AmdSmiMemoryPartitionType.NPS1 + devices = amdsmi_get_processor_handles() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + amdsmi_dev_memory_partition_set(device, memory_partition) +except AmdSmiException as e: + print(e) +``` + +### amdsmi_dev_memory_partition_reset + +Description: Reset the memory partitioning on the given GPU + +Input parameters: + +* `processor_handle` the device handle + +Output: String of the partition type + +Exceptions that can be thrown by `amdsmi_dev_memory_partition_reset` function: + +* `AmdSmiLibraryException` +* `AmdSmiRetryException` +* `AmdSmiParameterException` + +Example: + +```python +try: + devices = amdsmi_get_processor_handles() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + amdsmi_dev_memory_partition_reset(device) +except AmdSmiException as e: + print(e) +``` + ### amdsmi_get_xgmi_info Description: Returns XGMI information for the GPU. diff --git a/projects/amdsmi/py-interface/amdsmi_interface.py b/projects/amdsmi/py-interface/amdsmi_interface.py index 01ce67a793..b39b94d1b1 100644 --- a/projects/amdsmi/py-interface/amdsmi_interface.py +++ b/projects/amdsmi/py-interface/amdsmi_interface.py @@ -244,6 +244,23 @@ class AmdSmiVoltageType(IntEnum): INVALID = amdsmi_wrapper.AMDSMI_VOLT_TYPE_INVALID +class AmdSmiComputePartitionType(IntEnum): + CPX = amdsmi_wrapper.COMPUTE_PARTITION_CPX + SPX = amdsmi_wrapper.COMPUTE_PARTITION_SPX + DPX = amdsmi_wrapper.COMPUTE_PARTITION_DPX + TPX = amdsmi_wrapper.COMPUTE_PARTITION_TPX + QPX = amdsmi_wrapper.COMPUTE_PARTITION_QPX + INVALID = amdsmi_wrapper.COMPUTE_PARTITION_INVALID + + +class AmdSmiMemoryPartitionType(IntEnum): + NPS1 = amdsmi_wrapper.MEMORY_PARTITION_NPS1 + NPS2 = amdsmi_wrapper.MEMORY_PARTITION_NPS2 + NPS4 = amdsmi_wrapper.MEMORY_PARTITION_NPS4 + NPS8 = amdsmi_wrapper.MEMORY_PARTITION_NPS8 + UNKNOWN = amdsmi_wrapper.MEMORY_PARTITION_UNKNOWN + + class AmdSmiPowerProfilePresetMasks(IntEnum): CUSTOM_MASK = amdsmi_wrapper.AMDSMI_PWR_PROF_PRST_CUSTOM_MASK VIDEO_MASK = amdsmi_wrapper.AMDSMI_PWR_PROF_PRST_VIDEO_MASK @@ -1374,6 +1391,98 @@ def amdsmi_is_P2P_accessible( return accessible.value +def amdsmi_dev_compute_partition_get(processor_handle: amdsmi_wrapper.amdsmi_processor_handle): + if not isinstance(processor_handle, amdsmi_wrapper.amdsmi_processor_handle): + raise AmdSmiParameterException( + processor_handle, amdsmi_wrapper.amdsmi_processor_handle + ) + + length = ctypes.c_uint32() + length.value = _AMDSMI_STRING_LENGTH + + compute_partition = ctypes.create_string_buffer(_AMDSMI_STRING_LENGTH) + + _check_res( + amdsmi_wrapper.amdsmi_dev_compute_partition_get( + processor_handle, compute_partition, length + ) + ) + + return compute_partition.value.decode("utf-8") + + +def amdsmi_dev_compute_partition_set(processor_handle: amdsmi_wrapper.amdsmi_processor_handle, + compute_partition: AmdSmiComputePartitionType): + if not isinstance(processor_handle, amdsmi_wrapper.amdsmi_processor_handle): + raise AmdSmiParameterException( + processor_handle, amdsmi_wrapper.amdsmi_processor_handle + ) + + if not isinstance(compute_partition, AmdSmiComputePartitionType): + raise AmdSmiParameterException(compute_partition, AmdSmiComputePartitionType) + + _check_res( + amdsmi_wrapper.amdsmi_dev_compute_partition_set( + processor_handle, compute_partition + ) + ) + + +def amdsmi_dev_compute_partition_reset(processor_handle: amdsmi_wrapper.amdsmi_processor_handle): + if not isinstance(processor_handle, amdsmi_wrapper.amdsmi_processor_handle): + raise AmdSmiParameterException( + processor_handle, amdsmi_wrapper.amdsmi_processor_handle + ) + + _check_res(amdsmi_wrapper.amdsmi_dev_compute_partition_reset(processor_handle)) + + +def amdsmi_dev_memory_partition_get(processor_handle: amdsmi_wrapper.amdsmi_processor_handle): + if not isinstance(processor_handle, amdsmi_wrapper.amdsmi_processor_handle): + raise AmdSmiParameterException( + processor_handle, amdsmi_wrapper.amdsmi_processor_handle + ) + + length = ctypes.c_uint32() + length.value = _AMDSMI_STRING_LENGTH + + memory_partition = ctypes.create_string_buffer(_AMDSMI_STRING_LENGTH) + + _check_res( + amdsmi_wrapper.amdsmi_dev_memory_partition_get( + processor_handle, memory_partition, length + ) + ) + + return memory_partition.value.decode("utf-8") + + +def amdsmi_dev_memory_partition_set(processor_handle: amdsmi_wrapper.amdsmi_processor_handle, + memory_partition: AmdSmiMemoryPartitionType): + if not isinstance(processor_handle, amdsmi_wrapper.amdsmi_processor_handle): + raise AmdSmiParameterException( + processor_handle, amdsmi_wrapper.amdsmi_processor_handle + ) + + if not isinstance(memory_partition, AmdSmiMemoryPartitionType): + raise AmdSmiParameterException(memory_partition, AmdSmiMemoryPartitionType) + + _check_res( + amdsmi_wrapper.amdsmi_dev_memory_partition_set( + processor_handle, memory_partition + ) + ) + + +def amdsmi_dev_memory_partition_reset(processor_handle: amdsmi_wrapper.amdsmi_processor_handle): + if not isinstance(processor_handle, amdsmi_wrapper.amdsmi_processor_handle): + raise AmdSmiParameterException( + processor_handle, amdsmi_wrapper.amdsmi_processor_handle + ) + + _check_res(amdsmi_wrapper.amdsmi_dev_memory_partition_reset(processor_handle)) + + def amdsmi_get_xgmi_info(processor_handle: amdsmi_wrapper.amdsmi_processor_handle): if not isinstance(processor_handle, amdsmi_wrapper.amdsmi_processor_handle): raise AmdSmiParameterException( diff --git a/projects/amdsmi/py-interface/amdsmi_wrapper.py b/projects/amdsmi/py-interface/amdsmi_wrapper.py index 0b702ace1b..447bcbd540 100644 --- a/projects/amdsmi/py-interface/amdsmi_wrapper.py +++ b/projects/amdsmi/py-interface/amdsmi_wrapper.py @@ -368,6 +368,38 @@ CLK_TYPE_DCLK1 = 9 CLK_TYPE__MAX = 9 amdsmi_clk_type_t = ctypes.c_uint32 # enum +# values for enumeration 'amdsmi_compute_partition_type_t' +amdsmi_compute_partition_type_t__enumvalues = { + 0: 'COMPUTE_PARTITION_INVALID', + 1: 'COMPUTE_PARTITION_CPX', + 2: 'COMPUTE_PARTITION_SPX', + 3: 'COMPUTE_PARTITION_DPX', + 4: 'COMPUTE_PARTITION_TPX', + 5: 'COMPUTE_PARTITION_QPX', +} +COMPUTE_PARTITION_INVALID = 0 +COMPUTE_PARTITION_CPX = 1 +COMPUTE_PARTITION_SPX = 2 +COMPUTE_PARTITION_DPX = 3 +COMPUTE_PARTITION_TPX = 4 +COMPUTE_PARTITION_QPX = 5 +amdsmi_compute_partition_type_t = ctypes.c_uint32 # enum + +# values for enumeration 'amdsmi_memory_partition_type_t' +amdsmi_memory_partition_type_t__enumvalues = { + 0: 'MEMORY_PARTITION_UNKNOWN', + 1: 'MEMORY_PARTITION_NPS1', + 2: 'MEMORY_PARTITION_NPS2', + 3: 'MEMORY_PARTITION_NPS4', + 4: 'MEMORY_PARTITION_NPS8', +} +MEMORY_PARTITION_UNKNOWN = 0 +MEMORY_PARTITION_NPS1 = 1 +MEMORY_PARTITION_NPS2 = 2 +MEMORY_PARTITION_NPS4 = 3 +MEMORY_PARTITION_NPS8 = 4 +amdsmi_memory_partition_type_t = ctypes.c_uint32 # enum + # values for enumeration 'amdsmi_temperature_type_t' amdsmi_temperature_type_t__enumvalues = { 0: 'TEMPERATURE_TYPE_EDGE', @@ -1737,6 +1769,24 @@ amdsmi_topo_get_link_type.argtypes = [amdsmi_processor_handle, amdsmi_processor_ amdsmi_is_P2P_accessible = _libraries['libamd_smi.so'].amdsmi_is_P2P_accessible amdsmi_is_P2P_accessible.restype = amdsmi_status_t amdsmi_is_P2P_accessible.argtypes = [amdsmi_processor_handle, amdsmi_processor_handle, ctypes.POINTER(ctypes.c_bool)] +amdsmi_dev_compute_partition_get = _libraries['libamd_smi.so'].amdsmi_dev_compute_partition_get +amdsmi_dev_compute_partition_get.restype = amdsmi_status_t +amdsmi_dev_compute_partition_get.argtypes = [amdsmi_processor_handle, ctypes.POINTER(ctypes.c_char), uint32_t] +amdsmi_dev_compute_partition_set = _libraries['libamd_smi.so'].amdsmi_dev_compute_partition_set +amdsmi_dev_compute_partition_set.restype = amdsmi_status_t +amdsmi_dev_compute_partition_set.argtypes = [amdsmi_processor_handle, amdsmi_compute_partition_type_t] +amdsmi_dev_compute_partition_reset = _libraries['libamd_smi.so'].amdsmi_dev_compute_partition_reset +amdsmi_dev_compute_partition_reset.restype = amdsmi_status_t +amdsmi_dev_compute_partition_reset.argtypes = [amdsmi_processor_handle] +amdsmi_dev_memory_partition_get = _libraries['libamd_smi.so'].amdsmi_dev_memory_partition_get +amdsmi_dev_memory_partition_get.restype = amdsmi_status_t +amdsmi_dev_memory_partition_get.argtypes = [amdsmi_processor_handle, ctypes.POINTER(ctypes.c_char), uint32_t] +amdsmi_dev_memory_partition_set = _libraries['libamd_smi.so'].amdsmi_dev_memory_partition_set +amdsmi_dev_memory_partition_set.restype = amdsmi_status_t +amdsmi_dev_memory_partition_set.argtypes = [amdsmi_processor_handle, amdsmi_memory_partition_type_t] +amdsmi_dev_memory_partition_reset = _libraries['libamd_smi.so'].amdsmi_dev_memory_partition_reset +amdsmi_dev_memory_partition_reset.restype = amdsmi_status_t +amdsmi_dev_memory_partition_reset.argtypes = [amdsmi_processor_handle] amdsmi_init_gpu_event_notification = _libraries['libamd_smi.so'].amdsmi_init_gpu_event_notification amdsmi_init_gpu_event_notification.restype = amdsmi_status_t amdsmi_init_gpu_event_notification.argtypes = [amdsmi_processor_handle] @@ -1920,6 +1970,9 @@ __all__ = \ 'CLK_TYPE_DCLK1', 'CLK_TYPE_DF', 'CLK_TYPE_FIRST', 'CLK_TYPE_GFX', 'CLK_TYPE_MEM', 'CLK_TYPE_PCIE', 'CLK_TYPE_SOC', 'CLK_TYPE_SYS', 'CLK_TYPE_VCLK0', 'CLK_TYPE_VCLK1', 'CLK_TYPE__MAX', + 'COMPUTE_PARTITION_CPX', 'COMPUTE_PARTITION_DPX', + 'COMPUTE_PARTITION_INVALID', 'COMPUTE_PARTITION_QPX', + 'COMPUTE_PARTITION_SPX', 'COMPUTE_PARTITION_TPX', 'CONTAINER_DOCKER', 'CONTAINER_LXC', 'FW_ID_ASD', 'FW_ID_CP_CE', 'FW_ID_CP_ME', 'FW_ID_CP_MEC1', 'FW_ID_CP_MEC2', 'FW_ID_CP_MEC_JT1', 'FW_ID_CP_MEC_JT2', 'FW_ID_CP_MES', @@ -1947,21 +2000,30 @@ __all__ = \ 'FW_ID_SDMA6', 'FW_ID_SDMA7', 'FW_ID_SDMA_TH0', 'FW_ID_SDMA_TH1', 'FW_ID_SEC_POLICY_STAGE2', 'FW_ID_SMC', 'FW_ID_SMU', 'FW_ID_TA_RAS', 'FW_ID_UVD', 'FW_ID_VCE', 'FW_ID_VCN', - 'FW_ID_XGMI', 'FW_ID__MAX', 'NON_AMD_CPU', 'NON_AMD_GPU', - 'TEMPERATURE_TYPE_EDGE', 'TEMPERATURE_TYPE_FIRST', - 'TEMPERATURE_TYPE_HBM_0', 'TEMPERATURE_TYPE_HBM_1', - 'TEMPERATURE_TYPE_HBM_2', 'TEMPERATURE_TYPE_HBM_3', - 'TEMPERATURE_TYPE_HOTSPOT', 'TEMPERATURE_TYPE_JUNCTION', - 'TEMPERATURE_TYPE_PLX', 'TEMPERATURE_TYPE_VRAM', - 'TEMPERATURE_TYPE__MAX', 'UNKNOWN', 'VRAM_TYPE_DDR2', - 'VRAM_TYPE_DDR3', 'VRAM_TYPE_DDR4', 'VRAM_TYPE_GDDR1', - 'VRAM_TYPE_GDDR3', 'VRAM_TYPE_GDDR4', 'VRAM_TYPE_GDDR5', - 'VRAM_TYPE_GDDR6', 'VRAM_TYPE_HBM', 'VRAM_TYPE_UNKNOWN', - 'VRAM_TYPE__MAX', 'amd_metrics_table_header_t', - 'amdsmi_asic_info_t', 'amdsmi_bdf_t', 'amdsmi_bit_field_t', - 'amdsmi_board_info_t', 'amdsmi_clk_info_t', 'amdsmi_clk_type_t', - 'amdsmi_container_types_t', 'amdsmi_counter_command_t', - 'amdsmi_counter_value_t', 'amdsmi_dev_perf_level_t', + 'FW_ID_XGMI', 'FW_ID__MAX', 'MEMORY_PARTITION_NPS1', + 'MEMORY_PARTITION_NPS2', 'MEMORY_PARTITION_NPS4', + 'MEMORY_PARTITION_NPS8', 'MEMORY_PARTITION_UNKNOWN', + 'NON_AMD_CPU', 'NON_AMD_GPU', 'TEMPERATURE_TYPE_EDGE', + 'TEMPERATURE_TYPE_FIRST', 'TEMPERATURE_TYPE_HBM_0', + 'TEMPERATURE_TYPE_HBM_1', 'TEMPERATURE_TYPE_HBM_2', + 'TEMPERATURE_TYPE_HBM_3', 'TEMPERATURE_TYPE_HOTSPOT', + 'TEMPERATURE_TYPE_JUNCTION', 'TEMPERATURE_TYPE_PLX', + 'TEMPERATURE_TYPE_VRAM', 'TEMPERATURE_TYPE__MAX', 'UNKNOWN', + 'VRAM_TYPE_DDR2', 'VRAM_TYPE_DDR3', 'VRAM_TYPE_DDR4', + 'VRAM_TYPE_GDDR1', 'VRAM_TYPE_GDDR3', 'VRAM_TYPE_GDDR4', + 'VRAM_TYPE_GDDR5', 'VRAM_TYPE_GDDR6', 'VRAM_TYPE_HBM', + 'VRAM_TYPE_UNKNOWN', 'VRAM_TYPE__MAX', + 'amd_metrics_table_header_t', 'amdsmi_asic_info_t', + 'amdsmi_bdf_t', 'amdsmi_bit_field_t', 'amdsmi_board_info_t', + 'amdsmi_clk_info_t', 'amdsmi_clk_type_t', + 'amdsmi_compute_partition_type_t', 'amdsmi_container_types_t', + 'amdsmi_counter_command_t', 'amdsmi_counter_value_t', + 'amdsmi_dev_compute_partition_get', + 'amdsmi_dev_compute_partition_reset', + 'amdsmi_dev_compute_partition_set', + 'amdsmi_dev_memory_partition_get', + 'amdsmi_dev_memory_partition_reset', + 'amdsmi_dev_memory_partition_set', 'amdsmi_dev_perf_level_t', 'amdsmi_driver_info_t', 'amdsmi_engine_usage_t', 'amdsmi_error_count_t', 'amdsmi_event_group_t', 'amdsmi_event_handle_t', 'amdsmi_event_type_t', @@ -2017,12 +2079,13 @@ __all__ = \ 'amdsmi_init_gpu_event_notification', 'amdsmi_io_link_type_t', 'amdsmi_is_P2P_accessible', 'amdsmi_is_gpu_power_management_enabled', - 'amdsmi_memory_page_status_t', 'amdsmi_memory_type_t', - 'amdsmi_mm_ip_t', 'amdsmi_od_vddc_point_t', - 'amdsmi_od_volt_curve_t', 'amdsmi_od_volt_freq_data_t', - 'amdsmi_pcie_bandwidth_t', 'amdsmi_pcie_info_t', - 'amdsmi_pcie_slot_type_t', 'amdsmi_power_cap_info_t', - 'amdsmi_power_info_t', 'amdsmi_power_profile_preset_masks_t', + 'amdsmi_memory_page_status_t', 'amdsmi_memory_partition_type_t', + 'amdsmi_memory_type_t', 'amdsmi_mm_ip_t', + 'amdsmi_od_vddc_point_t', 'amdsmi_od_volt_curve_t', + 'amdsmi_od_volt_freq_data_t', 'amdsmi_pcie_bandwidth_t', + 'amdsmi_pcie_info_t', 'amdsmi_pcie_slot_type_t', + 'amdsmi_power_cap_info_t', 'amdsmi_power_info_t', + 'amdsmi_power_profile_preset_masks_t', 'amdsmi_power_profile_status_t', 'amdsmi_power_type_t', 'amdsmi_proc_info_t', 'amdsmi_process_handle_t', 'amdsmi_process_info_t', 'amdsmi_processor_handle', diff --git a/projects/amdsmi/rocm_smi/include/rocm_smi/rocm_smi.h b/projects/amdsmi/rocm_smi/include/rocm_smi/rocm_smi.h index 67607fa186..fef797cc5f 100755 --- a/projects/amdsmi/rocm_smi/include/rocm_smi/rocm_smi.h +++ b/projects/amdsmi/rocm_smi/include/rocm_smi/rocm_smi.h @@ -377,16 +377,16 @@ typedef rsmi_clk_type_t rsmi_clk_type; */ typedef enum { RSMI_COMPUTE_PARTITION_INVALID = 0, - RSMI_COMPUTE_PARTITION_CPX, //!< Core mode (CPX)- Per-chip XCC with - //!< shared memory - RSMI_COMPUTE_PARTITION_SPX, //!< Single GPU mode (SPX)- All XCCs work - //!< together with shared memory - RSMI_COMPUTE_PARTITION_DPX, //!< Dual GPU mode (DPX)- Half XCCs work - //!< together with shared memory - RSMI_COMPUTE_PARTITION_TPX, //!< Triple GPU mode (TPX)- One-third XCCs - //!< work together with shared memory - RSMI_COMPUTE_PARTITION_QPX //!< Quad GPU mode (QPX)- Quarter XCCs - //!< work together with shared memory + RSMI_COMPUTE_PARTITION_CPX, //!< 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; @@ -3902,7 +3902,7 @@ rsmi_is_P2P_accessible(uint32_t dv_ind_src, uint32_t dv_ind_dst, /** @} */ // end of HWTopo /*****************************************************************************/ -/** @defgroup ComputePartition Compute Partition Functions +/** @defgroup compute_partition Compute Partition Functions * These functions are used to configure and query the device's * compute parition setting. * @{ @@ -3983,10 +3983,10 @@ rsmi_dev_compute_partition_set(uint32_t dv_ind, */ rsmi_status_t rsmi_dev_compute_partition_reset(uint32_t dv_ind); -/** @} */ // end of ComputePartition +/** @} */ // end of compute_partition /*****************************************************************************/ -/** @defgroup memory_partition The Memory Partition Functions +/** @defgroup memory_partition Memory Partition Functions * These functions are used to query and set the device's current memory * partition. * @{ diff --git a/projects/amdsmi/src/amd_smi/amd_smi.cc b/projects/amdsmi/src/amd_smi/amd_smi.cc index 39903358d6..9253722628 100644 --- a/projects/amdsmi/src/amd_smi/amd_smi.cc +++ b/projects/amdsmi/src/amd_smi/amd_smi.cc @@ -986,6 +986,52 @@ amdsmi_is_P2P_accessible(amdsmi_processor_handle processor_handle_src, return amd::smi::rsmi_to_amdsmi_status(rstatus); } +// Compute Partition functions +amdsmi_status_t +amdsmi_dev_compute_partition_get(amdsmi_processor_handle processor_handle, + char *compute_partition, uint32_t len) { + AMDSMI_CHECK_INIT(); + return rsmi_wrapper(rsmi_dev_compute_partition_get, processor_handle, + compute_partition, len); +} + +amdsmi_status_t +amdsmi_dev_compute_partition_set(amdsmi_processor_handle processor_handle, + amdsmi_compute_partition_type_t compute_partition) { + AMDSMI_CHECK_INIT(); + return rsmi_wrapper(rsmi_dev_compute_partition_set, processor_handle, + static_cast(compute_partition)); +} + +amdsmi_status_t +amdsmi_dev_compute_partition_reset(amdsmi_processor_handle processor_handle) { + AMDSMI_CHECK_INIT(); + return rsmi_wrapper(rsmi_dev_compute_partition_reset, processor_handle); +} + +// Memory Partition functions +amdsmi_status_t +amdsmi_dev_memory_partition_get(amdsmi_processor_handle processor_handle, + char *memory_partition, uint32_t len) { + AMDSMI_CHECK_INIT(); + return rsmi_wrapper(rsmi_dev_memory_partition_get, processor_handle, + memory_partition, len); +} + +amdsmi_status_t +amdsmi_dev_memory_partition_set(amdsmi_processor_handle processor_handle, + amdsmi_memory_partition_type_t memory_partition) { + AMDSMI_CHECK_INIT(); + return rsmi_wrapper(rsmi_dev_memory_partition_set, processor_handle, + static_cast(memory_partition)); +} + +amdsmi_status_t +amdsmi_dev_memory_partition_reset(amdsmi_processor_handle processor_handle) { + AMDSMI_CHECK_INIT(); + return rsmi_wrapper(rsmi_dev_memory_partition_reset, processor_handle); +} + // TODO(bliu) : other xgmi related information amdsmi_status_t amdsmi_get_xgmi_info(amdsmi_processor_handle processor_handle, amdsmi_xgmi_info_t *info) { From 7ada0bba5a46f74e42ce8ba5585abf6cc2cb103d Mon Sep 17 00:00:00 2001 From: Maisam Arif Date: Fri, 13 Oct 2023 21:31:17 -0500 Subject: [PATCH 14/27] Fixed ecc_correction_schema call in python interface Signed-off-by: Maisam Arif Change-Id: I16e2bf566342a8272c07f30b8db4df4acb9c3649 [ROCm/amdsmi commit: 2076b2a736f7cad1ff3dad487e6a7eed7723f20f] --- projects/amdsmi/py-interface/amdsmi_interface.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/projects/amdsmi/py-interface/amdsmi_interface.py b/projects/amdsmi/py-interface/amdsmi_interface.py index b39b94d1b1..ff92663772 100644 --- a/projects/amdsmi/py-interface/amdsmi_interface.py +++ b/projects/amdsmi/py-interface/amdsmi_interface.py @@ -891,10 +891,10 @@ def amdsmi_get_gpu_ras_feature_info( return { "eeprom_version": ras_feature.ras_eeprom_version, - "parity_schema" : bool(ras_feature.ecc_correction_schema_flags & 1), - "single_bit_schema" : bool(ras_feature.ecc_correction_schema_flags & 2), - "double_bit_schema" : bool(ras_feature.ecc_correction_schema_flags & 4), - "poison_schema" : bool(ras_feature.ecc_correction_schema_flags & 8) + "parity_schema" : bool(ras_feature.ecc_correction_schema_flag & 1), + "single_bit_schema" : bool(ras_feature.ecc_correction_schema_flag & 2), + "double_bit_schema" : bool(ras_feature.ecc_correction_schema_flag & 4), + "poison_schema" : bool(ras_feature.ecc_correction_schema_flag & 8) } From 12e45f96dadd7527bbe533c1dd7aa558c6800fc8 Mon Sep 17 00:00:00 2001 From: Maisam Arif Date: Fri, 13 Oct 2023 04:57:34 -0500 Subject: [PATCH 15/27] Added memory & compute partitions to cli tool Signed-off-by: Maisam Arif Change-Id: I0db6e2b9e3ae2e19397a012e095173ec550c1e42 [ROCm/amdsmi commit: a0c2735343df5598718a8497629b247eb995045e] --- projects/amdsmi/amdsmi_cli/README.md | 22 ++-- projects/amdsmi/amdsmi_cli/amdsmi_commands.py | 100 +++++++++++++++--- projects/amdsmi/amdsmi_cli/amdsmi_helpers.py | 14 +++ projects/amdsmi/amdsmi_cli/amdsmi_parser.py | 36 ++++--- 4 files changed, 135 insertions(+), 37 deletions(-) diff --git a/projects/amdsmi/amdsmi_cli/README.md b/projects/amdsmi/amdsmi_cli/README.md index 7032b74d0c..19b269e63e 100644 --- a/projects/amdsmi/amdsmi_cli/README.md +++ b/projects/amdsmi/amdsmi_cli/README.md @@ -160,9 +160,9 @@ Command Modifiers: amd-smi static --help usage: amd-smi static [-h] [--json | --csv] [--file FILE] [--loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL}] [-g GPU [GPU ...]] - [-a] [-b] [-V] [-d] [-r] [-v] [-B] [-l] [-u] + [-a] [-b] [-V] [-d] [-v] [-c] [-B] [-r] [-p] [-l] [-u] -If no GPU is specified, returns static information for all GPUs on the system. +If no GPU is specified, returns static information for all GPUs on the system. If no static argument is provided, all static information will be displayed. Static Arguments: @@ -174,10 +174,11 @@ Static Arguments: -b, --bus All bus information -V, --vbios All video bios information (if available) -d, --driver Displays driver version - -r, --ras Displays RAS features information -v, --vram All vram information -c, --cache All cache information -B, --board All board information + -r, --ras Displays RAS features information + -p, --partition Partition information -l, --limit All limit metric values (i.e. power and thermal limits) -u, --numa All numa node information @@ -314,7 +315,8 @@ Command Modifiers: amd-smi set --help usage: amd-smi set [-h] [--json | --csv] [--file FILE] [--loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL}] -g GPU [GPU ...] - [-f %] [-l LEVEL] [-P SETPROFILE] [-d SCLKMAX] + [-f %] [-l LEVEL] [-P SETPROFILE] [-d SCLKMAX] [-C PARTITION] + [-M PARTITION] A GPU must be specified to set a configuration. A set argument must be provided; Multiple set arguments are accepted @@ -325,9 +327,11 @@ Set Arguments: ID:0 | BDF:0000:23:00.0 | UUID:c4ff73bf-0000-1000-80ff-ffffffffffff all | Selects all devices -f %, --fan % Sets GPU fan speed (0-255 or 0-100%) - -l LEVEL, --perflevel LEVEL Sets performance level + -l LEVEL, --perf-level LEVEL Sets performance level -P SETPROFILE, --profile SETPROFILE Set power profile level (#) or a quoted string of custom profile attributes - -d SCLKMAX, --perfdeterminism SCLKMAX Sets GPU clock frequency limit and performance level to determinism to get minimal performance variation + -d SCLKMAX, --perf-determinism SCLKMAX Sets GPU clock frequency limit and performance level to determinism to get minimal performance variation + -C PARTITION, --compute-partition PARTITION Sets compute partition mode + -M PARTITION, --memory-partition PARTITION Sets memory partition mode Command Modifiers: --json Displays output in JSON format (human readable by default). @@ -340,7 +344,7 @@ Command Modifiers: amd-smi reset --help usage: amd-smi reset [-h] [--json | --csv] [--file FILE] [--loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL}] -g GPU [GPU ...] - [-G] [-c] [-f] [-p] [-x] [-d] + [-G] [-c] [-f] [-p] [-x] [-d] [-C] [-M] A GPU must be specified to reset a configuration. A reset argument must be provided; Multiple reset arguments are accepted @@ -355,7 +359,9 @@ Reset Arguments: -f, --fans Reset fans to automatic (driver) control -p, --profile Reset power profile back to default -x, --xgmierr Reset XGMI error counts - -d, --perfdeterminism Disable performance determinism + -d, --perf-determinism Disable performance determinism + -C, --compute-partition Reset compute partitions on the specified GPU + -M, --memory-partition Reset memory partitions on the specified GPU Command Modifiers: --json Displays output in JSON format (human readable by default). diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_commands.py b/projects/amdsmi/amdsmi_cli/amdsmi_commands.py index 3d1cb78bf7..65afc71a79 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_commands.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_commands.py @@ -130,8 +130,8 @@ class AMDSMICommands(): def static(self, args, multiple_devices=False, gpu=None, asic=None, - bus=None, vbios=None, limit=None, driver=None, - ras=None, board=None, numa=None, vram=None, cache=None): + bus=None, vbios=None, limit=None, driver=None, ras=None, + board=None, numa=None, vram=None, cache=None, partition=None): """Get Static information for target gpu Args: @@ -148,6 +148,7 @@ class AMDSMICommands(): numa (bool, optional): Value override for args.numa. Defaults to None. vram (bool, optional): Value override for args.vram. Defaults to None. cache (bool, optional): Value override for args.cache. Defaults to None. + partition (bool, optional): Value override for args.partition. Defaults to None. Raises: IndexError: Index error if gpu list is empty @@ -177,6 +178,8 @@ class AMDSMICommands(): if self.helpers.is_linux() and self.helpers.is_baremetal(): if ras: args.ras = ras + if partition: + args.partition = partition if limit: args.limit = limit @@ -192,8 +195,8 @@ 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.board, args.ras, args.driver, args.numa, args.vram, args.cache]): - args.asic = args.bus = args.vbios = args.limit = args.board = args.ras = args.driver = args.numa = args.vram = args.cache = self.all_arguments = True + if not any([args.asic, args.bus, args.vbios, args.limit, args.board, args.ras, args.driver, args.numa, args.vram, args.cache, args.partition]): + args.asic = args.bus = args.vbios = args.limit = args.board = args.ras = args.driver = args.numa = args.vram = args.cache = args.partition = self.all_arguments = True if self.helpers.is_linux() and self.helpers.is_virtual_os(): if not any([args.asic, args.bus, args.vbios, args.board, args.driver, args.vram, args.cache]): args.asic = args.bus = args.vbios = args.board = args.driver = args.vram = args.cache = self.all_arguments = True @@ -448,6 +451,7 @@ class AMDSMICommands(): logging.debug("Failed to get cache info for gpu %s | %s", gpu_id, e.get_error_info()) static_dict['cache'] = cache_info + if self.helpers.is_hypervisor() or self.helpers.is_baremetal(): if args.ras: ras_dict = {"eeprom_version": "N/A", @@ -469,6 +473,22 @@ class AMDSMICommands(): logging.debug("Failed to get ras block features for gpu %s | %s", gpu_id, e.get_error_info()) static_dict["ras"] = ras_dict + if args.partition: + try: + compute_partition = amdsmi_interface.amdsmi_dev_compute_partition_get(args.gpu) + except amdsmi_exception.AmdSmiLibraryException as e: + compute_partition = "N/A" + logging.debug("Failed to get compute partition info for gpu %s | %s", gpu_id, e.get_error_info()) + + try: + memory_partition = amdsmi_interface.amdsmi_dev_memory_partition_get(args.gpu) + except amdsmi_exception.AmdSmiLibraryException as e: + memory_partition = "N/A" + logging.debug("Failed to get memory partition info for gpu %s | %s", gpu_id, e.get_error_info()) + + static_dict['partition'] = {"compute_partition": compute_partition, + "memory_partition": memory_partition} + if self.helpers.is_linux() and self.helpers.is_baremetal(): if args.numa: try: @@ -1711,8 +1731,9 @@ class AMDSMICommands(): self.logger.print_output(multiple_device_enabled=True) - def set_value(self, args, multiple_devices=False, gpu=None, fan=None, perflevel=None, - profile=None, perfdeterminism=None): + def set_value(self, args, multiple_devices=False, gpu=None, fan=None, perf_level=None, + profile=None, perfdeterminism=None, compute_partition=None, + memory_partition=None): """Issue reset commands to target gpu(s) Args: @@ -1720,9 +1741,11 @@ class AMDSMICommands(): multiple_devices (bool, optional): True if checking for multiple devices. Defaults to False. gpu (device_handle, optional): device_handle for target device. Defaults to None. fan (int, optional): Value override for args.fan. Defaults to None. - perflevel (amdsmi_interface.AmdSmiDevPerfLevel, optional): Value override for args.perflevel. Defaults to None. + perf_level (amdsmi_interface.AmdSmiDevPerfLevel, optional): Value override for args.perf_level. Defaults to None. profile (bool, optional): Value override for args.profile. Defaults to None. perfdeterminism (int, optional): Value override for args.perfdeterminism. Defaults to None. + compute_partition (amdsmi_interface.AmdSmiComputePartitionType, optional): Value override for args.compute_partition. Defaults to None. + memory_partition (amdsmi_interface.AmdSmiMemoryPartitionType, optional): Value override for args.memory_partition. Defaults to None. Raises: ValueError: Value error if no gpu value is provided @@ -1736,12 +1759,16 @@ class AMDSMICommands(): args.gpu = gpu if fan: args.fan = fan - if perflevel: - args.perflevel = perflevel + if perf_level: + args.perf_level = perf_level if profile: args.profile = profile if perfdeterminism: args.perfdeterminism = perfdeterminism + if compute_partition: + args.compute_partition = compute_partition + if memory_partition: + args.memory_partition = memory_partition # Handle No GPU passed if args.gpu == None: @@ -1775,16 +1802,16 @@ class AMDSMICommands(): raise ValueError(f"Unable to set fan speed {args.fan} on {gpu_string}") from e self.logger.store_output(args.gpu, 'fan', f"Successfully set fan speed {args.fan}") - if args.perflevel: - perf_level = amdsmi_interface.AmdSmiDevPerfLevel[args.perflevel] + if args.perf_level: + perf_level = amdsmi_interface.AmdSmiDevPerfLevel[args.perf_level] try: amdsmi_interface.amdsmi_set_gpu_perf_level(args.gpu, perf_level) except amdsmi_exception.AmdSmiLibraryException as e: if e.get_error_code() == amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NO_PERM: raise PermissionError('Command requires elevation') from e - raise ValueError(f"Unable to set performance level {args.perflevel} on {gpu_string}") from e + raise ValueError(f"Unable to set performance level {args.perf_level} on {gpu_string}") from e - self.logger.store_output(args.gpu, 'perflevel', f"Successfully set performance level {args.perflevel}") + self.logger.store_output(args.gpu, 'perflevel', f"Successfully set performance level {args.perf_level}") if args.profile: self.logger.store_output(args.gpu, 'profile', "Not Yet Implemented") if isinstance(args.perfdeterminism, int): @@ -1796,7 +1823,22 @@ class AMDSMICommands(): raise ValueError(f"Unable to set performance determinism and clock frequency to {args.perfdeterminism} on {gpu_string}") from e self.logger.store_output(args.gpu, 'perfdeterminism', f"Successfully enabled performance determinism and set GFX clock frequency to {args.perfdeterminism}") - + if args.compute_partition: + compute_partition = amdsmi_interface.AmdSmiComputePartitionType[args.compute_partition] + try: + amdsmi_interface.amdsmi_dev_compute_partition_set(args.gpu, compute_partition) + except amdsmi_exception.AmdSmiLibraryException as e: + if e.get_error_code() == amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NO_PERM: + raise PermissionError('Command requires elevation') from e + raise ValueError(f"Unable to set compute partition to {args.compute_partition} on {gpu_string}") from e + if args.memory_partition: + memory_partition = amdsmi_interface.AmdSmiMemoryPartitionType[args.memory_partition] + try: + amdsmi_interface.amdsmi_dev_memory_partition_set(args.gpu, memory_partition) + except amdsmi_exception.AmdSmiLibraryException as e: + if e.get_error_code() == amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NO_PERM: + raise PermissionError('Command requires elevation') from e + raise ValueError(f"Unable to set memory partition to {args.memory_partition} on {gpu_string}") from e if multiple_devices: self.logger.store_multiple_device_output() return # Skip printing when there are multiple devices @@ -1805,7 +1847,8 @@ class AMDSMICommands(): def reset(self, args, multiple_devices=False, gpu=None, gpureset=None, - clocks=None, fans=None, profile=None, xgmierr=None, perfdeterminism=None): + clocks=None, fans=None, profile=None, xgmierr=None, perfdeterminism=None, + compute_partition=None, memory_partition=None): """Issue reset commands to target gpu(s) Args: @@ -1818,6 +1861,8 @@ class AMDSMICommands(): profile (bool, optional): Value override for args.profile. Defaults to None. xgmierr (bool, optional): Value override for args.xgmierr. Defaults to None. perfdeterminism (bool, optional): Value override for args.perfdeterminism. Defaults to None. + compute_partition (bool, optional): Value override for args.compute_partition. Defaults to None. + memory_partition (bool, optional): Value override for args.memory_partition. Defaults to None. Raises: ValueError: Value error if no gpu value is provided @@ -1841,6 +1886,10 @@ class AMDSMICommands(): args.xgmierr = xgmierr if perfdeterminism: args.perfdeterminism = perfdeterminism + if compute_partition: + args.compute_partition = compute_partition + if memory_partition: + args.memory_partition = memory_partition # Handle No GPU passed if args.gpu == None: @@ -1958,8 +2007,27 @@ class AMDSMICommands(): raise PermissionError('Command requires elevation') from e result = "N/A" logging.debug("Failed to set perf level on gpu %s | %s", gpu_id, e.get_error_info()) - self.logger.store_output(args.gpu, 'reset_perf_determinism', result) + if args.compute_partition: + try: + amdsmi_interface.amdsmi_reset_gpu_compute_partition(args.gpu) + result = 'Successfully reset compute partition' + except amdsmi_exception.AmdSmiLibraryException as e: + if e.get_error_code() == amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NO_PERM: + raise PermissionError('Command requires elevation') from e + result = "N/A" + logging.debug("Failed to reset compute partition on gpu %s | %s", gpu_id, e.get_error_info()) + self.logger.store_output(args.gpu, 'reset_compute_partition', result) + if args.memory_partition: + try: + amdsmi_interface.amdsmi_reset_gpu_memory_partition(args.gpu) + result = 'Successfully reset memory partition' + except amdsmi_exception.AmdSmiLibraryException as e: + if e.get_error_code() == amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NO_PERM: + raise PermissionError('Command requires elevation') from e + result = "N/A" + logging.debug("Failed to reset memory partition on gpu %s | %s", gpu_id, e.get_error_info()) + self.logger.store_output(args.gpu, 'reset_memory_partition', result) if multiple_devices: self.logger.store_multiple_device_output() diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_helpers.py b/projects/amdsmi/amdsmi_cli/amdsmi_helpers.py index f4914e01a4..9fbc4398ab 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_helpers.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_helpers.py @@ -342,6 +342,20 @@ class AMDSMIHelpers(): return perf_levels_str, perf_levels_int + def get_compute_partition_types(self): + compute_partitions_str = [partition.name for partition in amdsmi_interface.AmdSmiComputePartitionType] + if 'INVALID' in compute_partitions_str: + compute_partitions_str.remove('INVALID') + return compute_partitions_str + + + def get_memory_partition_types(self): + memory_partitions_str = [partition.name for partition in amdsmi_interface.AmdSmiMemoryPartitionType] + if 'UNKNOWN' in memory_partitions_str: + memory_partitions_str.remove('UNKNOWN') + return memory_partitions_str + + def get_clock_types(self): clock_types_str = [clock.name for clock in amdsmi_interface.AmdSmiClkType] clock_types_int = list(set(clock.value for clock in amdsmi_interface.AmdSmiClkType)) diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_parser.py b/projects/amdsmi/amdsmi_cli/amdsmi_parser.py index 97c3a53573..098fe2f629 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_parser.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_parser.py @@ -311,6 +311,7 @@ class AMDSMIParser(argparse.ArgumentParser): # Options arguments help text for Hypervisors and Baremetal ras_help = "Displays RAS features information" numa_help = "All numa node information" # Linux Baremetal only + partition_help = "Partition information" # Options arguments help text for Hypervisors dfc_help = "All DFC FW table information" @@ -339,6 +340,7 @@ class AMDSMIParser(argparse.ArgumentParser): # Options to display on Hypervisors and Baremetal if self.helpers.is_hypervisor() or self.helpers.is_baremetal(): static_parser.add_argument('-r', '--ras', action='store_true', required=False, help=ras_help) + static_parser.add_argument('-p', '--partition', action='store_true', required=False, help=partition_help) if self.helpers.is_linux(): static_parser.add_argument('-l', '--limit', action='store_true', required=False, help=limit_help) static_parser.add_argument('-u', '--numa', action='store_true', required=False, help=numa_help) @@ -615,11 +617,13 @@ class AMDSMIParser(argparse.ArgumentParser): \nA set argument must be provided; Multiple set arguments are accepted" set_value_optionals_title = "Set Arguments" - # Help text for Arguments only on Guest and BM platforms + # Help text for Arguments only on BM platforms set_fan_help = "Sets GPU fan speed (0-255 or 0-100%%)" set_perf_level_help = "Sets performance level" set_profile_help = "Set power profile level (#) or a quoted string of custom profile attributes" set_perf_det_help = "Sets GPU clock frequency limit and performance level to determinism to get minimal performance variation" + set_compute_partition_help = "Sets compute partition mode" + set_memory_partition_help = "Sets memory partition mode" # Create set_value subparser set_value_parser = subparsers.add_parser('set', help=set_value_help, description=set_value_subcommand_help) @@ -633,9 +637,11 @@ class AMDSMIParser(argparse.ArgumentParser): # Optional Args set_value_parser.add_argument('-f', '--fan', action=self._validate_fan_speed(), required=False, help=set_fan_help, metavar='%') - set_value_parser.add_argument('-l', '--perflevel', action='store', choices=self.helpers.get_perf_levels()[0], type=str.upper, required=False, help=set_perf_level_help, metavar='LEVEL') + set_value_parser.add_argument('-l', '--perf-level', action='store', choices=self.helpers.get_perf_levels()[0], type=str.upper, required=False, help=set_perf_level_help, metavar='LEVEL') set_value_parser.add_argument('-P', '--profile', action='store', required=False, help=set_profile_help, metavar='SETPROFILE') - set_value_parser.add_argument('-d', '--perfdeterminism', action='store', type=self._positive_int, required=False, help=set_perf_det_help, metavar='SCLKMAX') + set_value_parser.add_argument('-d', '--perf-determinism', action='store', type=self._positive_int, required=False, help=set_perf_det_help, metavar='SCLKMAX') + set_value_parser.add_argument('-C', '--compute-partition', action='store', choices=self.helpers.get_compute_partition_types(), type=str.upper, required=False, help=set_compute_partition_help, metavar='PARTITION') + set_value_parser.add_argument('-M', '--memory-partition', action='store', choices=self.helpers.get_memory_partition_types(), type=str.upper, required=False, help=set_memory_partition_help, metavar='PARTITION') def _validate_set_clock(self, validate_clock_type=True): @@ -744,11 +750,13 @@ class AMDSMIParser(argparse.ArgumentParser): # Help text for Arguments only on Guest and BM platforms gpureset_help = "Reset the specified GPU" - resetclocks_help = "Reset clocks and overdrive to default" - resetfans_help = "Reset fans to automatic (driver) control" - resetprofile_help = "Reset power profile back to default" - resetxgmierr_help = "Reset XGMI error counts" - resetperfdet_help = "Disable performance determinism" + reset_clocks_help = "Reset clocks and overdrive to default" + reset_fans_help = "Reset fans to automatic (driver) control" + reset_profile_help = "Reset power profile back to default" + reset_xgmierr_help = "Reset XGMI error counts" + reset_perfdet_help = "Disable performance determinism" + reset_compute_help = "Reset compute partitions on the specified GPU" + reset_memory_help = "Reset memory partitions on the specified GPU" # Create reset subparser reset_parser = subparsers.add_parser('reset', help=reset_help, description=reset_subcommand_help) @@ -762,11 +770,13 @@ class AMDSMIParser(argparse.ArgumentParser): # Optional Args reset_parser.add_argument('-G', '--gpureset', action='store_true', required=False, help=gpureset_help) - reset_parser.add_argument('-c', '--clocks', action='store_true', required=False, help=resetclocks_help) - reset_parser.add_argument('-f', '--fans', action='store_true', required=False, help=resetfans_help) - reset_parser.add_argument('-p', '--profile', action='store_true', required=False, help=resetprofile_help) - reset_parser.add_argument('-x', '--xgmierr', action='store_true', required=False, help=resetxgmierr_help) - reset_parser.add_argument('-d', '--perfdeterminism', action='store_true', required=False, help=resetperfdet_help) + reset_parser.add_argument('-c', '--clocks', action='store_true', required=False, help=reset_clocks_help) + reset_parser.add_argument('-f', '--fans', action='store_true', required=False, help=reset_fans_help) + reset_parser.add_argument('-p', '--profile', action='store_true', required=False, help=reset_profile_help) + reset_parser.add_argument('-x', '--xgmierr', action='store_true', required=False, help=reset_xgmierr_help) + reset_parser.add_argument('-d', '--perf-determinism', action='store_true', required=False, help=reset_perfdet_help) + reset_parser.add_argument('-C', '--compute-partition', action='store_true', required=False, help=reset_compute_help) + reset_parser.add_argument('-M', '--memory-partition', action='store_true', required=False, help=reset_memory_help) def _add_rocm_smi_parser(self, subparsers, func): From 4c90eef8ff46c6fdcb36d57e418bb24a81f4eec9 Mon Sep 17 00:00:00 2001 From: Maisam Arif Date: Fri, 13 Oct 2023 14:03:24 -0500 Subject: [PATCH 16/27] Added custom help formatters for subparsers Signed-off-by: Maisam Arif Change-Id: Ib7209ad7188733fa2492cde302f5c82c9c9bfa42 [ROCm/amdsmi commit: ddc63db14c49fe457d4b0d60970d65c853a1f098] --- projects/amdsmi/amdsmi_cli/amdsmi_parser.py | 103 +++++++++++--------- 1 file changed, 57 insertions(+), 46 deletions(-) diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_parser.py b/projects/amdsmi/amdsmi_cli/amdsmi_parser.py index 098fe2f629..679c8138b6 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_parser.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_parser.py @@ -34,18 +34,28 @@ import amdsmi_cli_exceptions # Custom Help Formatter for increasing the action max length -class SubparserHelpFormatter(argparse.HelpFormatter): - def __init__(self, prog, - indent_increment=2, - max_help_position=24, - width=90): - super().__init__(prog, - indent_increment=indent_increment, - max_help_position=max_help_position, - width=width) +class AMDSMIParserHelpFormatter(argparse.HelpFormatter): + def __init__(self, prog): + super().__init__(prog=prog, + indent_increment=2, + max_help_position=24, + width=90) self._action_max_length = 20 +# Custom Help Formatter for not duplicating the metavar in the subparsers +class AMDSMISubparserHelpFormatter(argparse.RawTextHelpFormatter): + def __init__(self, prog): + super().__init__(prog, max_help_position=80, width=90) + + def _format_action_invocation(self, action): + if not action.option_strings or action.nargs == 0: + return super()._format_action_invocation(action) + default = self._get_default_metavar_for_optional(action) + args_string = self._format_args(action, default) + return ', '.join(action.option_strings) + ' ' + args_string + + class AMDSMIParser(argparse.ArgumentParser): """Unified Parser for AMDSMI CLI. This parser doesn't access amdsmi's lib directly,but via AMDSMIHelpers, @@ -69,32 +79,32 @@ class AMDSMIParser(argparse.ArgumentParser): # Adjust argument parser options super().__init__( - formatter_class= lambda prog: SubparserHelpFormatter(prog), + formatter_class= lambda prog: AMDSMIParserHelpFormatter(prog), description=f"AMD System Management Interface | {version_string} | {platform_string}", add_help=True, prog=program_name) # Setup subparsers - subparsers = self.add_subparsers( + self.subparsers = self.add_subparsers( title="AMD-SMI Commands", parser_class=argparse.ArgumentParser, help="Descriptions:", metavar='') # Add all subparsers - self._add_version_parser(subparsers, version) - self._add_list_parser(subparsers, list) - self._add_static_parser(subparsers, static) - self._add_firmware_parser(subparsers, firmware) - self._add_bad_pages_parser(subparsers, bad_pages) - self._add_metric_parser(subparsers, metric) - self._add_process_parser(subparsers, process) - self._add_profile_parser(subparsers, profile) - self._add_event_parser(subparsers, event) - self._add_topology_parser(subparsers, topology) - self._add_set_value_parser(subparsers, set_value) - self._add_reset_parser(subparsers, reset) - self._add_rocm_smi_parser(subparsers, rocmsmi) + self._add_version_parser(self.subparsers, version) + self._add_list_parser(self.subparsers, list) + self._add_static_parser(self.subparsers, static) + self._add_firmware_parser(self.subparsers, firmware) + self._add_bad_pages_parser(self.subparsers, bad_pages) + self._add_metric_parser(self.subparsers, metric) + self._add_process_parser(self.subparsers, process) + self._add_profile_parser(self.subparsers, profile) + self._add_event_parser(self.subparsers, event) + self._add_topology_parser(self.subparsers, topology) + self._add_set_value_parser(self.subparsers, set_value) + self._add_reset_parser(self.subparsers, reset) + self._add_rocm_smi_parser(self.subparsers, rocmsmi) def _positive_int(self, int_value): @@ -212,7 +222,8 @@ class AMDSMIParser(argparse.ArgumentParser): json_help = "Displays output in JSON format (human readable by default)." csv_help = "Displays output in CSV format (human readable by default)." file_help = "Saves output into a file on the provided path (stdout by default)." - loglevel_help = "Set the logging level for the parser commands (ERROR by default)." + loglevel_choices = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"] + loglevel_help = f"Set the logging level from the possible choices:\n{loglevel_choices}" command_modifier_group = subcommand_parser.add_argument_group('Command Modifiers') @@ -223,22 +234,22 @@ class AMDSMIParser(argparse.ArgumentParser): command_modifier_group.add_argument('--file', action=self._check_output_file_path(), type=str, required=False, help=file_help) # Placing loglevel outside the subcommands so it can be used with any subcommand - command_modifier_group.add_argument('--loglevel', action='store', required=False, help=loglevel_help, default='ERROR', - choices=["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]) + command_modifier_group.add_argument('--loglevel', action='store', required=False, help=loglevel_help, default='ERROR', metavar='LEVEL', + choices=loglevel_choices) def _add_watch_arguments(self, subcommand_parser): # Device arguments help text - watch_help = "Reprint the command in a loop of Interval seconds" - watch_time_help = "The total time to watch the given command" - iterations_help = "Total number of iterations to loop on the given command" + watch_help = "Reprint the command in a loop of INTERVAL seconds" + watch_time_help = "The total TIME to watch the given command" + iterations_help = "Total number of ITERATIONS to loop on the given command" # Mutually Exclusive Args within the subparser - subcommand_parser.add_argument('-w', '--watch', action='store', metavar='loop_time', + subcommand_parser.add_argument('-w', '--watch', action='store', metavar='INTERVAL', type=self._positive_int, required=False, help=watch_help) - subcommand_parser.add_argument('-W', '--watch_time', action=self._check_watch_selected(), metavar='total_loop_time', + subcommand_parser.add_argument('-W', '--watch_time', action=self._check_watch_selected(), metavar='TIME', type=self._positive_int, required=False, help=watch_time_help) - subcommand_parser.add_argument('-i', '--iterations', action=self._check_watch_selected(), metavar='number_of_iterations', + subcommand_parser.add_argument('-i', '--iterations', action=self._check_watch_selected(), metavar='ITERATIONS', type=self._positive_int, required=False, help=iterations_help) @@ -265,7 +276,7 @@ class AMDSMIParser(argparse.ArgumentParser): # Create version subparser version_parser = subparsers.add_parser('version', help=version_help, description=None) version_parser._optionals.title = None - version_parser.formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, max_help_position=80, width=90) + version_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) version_parser.set_defaults(func=func) self._add_command_modifiers(version_parser) @@ -281,7 +292,7 @@ class AMDSMIParser(argparse.ArgumentParser): # Create list subparser list_parser = subparsers.add_parser('list', help=list_help, description=list_subcommand_help) - list_parser.formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, max_help_position=80, width=90) + list_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) list_parser.set_defaults(func=func) # Add Command Modifiers @@ -321,7 +332,7 @@ class AMDSMIParser(argparse.ArgumentParser): # Create static subparser static_parser = subparsers.add_parser('static', help=static_help, description=static_subcommand_help) static_parser._optionals.title = static_optionals_title - static_parser.formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, max_help_position=80, width=90) + static_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) static_parser.set_defaults(func=func) self._add_command_modifiers(static_parser) @@ -365,7 +376,7 @@ class AMDSMIParser(argparse.ArgumentParser): # Create firmware subparser firmware_parser = subparsers.add_parser('firmware', help=firmware_help, description=firmware_subcommand_help, aliases=['ucode']) firmware_parser._optionals.title = firmware_optionals_title - firmware_parser.formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, max_help_position=80, width=90) + firmware_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) firmware_parser.set_defaults(func=func) self._add_command_modifiers(firmware_parser) @@ -398,7 +409,7 @@ class AMDSMIParser(argparse.ArgumentParser): # Create bad_pages subparser bad_pages_parser = subparsers.add_parser('bad-pages', help=bad_pages_help, description=bad_pages_subcommand_help) bad_pages_parser._optionals.title = bad_pages_optionals_title - bad_pages_parser.formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, max_help_position=80, width=90) + bad_pages_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) bad_pages_parser.set_defaults(func=func) self._add_command_modifiers(bad_pages_parser) @@ -448,7 +459,7 @@ class AMDSMIParser(argparse.ArgumentParser): # Create metric subparser metric_parser = subparsers.add_parser('metric', help=metric_help, description=metric_subcommand_help) metric_parser._optionals.title = metric_optionals_title - metric_parser.formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, max_help_position=80, width=90) + metric_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) metric_parser.set_defaults(func=func) self._add_command_modifiers(metric_parser) @@ -511,7 +522,7 @@ class AMDSMIParser(argparse.ArgumentParser): # Create process subparser process_parser = subparsers.add_parser('process', help=process_help, description=process_subcommand_help) process_parser._optionals.title = process_optionals_title - process_parser.formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, max_help_position=80, width=90) + process_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) process_parser.set_defaults(func=func) self._add_command_modifiers(process_parser) @@ -541,7 +552,7 @@ class AMDSMIParser(argparse.ArgumentParser): # Create profile subparser profile_parser = subparsers.add_parser('profile', help=profile_help, description=profile_subcommand_help) profile_parser._optionals.title = profile_optionals_title - profile_parser.formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, max_help_position=80, width=90) + profile_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) profile_parser.set_defaults(func=func) self._add_command_modifiers(profile_parser) @@ -562,7 +573,7 @@ class AMDSMIParser(argparse.ArgumentParser): # Create event subparser event_parser = subparsers.add_parser('event', help=event_help, description=event_subcommand_help) event_parser._optionals.title = event_optionals_title - event_parser.formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, max_help_position=80, width=90) + event_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) event_parser.set_defaults(func=func) self._add_command_modifiers(event_parser) @@ -591,7 +602,7 @@ class AMDSMIParser(argparse.ArgumentParser): # Create topology subparser topology_parser = subparsers.add_parser('topology', help=topology_help, description=topology_subcommand_help) topology_parser._optionals.title = topology_optionals_title - topology_parser.formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, max_help_position=80, width=90) + topology_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) topology_parser.set_defaults(func=func) self._add_command_modifiers(topology_parser) @@ -628,7 +639,7 @@ class AMDSMIParser(argparse.ArgumentParser): # Create set_value subparser set_value_parser = subparsers.add_parser('set', help=set_value_help, description=set_value_subcommand_help) set_value_parser._optionals.title = set_value_optionals_title - set_value_parser.formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, max_help_position=80, width=90) + set_value_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) set_value_parser.set_defaults(func=func) self._add_command_modifiers(set_value_parser) @@ -761,7 +772,7 @@ class AMDSMIParser(argparse.ArgumentParser): # Create reset subparser reset_parser = subparsers.add_parser('reset', help=reset_help, description=reset_subcommand_help) reset_parser._optionals.title = reset_optionals_title - reset_parser.formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, max_help_position=80, width=90) + reset_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) reset_parser.set_defaults(func=func) self._add_command_modifiers(reset_parser) @@ -802,7 +813,7 @@ class AMDSMIParser(argparse.ArgumentParser): # Create rocm_smi subparser rocm_smi_parser = subparsers.add_parser('rocm-smi', help=rocm_smi_help, description=rocm_smi_subcommand_help) rocm_smi_parser._optionals.title = rocm_smi_optionals_title - rocm_smi_parser.formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, max_help_position=80, width=90) + rocm_smi_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) rocm_smi_parser.set_defaults(func=func) self._add_command_modifiers(rocm_smi_parser) From 45fb716d652c164799ffb0683d8cdda3407689a9 Mon Sep 17 00:00:00 2001 From: Maisam Arif Date: Mon, 16 Oct 2023 03:26:17 -0500 Subject: [PATCH 17/27] Adjusting cli exception handling Signed-off-by: Maisam Arif Change-Id: I37f44f0d07a8d1fc65e6109edf9b4cf7f30695a9 Signed-off-by: Maisam Arif [ROCm/amdsmi commit: 2468a6039cfe01a3a40e273cdeff3ce519171b12] --- projects/amdsmi/amdsmi_cli/amdsmi_cli_exceptions.py | 3 ++- projects/amdsmi/amdsmi_cli/amdsmi_commands.py | 1 - projects/amdsmi/amdsmi_cli/amdsmi_helpers.py | 11 +++++++---- projects/amdsmi/amdsmi_cli/amdsmi_parser.py | 7 +++++-- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_cli_exceptions.py b/projects/amdsmi/amdsmi_cli/amdsmi_cli_exceptions.py index c43f37379a..13fe9753eb 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_cli_exceptions.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_cli_exceptions.py @@ -22,6 +22,7 @@ import json + AMDSMI_ERROR_MESSAGES = { 0: "Sucess", 1: "Invalid parameters", @@ -117,7 +118,7 @@ class AmdSmiDeviceNotFoundException(AmdSmiException): self.command = command self.output_format = outputformat - common_message = f"GPU Device with GPU_INDEX '{self.command}' cannot be found on the system." + common_message = f"Can not find a GPU with the corresponding identifier: '{self.command}'" self.json_message["error"] = common_message self.json_message["code"] = self.value diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_commands.py b/projects/amdsmi/amdsmi_cli/amdsmi_commands.py index 65afc71a79..7326c83214 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_commands.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_commands.py @@ -659,7 +659,6 @@ class AMDSMICommands(): args.retired = args.pending = args.un_res = True values_dict = {} - bad_page_err_output = '' # Get gpu_id for logging gpu_id = self.helpers.get_gpu_id_from_device_handle(args.gpu) diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_helpers.py b/projects/amdsmi/amdsmi_cli/amdsmi_helpers.py index 9fbc4398ab..9bb790a73c 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_helpers.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_helpers.py @@ -27,6 +27,7 @@ import time from subprocess import run from subprocess import PIPE, STDOUT +from typing import List from amdsmi_init import * from BDF import BDF @@ -169,11 +170,11 @@ class AMDSMIHelpers(): return (gpu_choices, gpu_choices_str) - def get_device_handles_from_gpu_selections(self, gpu_selections, gpu_choices=None): + def get_device_handles_from_gpu_selections(self, gpu_selections: List[str], gpu_choices=None): """Convert provided gpu_selections to device_handles Args: - gpu_selections (list[str]): This will be the GPU ID, BDF, or UUID: + gpu_selections (list[str]): Selected GPU ID(s), BDF(s), or UUID(s): ex: ID:0 | BDF:0000:23:00.0 | UUID:ffffffff-0000-1000-0000-000000000000 gpu_choices (dict{gpu_choices}): This is a dictionary of the possible gpu_choices Returns: @@ -181,7 +182,7 @@ class AMDSMIHelpers(): amdsmi device_handles (False, str): Return False, and the first input that failed to be converted """ - if gpu_selections == ["all"]: + if 'all' in gpu_selections: return (True, amdsmi_interface.amdsmi_get_processor_handles()) if isinstance(gpu_selections, str): @@ -307,7 +308,9 @@ class AMDSMIHelpers(): for gpu_index, device_handle in enumerate(device_handles): if input_device_handle.value == device_handle.value: return gpu_index - raise IndexError("Unable to find gpu ID from device_handle") + raise amdsmi_exception.AmdSmiParameterException(input_device_handle, + amdsmi_interface.amdsmi_wrapper.amdsmi_processor_handle, + "Unable to find gpu ID from device_handle") def get_amd_gpu_bdfs(self): diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_parser.py b/projects/amdsmi/amdsmi_cli/amdsmi_parser.py index 679c8138b6..8ad7686f86 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_parser.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_parser.py @@ -24,9 +24,10 @@ import argparse import errno import os -import time -from pathlib import Path import sys +import time + +from pathlib import Path from _version import __version__ from amdsmi_helpers import AMDSMIHelpers @@ -205,6 +206,8 @@ class AMDSMIParser(argparse.ArgumentParser): ouputformat=self.helpers.get_output_format() # Checks the values def __call__(self, parser, args, values, option_string=None): + if "all" in gpu_choices: + del gpu_choices["all"] status, selected_device_handles = amdsmi_helpers.get_device_handles_from_gpu_selections(gpu_selections=values, gpu_choices=gpu_choices) if status: From 1bf35b5c05948d0a9880bd3ba8ab8db588df484b Mon Sep 17 00:00:00 2001 From: Suma Hegde Date: Fri, 13 Oct 2023 08:11:21 -0400 Subject: [PATCH 18/27] esmi: Clone open-source esmi repo as part of build 1. Remove esmi (internal gerrit) repo as git submodule 2. Clone esmi (open-source) repo during cmake using "git clone" 3. Download amd_hsmp.h header file during cmake build TODO: We can update the amd_hsmp.h to mainline linux kernel repo after next Linux kernel release. Change-Id: I763b5e287e24337c8e9e25f4e421cdb8698b9322 [ROCm/amdsmi commit: 597fb00bef0b15e964db21f12b29e165656c22d3] --- projects/amdsmi/.gitignore | 3 +++ projects/amdsmi/.gitmodules | 4 ---- projects/amdsmi/CMakeLists.txt | 27 ++++++++++++++++----------- projects/amdsmi/e_smi_library | 1 - projects/amdsmi/src/CMakeLists.txt | 2 +- 5 files changed, 20 insertions(+), 17 deletions(-) delete mode 160000 projects/amdsmi/e_smi_library diff --git a/projects/amdsmi/.gitignore b/projects/amdsmi/.gitignore index 6f052a082c..9dae753e46 100644 --- a/projects/amdsmi/.gitignore +++ b/projects/amdsmi/.gitignore @@ -31,3 +31,6 @@ docBin/ # Simulated SYSFS - for early development or debug device/ + +# misc +esmi_ib_library/ diff --git a/projects/amdsmi/.gitmodules b/projects/amdsmi/.gitmodules index 78e8455b04..e69de29bb2 100644 --- a/projects/amdsmi/.gitmodules +++ b/projects/amdsmi/.gitmodules @@ -1,4 +0,0 @@ -[submodule "e_smi_library"] - path = e_smi_library - url = ssh://gerritgit/SYS-MGMT/er/HPC/e_smi_library - branch = amd-dev diff --git a/projects/amdsmi/CMakeLists.txt b/projects/amdsmi/CMakeLists.txt index 359c24bdef..8615c073dc 100755 --- a/projects/amdsmi/CMakeLists.txt +++ b/projects/amdsmi/CMakeLists.txt @@ -60,7 +60,7 @@ option(BUILD_WRAPPER "Rebuild AMDSMI-wrapper" OFF) option(BUILD_CLI "Build AMDSMI-CLI and install" ON) option(ENABLE_LDCONFIG "Set library links and caches using ldconfig." ON) option(ENABLE_ASAN_PACKAGING "" OFF) -option(ENABLE_ESMI_LIB "" OFF) +option(ENABLE_ESMI_LIB "" ON) # Set share path here because project name != amd_smi set(SHARE_INSTALL_PREFIX "share/${AMD_SMI}" CACHE STRING "Tests and Example install directory") @@ -95,16 +95,21 @@ set(AMDSMI_INC_DIR "${PROJECT_SOURCE_DIR}/include/amd_smi") set(ROCM_INC_DIR "${PROJECT_SOURCE_DIR}/rocm_smi/include/rocm_smi") 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) + if(NOT EXISTS ${PROJECT_SOURCE_DIR}/esmi_ib_library/src) + # TODO: use ExternalProject_Add instead or a submodule + # as of 2023.10.16 CI builds are broken with an updated submodule + execute_process(COMMAND git clone --depth=1 -b esmi_so_ver-3.0 https://github.com/amd/esmi_ib_library.git ${PROJECT_SOURCE_DIR}/esmi_ib_library) + endif() + if(NOT EXISTS ${PROJECT_SOURCE_DIR}/esmi_ib_library/include/asm/amd_hsmp.h) + file(DOWNLOAD + https://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86.git/plain/arch/x86/include/uapi/asm/amd_hsmp.h?h=review-ilpo + ${PROJECT_SOURCE_DIR}/esmi_ib_library/include/asm/amd_hsmp.h) + endif() add_definitions("-DENABLE_ESMI_LIB=1") -else() - message("E-smi source not found. Errors will be encountered during compilation!!!") -endif() -if(ESMI_AVAILABLE) - set(ESMI_INC_DIR "${PROJECT_SOURCE_DIR}/e_smi_library/include") - set(ESMI_SRC_DIR "${PROJECT_SOURCE_DIR}/e_smi_library/src") -endif() + set(ESMI_INC_DIR "${PROJECT_SOURCE_DIR}/esmi_ib_library/include") + set(ESMI_SRC_DIR "${PROJECT_SOURCE_DIR}/esmi_ib_library/src") + # esmi has a lot of write-strings warnings - silence them + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-write-strings") endif() pkg_check_modules(DRM REQUIRED libdrm) @@ -127,7 +132,7 @@ set(CMN_SRC_LIST "${ROCM_SRC_DIR}/rocm_smi_logger.cc" "${SHR_MUTEX_DIR}/shared_mutex.cc") -if(ESMI_AVAILABLE) +if(ENABLE_ESMI_LIB) list(APPEND CMN_SRC_LIST ${ESMI_SRC_DIR}/e_smi.c) list(APPEND CMN_SRC_LIST ${ESMI_SRC_DIR}/e_smi_monitor.c) list(APPEND CMN_SRC_LIST ${ESMI_SRC_DIR}/e_smi_plat.c) diff --git a/projects/amdsmi/e_smi_library b/projects/amdsmi/e_smi_library deleted file mode 160000 index 1b2de9f700..0000000000 --- a/projects/amdsmi/e_smi_library +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 1b2de9f700045ce83319e6a3b7193c3f4746a9d7 diff --git a/projects/amdsmi/src/CMakeLists.txt b/projects/amdsmi/src/CMakeLists.txt index 956bb98fec..3e22f52ffe 100644 --- a/projects/amdsmi/src/CMakeLists.txt +++ b/projects/amdsmi/src/CMakeLists.txt @@ -50,7 +50,7 @@ set(INC_LIST "${PROJECT_SOURCE_DIR}/rocm_smi/include/rocm_smi/rocm_smi.h" "${PROJECT_SOURCE_DIR}/rocm_smi/include/rocm_smi/rocm_smi_utils.h") -if(ESMI_AVAILABLE) +if(ENABLE_ESMI_LIB) list(APPEND INC_LIST ${ESMI_INC_DIR}/e_smi/e_smi.h) list(APPEND INC_LIST ${ESMI_INC_DIR}/e_smi/e_smi_monitor.h) list(APPEND INC_LIST ${ESMI_INC_DIR}/e_smi/e_smi_utils.h) From 614930f90ec714d50880dbb4242d49396b58718e Mon Sep 17 00:00:00 2001 From: Suma Hegde Date: Mon, 16 Oct 2023 04:29:26 -0400 Subject: [PATCH 19/27] amdsmi_esmi_intg_example.cc: Fix compilation warnings remove unused variables, fix uninitialized variables Change-Id: Ia0b529d3bb0ec8c541bcf1abd8b06d4237d593e8 [ROCm/amdsmi commit: abad3305a1a366f52b8345d4722e092da2baac06] --- .../example/amdsmi_esmi_intg_example.cc | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/projects/amdsmi/example/amdsmi_esmi_intg_example.cc b/projects/amdsmi/example/amdsmi_esmi_intg_example.cc index a17554b3e6..8e8915d6e0 100644 --- a/projects/amdsmi/example/amdsmi_esmi_intg_example.cc +++ b/projects/amdsmi/example/amdsmi_esmi_intg_example.cc @@ -72,7 +72,6 @@ int main(int argc, char **argv) { amdsmi_status_t ret; uint32_t proto_ver; amdsmi_smu_fw_version_t smu_fw = {}; - amdsmi_cpusocket_handle socket_handle; // Initialize esmi for AMD CPUs ret = amdsmi_init(AMDSMI_INIT_AMD_CPUS); @@ -94,9 +93,9 @@ int main(int argc, char **argv) { cout << "Total Socket: " << socket_count << endl; // For each socket, get identifier and cores - for (uint32_t i = 0; i < socket_count; i++) { + for (uint8_t i = 0; i < socket_count; i++) { // Get Socket info - uint32_t socket_info; + uint32_t socket_info = 0; ret = amdsmi_get_cpusocket_info(sockets[i], socket_info); CHK_AMDSMI_RET(ret) cout << "Socket " << socket_info << endl; @@ -134,9 +133,6 @@ int main(int argc, char **argv) { uint32_t err_bits = 0; - uint64_t pkg_input; - - err_bits = 0; uint32_t prochot; cout<<"\n-------------------------------------------------"; cout<<"\n| Sensor Name\t\t\t |"; @@ -379,7 +375,7 @@ int main(int argc, char **argv) { cout<<"\n-------------------------------------------------\n"; amdsmi_temp_range_refresh_rate_t rate; - uint8_t dimm_addr; + uint8_t dimm_addr = 0x80; cout<<"\n| Socket DIMM temp range and refresh rate\t\t |\n"; ret = amdsmi_get_cpu_dimm_temp_range_and_refresh_rate(sockets[i], i, dimm_addr, &rate); CHK_AMDSMI_RET(ret) @@ -468,7 +464,7 @@ int main(int argc, char **argv) { cout<<"\n-------------------------------------------------\n"; - int32_t pstate; + int8_t pstate; cout<<"\nEnter the pstate to be set:\n"; cin>>pstate; ret = amdsmi_cpu_apb_disable(sockets[i], i, pstate); @@ -552,7 +548,7 @@ int main(int argc, char **argv) { amdsmi_link_id_bw_type_t io_link; uint32_t bw; - char *link = "P0"; + char* link = "P0"; io_link.link_name = link; io_link.bw_type = static_cast(1) ; ret = amdsmi_get_cpu_current_io_bandwidth(sockets[i], i, io_link, &bw); @@ -568,8 +564,8 @@ int main(int argc, char **argv) { amdsmi_link_id_bw_type_t xgmi_link; uint32_t bw1; - char *link1 = "P0"; int bw_ind = 1; + char* link1 = "P1"; xgmi_link.link_name = link1; xgmi_link.bw_type = static_cast(1< Date: Mon, 16 Oct 2023 11:24:04 -0500 Subject: [PATCH 20/27] ESMI - Clean-up example code Change-Id: Iacd150209d4695a39de39bd5633293d3e040ff4b Signed-off-by: Galantsev, Dmitrii [ROCm/amdsmi commit: 8333ffc6400edce252581ad0ae3aead8815806d3] --- projects/amdsmi/.gitmodules | 0 projects/amdsmi/CMakeLists.txt | 1 + .../example/amdsmi_esmi_intg_example.cc | 50 +++++++++++-------- 3 files changed, 29 insertions(+), 22 deletions(-) delete mode 100644 projects/amdsmi/.gitmodules diff --git a/projects/amdsmi/.gitmodules b/projects/amdsmi/.gitmodules deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/projects/amdsmi/CMakeLists.txt b/projects/amdsmi/CMakeLists.txt index 8615c073dc..785137f2e7 100755 --- a/projects/amdsmi/CMakeLists.txt +++ b/projects/amdsmi/CMakeLists.txt @@ -51,6 +51,7 @@ set(AMD_SMI_PACKAGE project(${AMD_SMI_LIBS_TARGET}) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) include(GNUInstallDirs) diff --git a/projects/amdsmi/example/amdsmi_esmi_intg_example.cc b/projects/amdsmi/example/amdsmi_esmi_intg_example.cc index 8e8915d6e0..64114852b3 100644 --- a/projects/amdsmi/example/amdsmi_esmi_intg_example.cc +++ b/projects/amdsmi/example/amdsmi_esmi_intg_example.cc @@ -48,11 +48,10 @@ #include #include #include "amd_smi/amdsmi.h" +#include "asm/amd_hsmp.h" #include #include -using namespace std; - #define SHOWLINESZ 256 #define CHK_AMDSMI_RET(RET) \ @@ -68,6 +67,13 @@ using namespace std; } \ } +using std::cin; +using std::cout; +using std::endl; +using std::fixed; +using std::setprecision; +using std::vector; + int main(int argc, char **argv) { amdsmi_status_t ret; uint32_t proto_ver; @@ -196,7 +202,7 @@ int main(int argc, char **argv) { cout<<"\n| CPU["<(power)/1000<<"\t|"; + cout<(socket_power)/1000<<"\t|"; } else { err_bits |= 1 << ret; cout<<" NA (Err:" <(powerlimit)/1000<<"\t|"; + cout<(power_limit)/1000<<"\t|"; } else { err_bits |= 1 << ret; cout<<" NA (Err:" <(powermax)/1000<<"\t|"; + cout<(power_max)/1000<<"\t|"; } else { err_bits |= 1 << ret; cout<<" NA (Err:" <>input_power; - ret = amdsmi_get_cpu_socket_power_cap_max(sockets[i], i, &powermax); + ret = amdsmi_get_cpu_socket_power_cap_max(sockets[i], i, &power_max); CHK_AMDSMI_RET(ret) - if ((ret == AMDSMI_STATUS_SUCCESS) && (input_power > powermax)) { + if ((ret == AMDSMI_STATUS_SUCCESS) && (input_power > power_max)) { cout<<"Input power is more than max power limit," - " limiting to "<(powermax)/1000<<"Watts\n"; - input_power = powermax; + " limiting to "<(power_max)/1000<<"Watts\n"; + input_power = power_max; } ret = amdsmi_set_cpu_socket_power_cap(sockets[i], i, input_power); CHK_AMDSMI_RET(ret) @@ -389,15 +395,15 @@ int main(int argc, char **argv) { cout<<"\n-------------------------------------------------\n"; - amdsmi_dimm_power_t p; + amdsmi_dimm_power_t dimm_power; cout<<"\n| Socket DIMM power consumption\t\t |\n"; - ret = amdsmi_get_cpu_dimm_power_consumption(sockets[i], i, dimm_addr, &p); + ret = amdsmi_get_cpu_dimm_power_consumption(sockets[i], i, dimm_addr, &dimm_power); CHK_AMDSMI_RET(ret) if(ret) { - cout<<"\n| Power(mWatts)\t\t |"< Date: Mon, 16 Oct 2023 16:22:11 -0500 Subject: [PATCH 21/27] CMAKE - Generate ESMI wrapper The wrapper is only generated if ENABLE_ESMI_LIB option is set. ./update_wrapper.sh will check the option if cmake was ran first. Change-Id: I6267cdba8c6ecdff58ced75a2aa59afae964446c Signed-off-by: Galantsev, Dmitrii [ROCm/amdsmi commit: 8568af65ff92d640603fe38fddacb8b8fc41de29] --- projects/amdsmi/py-interface/CMakeLists.txt | 2 +- projects/amdsmi/py-interface/__init__.py | 2 +- .../amdsmi/py-interface/amdsmi_wrapper.py | 346 ++++++++++++++++-- projects/amdsmi/tools/generator.py | 14 +- projects/amdsmi/update_wrapper.sh | 16 +- 5 files changed, 343 insertions(+), 37 deletions(-) diff --git a/projects/amdsmi/py-interface/CMakeLists.txt b/projects/amdsmi/py-interface/CMakeLists.txt index 4582776ecc..7996d04bf1 100644 --- a/projects/amdsmi/py-interface/CMakeLists.txt +++ b/projects/amdsmi/py-interface/CMakeLists.txt @@ -66,7 +66,7 @@ else() generator.py ${PROJECT_SOURCE_DIR}/include/amd_smi/amdsmi.h COMMAND cp ${PROJECT_SOURCE_DIR}/include/amd_smi/amdsmi.h ./ - COMMAND ${Python3_EXECUTABLE} generator.py -i amdsmi.h -l ${PROJECT_BINARY_DIR}/src/libamd_smi.so -o ${CMAKE_CURRENT_SOURCE_DIR}/amdsmi_wrapper.py + COMMAND ${Python3_EXECUTABLE} generator.py "$<$:-e -DENABLE_ESMI_LIB>" -i amdsmi.h -l ${PROJECT_BINARY_DIR}/src/libamd_smi.so -o ${CMAKE_CURRENT_SOURCE_DIR}/amdsmi_wrapper.py COMMAND cp -f ${CMAKE_CURRENT_SOURCE_DIR}/amdsmi_wrapper.py ${CMAKE_CURRENT_BINARY_DIR}/ # hacky alternative to configure_file that will run at MAKE compile instead of CMake configure COMMAND sed -i diff --git a/projects/amdsmi/py-interface/__init__.py b/projects/amdsmi/py-interface/__init__.py index d0b7bc417a..bac8f6745d 100644 --- a/projects/amdsmi/py-interface/__init__.py +++ b/projects/amdsmi/py-interface/__init__.py @@ -23,7 +23,7 @@ from .amdsmi_interface import amdsmi_init from .amdsmi_interface import amdsmi_shut_down -# Device Descovery +# Device Discovery from .amdsmi_interface import amdsmi_get_processor_type from .amdsmi_interface import amdsmi_get_processor_handles from .amdsmi_interface import amdsmi_get_socket_handles diff --git a/projects/amdsmi/py-interface/amdsmi_wrapper.py b/projects/amdsmi/py-interface/amdsmi_wrapper.py index 447bcbd540..a7a16ce2de 100644 --- a/projects/amdsmi/py-interface/amdsmi_wrapper.py +++ b/projects/amdsmi/py-interface/amdsmi_wrapper.py @@ -23,7 +23,7 @@ import os # -*- coding: utf-8 -*- # -# TARGET arch is: ['-I/usr/lib/llvm-16/lib/clang/16/include'] +# TARGET arch is: ['-I/usr/lib/llvm-16/lib/clang/16/include', '-DENABLE_ESMI_LIB'] # WORD_SIZE is: 8 # POINTER_SIZE is: 8 # LONGDOUBLE_SIZE is: 16 @@ -230,6 +230,7 @@ CONTAINER_DOCKER = 1 amdsmi_container_types_t = ctypes.c_uint32 # enum amdsmi_processor_handle = ctypes.POINTER(None) amdsmi_socket_handle = ctypes.POINTER(None) +amdsmi_cpusocket_handle = ctypes.POINTER(None) # values for enumeration 'processor_type_t' processor_type_t__enumvalues = { @@ -1541,6 +1542,101 @@ struct_amdsmi_process_info_t._fields_ = [ ] amdsmi_process_info_t = struct_amdsmi_process_info_t +class struct_amdsmi_smu_fw_version_t(Structure): + pass + +struct_amdsmi_smu_fw_version_t._pack_ = 1 # source:False +struct_amdsmi_smu_fw_version_t._fields_ = [ + ('debug', ctypes.c_ubyte), + ('minor', ctypes.c_ubyte), + ('major', ctypes.c_ubyte), + ('unused', ctypes.c_ubyte), +] + +amdsmi_smu_fw_version_t = struct_amdsmi_smu_fw_version_t +class struct_amdsmi_ddr_bw_metrics_t(Structure): + pass + +struct_amdsmi_ddr_bw_metrics_t._pack_ = 1 # source:False +struct_amdsmi_ddr_bw_metrics_t._fields_ = [ + ('max_bw', ctypes.c_uint32), + ('utilized_bw', ctypes.c_uint32), + ('utilized_pct', ctypes.c_uint32), +] + +amdsmi_ddr_bw_metrics_t = struct_amdsmi_ddr_bw_metrics_t +class struct_amdsmi_temp_range_refresh_rate_t(Structure): + pass + +struct_amdsmi_temp_range_refresh_rate_t._pack_ = 1 # source:False +struct_amdsmi_temp_range_refresh_rate_t._fields_ = [ + ('range', ctypes.c_ubyte, 3), + ('ref_rate', ctypes.c_ubyte, 1), + ('PADDING_0', ctypes.c_uint8, 4), +] + +amdsmi_temp_range_refresh_rate_t = struct_amdsmi_temp_range_refresh_rate_t +class struct_amdsmi_dimm_power_t(Structure): + pass + +struct_amdsmi_dimm_power_t._pack_ = 1 # source:False +struct_amdsmi_dimm_power_t._fields_ = [ + ('power', ctypes.c_uint16, 15), + ('PADDING_0', ctypes.c_uint8, 1), + ('update_rate', ctypes.c_uint16, 9), + ('PADDING_1', ctypes.c_uint8, 7), + ('dimm_addr', ctypes.c_uint16, 8), + ('PADDING_2', ctypes.c_uint8, 8), +] + +amdsmi_dimm_power_t = struct_amdsmi_dimm_power_t +class struct_amdsmi_dimm_thermal_t(Structure): + pass + +struct_amdsmi_dimm_thermal_t._pack_ = 1 # source:False +struct_amdsmi_dimm_thermal_t._fields_ = [ + ('sensor', ctypes.c_uint16, 11), + ('PADDING_0', ctypes.c_uint8, 5), + ('update_rate', ctypes.c_uint16, 9), + ('PADDING_1', ctypes.c_uint8, 7), + ('dimm_addr', ctypes.c_uint16, 8), + ('PADDING_2', ctypes.c_uint32, 24), + ('temp', ctypes.c_float), +] + +amdsmi_dimm_thermal_t = struct_amdsmi_dimm_thermal_t + +# values for enumeration 'amdsmi_io_bw_encoding_t' +amdsmi_io_bw_encoding_t__enumvalues = { + 1: 'AGG_BW0', + 2: 'RD_BW0', + 4: 'WR_BW0', +} +AGG_BW0 = 1 +RD_BW0 = 2 +WR_BW0 = 4 +amdsmi_io_bw_encoding_t = ctypes.c_uint32 # enum +class struct_amdsmi_link_id_bw_type_t(Structure): + pass + +struct_amdsmi_link_id_bw_type_t._pack_ = 1 # source:False +struct_amdsmi_link_id_bw_type_t._fields_ = [ + ('bw_type', amdsmi_io_bw_encoding_t), + ('PADDING_0', ctypes.c_ubyte * 4), + ('link_name', ctypes.POINTER(ctypes.c_char)), +] + +amdsmi_link_id_bw_type_t = struct_amdsmi_link_id_bw_type_t +class struct_amdsmi_dpm_level_t(Structure): + pass + +struct_amdsmi_dpm_level_t._pack_ = 1 # source:False +struct_amdsmi_dpm_level_t._fields_ = [ + ('max_dpm_level', ctypes.c_ubyte), + ('min_dpm_level', ctypes.c_ubyte), +] + +amdsmi_dpm_level_t = struct_amdsmi_dpm_level_t uint64_t = ctypes.c_uint64 amdsmi_init = _libraries['libamd_smi.so'].amdsmi_init amdsmi_init.restype = amdsmi_status_t @@ -1551,13 +1647,23 @@ amdsmi_shut_down.argtypes = [] amdsmi_get_socket_handles = _libraries['libamd_smi.so'].amdsmi_get_socket_handles amdsmi_get_socket_handles.restype = amdsmi_status_t amdsmi_get_socket_handles.argtypes = [ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.POINTER(None))] +amdsmi_get_cpusocket_handles = _libraries['libamd_smi.so'].amdsmi_get_cpusocket_handles +amdsmi_get_cpusocket_handles.restype = amdsmi_status_t +amdsmi_get_cpusocket_handles.argtypes = [ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.POINTER(None))] size_t = ctypes.c_uint64 amdsmi_get_socket_info = _libraries['libamd_smi.so'].amdsmi_get_socket_info amdsmi_get_socket_info.restype = amdsmi_status_t amdsmi_get_socket_info.argtypes = [amdsmi_socket_handle, size_t, ctypes.POINTER(ctypes.c_char)] +uint32_t = ctypes.c_uint32 +amdsmi_get_cpusocket_info = _libraries['libamd_smi.so'].amdsmi_get_cpusocket_info +amdsmi_get_cpusocket_info.restype = amdsmi_status_t +amdsmi_get_cpusocket_info.argtypes = [amdsmi_cpusocket_handle, uint32_t] amdsmi_get_processor_handles = _libraries['libamd_smi.so'].amdsmi_get_processor_handles amdsmi_get_processor_handles.restype = amdsmi_status_t amdsmi_get_processor_handles.argtypes = [amdsmi_socket_handle, ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.POINTER(None))] +amdsmi_get_cpucore_handles = _libraries['libamd_smi.so'].amdsmi_get_cpucore_handles +amdsmi_get_cpucore_handles.restype = amdsmi_status_t +amdsmi_get_cpucore_handles.argtypes = [amdsmi_cpusocket_handle, ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.POINTER(None))] amdsmi_get_processor_type = _libraries['libamd_smi.so'].amdsmi_get_processor_type amdsmi_get_processor_type.restype = amdsmi_status_t amdsmi_get_processor_type.argtypes = [amdsmi_processor_handle, ctypes.POINTER(processor_type_t)] @@ -1573,7 +1679,6 @@ amdsmi_get_gpu_revision.argtypes = [amdsmi_processor_handle, ctypes.POINTER(ctyp amdsmi_get_gpu_vendor_name = _libraries['libamd_smi.so'].amdsmi_get_gpu_vendor_name amdsmi_get_gpu_vendor_name.restype = amdsmi_status_t amdsmi_get_gpu_vendor_name.argtypes = [amdsmi_processor_handle, ctypes.POINTER(ctypes.c_char), size_t] -uint32_t = ctypes.c_uint32 amdsmi_get_gpu_vram_vendor = _libraries['libamd_smi.so'].amdsmi_get_gpu_vram_vendor amdsmi_get_gpu_vram_vendor.restype = amdsmi_status_t amdsmi_get_gpu_vram_vendor.argtypes = [amdsmi_processor_handle, ctypes.POINTER(ctypes.c_char), uint32_t] @@ -1853,8 +1958,144 @@ amdsmi_get_gpu_process_info.argtypes = [amdsmi_processor_handle, amdsmi_process_ amdsmi_get_gpu_total_ecc_count = _libraries['libamd_smi.so'].amdsmi_get_gpu_total_ecc_count amdsmi_get_gpu_total_ecc_count.restype = amdsmi_status_t amdsmi_get_gpu_total_ecc_count.argtypes = [amdsmi_processor_handle, ctypes.POINTER(struct_amdsmi_error_count_t)] +amdsmi_get_cpu_core_energy = _libraries['libamd_smi.so'].amdsmi_get_cpu_core_energy +amdsmi_get_cpu_core_energy.restype = amdsmi_status_t +amdsmi_get_cpu_core_energy.argtypes = [amdsmi_processor_handle, uint32_t, ctypes.POINTER(ctypes.c_uint64)] +amdsmi_get_cpu_socket_energy = _libraries['libamd_smi.so'].amdsmi_get_cpu_socket_energy +amdsmi_get_cpu_socket_energy.restype = amdsmi_status_t +amdsmi_get_cpu_socket_energy.argtypes = [amdsmi_cpusocket_handle, uint32_t, ctypes.POINTER(ctypes.c_uint64)] +amdsmi_get_cpu_smu_fw_version = _libraries['libamd_smi.so'].amdsmi_get_cpu_smu_fw_version +amdsmi_get_cpu_smu_fw_version.restype = amdsmi_status_t +amdsmi_get_cpu_smu_fw_version.argtypes = [amdsmi_cpusocket_handle, ctypes.POINTER(struct_amdsmi_smu_fw_version_t)] +amdsmi_get_cpu_hsmp_proto_ver = _libraries['libamd_smi.so'].amdsmi_get_cpu_hsmp_proto_ver +amdsmi_get_cpu_hsmp_proto_ver.restype = amdsmi_status_t +amdsmi_get_cpu_hsmp_proto_ver.argtypes = [amdsmi_cpusocket_handle, ctypes.POINTER(ctypes.c_uint32)] +amdsmi_get_cpu_prochot_status = _libraries['libamd_smi.so'].amdsmi_get_cpu_prochot_status +amdsmi_get_cpu_prochot_status.restype = amdsmi_status_t +amdsmi_get_cpu_prochot_status.argtypes = [amdsmi_cpusocket_handle, uint32_t, ctypes.POINTER(ctypes.c_uint32)] +amdsmi_get_cpu_fclk_mclk = _libraries['libamd_smi.so'].amdsmi_get_cpu_fclk_mclk +amdsmi_get_cpu_fclk_mclk.restype = amdsmi_status_t +amdsmi_get_cpu_fclk_mclk.argtypes = [amdsmi_cpusocket_handle, uint32_t, ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.c_uint32)] +amdsmi_get_cpu_cclk_limit = _libraries['libamd_smi.so'].amdsmi_get_cpu_cclk_limit +amdsmi_get_cpu_cclk_limit.restype = amdsmi_status_t +amdsmi_get_cpu_cclk_limit.argtypes = [amdsmi_cpusocket_handle, uint32_t, ctypes.POINTER(ctypes.c_uint32)] +amdsmi_get_cpu_socket_current_active_freq_limit = _libraries['libamd_smi.so'].amdsmi_get_cpu_socket_current_active_freq_limit +amdsmi_get_cpu_socket_current_active_freq_limit.restype = amdsmi_status_t +amdsmi_get_cpu_socket_current_active_freq_limit.argtypes = [amdsmi_cpusocket_handle, uint32_t, ctypes.POINTER(ctypes.c_uint16), ctypes.POINTER(ctypes.POINTER(ctypes.c_char))] +amdsmi_get_cpu_socket_freq_range = _libraries['libamd_smi.so'].amdsmi_get_cpu_socket_freq_range +amdsmi_get_cpu_socket_freq_range.restype = amdsmi_status_t +amdsmi_get_cpu_socket_freq_range.argtypes = [amdsmi_cpusocket_handle, uint32_t, ctypes.POINTER(ctypes.c_uint16), ctypes.POINTER(ctypes.c_uint16)] +amdsmi_get_cpu_core_current_freq_limit = _libraries['libamd_smi.so'].amdsmi_get_cpu_core_current_freq_limit +amdsmi_get_cpu_core_current_freq_limit.restype = amdsmi_status_t +amdsmi_get_cpu_core_current_freq_limit.argtypes = [amdsmi_processor_handle, uint32_t, ctypes.POINTER(ctypes.c_uint32)] +amdsmi_get_cpu_socket_power = _libraries['libamd_smi.so'].amdsmi_get_cpu_socket_power +amdsmi_get_cpu_socket_power.restype = amdsmi_status_t +amdsmi_get_cpu_socket_power.argtypes = [amdsmi_cpusocket_handle, uint32_t, ctypes.POINTER(ctypes.c_uint32)] +amdsmi_get_cpu_socket_power_cap = _libraries['libamd_smi.so'].amdsmi_get_cpu_socket_power_cap +amdsmi_get_cpu_socket_power_cap.restype = amdsmi_status_t +amdsmi_get_cpu_socket_power_cap.argtypes = [amdsmi_cpusocket_handle, uint32_t, ctypes.POINTER(ctypes.c_uint32)] +amdsmi_get_cpu_socket_power_cap_max = _libraries['libamd_smi.so'].amdsmi_get_cpu_socket_power_cap_max +amdsmi_get_cpu_socket_power_cap_max.restype = amdsmi_status_t +amdsmi_get_cpu_socket_power_cap_max.argtypes = [amdsmi_cpusocket_handle, uint32_t, ctypes.POINTER(ctypes.c_uint32)] +amdsmi_get_cpu_pwr_svi_telemetry_all_rails = _libraries['libamd_smi.so'].amdsmi_get_cpu_pwr_svi_telemetry_all_rails +amdsmi_get_cpu_pwr_svi_telemetry_all_rails.restype = amdsmi_status_t +amdsmi_get_cpu_pwr_svi_telemetry_all_rails.argtypes = [amdsmi_cpusocket_handle, uint32_t, ctypes.POINTER(ctypes.c_uint32)] +amdsmi_set_cpu_socket_power_cap = _libraries['libamd_smi.so'].amdsmi_set_cpu_socket_power_cap +amdsmi_set_cpu_socket_power_cap.restype = amdsmi_status_t +amdsmi_set_cpu_socket_power_cap.argtypes = [amdsmi_cpusocket_handle, uint32_t, uint32_t] +uint8_t = ctypes.c_uint8 +amdsmi_set_cpu_pwr_efficiency_mode = _libraries['libamd_smi.so'].amdsmi_set_cpu_pwr_efficiency_mode +amdsmi_set_cpu_pwr_efficiency_mode.restype = amdsmi_status_t +amdsmi_set_cpu_pwr_efficiency_mode.argtypes = [amdsmi_cpusocket_handle, uint8_t, uint8_t] +amdsmi_get_cpu_core_boostlimit = _libraries['libamd_smi.so'].amdsmi_get_cpu_core_boostlimit +amdsmi_get_cpu_core_boostlimit.restype = amdsmi_status_t +amdsmi_get_cpu_core_boostlimit.argtypes = [amdsmi_processor_handle, uint32_t, ctypes.POINTER(ctypes.c_uint32)] +amdsmi_get_cpu_socket_c0_residency = _libraries['libamd_smi.so'].amdsmi_get_cpu_socket_c0_residency +amdsmi_get_cpu_socket_c0_residency.restype = amdsmi_status_t +amdsmi_get_cpu_socket_c0_residency.argtypes = [amdsmi_cpusocket_handle, uint32_t, ctypes.POINTER(ctypes.c_uint32)] +amdsmi_set_cpu_core_boostlimit = _libraries['libamd_smi.so'].amdsmi_set_cpu_core_boostlimit +amdsmi_set_cpu_core_boostlimit.restype = amdsmi_status_t +amdsmi_set_cpu_core_boostlimit.argtypes = [amdsmi_processor_handle, uint32_t, uint32_t] +amdsmi_set_cpu_socket_boostlimit = _libraries['libamd_smi.so'].amdsmi_set_cpu_socket_boostlimit +amdsmi_set_cpu_socket_boostlimit.restype = amdsmi_status_t +amdsmi_set_cpu_socket_boostlimit.argtypes = [amdsmi_cpusocket_handle, uint32_t, uint32_t] +amdsmi_get_cpu_ddr_bw = _libraries['libamd_smi.so'].amdsmi_get_cpu_ddr_bw +amdsmi_get_cpu_ddr_bw.restype = amdsmi_status_t +amdsmi_get_cpu_ddr_bw.argtypes = [amdsmi_cpusocket_handle, ctypes.POINTER(struct_amdsmi_ddr_bw_metrics_t)] +amdsmi_get_cpu_socket_temperature = _libraries['libamd_smi.so'].amdsmi_get_cpu_socket_temperature +amdsmi_get_cpu_socket_temperature.restype = amdsmi_status_t +amdsmi_get_cpu_socket_temperature.argtypes = [amdsmi_cpusocket_handle, uint32_t, ctypes.POINTER(ctypes.c_uint32)] +amdsmi_get_cpu_dimm_temp_range_and_refresh_rate = _libraries['libamd_smi.so'].amdsmi_get_cpu_dimm_temp_range_and_refresh_rate +amdsmi_get_cpu_dimm_temp_range_and_refresh_rate.restype = amdsmi_status_t +amdsmi_get_cpu_dimm_temp_range_and_refresh_rate.argtypes = [amdsmi_cpusocket_handle, uint8_t, uint8_t, ctypes.POINTER(struct_amdsmi_temp_range_refresh_rate_t)] +amdsmi_get_cpu_dimm_power_consumption = _libraries['libamd_smi.so'].amdsmi_get_cpu_dimm_power_consumption +amdsmi_get_cpu_dimm_power_consumption.restype = amdsmi_status_t +amdsmi_get_cpu_dimm_power_consumption.argtypes = [amdsmi_cpusocket_handle, uint8_t, uint8_t, ctypes.POINTER(struct_amdsmi_dimm_power_t)] +amdsmi_get_cpu_dimm_thermal_sensor = _libraries['libamd_smi.so'].amdsmi_get_cpu_dimm_thermal_sensor +amdsmi_get_cpu_dimm_thermal_sensor.restype = amdsmi_status_t +amdsmi_get_cpu_dimm_thermal_sensor.argtypes = [amdsmi_cpusocket_handle, uint8_t, uint8_t, ctypes.POINTER(struct_amdsmi_dimm_thermal_t)] +amdsmi_set_cpu_xgmi_width = _libraries['libamd_smi.so'].amdsmi_set_cpu_xgmi_width +amdsmi_set_cpu_xgmi_width.restype = amdsmi_status_t +amdsmi_set_cpu_xgmi_width.argtypes = [amdsmi_cpusocket_handle, uint8_t, uint8_t] +amdsmi_set_cpu_gmi3_link_width_range = _libraries['libamd_smi.so'].amdsmi_set_cpu_gmi3_link_width_range +amdsmi_set_cpu_gmi3_link_width_range.restype = amdsmi_status_t +amdsmi_set_cpu_gmi3_link_width_range.argtypes = [amdsmi_cpusocket_handle, uint8_t, uint8_t, uint8_t] +amdsmi_cpu_apb_enable = _libraries['libamd_smi.so'].amdsmi_cpu_apb_enable +amdsmi_cpu_apb_enable.restype = amdsmi_status_t +amdsmi_cpu_apb_enable.argtypes = [amdsmi_cpusocket_handle, uint32_t] +amdsmi_cpu_apb_disable = _libraries['libamd_smi.so'].amdsmi_cpu_apb_disable +amdsmi_cpu_apb_disable.restype = amdsmi_status_t +amdsmi_cpu_apb_disable.argtypes = [amdsmi_cpusocket_handle, uint32_t, uint8_t] +amdsmi_set_cpu_socket_lclk_dpm_level = _libraries['libamd_smi.so'].amdsmi_set_cpu_socket_lclk_dpm_level +amdsmi_set_cpu_socket_lclk_dpm_level.restype = amdsmi_status_t +amdsmi_set_cpu_socket_lclk_dpm_level.argtypes = [amdsmi_cpusocket_handle, uint32_t, uint8_t, uint8_t, uint8_t] +amdsmi_get_cpu_socket_lclk_dpm_level = _libraries['libamd_smi.so'].amdsmi_get_cpu_socket_lclk_dpm_level +amdsmi_get_cpu_socket_lclk_dpm_level.restype = amdsmi_status_t +amdsmi_get_cpu_socket_lclk_dpm_level.argtypes = [amdsmi_cpusocket_handle, uint8_t, uint8_t, ctypes.POINTER(struct_amdsmi_dpm_level_t)] +amdsmi_set_cpu_pcie_link_rate = _libraries['libamd_smi.so'].amdsmi_set_cpu_pcie_link_rate +amdsmi_set_cpu_pcie_link_rate.restype = amdsmi_status_t +amdsmi_set_cpu_pcie_link_rate.argtypes = [amdsmi_cpusocket_handle, uint8_t, uint8_t, ctypes.POINTER(ctypes.c_ubyte)] +amdsmi_set_cpu_df_pstate_range = _libraries['libamd_smi.so'].amdsmi_set_cpu_df_pstate_range +amdsmi_set_cpu_df_pstate_range.restype = amdsmi_status_t +amdsmi_set_cpu_df_pstate_range.argtypes = [amdsmi_cpusocket_handle, uint8_t, uint8_t, uint8_t] +amdsmi_get_cpu_current_io_bandwidth = _libraries['libamd_smi.so'].amdsmi_get_cpu_current_io_bandwidth +amdsmi_get_cpu_current_io_bandwidth.restype = amdsmi_status_t +amdsmi_get_cpu_current_io_bandwidth.argtypes = [amdsmi_cpusocket_handle, uint8_t, amdsmi_link_id_bw_type_t, ctypes.POINTER(ctypes.c_uint32)] +amdsmi_get_cpu_current_xgmi_bw = _libraries['libamd_smi.so'].amdsmi_get_cpu_current_xgmi_bw +amdsmi_get_cpu_current_xgmi_bw.restype = amdsmi_status_t +amdsmi_get_cpu_current_xgmi_bw.argtypes = [amdsmi_cpusocket_handle, amdsmi_link_id_bw_type_t, ctypes.POINTER(ctypes.c_uint32)] +amdsmi_get_metrics_table_version = _libraries['libamd_smi.so'].amdsmi_get_metrics_table_version +amdsmi_get_metrics_table_version.restype = amdsmi_status_t +amdsmi_get_metrics_table_version.argtypes = [amdsmi_cpusocket_handle, ctypes.POINTER(ctypes.c_uint32)] +class struct_hsmp_metric_table(Structure): + pass + +amdsmi_get_metrics_table = _libraries['libamd_smi.so'].amdsmi_get_metrics_table +amdsmi_get_metrics_table.restype = amdsmi_status_t +amdsmi_get_metrics_table.argtypes = [amdsmi_cpusocket_handle, uint8_t, ctypes.POINTER(struct_hsmp_metric_table)] +amdsmi_get_cpu_family = _libraries['libamd_smi.so'].amdsmi_get_cpu_family +amdsmi_get_cpu_family.restype = amdsmi_status_t +amdsmi_get_cpu_family.argtypes = [uint32_t] +amdsmi_get_cpu_model = _libraries['libamd_smi.so'].amdsmi_get_cpu_model +amdsmi_get_cpu_model.restype = amdsmi_status_t +amdsmi_get_cpu_model.argtypes = [uint32_t] +amdsmi_get_cpu_threads_per_core = _libraries['libamd_smi.so'].amdsmi_get_cpu_threads_per_core +amdsmi_get_cpu_threads_per_core.restype = amdsmi_status_t +amdsmi_get_cpu_threads_per_core.argtypes = [uint32_t] +amdsmi_get_number_of_cpu_cores = _libraries['libamd_smi.so'].amdsmi_get_number_of_cpu_cores +amdsmi_get_number_of_cpu_cores.restype = amdsmi_status_t +amdsmi_get_number_of_cpu_cores.argtypes = [uint32_t] +amdsmi_get_number_of_cpu_sockets = _libraries['libamd_smi.so'].amdsmi_get_number_of_cpu_sockets +amdsmi_get_number_of_cpu_sockets.restype = amdsmi_status_t +amdsmi_get_number_of_cpu_sockets.argtypes = [uint32_t] +amdsmi_first_online_core_on_cpu_socket = _libraries['libamd_smi.so'].amdsmi_first_online_core_on_cpu_socket +amdsmi_first_online_core_on_cpu_socket.restype = amdsmi_status_t +amdsmi_first_online_core_on_cpu_socket.argtypes = [amdsmi_cpusocket_handle, uint32_t, ctypes.POINTER(ctypes.c_uint32)] +amdsmi_get_esmi_err_msg = _libraries['libamd_smi.so'].amdsmi_get_esmi_err_msg +amdsmi_get_esmi_err_msg.restype = ctypes.POINTER(ctypes.POINTER(ctypes.c_char)) +amdsmi_get_esmi_err_msg.argtypes = [amdsmi_status_t, ctypes.POINTER(ctypes.POINTER(ctypes.c_char))] __all__ = \ - ['AMDSMI_ARG_PTR_NULL', 'AMDSMI_AVERAGE_POWER', + ['AGG_BW0', 'AMDSMI_ARG_PTR_NULL', 'AMDSMI_AVERAGE_POWER', 'AMDSMI_CNTR_CMD_START', 'AMDSMI_CNTR_CMD_STOP', 'AMDSMI_COARSE_GRAIN_GFX_ACTIVITY', 'AMDSMI_COARSE_GRAIN_MEM_ACTIVITY', 'AMDSMI_CURRENT_POWER', @@ -2003,7 +2244,7 @@ __all__ = \ 'FW_ID_XGMI', 'FW_ID__MAX', 'MEMORY_PARTITION_NPS1', 'MEMORY_PARTITION_NPS2', 'MEMORY_PARTITION_NPS4', 'MEMORY_PARTITION_NPS8', 'MEMORY_PARTITION_UNKNOWN', - 'NON_AMD_CPU', 'NON_AMD_GPU', 'TEMPERATURE_TYPE_EDGE', + 'NON_AMD_CPU', 'NON_AMD_GPU', 'RD_BW0', 'TEMPERATURE_TYPE_EDGE', 'TEMPERATURE_TYPE_FIRST', 'TEMPERATURE_TYPE_HBM_0', 'TEMPERATURE_TYPE_HBM_1', 'TEMPERATURE_TYPE_HBM_2', 'TEMPERATURE_TYPE_HBM_3', 'TEMPERATURE_TYPE_HOTSPOT', @@ -2012,27 +2253,54 @@ __all__ = \ 'VRAM_TYPE_DDR2', 'VRAM_TYPE_DDR3', 'VRAM_TYPE_DDR4', 'VRAM_TYPE_GDDR1', 'VRAM_TYPE_GDDR3', 'VRAM_TYPE_GDDR4', 'VRAM_TYPE_GDDR5', 'VRAM_TYPE_GDDR6', 'VRAM_TYPE_HBM', - 'VRAM_TYPE_UNKNOWN', 'VRAM_TYPE__MAX', + 'VRAM_TYPE_UNKNOWN', 'VRAM_TYPE__MAX', 'WR_BW0', 'amd_metrics_table_header_t', 'amdsmi_asic_info_t', 'amdsmi_bdf_t', 'amdsmi_bit_field_t', 'amdsmi_board_info_t', 'amdsmi_clk_info_t', 'amdsmi_clk_type_t', 'amdsmi_compute_partition_type_t', 'amdsmi_container_types_t', 'amdsmi_counter_command_t', 'amdsmi_counter_value_t', + 'amdsmi_cpu_apb_disable', 'amdsmi_cpu_apb_enable', + 'amdsmi_cpusocket_handle', 'amdsmi_ddr_bw_metrics_t', 'amdsmi_dev_compute_partition_get', 'amdsmi_dev_compute_partition_reset', 'amdsmi_dev_compute_partition_set', 'amdsmi_dev_memory_partition_get', 'amdsmi_dev_memory_partition_reset', 'amdsmi_dev_memory_partition_set', 'amdsmi_dev_perf_level_t', - 'amdsmi_driver_info_t', 'amdsmi_engine_usage_t', - 'amdsmi_error_count_t', 'amdsmi_event_group_t', - 'amdsmi_event_handle_t', 'amdsmi_event_type_t', - 'amdsmi_evt_notification_data_t', - 'amdsmi_evt_notification_type_t', 'amdsmi_freq_ind_t', + 'amdsmi_dimm_power_t', 'amdsmi_dimm_thermal_t', + 'amdsmi_dpm_level_t', 'amdsmi_driver_info_t', + 'amdsmi_engine_usage_t', 'amdsmi_error_count_t', + 'amdsmi_event_group_t', 'amdsmi_event_handle_t', + 'amdsmi_event_type_t', 'amdsmi_evt_notification_data_t', + 'amdsmi_evt_notification_type_t', + 'amdsmi_first_online_core_on_cpu_socket', 'amdsmi_freq_ind_t', 'amdsmi_freq_volt_region_t', 'amdsmi_frequencies_t', 'amdsmi_frequency_range_t', 'amdsmi_fw_block_t', 'amdsmi_fw_info_t', 'amdsmi_get_clk_freq', - 'amdsmi_get_clock_info', 'amdsmi_get_energy_count', + 'amdsmi_get_clock_info', 'amdsmi_get_cpu_cclk_limit', + 'amdsmi_get_cpu_core_boostlimit', + 'amdsmi_get_cpu_core_current_freq_limit', + 'amdsmi_get_cpu_core_energy', + 'amdsmi_get_cpu_current_io_bandwidth', + 'amdsmi_get_cpu_current_xgmi_bw', 'amdsmi_get_cpu_ddr_bw', + 'amdsmi_get_cpu_dimm_power_consumption', + 'amdsmi_get_cpu_dimm_temp_range_and_refresh_rate', + 'amdsmi_get_cpu_dimm_thermal_sensor', 'amdsmi_get_cpu_family', + 'amdsmi_get_cpu_fclk_mclk', 'amdsmi_get_cpu_hsmp_proto_ver', + 'amdsmi_get_cpu_model', 'amdsmi_get_cpu_prochot_status', + 'amdsmi_get_cpu_pwr_svi_telemetry_all_rails', + 'amdsmi_get_cpu_smu_fw_version', + 'amdsmi_get_cpu_socket_c0_residency', + 'amdsmi_get_cpu_socket_current_active_freq_limit', + 'amdsmi_get_cpu_socket_energy', + 'amdsmi_get_cpu_socket_freq_range', + 'amdsmi_get_cpu_socket_lclk_dpm_level', + 'amdsmi_get_cpu_socket_power', 'amdsmi_get_cpu_socket_power_cap', + 'amdsmi_get_cpu_socket_power_cap_max', + 'amdsmi_get_cpu_socket_temperature', + 'amdsmi_get_cpu_threads_per_core', 'amdsmi_get_cpucore_handles', + 'amdsmi_get_cpusocket_handles', 'amdsmi_get_cpusocket_info', + 'amdsmi_get_energy_count', 'amdsmi_get_esmi_err_msg', 'amdsmi_get_fw_info', 'amdsmi_get_gpu_activity', 'amdsmi_get_gpu_asic_info', 'amdsmi_get_gpu_available_counters', 'amdsmi_get_gpu_bad_page_info', 'amdsmi_get_gpu_bdf_id', @@ -2063,10 +2331,12 @@ __all__ = \ 'amdsmi_get_gpu_vendor_name', 'amdsmi_get_gpu_volt_metric', 'amdsmi_get_gpu_vram_info', 'amdsmi_get_gpu_vram_usage', 'amdsmi_get_gpu_vram_vendor', 'amdsmi_get_lib_version', + 'amdsmi_get_metrics_table', 'amdsmi_get_metrics_table_version', 'amdsmi_get_minmax_bandwidth_between_processors', - 'amdsmi_get_pcie_link_caps', 'amdsmi_get_pcie_link_status', - 'amdsmi_get_power_cap_info', 'amdsmi_get_power_info', - 'amdsmi_get_processor_handle_from_bdf', + 'amdsmi_get_number_of_cpu_cores', + 'amdsmi_get_number_of_cpu_sockets', 'amdsmi_get_pcie_link_caps', + 'amdsmi_get_pcie_link_status', 'amdsmi_get_power_cap_info', + 'amdsmi_get_power_info', 'amdsmi_get_processor_handle_from_bdf', 'amdsmi_get_processor_handles', 'amdsmi_get_processor_type', 'amdsmi_get_socket_handles', 'amdsmi_get_socket_info', 'amdsmi_get_temp_metric', 'amdsmi_get_utilization_count', @@ -2076,16 +2346,16 @@ __all__ = \ 'amdsmi_gpu_destroy_counter', 'amdsmi_gpu_metrics_t', 'amdsmi_gpu_read_counter', 'amdsmi_gpu_xgmi_error_status', 'amdsmi_init', 'amdsmi_init_flags_t', - 'amdsmi_init_gpu_event_notification', 'amdsmi_io_link_type_t', - 'amdsmi_is_P2P_accessible', + 'amdsmi_init_gpu_event_notification', 'amdsmi_io_bw_encoding_t', + 'amdsmi_io_link_type_t', 'amdsmi_is_P2P_accessible', 'amdsmi_is_gpu_power_management_enabled', - 'amdsmi_memory_page_status_t', 'amdsmi_memory_partition_type_t', - 'amdsmi_memory_type_t', 'amdsmi_mm_ip_t', - 'amdsmi_od_vddc_point_t', 'amdsmi_od_volt_curve_t', - 'amdsmi_od_volt_freq_data_t', 'amdsmi_pcie_bandwidth_t', - 'amdsmi_pcie_info_t', 'amdsmi_pcie_slot_type_t', - 'amdsmi_power_cap_info_t', 'amdsmi_power_info_t', - 'amdsmi_power_profile_preset_masks_t', + 'amdsmi_link_id_bw_type_t', 'amdsmi_memory_page_status_t', + 'amdsmi_memory_partition_type_t', 'amdsmi_memory_type_t', + 'amdsmi_mm_ip_t', 'amdsmi_od_vddc_point_t', + 'amdsmi_od_volt_curve_t', 'amdsmi_od_volt_freq_data_t', + 'amdsmi_pcie_bandwidth_t', 'amdsmi_pcie_info_t', + 'amdsmi_pcie_slot_type_t', 'amdsmi_power_cap_info_t', + 'amdsmi_power_info_t', 'amdsmi_power_profile_preset_masks_t', 'amdsmi_power_profile_status_t', 'amdsmi_power_type_t', 'amdsmi_proc_info_t', 'amdsmi_process_handle_t', 'amdsmi_process_info_t', 'amdsmi_processor_handle', @@ -2093,6 +2363,14 @@ __all__ = \ 'amdsmi_ras_feature_t', 'amdsmi_reset_gpu', 'amdsmi_reset_gpu_fan', 'amdsmi_reset_gpu_xgmi_error', 'amdsmi_retired_page_record_t', 'amdsmi_set_clk_freq', + 'amdsmi_set_cpu_core_boostlimit', + 'amdsmi_set_cpu_df_pstate_range', + 'amdsmi_set_cpu_gmi3_link_width_range', + 'amdsmi_set_cpu_pcie_link_rate', + 'amdsmi_set_cpu_pwr_efficiency_mode', + 'amdsmi_set_cpu_socket_boostlimit', + 'amdsmi_set_cpu_socket_lclk_dpm_level', + 'amdsmi_set_cpu_socket_power_cap', 'amdsmi_set_cpu_xgmi_width', 'amdsmi_set_gpu_clk_range', 'amdsmi_set_gpu_event_notification_mask', 'amdsmi_set_gpu_fan_speed', 'amdsmi_set_gpu_od_clk_info', @@ -2101,11 +2379,12 @@ __all__ = \ 'amdsmi_set_gpu_perf_determinism_mode', 'amdsmi_set_gpu_perf_level', 'amdsmi_set_gpu_power_profile', 'amdsmi_set_power_cap', 'amdsmi_shut_down', - 'amdsmi_socket_handle', 'amdsmi_status_code_to_string', - 'amdsmi_status_t', 'amdsmi_stop_gpu_event_notification', - 'amdsmi_temperature_metric_t', 'amdsmi_temperature_type_t', - 'amdsmi_topo_get_link_type', 'amdsmi_topo_get_link_weight', - 'amdsmi_topo_get_numa_node_number', + 'amdsmi_smu_fw_version_t', 'amdsmi_socket_handle', + 'amdsmi_status_code_to_string', 'amdsmi_status_t', + 'amdsmi_stop_gpu_event_notification', + 'amdsmi_temp_range_refresh_rate_t', 'amdsmi_temperature_metric_t', + 'amdsmi_temperature_type_t', 'amdsmi_topo_get_link_type', + 'amdsmi_topo_get_link_weight', 'amdsmi_topo_get_numa_node_number', 'amdsmi_utilization_counter_t', 'amdsmi_utilization_counter_type_t', 'amdsmi_vbios_info_t', 'amdsmi_version_t', 'amdsmi_voltage_metric_t', @@ -2115,12 +2394,15 @@ __all__ = \ 'amdsmi_xgmi_status_t', 'processor_type_t', 'size_t', 'struct_amd_metrics_table_header_t', 'struct_amdsmi_asic_info_t', 'struct_amdsmi_board_info_t', 'struct_amdsmi_clk_info_t', - 'struct_amdsmi_counter_value_t', 'struct_amdsmi_driver_info_t', + 'struct_amdsmi_counter_value_t', 'struct_amdsmi_ddr_bw_metrics_t', + 'struct_amdsmi_dimm_power_t', 'struct_amdsmi_dimm_thermal_t', + 'struct_amdsmi_dpm_level_t', 'struct_amdsmi_driver_info_t', 'struct_amdsmi_engine_usage_t', 'struct_amdsmi_error_count_t', 'struct_amdsmi_evt_notification_data_t', 'struct_amdsmi_freq_volt_region_t', 'struct_amdsmi_frequencies_t', 'struct_amdsmi_frequency_range_t', 'struct_amdsmi_fw_info_t', 'struct_amdsmi_gpu_cache_info_t', 'struct_amdsmi_gpu_metrics_t', + 'struct_amdsmi_link_id_bw_type_t', 'struct_amdsmi_od_vddc_point_t', 'struct_amdsmi_od_volt_curve_t', 'struct_amdsmi_od_volt_freq_data_t', 'struct_amdsmi_pcie_bandwidth_t', 'struct_amdsmi_pcie_info_t', @@ -2129,10 +2411,12 @@ __all__ = \ 'struct_amdsmi_proc_info_t', 'struct_amdsmi_process_info_t', 'struct_amdsmi_range_t', 'struct_amdsmi_ras_feature_t', 'struct_amdsmi_retired_page_record_t', + 'struct_amdsmi_smu_fw_version_t', + 'struct_amdsmi_temp_range_refresh_rate_t', 'struct_amdsmi_utilization_counter_t', 'struct_amdsmi_vbios_info_t', 'struct_amdsmi_version_t', 'struct_amdsmi_vram_info_t', 'struct_amdsmi_vram_usage_t', 'struct_amdsmi_xgmi_info_t', 'struct_cache_', 'struct_engine_usage_', 'struct_fields_', 'struct_fw_info_list_', - 'struct_memory_usage_', 'uint32_t', 'uint64_t', - 'union_amdsmi_bdf_t'] + 'struct_hsmp_metric_table', 'struct_memory_usage_', 'uint32_t', + 'uint64_t', 'uint8_t', 'union_amdsmi_bdf_t'] diff --git a/projects/amdsmi/tools/generator.py b/projects/amdsmi/tools/generator.py index 31b824ecfd..18383ee118 100644 --- a/projects/amdsmi/tools/generator.py +++ b/projects/amdsmi/tools/generator.py @@ -63,9 +63,11 @@ def parseArgument(): help='The input file name') parser.add_argument('-l', '--library', type=str, required=True, help='Loading dynamic link libraries') + parser.add_argument('-e', '--extra-args', type=str, required=False, + help='Parse extra arguments to clang') args = vars(parser.parse_args()) - return args['output'], args['input'], args['library'] + return args['output'], args['input'], args['library'], args['extra_args'] def replace_line(full_path_file_name, string_to_repalce, new_string): @@ -82,7 +84,13 @@ def replace_line(full_path_file_name, string_to_repalce, new_string): def main(): - output_file, input_file, library = parseArgument() + output_file, input_file, library, clang_extra_args = parseArgument() + + # make args string easy to append + if clang_extra_args is None: + clang_extra_args = "" + else: + clang_extra_args = " " + clang_extra_args library_name = os.path.basename(library) @@ -131,7 +139,7 @@ except OSError as error: print("Unknown operating system. It is only supporing Linux and Windows.") return - arguments.append("--clang-args=-I" + clang_include_dir) + arguments.append("--clang-args=-I" + clang_include_dir + clang_extra_args) clangToPy(arguments) replace_line(output_file, line_to_replace, new_line) diff --git a/projects/amdsmi/update_wrapper.sh b/projects/amdsmi/update_wrapper.sh index d7bc4da8e8..0a836f5405 100755 --- a/projects/amdsmi/update_wrapper.sh +++ b/projects/amdsmi/update_wrapper.sh @@ -30,7 +30,21 @@ if ! does_image_exist; then DOCKER_BUILDKIT="${DOCKER_BUILDKIT:0}" docker build "$DIR/py-interface" -t "$DOCKER_NAME":latest fi -docker run --rm -ti --volume "$DIR":/src:rw "$DOCKER_NAME":latest +ENABLE_ESMI_LIB="" +# source ENABLE_ESMI_LIB variable from the previous build if it exists +if [ -e 'build/CMakeCache.txt' ]; then + GREP_RESULT=$(grep "ENABLE_ESMI_LIB" "${DIR}/build/CMakeCache.txt" | cut -d = -f 2) + ENABLE_ESMI_LIB="-DENABLE_ESMI_LIB=$GREP_RESULT" + echo "ENABLE_ESMI_LIB: [$ENABLE_ESMI_LIB]" +fi + +docker run --rm -ti --volume "$DIR":/src:rw "$DOCKER_NAME":latest bash -c " +cp -r /src /tmp/src \ + && cd /tmp/src \ + && rm -rf build .cache \ + && cmake -B build -DBUILD_WRAPPER=ON $ENABLE_ESMI_LIB \ + && make -C build -j $(nproc) \ + && cp /tmp/src/py-interface/amdsmi_wrapper.py /src/py-interface/amdsmi_wrapper.py" echo -e "Generated new wrapper! [$DIR/py-interface/amdsmi_wrapper.py]" From b734f45231ba8e58c8cd54ede2f3137396d6db88 Mon Sep 17 00:00:00 2001 From: Deepak Mewar Date: Wed, 11 Oct 2023 06:26:14 -0400 Subject: [PATCH 22/27] Added another set of esmi python wrappers for amdsmi python library Change-Id: Ib49efe21d4909c3e4a011eddcd96f587a9b6570c [ROCm/amdsmi commit: e6d82912e3b59f7892ad1f58f13ce09a4743dc80] --- projects/amdsmi/py-interface/__init__.py | 15 ++ .../amdsmi/py-interface/amdsmi_interface.py | 180 ++++++++++++++++++ 2 files changed, 195 insertions(+) diff --git a/projects/amdsmi/py-interface/__init__.py b/projects/amdsmi/py-interface/__init__.py index bac8f6745d..54885114a4 100644 --- a/projects/amdsmi/py-interface/__init__.py +++ b/projects/amdsmi/py-interface/__init__.py @@ -29,6 +29,21 @@ from .amdsmi_interface import amdsmi_get_processor_handles from .amdsmi_interface import amdsmi_get_socket_handles from .amdsmi_interface import amdsmi_get_socket_info +from .amdsmi_interface import amdsmi_get_cpusocket_handles +from .amdsmi_interface import amdsmi_get_cpusocket_info +from .amdsmi_interface import amdsmi_get_cpucore_handles +from .amdsmi_interface import amdsmi_get_cpu_hsmp_proto_ver +from .amdsmi_interface import amdsmi_get_cpu_smu_fw_version +from .amdsmi_interface import amdsmi_get_cpu_core_energy +from .amdsmi_interface import amdsmi_get_cpu_socket_energy +from .amdsmi_interface import amdsmi_get_cpu_prochot_status +from .amdsmi_interface import amdsmi_get_cpu_fclk_mclk +from .amdsmi_interface import amdsmi_get_cpu_cclk_limit +from .amdsmi_interface import amdsmi_get_cpu_socket_current_active_freq_limit +from .amdsmi_interface import amdsmi_get_cpu_socket_freq_range +from .amdsmi_interface import amdsmi_get_cpu_core_current_freq_limit +from .amdsmi_interface import amdsmi_get_cpu_socket_power + from .amdsmi_interface import amdsmi_get_gpu_device_bdf from .amdsmi_interface import amdsmi_get_gpu_device_uuid from .amdsmi_interface import amdsmi_get_processor_handle_from_bdf diff --git a/projects/amdsmi/py-interface/amdsmi_interface.py b/projects/amdsmi/py-interface/amdsmi_interface.py index ff92663772..1087a35146 100644 --- a/projects/amdsmi/py-interface/amdsmi_interface.py +++ b/projects/amdsmi/py-interface/amdsmi_interface.py @@ -595,6 +595,186 @@ def amdsmi_get_processor_handles() -> List[amdsmi_wrapper.amdsmi_processor_handl return devices +def amdsmi_get_cpu_core_energy( + processor_handle: amdsmi_wrapper.amdsmi_processor_handle, core_idx: int +) -> int: + if not isinstance(processor_handle, amdsmi_wrapper.amdsmi_processor_handle): + raise AmdSmiParameterException( + processor_handle, amdsmi_wrapper.amdsmi_processor_handle + ) + if not isinstance(core_idx, int): + raise AmdSmiParameterException(core_idx, int) + + penergy = ctypes.c_uint64() + _check_res( + amdsmi_wrapper.amdsmi_get_cpu_core_energy( + processor_handle, core_idx, ctypes.byref(penergy) + ) + ) + + return penergy.value + +def amdsmi_get_cpu_socket_energy( + socket_handle: amdsmi_wrapper.amdsmi_cpusocket_handle, sock_idx: int +) -> int: + if not isinstance(socket_handle, amdsmi_wrapper.amdsmi_cpusocket_handle): + raise AmdSmiParameterException( + socket_handle, amdsmi_wrapper.amdsmi_cpusocket_handle + ) + if not isinstance(sock_idx, int): + raise AmdSmiParameterException(sock_idx, int) + + penergy = ctypes.c_uint64() + _check_res( + amdsmi_wrapper.amdsmi_get_cpu_socket_energy( + socket_handle, sock_idx, ctypes.byref(penergy) + ) + ) + + return penergy.value + +def amdsmi_get_cpu_prochot_status( + socket_handle: amdsmi_wrapper.amdsmi_cpusocket_handle, sock_idx: int +) -> int: + if not isinstance(socket_handle, amdsmi_wrapper.amdsmi_cpusocket_handle): + raise AmdSmiParameterException( + socket_handle, amdsmi_wrapper.amdsmi_cpusocket_handle + ) + if not isinstance(sock_idx, int): + raise AmdSmiParameterException(sock_idx, int) + + prochot = ctypes.c_uint32() + _check_res( + amdsmi_wrapper.amdsmi_get_cpu_socket_energy( + socket_handle, sock_idx, ctypes.byref(prochot) + ) + ) + + return prochot.value + +def amdsmi_get_cpu_fclk_mclk( + socket_handle: amdsmi_wrapper.amdsmi_cpusocket_handle, sock_idx: int +): + if not isinstance(socket_handle, amdsmi_wrapper.amdsmi_cpusocket_handle): + raise AmdSmiParameterException( + socket_handle, amdsmi_wrapper.amdsmi_cpusocket_handle + ) + if not isinstance(sock_idx, int): + raise AmdSmiParameterException(sock_idx, int) + + fclk = ctypes.c_uint32() + mclk = ctypes.c_uint32() + _check_res( + amdsmi_wrapper.amdsmi_get_cpu_fclk_mclk( + socket_handle, sock_idx, ctypes.byref(fclk), ctypes.byref(mclk) + ) + ) + + return { + "fclk": fclk.value, + "mclk": mclk.value + } + +def amdsmi_get_cpu_cclk_limit( + socket_handle: amdsmi_wrapper.amdsmi_cpusocket_handle, sock_idx: int +) -> int: + if not isinstance(socket_handle, amdsmi_wrapper.amdsmi_cpusocket_handle): + raise AmdSmiParameterException( + socket_handle, amdsmi_wrapper.amdsmi_cpusocket_handle + ) + if not isinstance(sock_idx, int): + raise AmdSmiParameterException(sock_idx, int) + + cclk = ctypes.c_uint32() + _check_res( + amdsmi_wrapper.amdsmi_get_cpu_cclk_limit( + socket_handle, sock_idx, ctypes.byref(cclk) + ) + ) + + return cclk.value + +def amdsmi_get_cpu_socket_current_active_freq_limit( + socket_handle: amdsmi_wrapper.amdsmi_cpusocket_handle, sock_idx: int +) -> int: + if not isinstance(socket_handle, amdsmi_wrapper.amdsmi_cpusocket_handle): + raise AmdSmiParameterException( + socket_handle, amdsmi_wrapper.amdsmi_cpusocket_handle + ) + if not isinstance(sock_idx, int): + raise AmdSmiParameterException(sock_idx, int) + + freq = ctypes.c_uint16() + src_type = ctypes.pointer(ctypes.pointer(ctypes.c_char())) + _check_res( + amdsmi_wrapper.amdsmi_get_cpu_socket_current_active_freq_limit( + socket_handle, sock_idx, ctypes.byref(freq), src_type + ) + ) + + return freq.value + +def amdsmi_get_cpu_socket_freq_range( + socket_handle: amdsmi_wrapper.amdsmi_cpusocket_handle, sock_idx: int +): + if not isinstance(socket_handle, amdsmi_wrapper.amdsmi_cpusocket_handle): + raise AmdSmiParameterException( + socket_handle, amdsmi_wrapper.amdsmi_cpusocket_handle + ) + if not isinstance(sock_idx, int): + raise AmdSmiParameterException(sock_idx, int) + + freq_max = ctypes.c_uint16() + freq_min = ctypes.c_uint16() + _check_res( + amdsmi_wrapper.amdsmi_get_cpu_socket_freq_range( + socket_handle, sock_idx, ctypes.byref(freq_max), ctypes.byref(freq_min) + ) + ) + + return { + "max_socket_freq": freq_max.value, + "min_socket_freq": freq_min.value + } + +def amdsmi_get_cpu_core_current_freq_limit( + processor_handle: amdsmi_wrapper.amdsmi_processor_handle, core_idx: int +) -> int: + if not isinstance(processor_handle, amdsmi_wrapper.amdsmi_processor_handle): + raise AmdSmiParameterException( + processor_handle, amdsmi_wrapper.amdsmi_processor_handle + ) + if not isinstance(core_idx, int): + raise AmdSmiParameterException(core_idx, int) + + freq = ctypes.c_uint32() + _check_res( + amdsmi_wrapper.amdsmi_get_cpu_core_current_freq_limit( + processor_handle, core_idx, ctypes.byref(freq) + ) + ) + + return freq.value + +def amdsmi_get_cpu_socket_power( + socket_handle: amdsmi_wrapper.amdsmi_cpusocket_handle, sock_idx: int +) -> int: + if not isinstance(socket_handle, amdsmi_wrapper.amdsmi_cpusocket_handle): + raise AmdSmiParameterException( + socket_handle, amdsmi_wrapper.amdsmi_cpusocket_handle + ) + if not isinstance(sock_idx, int): + raise AmdSmiParameterException(sock_idx, int) + + ppower = ctypes.c_uint32() + _check_res( + amdsmi_wrapper.amdsmi_get_cpu_socket_power( + socket_handle, sock_idx, ctypes.byref(ppower) + ) + ) + + return ppower.value + def amdsmi_init(flag=AmdSmiInitFlags.INIT_AMD_GPUS): if not isinstance(flag, AmdSmiInitFlags): raise AmdSmiParameterException(flag, AmdSmiInitFlags) From e114a2ad275e06dc4f5f3fa0298d78cd243c0cd5 Mon Sep 17 00:00:00 2001 From: Deepak Mewar Date: Tue, 10 Oct 2023 04:16:45 -0400 Subject: [PATCH 23/27] esmi python wrappers for amdsmi python library Change-Id: I51be2e4ce76f1e99820c50d4722de4e5deb87ceb [ROCm/amdsmi commit: 806652a697bfdfa7a8cce2dd50f234797fb5ab92] --- .../amdsmi/py-interface/amdsmi_interface.py | 104 ++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/projects/amdsmi/py-interface/amdsmi_interface.py b/projects/amdsmi/py-interface/amdsmi_interface.py index 1087a35146..f97dd8e3ef 100644 --- a/projects/amdsmi/py-interface/amdsmi_interface.py +++ b/projects/amdsmi/py-interface/amdsmi_interface.py @@ -549,6 +549,34 @@ def amdsmi_get_socket_handles() -> List[amdsmi_wrapper.amdsmi_socket_handle]: return sockets +def amdsmi_get_cpusocket_handles() -> List[amdsmi_wrapper.amdsmi_cpusocket_handle]: + """ + Function that gets cpu socket handles. Wraps the same named function call. + + Parameters: + `None`. + + Returns: + `List`: List containing all of the found cpu socket handles. + """ + socket_count = ctypes.c_uint32(0) + null_ptr = ctypes.POINTER(amdsmi_wrapper.amdsmi_cpusocket_handle)() + _check_res( + amdsmi_wrapper.amdsmi_get_cpusocket_handles( + ctypes.byref(socket_count), null_ptr) + ) + socket_handles = (amdsmi_wrapper.amdsmi_cpusocket_handle * + socket_count.value)() + _check_res( + amdsmi_wrapper.amdsmi_get_cpusocket_handles( + ctypes.byref(socket_count), socket_handles) + ) + sockets = [ + amdsmi_wrapper.amdsmi_cpusocket_handle(socket_handles[sock_idx]) + for sock_idx in range(socket_count.value) + ] + + return sockets def amdsmi_get_socket_info(socket_handle): if not isinstance(socket_handle, amdsmi_wrapper.amdsmi_socket_handle): @@ -563,6 +591,19 @@ def amdsmi_get_socket_info(socket_handle): return socket_info.value.decode() +def amdsmi_get_cpusocket_info(socket_handle): + if not isinstance(socket_handle, amdsmi_wrapper.amdsmi_cpusocket_handle): + raise AmdSmiParameterException( + socket_handle, amdsmi_wrapper.amdsmi_cpusocket_handle) + + socket_id = ctypes.c_uint32() + _check_res( + amdsmi_wrapper.amdsmi_get_cpusocket_info( + socket_handle, socket_id) + ) + + return socket_id + def amdsmi_get_processor_handles() -> List[amdsmi_wrapper.amdsmi_processor_handle]: socket_handles = amdsmi_get_socket_handles() devices = [] @@ -594,6 +635,69 @@ def amdsmi_get_processor_handles() -> List[amdsmi_wrapper.amdsmi_processor_handl return devices +def amdsmi_get_cpucore_handles() -> List[amdsmi_wrapper.amdsmi_processor_handle]: + socket_handles = amdsmi_get_cpusocket_handles() + processors = [] + for socket in socket_handles: + processor_count = ctypes.c_uint32() + null_ptr = ctypes.POINTER(amdsmi_wrapper.amdsmi_processor_handle)() + _check_res( + amdsmi_wrapper.amdsmi_get_cpucore_handles( + socket, + ctypes.byref(processor_count), + null_ptr, + ) + ) + processor_handles = ( + amdsmi_wrapper.amdsmi_processor_handle * processor_count.value)() + _check_res( + amdsmi_wrapper.amdsmi_get_cpucore_handles( + socket, + ctypes.byref(processor_count), + processor_handles, + ) + ) + processors.extend( + [ + amdsmi_wrapper.amdsmi_processor_handle(processor_handles[dev_idx]) + for dev_idx in range(processor_count.value) + ] + ) + + return processors + +def amdsmi_get_cpu_hsmp_proto_ver( + socket_handle: amdsmi_wrapper.amdsmi_cpusocket_handle, +) -> int: + if not isinstance(socket_handle, amdsmi_wrapper.amdsmi_cpusocket_handle): + raise AmdSmiParameterException( + socket_handle, amdsmi_wrapper.amdsmi_cpusocket_handle + ) + + proto_ver = ctypes.c_uint32() + _check_res( + amdsmi_wrapper.amdsmi_get_cpu_hsmp_proto_ver( + socket_handle, ctypes.byref(proto_ver) + ) + ) + + return proto_ver.value + +def amdsmi_get_cpu_smu_fw_version(socket_handle: amdsmi_wrapper.amdsmi_cpusocket_handle): + if not isinstance(socket_handle, amdsmi_wrapper.amdsmi_cpusocket_handle): + raise AmdSmiParameterException( + socket_handle, amdsmi_wrapper.amdsmi_cpusocket_handle + ) + + smu_fw = amdsmi_wrapper.amdsmi_smu_fw_version_t() + + _check_res(amdsmi_wrapper.amdsmi_get_cpu_smu_fw_version(socket_handle, smu_fw)) + + return { + "smu_fw_debug_ver_num": smu_fw.debug, + "smu_fw_minor_ver_num": smu_fw.minor, + "smu_fw_major_ver_num": smu_fw.major + } def amdsmi_get_cpu_core_energy( processor_handle: amdsmi_wrapper.amdsmi_processor_handle, core_idx: int From 49a797f36e13f1eba804fdb562dc082584aa6343 Mon Sep 17 00:00:00 2001 From: Maisam Arif Date: Mon, 16 Oct 2023 06:24:42 -0500 Subject: [PATCH 24/27] Fixed set & reset parser no argument handling Change-Id: If8161059810a9a4fc7845eb4ffd6d3dbd0e8df64 Signed-off-by: Maisam Arif [ROCm/amdsmi commit: 5405615062688391f9884e04386e06027e0d19cd] --- .../amdsmi_cli/amdsmi_cli_exceptions.py | 19 ++++++++ projects/amdsmi/amdsmi_cli/amdsmi_commands.py | 12 +++++ projects/amdsmi/amdsmi_cli/amdsmi_parser.py | 46 ++++++++++--------- 3 files changed, 55 insertions(+), 22 deletions(-) diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_cli_exceptions.py b/projects/amdsmi/amdsmi_cli/amdsmi_cli_exceptions.py index 13fe9753eb..e42fc9f9f2 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_cli_exceptions.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_cli_exceptions.py @@ -61,6 +61,7 @@ def _get_error_message(error_code): return AMDSMI_ERROR_MESSAGES[abs(error_code)] return "Generic error" + class AmdSmiException(Exception): def __init__(self): self.json_message = {} @@ -125,6 +126,7 @@ class AmdSmiDeviceNotFoundException(AmdSmiException): self.csv_message = f"error,code\n{common_message}, {self.value}" self.stdout_message = f"{common_message} Error code: {self.value}" + class AmdSmiInvalidFilePathException(AmdSmiException): def __init__(self, command, outputformat): super().__init__() @@ -184,6 +186,22 @@ class AmdSmiParameterNotSupportedException(AmdSmiException): self.csv_message = f"error,code\n{common_message}, {self.value}" self.stdout_message = f"{common_message} Error code: {self.value}" + +class AmdSmiRequiredCommandException(AmdSmiException): + def __init__(self, command, outputformat): + super().__init__() + self.value = -9 + self.command = command + self.output_format = outputformat + + common_message = f"Command '{self.command}' requires a target argument. Run '--help' for more info." + + self.json_message["error"] = common_message + self.json_message["code"] = self.value + self.csv_message = f"error,code\n{common_message}, {self.value}" + self.stdout_message = f"{common_message} Error code: {self.value}" + + class AmdSmiUnknownErrorException(AmdSmiException): def __init__(self, command, outputformat): super().__init__() @@ -198,6 +216,7 @@ class AmdSmiUnknownErrorException(AmdSmiException): self.csv_message = f"error,code\n{common_message}, {self.value}" self.stdout_message = f"{common_message} Error code: {self.value}" + class AmdSmiAMDSMIErrorException(AmdSmiException): def __init__(self, outputformat, error_code): super().__init__() diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_commands.py b/projects/amdsmi/amdsmi_cli/amdsmi_commands.py index 7326c83214..36f86fecb9 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_commands.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_commands.py @@ -20,6 +20,7 @@ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # +import argparse import logging import sys import threading @@ -28,6 +29,7 @@ import time from _version import __version__ from amdsmi_helpers import AMDSMIHelpers from amdsmi_logger import AMDSMILogger +from amdsmi_cli_exceptions import AmdSmiRequiredCommandException from amdsmi import amdsmi_interface from amdsmi import amdsmi_exception @@ -1780,6 +1782,11 @@ class AMDSMICommands(): args.gpu = device_handle + # Error if no subcommand args are passed + if not any([args.fan, args.perflevel, args.profile, args.perfdeterminism]): + command = " ".join(sys.argv[1:]) + raise AmdSmiRequiredCommandException(command, self.logger.format) + # Build GPU string for errors try: gpu_bdf = amdsmi_interface.amdsmi_get_gpu_device_bdf(args.gpu) @@ -1904,6 +1911,11 @@ class AMDSMICommands(): # Get gpu_id for logging gpu_id = self.helpers.get_gpu_id_from_device_handle(args.gpu) + # Error if no subcommand args are passed + if not any([args.gpureset, args.clocks, args.fans, args.profile, args.xgmierr, args.perfdeterminism]): + command = " ".join(sys.argv[1:]) + raise AmdSmiRequiredCommandException(command, self.logger.format) + if args.gpureset: if self.helpers.is_amd_device(args.gpu): try: diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_parser.py b/projects/amdsmi/amdsmi_cli/amdsmi_parser.py index 8ad7686f86..27c42f696f 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_parser.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_parser.py @@ -281,6 +281,8 @@ class AMDSMIParser(argparse.ArgumentParser): version_parser._optionals.title = None version_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) version_parser.set_defaults(func=func) + + # Add Universal Arguments self._add_command_modifiers(version_parser) @@ -298,10 +300,8 @@ class AMDSMIParser(argparse.ArgumentParser): list_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) list_parser.set_defaults(func=func) - # Add Command Modifiers + # Add Universal Arguments self._add_command_modifiers(list_parser) - - # Add Device args self._add_device_arguments(list_parser, required=False) @@ -337,9 +337,9 @@ class AMDSMIParser(argparse.ArgumentParser): static_parser._optionals.title = static_optionals_title static_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) static_parser.set_defaults(func=func) - self._add_command_modifiers(static_parser) - # Add Device args + # Add Universal Arguments + self._add_command_modifiers(static_parser) self._add_device_arguments(static_parser, required=False) # Optional Args @@ -381,9 +381,9 @@ class AMDSMIParser(argparse.ArgumentParser): firmware_parser._optionals.title = firmware_optionals_title firmware_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) firmware_parser.set_defaults(func=func) - self._add_command_modifiers(firmware_parser) - # Add Device args + # Add Universal Arguments + self._add_command_modifiers(firmware_parser) self._add_device_arguments(firmware_parser, required=False) # Optional Args @@ -414,9 +414,9 @@ class AMDSMIParser(argparse.ArgumentParser): bad_pages_parser._optionals.title = bad_pages_optionals_title bad_pages_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) bad_pages_parser.set_defaults(func=func) - self._add_command_modifiers(bad_pages_parser) - # Add Device args + # Add Universal Arguments + self._add_command_modifiers(bad_pages_parser) self._add_device_arguments(bad_pages_parser, required=False) # Optional Args @@ -464,9 +464,9 @@ class AMDSMIParser(argparse.ArgumentParser): metric_parser._optionals.title = metric_optionals_title metric_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) metric_parser.set_defaults(func=func) - self._add_command_modifiers(metric_parser) - # Add Device args + # Add Universal Arguments + self._add_command_modifiers(metric_parser) self._add_device_arguments(metric_parser, required=False) # Add Watch args @@ -527,9 +527,9 @@ class AMDSMIParser(argparse.ArgumentParser): process_parser._optionals.title = process_optionals_title process_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) process_parser.set_defaults(func=func) - self._add_command_modifiers(process_parser) - # Add Device args + # Add Universal Arguments + self._add_command_modifiers(process_parser) self._add_device_arguments(process_parser, required=False) # Add Watch args @@ -557,9 +557,9 @@ class AMDSMIParser(argparse.ArgumentParser): profile_parser._optionals.title = profile_optionals_title profile_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) profile_parser.set_defaults(func=func) - self._add_command_modifiers(profile_parser) - # Add Device args + # Add Universal Arguments + self._add_command_modifiers(profile_parser) self._add_device_arguments(profile_parser, required=False) @@ -578,9 +578,9 @@ class AMDSMIParser(argparse.ArgumentParser): event_parser._optionals.title = event_optionals_title event_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) event_parser.set_defaults(func=func) - self._add_command_modifiers(event_parser) - # Add Device args + # Add Universal Arguments + self._add_command_modifiers(event_parser) self._add_device_arguments(event_parser, required=False) @@ -607,9 +607,9 @@ class AMDSMIParser(argparse.ArgumentParser): topology_parser._optionals.title = topology_optionals_title topology_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) topology_parser.set_defaults(func=func) - self._add_command_modifiers(topology_parser) - # Add Device args + # Add Universal Arguments + self._add_command_modifiers(topology_parser) self._add_device_arguments(topology_parser, required=False) # Optional Args @@ -644,8 +644,9 @@ class AMDSMIParser(argparse.ArgumentParser): set_value_parser._optionals.title = set_value_optionals_title set_value_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) set_value_parser.set_defaults(func=func) - self._add_command_modifiers(set_value_parser) + # Add Universal Arguments + self._add_command_modifiers(set_value_parser) # Device args are required as safeguard from the user applying the operation to all gpus unintentionally self._add_device_arguments(set_value_parser, required=True) @@ -777,12 +778,13 @@ class AMDSMIParser(argparse.ArgumentParser): reset_parser._optionals.title = reset_optionals_title reset_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) reset_parser.set_defaults(func=func) - self._add_command_modifiers(reset_parser) + # Add Universal Arguments + self._add_command_modifiers(reset_parser) # Device args are required as safeguard from the user applying the operation to all gpus unintentionally self._add_device_arguments(reset_parser, required=True) - # Optional Args + # Add reset arguments reset_parser.add_argument('-G', '--gpureset', action='store_true', required=False, help=gpureset_help) reset_parser.add_argument('-c', '--clocks', action='store_true', required=False, help=reset_clocks_help) reset_parser.add_argument('-f', '--fans', action='store_true', required=False, help=reset_fans_help) From 35887047184bc4ed6f013c5c4533f45e6c2885eb Mon Sep 17 00:00:00 2001 From: Maisam Arif Date: Mon, 16 Oct 2023 07:20:13 -0500 Subject: [PATCH 25/27] Enabled events subcommand to non-virtual systems Signed-off-by: Maisam Arif Change-Id: Ied56ef015bba606b1bca1a1108a237d0c1cc7fdb [ROCm/amdsmi commit: ec24a0f66d81cc59668382ebe493e17a2737e7b7] --- projects/amdsmi/amdsmi_cli/amdsmi_commands.py | 30 +++++++++++++++---- projects/amdsmi/amdsmi_cli/amdsmi_parser.py | 4 +-- .../amdsmi/py-interface/amdsmi_interface.py | 15 ++++------ projects/amdsmi/src/amd_smi/amd_smi.cc | 8 ++--- 4 files changed, 36 insertions(+), 21 deletions(-) diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_commands.py b/projects/amdsmi/amdsmi_cli/amdsmi_commands.py index 36f86fecb9..4e137f99ec 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_commands.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_commands.py @@ -1526,13 +1526,31 @@ class AMDSMICommands(): print('Not applicable to linux baremetal') - def event(self, args): + def event(self, args, gpu=None): + """ Get event information for target gpus + + Args: + args (Namespace): argparser args to pass to subcommand + gpu (device_handle, optional): device_handle for target device. Defaults to None. + + Return: + stdout event information for target gpus + """ + if args.gpu: + gpu = args.gpu + + if gpu == None: + args.gpu = self.device_handles + + if not isinstance(args.gpu, list): + args.gpu = [args.gpu] + print('EVENT LISTENING:\n') - print('Press q and hit ENTER when you want to stop (listening will stop inside 10 seconds)') + print('Press q and hit ENTER when you want to stop (listening will stop within 10 seconds)') threads = [] - for i in range(len(self.device_handles)): - x = threading.Thread(target=self._event_thread, args=(self, i)) + for gpu in range(len(args.gpu)): + x = threading.Thread(target=self._event_thread, args=(self, gpu)) threads.append(x) x.start() @@ -2058,8 +2076,8 @@ class AMDSMICommands(): return device = devices[i] - listener = amdsmi_interface.AmdSmiEventReader(device, amdsmi_interface.AmdSmiEvtNotificationType.GPU_PRE_RESET, - amdsmi_interface.AmdSmiEvtNotificationType.GPU_POST_RESET) + listener = amdsmi_interface.AmdSmiEventReader(device, + amdsmi_interface.AmdSmiEvtNotificationType) values_dict = {} while self.stop!='q': diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_parser.py b/projects/amdsmi/amdsmi_cli/amdsmi_parser.py index 27c42f696f..76273578f6 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_parser.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_parser.py @@ -564,8 +564,8 @@ class AMDSMIParser(argparse.ArgumentParser): def _add_event_parser(self, subparsers, func): - if self.helpers.is_linux() and not self.helpers.is_virtual_os(): - # This subparser only applies to Linux Hypervisors, NOT Linux Guest + if self.helpers.is_virtual_os(): + # This subparser doesn't only apply to guest systems return # Subparser help text diff --git a/projects/amdsmi/py-interface/amdsmi_interface.py b/projects/amdsmi/py-interface/amdsmi_interface.py index f97dd8e3ef..2b832eb7cd 100644 --- a/projects/amdsmi/py-interface/amdsmi_interface.py +++ b/projects/amdsmi/py-interface/amdsmi_interface.py @@ -348,7 +348,8 @@ class AmdSmiProcessorType(IntEnum): class AmdSmiEventReader: def __init__( - self, processor_handle: amdsmi_wrapper.amdsmi_processor_handle, *event_types + self, processor_handle: amdsmi_wrapper.amdsmi_processor_handle, + event_types: List[AmdSmiEvtNotificationType] ): if not isinstance(processor_handle, amdsmi_wrapper.amdsmi_processor_handle): raise AmdSmiParameterException( @@ -375,8 +376,7 @@ class AmdSmiEventReader: processor_handle, ctypes.c_uint64(mask))) def read(self, timestamp, num_elem=10): - self.event_info = ( - amdsmi_wrapper.amdsmi_evt_notification_data_t * num_elem)() + self.event_info = (amdsmi_wrapper.amdsmi_evt_notification_data_t * num_elem)() _check_res( amdsmi_wrapper.amdsmi_get_gpu_event_notification( ctypes.c_int(timestamp), @@ -387,15 +387,12 @@ class AmdSmiEventReader: ret = list() for i in range(0, num_elem): - if self.event_info[i].event in set( - event.value for event in AmdSmiEvtNotificationType - ): + unique_event_values = set(event.value for event in AmdSmiEvtNotificationType) + if self.event_info[i].event in unique_event_values: ret.append( { "processor_handle": self.event_info[i].processor_handle, - "event": AmdSmiEvtNotificationType( - self.event_info[i].event - ).name, + "event": AmdSmiEvtNotificationType(self.event_info[i].event).name, "message": self.event_info[i].message.decode("utf-8"), } ) diff --git a/projects/amdsmi/src/amd_smi/amd_smi.cc b/projects/amdsmi/src/amd_smi/amd_smi.cc index 9253722628..145f4e639b 100644 --- a/projects/amdsmi/src/amd_smi/amd_smi.cc +++ b/projects/amdsmi/src/amd_smi/amd_smi.cc @@ -823,14 +823,14 @@ amdsmi_init_gpu_event_notification(amdsmi_processor_handle processor_handle) { } amdsmi_status_t - amdsmi_set_gpu_event_notification_mask(amdsmi_processor_handle processor_handle, - uint64_t mask) { +amdsmi_set_gpu_event_notification_mask(amdsmi_processor_handle processor_handle, + uint64_t mask) { return rsmi_wrapper(rsmi_event_notification_mask_set, processor_handle, mask); } amdsmi_status_t - amdsmi_get_gpu_event_notification(int timeout_ms, - uint32_t *num_elem, amdsmi_evt_notification_data_t *data) { +amdsmi_get_gpu_event_notification(int timeout_ms, + uint32_t *num_elem, amdsmi_evt_notification_data_t *data) { AMDSMI_CHECK_INIT(); if (num_elem == nullptr || data == nullptr) { From 710cc741367d24c6882e0e5a62ba950339699dea Mon Sep 17 00:00:00 2001 From: Maisam Arif Date: Mon, 16 Oct 2023 11:11:03 -0500 Subject: [PATCH 26/27] CLI help text clean up Signed-off-by: Maisam Arif Change-Id: I46d8071f2bb38f3a6e366b436e7451116bfb6df9 [ROCm/amdsmi commit: 6d4d706f085b34a4a221eb226ae9089545462540] --- projects/amdsmi/amdsmi_cli/amdsmi_commands.py | 34 +++++++++---------- projects/amdsmi/amdsmi_cli/amdsmi_helpers.py | 15 ++++++-- projects/amdsmi/amdsmi_cli/amdsmi_parser.py | 19 ++++++----- 3 files changed, 40 insertions(+), 28 deletions(-) diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_commands.py b/projects/amdsmi/amdsmi_cli/amdsmi_commands.py index 4e137f99ec..e58adc7981 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_commands.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_commands.py @@ -1751,7 +1751,7 @@ class AMDSMICommands(): def set_value(self, args, multiple_devices=False, gpu=None, fan=None, perf_level=None, - profile=None, perfdeterminism=None, compute_partition=None, + profile=None, perf_determinism=None, compute_partition=None, memory_partition=None): """Issue reset commands to target gpu(s) @@ -1762,7 +1762,7 @@ class AMDSMICommands(): fan (int, optional): Value override for args.fan. Defaults to None. perf_level (amdsmi_interface.AmdSmiDevPerfLevel, optional): Value override for args.perf_level. Defaults to None. profile (bool, optional): Value override for args.profile. Defaults to None. - perfdeterminism (int, optional): Value override for args.perfdeterminism. Defaults to None. + perf_determinism (int, optional): Value override for args.perf_determinism. Defaults to None. compute_partition (amdsmi_interface.AmdSmiComputePartitionType, optional): Value override for args.compute_partition. Defaults to None. memory_partition (amdsmi_interface.AmdSmiMemoryPartitionType, optional): Value override for args.memory_partition. Defaults to None. @@ -1782,8 +1782,8 @@ class AMDSMICommands(): args.perf_level = perf_level if profile: args.profile = profile - if perfdeterminism: - args.perfdeterminism = perfdeterminism + if perf_determinism: + args.perf_determinism = perf_determinism if compute_partition: args.compute_partition = compute_partition if memory_partition: @@ -1801,7 +1801,7 @@ class AMDSMICommands(): args.gpu = device_handle # Error if no subcommand args are passed - if not any([args.fan, args.perflevel, args.profile, args.perfdeterminism]): + if not any([args.fan, args.perflevel, args.profile, args.perf_determinism]): command = " ".join(sys.argv[1:]) raise AmdSmiRequiredCommandException(command, self.logger.format) @@ -1838,15 +1838,15 @@ class AMDSMICommands(): self.logger.store_output(args.gpu, 'perflevel', f"Successfully set performance level {args.perf_level}") if args.profile: self.logger.store_output(args.gpu, 'profile', "Not Yet Implemented") - if isinstance(args.perfdeterminism, int): + if isinstance(args.perf_determinism, int): try: - amdsmi_interface.amdsmi_set_gpu_perf_determinism_mode(args.gpu, args.perfdeterminism) + amdsmi_interface.amdsmi_set_gpu_perf_determinism_mode(args.gpu, args.perf_determinism) except amdsmi_exception.AmdSmiLibraryException as e: if e.get_error_code() == amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NO_PERM: raise PermissionError('Command requires elevation') from e - raise ValueError(f"Unable to set performance determinism and clock frequency to {args.perfdeterminism} on {gpu_string}") from e + raise ValueError(f"Unable to set performance determinism and clock frequency to {args.perf_determinism} on {gpu_string}") from e - self.logger.store_output(args.gpu, 'perfdeterminism', f"Successfully enabled performance determinism and set GFX clock frequency to {args.perfdeterminism}") + self.logger.store_output(args.gpu, 'perfdeterminism', f"Successfully enabled performance determinism and set GFX clock frequency to {args.perf_determinism}") if args.compute_partition: compute_partition = amdsmi_interface.AmdSmiComputePartitionType[args.compute_partition] try: @@ -1871,7 +1871,7 @@ class AMDSMICommands(): def reset(self, args, multiple_devices=False, gpu=None, gpureset=None, - clocks=None, fans=None, profile=None, xgmierr=None, perfdeterminism=None, + clocks=None, fans=None, profile=None, xgmierr=None, perf_determinism=None, compute_partition=None, memory_partition=None): """Issue reset commands to target gpu(s) @@ -1884,7 +1884,7 @@ class AMDSMICommands(): fans (bool, optional): Value override for args.fans. Defaults to None. profile (bool, optional): Value override for args.profile. Defaults to None. xgmierr (bool, optional): Value override for args.xgmierr. Defaults to None. - perfdeterminism (bool, optional): Value override for args.perfdeterminism. Defaults to None. + perf_determinism (bool, optional): Value override for args.perf_determinism. Defaults to None. compute_partition (bool, optional): Value override for args.compute_partition. Defaults to None. memory_partition (bool, optional): Value override for args.memory_partition. Defaults to None. @@ -1908,8 +1908,8 @@ class AMDSMICommands(): args.profile = profile if xgmierr: args.xgmierr = xgmierr - if perfdeterminism: - args.perfdeterminism = perfdeterminism + if perf_determinism: + args.perf_determinism = perf_determinism if compute_partition: args.compute_partition = compute_partition if memory_partition: @@ -1930,7 +1930,7 @@ class AMDSMICommands(): gpu_id = self.helpers.get_gpu_id_from_device_handle(args.gpu) # Error if no subcommand args are passed - if not any([args.gpureset, args.clocks, args.fans, args.profile, args.xgmierr, args.perfdeterminism]): + if not any([args.gpureset, args.clocks, args.fans, args.profile, args.xgmierr, args.perf_determinism]): command = " ".join(sys.argv[1:]) raise AmdSmiRequiredCommandException(command, self.logger.format) @@ -2026,7 +2026,7 @@ class AMDSMICommands(): result = "N/A" logging.debug("Failed to reset xgmi error count on gpu %s | %s", gpu_id, e.get_error_info()) self.logger.store_output(args.gpu, 'reset_xgmi_err', result) - if args.perfdeterminism: + if args.perf_determinism: try: level_auto = amdsmi_interface.AmdSmiDevPerfLevel.AUTO amdsmi_interface.amdsmi_set_gpu_perf_level(args.gpu, level_auto) @@ -2039,7 +2039,7 @@ class AMDSMICommands(): self.logger.store_output(args.gpu, 'reset_perf_determinism', result) if args.compute_partition: try: - amdsmi_interface.amdsmi_reset_gpu_compute_partition(args.gpu) + amdsmi_interface.amdsmi_dev_compute_partition_reset(args.gpu) result = 'Successfully reset compute partition' except amdsmi_exception.AmdSmiLibraryException as e: if e.get_error_code() == amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NO_PERM: @@ -2049,7 +2049,7 @@ class AMDSMICommands(): self.logger.store_output(args.gpu, 'reset_compute_partition', result) if args.memory_partition: try: - amdsmi_interface.amdsmi_reset_gpu_memory_partition(args.gpu) + amdsmi_interface.amdsmi_dev_memory_partition_reset(args.gpu) result = 'Successfully reset memory partition' except amdsmi_exception.AmdSmiLibraryException as e: if e.get_error_code() == amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NO_PERM: diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_helpers.py b/projects/amdsmi/amdsmi_cli/amdsmi_helpers.py index 9bb790a73c..2efb9a573b 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_helpers.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_helpers.py @@ -21,6 +21,7 @@ # import logging +import math import platform import sys import time @@ -133,7 +134,7 @@ class AMDSMIHelpers(): """Return dictionary of possible GPU choices and string of the output: Dictionary will be in format: gpus[ID] : (BDF, UUID, Device Handle) String output will be in format: - "ID:0 | BDF:0000:23:00.0 | UUID:ffffffff-0000-1000-0000-000000000000" + "ID: 0 | BDF: 0000:23:00.0 | UUID: ffffffff-0000-1000-0000-000000000000" params: None return: @@ -153,6 +154,9 @@ class AMDSMIHelpers(): else: raise e + # Handle spacing for the gpu_choices_str + max_padding = int(math.log10(len(device_handles))) + 1 + for gpu_id, device_handle in enumerate(device_handles): bdf = amdsmi_interface.amdsmi_get_gpu_device_bdf(device_handle) uuid = amdsmi_interface.amdsmi_get_gpu_device_uuid(device_handle) @@ -161,11 +165,16 @@ class AMDSMIHelpers(): "UUID": uuid, "Device Handle": device_handle, } - gpu_choices_str += f"ID:{gpu_id} | BDF:{bdf} | UUID:{uuid}\n" + + if gpu_id == 0: + id_padding = max_padding + else: + id_padding = max_padding - int(math.log10(gpu_id)) + gpu_choices_str += f"\tID: {gpu_id}{' ' * id_padding}| BDF: {bdf} | UUID: {uuid}\n" # Add the all option to the gpu_choices gpu_choices["all"] = "all" - gpu_choices_str += " all | Selects all devices\n" + gpu_choices_str += f"\t all{' ' * max_padding}| Selects all devices\n" return (gpu_choices, gpu_choices_str) diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_parser.py b/projects/amdsmi/amdsmi_cli/amdsmi_parser.py index 76273578f6..455b793aa7 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_parser.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_parser.py @@ -226,7 +226,8 @@ class AMDSMIParser(argparse.ArgumentParser): csv_help = "Displays output in CSV format (human readable by default)." file_help = "Saves output into a file on the provided path (stdout by default)." loglevel_choices = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"] - loglevel_help = f"Set the logging level from the possible choices:\n{loglevel_choices}" + loglevel_choices_str = ", ".join(loglevel_choices) + loglevel_help = f"Set the logging level from the possible choices:\n\t{loglevel_choices_str}" command_modifier_group = subcommand_parser.add_argument_group('Command Modifiers') @@ -632,12 +633,14 @@ class AMDSMIParser(argparse.ArgumentParser): set_value_optionals_title = "Set Arguments" # Help text for Arguments only on BM platforms - set_fan_help = "Sets GPU fan speed (0-255 or 0-100%%)" - set_perf_level_help = "Sets performance level" + set_fan_help = "Set GPU fan speed (0-255 or 0-100%%)" + set_perf_level_help = "Set performance level" set_profile_help = "Set power profile level (#) or a quoted string of custom profile attributes" - set_perf_det_help = "Sets GPU clock frequency limit and performance level to determinism to get minimal performance variation" - set_compute_partition_help = "Sets compute partition mode" - set_memory_partition_help = "Sets memory partition mode" + set_perf_det_help = "Set GPU clock frequency limit and performance level to determinism to get minimal performance variation" + compute_partition_choices_str = ", ".join(self.helpers.get_compute_partition_types()) + memory_partition_choices_str = ", ".join(self.helpers.get_memory_partition_types()) + set_compute_partition_help = f"Set one of the following the compute partition modes:\n\t{compute_partition_choices_str}" + set_memory_partition_help = f"Set one of the following the memory partition modes:\n\t{memory_partition_choices_str}" # Create set_value subparser set_value_parser = subparsers.add_parser('set', help=set_value_help, description=set_value_subcommand_help) @@ -769,7 +772,7 @@ class AMDSMIParser(argparse.ArgumentParser): reset_fans_help = "Reset fans to automatic (driver) control" reset_profile_help = "Reset power profile back to default" reset_xgmierr_help = "Reset XGMI error counts" - reset_perfdet_help = "Disable performance determinism" + reset_perf_det_help = "Disable performance determinism" reset_compute_help = "Reset compute partitions on the specified GPU" reset_memory_help = "Reset memory partitions on the specified GPU" @@ -790,7 +793,7 @@ class AMDSMIParser(argparse.ArgumentParser): reset_parser.add_argument('-f', '--fans', action='store_true', required=False, help=reset_fans_help) reset_parser.add_argument('-p', '--profile', action='store_true', required=False, help=reset_profile_help) reset_parser.add_argument('-x', '--xgmierr', action='store_true', required=False, help=reset_xgmierr_help) - reset_parser.add_argument('-d', '--perf-determinism', action='store_true', required=False, help=reset_perfdet_help) + reset_parser.add_argument('-d', '--perf-determinism', action='store_true', required=False, help=reset_perf_det_help) reset_parser.add_argument('-C', '--compute-partition', action='store_true', required=False, help=reset_compute_help) reset_parser.add_argument('-M', '--memory-partition', action='store_true', required=False, help=reset_memory_help) From 0bddd177178cacc1ca0c13a31767744d7c55af16 Mon Sep 17 00:00:00 2001 From: Maisam Arif Date: Mon, 16 Oct 2023 08:14:56 -0500 Subject: [PATCH 27/27] Updated READMEs & Versioning for 6.0 Release Signed-off-by: Maisam Arif Change-Id: Idadece3c1022ecba4291b96ddbe23112e27394de [ROCm/amdsmi commit: 5018a57b62c4ae19d16238e293b874f9e8ff0421] --- projects/amdsmi/CMakeLists.txt | 2 +- projects/amdsmi/README.md | 19 +- projects/amdsmi/amdsmi_cli/README.md | 463 +++++++++++--------- projects/amdsmi/amdsmi_cli/__init__.py | 2 +- projects/amdsmi/amdsmi_cli/_version.py | 2 +- projects/amdsmi/docs/doxygen/Doxyfile | 2 +- projects/amdsmi/include/amd_smi/amdsmi.h | 4 +- projects/amdsmi/py-interface/pyproject.toml | 2 +- projects/amdsmi/src/CMakeLists.txt | 2 +- 9 files changed, 278 insertions(+), 220 deletions(-) diff --git a/projects/amdsmi/CMakeLists.txt b/projects/amdsmi/CMakeLists.txt index 785137f2e7..50683e7d81 100755 --- a/projects/amdsmi/CMakeLists.txt +++ b/projects/amdsmi/CMakeLists.txt @@ -28,7 +28,7 @@ find_program(GIT NAMES git) ## Setup the package version based on git tags. set(PKG_VERSION_GIT_TAG_PREFIX "amdsmi_pkg_ver") -get_package_version_number("1.0.0" ${PKG_VERSION_GIT_TAG_PREFIX} GIT) +get_package_version_number("23.4.0" ${PKG_VERSION_GIT_TAG_PREFIX} GIT) message("Package version: ${PKG_VERSION_STR}") set(${AMD_SMI_LIBS_TARGET}_VERSION_MAJOR "${VERSION_MAJOR}") set(${AMD_SMI_LIBS_TARGET}_VERSION_MINOR "${VERSION_MINOR}") diff --git a/projects/amdsmi/README.md b/projects/amdsmi/README.md index 3e78fb9321..4fa348f431 100755 --- a/projects/amdsmi/README.md +++ b/projects/amdsmi/README.md @@ -132,7 +132,7 @@ For additional details, see the [ROCm Contributing Guide](https://rocm.docs.amd. ### Requirements * python 3.7+ 64-bit -* driver must be loaded for amdsmi_init() to pass +* amdgpu driver must be loaded for amdsmi_init() to pass ### CLI Installation @@ -147,7 +147,7 @@ python3 -m pip uninstall amdsmi * Install amd-smi-lib package through package manager * amd-smi --help -#### Install Example for Ubuntu 22.04 +### Install Example for Ubuntu 22.04 ``` bash python3 -m pip list | grep amd @@ -156,7 +156,7 @@ apt install amd-smi-lib amd-smi --help ``` -### Python Library Installation +### Python Development Library Installation This option is for users who want to develop their own scripts using amd-smi's python library @@ -171,11 +171,18 @@ Verify that your python version is 3.7+ to install the python library Warning: this will take precedence over the cli tool's library install, to avoid issues run these steps after every amd-smi-lib update. -#### RHEL 8 & SLES 15 +#### Older RPM Packaged OS's -The default python versions in RHEL 8 and SLES 15 are 3.6.8 and 3.6.15 +The default python versions in older RPM based OS's are not gauranteed to have the minium version. -While the CLI will work with these python versions, to install the python library you need to upgrade to python 3.7+ +For example RHEL 8 and SLES 15 are 3.6.8 and 3.6.15 . You will need to ensure the latest yaml package is installed ( pyyaml >= 5.1) pyyaml is installed to your pip instance: + +``` bash +python3 -m pip install pyyaml +amd-smi list +``` + +While the CLI will work with these older python versions, to install the python development library you need to upgrade to python 3.7+ #### Python Library Install Example for Ubuntu 22.04 diff --git a/projects/amdsmi/amdsmi_cli/README.md b/projects/amdsmi/amdsmi_cli/README.md index 19b269e63e..45281d39f1 100644 --- a/projects/amdsmi/amdsmi_cli/README.md +++ b/projects/amdsmi/amdsmi_cli/README.md @@ -26,7 +26,7 @@ python3 -m pip uninstall amdsmi * Install amd-smi-lib package through package manager * amd-smi --help -#### Install Example for Ubuntu 22.04 +### Install Example for Ubuntu 22.04 ``` bash python3 -m pip list | grep amd @@ -35,7 +35,7 @@ apt install amd-smi-lib amd-smi --help ``` -### Python Library Installation +### Python Development Library Installation This option is for users who want to develop their own scripts using amd-smi's python library @@ -50,11 +50,18 @@ Verify that your python version is 3.7+ to install the python library Warning: this will take precedence over the cli tool's library install, to avoid issues run these steps after every amd-smi-lib update. -#### RHEL 8 & SLES 15 +#### Older RPM Packaged OS's -The default python versions in RHEL 8 and SLES 15 are 3.6.8 and 3.6.15 +The default python versions in older RPM based OS's are not gauranteed to have the minium version. -While the CLI will work with these python versions, to install the python library you need to upgrade to python 3.7+ +For example RHEL 8 and SLES 15 are 3.6.8 and 3.6.15 . You will need to ensure the latest yaml package is installed ( pyyaml >= 5.1) pyyaml is installed to your pip instance: + +``` bash +python3 -m pip install pyyaml +amd-smi list +``` + +While the CLI will work with these older python versions, to install the python development library you need to upgrade to python 3.7+ #### Python Library Install Example for Ubuntu 22.04 @@ -67,7 +74,7 @@ python3 -m pip install --user . ``` ``` bash -python3 +~$ python3 Python 3.8.10 (default, May 26 2023, 14:05:08) [GCC 9.4.0] on linux Type "help", "copyright", "credits" or "license" for more information. @@ -80,27 +87,27 @@ Type "help", "copyright", "credits" or "license" for more information. amd-smi will report the version and current platform detected when running the command without arguments: ``` bash -amd-smi +~$ amd-smi usage: amd-smi [-h] ... -AMD System Management Interface | Version: 23.3.1.0 | Platform: Linux Baremetal +AMD System Management Interface | Version: 23.4.0.0 | Platform: Linux Baremetal optional arguments: - -h, --help show this help message and exit + -h, --help show this help message and exit AMD-SMI Commands: - Descriptions: - version Display version information - list List GPU information - static Gets static information about the specified GPU - firmware Gets firmware information about the specified GPU - bad-pages - Gets bad page information about the specified GPU - metric Gets metric/performance information about the specified GPU - process Lists general process information running on the specified GPU - topology Displays topology information of the devices - set Set options for devices - reset Reset options for devices + Descriptions: + version Display version information + list List GPU information + static Gets static information about the specified GPU + firmware (ucode) Gets firmware information about the specified GPU + bad-pages Gets bad page information about the specified GPU + metric Gets metric/performance information about the specified GPU + process Lists general process information running on the specified GPU + event Displays event information for the given GPU + topology Displays topology information of the devices + set Set options for devices + reset Reset options for devices ``` More detailed verison information is available from `amd-smi version` @@ -112,209 +119,233 @@ Each command will have detailed information via `amd-smi [command] --help` For convenience, here is the help output for each command ``` bash -usage: amd-smi list [-h] [--json | --csv] [--file FILE] - [--loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL}] [-g GPU [GPU ...]] +~$ amd-smi list --help +usage: amd-smi list [-h] [--json | --csv] [--file FILE] [--loglevel LEVEL] + [-g GPU [GPU ...]] -Lists all the devices on the system and the links between devices. -Lists all the sockets and for each socket, GPUs and/or CPUs associated to -that socket alongside some basic information for each device. -In virtualization environments, it can also list VFs associated to each +Lists all the devices on the system and the links between devices. +Lists all the sockets and for each socket, GPUs and/or CPUs associated to +that socket alongside some basic information for each device. +In virtualization environments, it can also list VFs associated to each GPU with some basic information for each VF. optional arguments: - -h, --help show this help message and exit - -g GPU [GPU ...], --gpu GPU [GPU ...] Select a GPU ID, BDF, or UUID from the possible choices: - ID:0 | BDF:0000:23:00.0 | UUID:c4ff73bf-0000-1000-80ff-ffffffffffff - all | Selects all devices + -h, --help show this help message and exit + -g, --gpu GPU [GPU ...] Select a GPU ID, BDF, or UUID from the possible choices: + ID:0 | BDF:0000:23:00.0 | UUID:ffff73bf-0000-1000-80ff-ffffffffffff + all | Selects all devices Command Modifiers: - --json Displays output in JSON format (human readable by default). - --csv Displays output in CSV format (human readable by default). - --file FILE Saves output into a file on the provided path (stdout by default). - --loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL} Set the logging level for the parser commands (ERROR by default). -``` - -``` bash -amd-smi firmware --help -usage: amd-smi firmware [-h] [--json | --csv] [--file FILE] - [--loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL}] - [-g GPU [GPU ...]] [-f] - -If no GPU is specified, return firmware information for all GPUs on the system. - -Firmware Arguments: - -h, --help show this help message and exit - -g GPU [GPU ...], --gpu GPU [GPU ...] Select a GPU ID, BDF, or UUID from the possible choices: - ID:0 | BDF:0000:23:00.0 | UUID:c4ff73bf-0000-1000-80ff-ffffffffffff - all | Selects all devices - -f, --ucode-list, --fw-list All FW list information - -Command Modifiers: - --json Displays output in JSON format (human readable by default). - --csv Displays output in CSV format (human readable by default). - --file FILE Saves output into a file on the provided path (stdout by default). - --loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL} Set the logging level for the parser commands (ERROR by default). + --json Displays output in JSON format (human readable by default). + --csv Displays output in CSV format (human readable by default). + --file FILE Saves output into a file on the provided path (stdout by default). + --loglevel LEVEL Set the logging level from the possible choices: + DEBUG, INFO, WARNING, ERROR, CRITICAL ``` ```bash -amd-smi static --help -usage: amd-smi static [-h] [--json | --csv] [--file FILE] - [--loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL}] [-g GPU [GPU ...]] - [-a] [-b] [-V] [-d] [-v] [-c] [-B] [-r] [-p] [-l] [-u] +~$ amd-smi static --help +usage: amd-smi static [-h] [--json | --csv] [--file FILE] [--loglevel LEVEL] + [-g GPU [GPU ...]] [-a] [-b] [-V] [-d] [-v] [-c] [-B] [-r] [-p] [-l] + [-u] If no GPU is specified, returns static information for all GPUs on the system. If no static argument is provided, all static information will be displayed. Static Arguments: - -h, --help show this help message and exit - -g GPU [GPU ...], --gpu GPU [GPU ...] Select a GPU ID, BDF, or UUID from the possible choices: - ID:0 | BDF:0000:23:00.0 | UUID:c4ff73bf-0000-1000-80ff-ffffffffffff - all | Selects all devices - -a, --asic All asic information - -b, --bus All bus information - -V, --vbios All video bios information (if available) - -d, --driver Displays driver version - -v, --vram All vram information - -c, --cache All cache information - -B, --board All board information - -r, --ras Displays RAS features information - -p, --partition Partition information - -l, --limit All limit metric values (i.e. power and thermal limits) - -u, --numa All numa node information + -h, --help show this help message and exit + -g, --gpu GPU [GPU ...] Select a GPU ID, BDF, or UUID from the possible choices: + ID:0 | BDF:0000:23:00.0 | UUID:ffff73bf-0000-1000-80ff-ffffffffffff + all | Selects all devices + -a, --asic All asic information + -b, --bus All bus information + -V, --vbios All video bios information (if available) + -d, --driver Displays driver version + -v, --vram All vram information + -c, --cache All cache information + -B, --board All board information + -r, --ras Displays RAS features information + -p, --partition Partition information + -l, --limit All limit metric values (i.e. power and thermal limits) + -u, --numa All numa node information Command Modifiers: - --json Displays output in JSON format (human readable by default). - --csv Displays output in CSV format (human readable by default). - --file FILE Saves output into a file on the provided path (stdout by default). - --loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL} Set the logging level for the parser commands (ERROR by default). + --json Displays output in JSON format (human readable by default). + --csv Displays output in CSV format (human readable by default). + --file FILE Saves output into a file on the provided path (stdout by default). + --loglevel LEVEL Set the logging level from the possible choices: + DEBUG, INFO, WARNING, ERROR, CRITICAL +``` + +``` bash +~$ amd-smi firmware --help +usage: amd-smi firmware [-h] [--json | --csv] [--file FILE] [--loglevel LEVEL] + [-g GPU [GPU ...]] [-f] + +If no GPU is specified, return firmware information for all GPUs on the system. + +Firmware Arguments: + -h, --help show this help message and exit + -g, --gpu GPU [GPU ...] Select a GPU ID, BDF, or UUID from the possible choices: + ID:0 | BDF:0000:23:00.0 | UUID:ffff73bf-0000-1000-80ff-ffffffffffff + all | Selects all devices + -f, --ucode-list, --fw-list All FW list information + +Command Modifiers: + --json Displays output in JSON format (human readable by default). + --csv Displays output in CSV format (human readable by default). + --file FILE Saves output into a file on the provided path (stdout by default). + --loglevel LEVEL Set the logging level from the possible choices: + DEBUG, INFO, WARNING, ERROR, CRITICAL ``` ```bash -amd-smi bad-pages --help -usage: amd-smi bad-pages [-h] [--json | --csv] [--file FILE] - [--loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL}] +~$ amd-smi bad-pages --help +usage: amd-smi bad-pages [-h] [--json | --csv] [--file FILE] [--loglevel LEVEL] [-g GPU [GPU ...]] [-p] [-r] [-u] If no GPU is specified, return bad page information for all GPUs on the system. Bad Pages Arguments: - -h, --help show this help message and exit - -g GPU [GPU ...], --gpu GPU [GPU ...] Select a GPU ID, BDF, or UUID from the possible choices: - ID:0 | BDF:0000:23:00.0 | UUID:c4ff73bf-0000-1000-80ff-ffffffffffff - all | Selects all devices - -p, --pending Displays all pending retired pages - -r, --retired Displays retired pages - -u, --un-res Displays unreservable pages + -h, --help show this help message and exit + -g, --gpu GPU [GPU ...] Select a GPU ID, BDF, or UUID from the possible choices: + ID:0 | BDF:0000:23:00.0 | UUID:ffff73bf-0000-1000-80ff-ffffffffffff + all | Selects all devices + -p, --pending Displays all pending retired pages + -r, --retired Displays retired pages + -u, --un-res Displays unreservable pages Command Modifiers: - --json Displays output in JSON format (human readable by default). - --csv Displays output in CSV format (human readable by default). - --file FILE Saves output into a file on the provided path (stdout by default). - --loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL} Set the logging level for the parser commands (ERROR by default). + --json Displays output in JSON format (human readable by default). + --csv Displays output in CSV format (human readable by default). + --file FILE Saves output into a file on the provided path (stdout by default). + --loglevel LEVEL Set the logging level from the possible choices: + DEBUG, INFO, WARNING, ERROR, CRITICAL ``` ```bash -amd-smi metric --help -usage: amd-smi metric [-h] [--json | --csv] [--file FILE] - [--loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL}] [-g GPU [GPU ...]] - [-w loop_time] [-W total_loop_time] [-i number_of_iterations] [-m] - [-u] [-p] [-c] [-t] [-e] [-k] [-P] [-f] [-C] [-o] [-l] [-x] [-E] +~$ amd-smi metric --help +usage: amd-smi metric [-h] [--json | --csv] [--file FILE] [--loglevel LEVEL] + [-g GPU [GPU ...]] [-w INTERVAL] [-W TIME] [-i ITERATIONS] [-m] [-u] + [-p] [-c] [-t] [-e] [-k] [-P] [-f] [-C] [-o] [-l] [-x] [-E] -If no GPU is specified, returns metric information for all GPUs on the system. +If no GPU is specified, returns metric information for all GPUs on the system. If no metric argument is provided all metric information will be displayed. Metric arguments: - -h, --help show this help message and exit - -g GPU [GPU ...], --gpu GPU [GPU ...] Select a GPU ID, BDF, or UUID from the possible choices: - ID:0 | BDF:0000:23:00.0 | UUID:c4ff73bf-0000-1000-80ff-ffffffffffff - all | Selects all devices - -w loop_time, --watch loop_time Reprint the command in a loop of Interval seconds - -W total_loop_time, --watch_time total_loop_time The total time to watch the given command - -i number_of_iterations, --iterations number_of_iterations Total number of iterations to loop on the given command - -m, --mem-usage Memory usage per block - -u, --usage Displays engine usage information - -p, --power Current power usage - -c, --clock Average, max, and current clock frequencies - -t, --temperature Current temperatures - -e, --ecc Number of ECC errors - -k, --ecc-block Number of ECC errors per block - -P, --pcie Current PCIe speed, width, and replay count - -f, --fan Current fan speed - -C, --voltage-curve Display voltage curve - -o, --overdrive Current GPU clock overdrive level - -l, --perf-level Current DPM performance level - -x, --xgmi-err XGMI error information since last read - -E, --energy Amount of energy consumed + -h, --help show this help message and exit + -g, --gpu GPU [GPU ...] Select a GPU ID, BDF, or UUID from the possible choices: + ID:0 | BDF:0000:23:00.0 | UUID:ffff73bf-0000-1000-80ff-ffffffffffff + all | Selects all devices + -w, --watch INTERVAL Reprint the command in a loop of INTERVAL seconds + -W, --watch_time TIME The total TIME to watch the given command + -i, --iterations ITERATIONS Total number of ITERATIONS to loop on the given command + -m, --mem-usage Memory usage per block + -u, --usage Displays engine usage information + -p, --power Current power usage + -c, --clock Average, max, and current clock frequencies + -t, --temperature Current temperatures + -e, --ecc Total number of ECC errors + -k, --ecc-block Number of ECC errors per block + -P, --pcie Current PCIe speed, width, and replay count + -f, --fan Current fan speed + -C, --voltage-curve Display voltage curve + -o, --overdrive Current GPU clock overdrive level + -l, --perf-level Current DPM performance level + -x, --xgmi-err XGMI error information since last read + -E, --energy Amount of energy consumed Command Modifiers: - --json Displays output in JSON format (human readable by default). - --csv Displays output in CSV format (human readable by default). - --file FILE Saves output into a file on the provided path (stdout by default). - --loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL} Set the logging level for the parser commands (ERROR by default). + --json Displays output in JSON format (human readable by default). + --csv Displays output in CSV format (human readable by default). + --file FILE Saves output into a file on the provided path (stdout by default). + --loglevel LEVEL Set the logging level from the possible choices: + DEBUG, INFO, WARNING, ERROR, CRITICAL ``` ```bash -amd-smi process --help -usage: amd-smi process [-h] [--json | --csv] [--file FILE] - [--loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL}] [-g GPU [GPU ...]] - [-w loop_time] [-W total_loop_time] [-i number_of_iterations] [-G] +~$ amd-smi process --help +usage: amd-smi process [-h] [--json | --csv] [--file FILE] [--loglevel LEVEL] + [-g GPU [GPU ...]] [-w INTERVAL] [-W TIME] [-i ITERATIONS] [-G] [-e] [-p PID] [-n NAME] If no GPU is specified, returns information for all GPUs on the system. If no process argument is provided all process information will be displayed. Process arguments: - -h, --help show this help message and exit - -g GPU [GPU ...], --gpu GPU [GPU ...] Select a GPU ID, BDF, or UUID from the possible choices: - ID:0 | BDF:0000:23:00.0 | UUID:c4ff73bf-0000-1000-80ff-ffffffffffff - all | Selects all devices - -w loop_time, --watch loop_time Reprint the command in a loop of Interval seconds - -W total_loop_time, --watch_time total_loop_time The total time to watch the given command - -i number_of_iterations, --iterations number_of_iterations Total number of iterations to loop on the given command - -G, --general pid, process name, memory usage - -e, --engine All engine usages - -p PID, --pid PID Gets all process information about the specified process based on Process ID - -n NAME, --name NAME Gets all process information about the specified process based on Process Name. - If multiple processes have the same name information is returned for all of them. + -h, --help show this help message and exit + -g, --gpu GPU [GPU ...] Select a GPU ID, BDF, or UUID from the possible choices: + ID:0 | BDF:0000:23:00.0 | UUID:ffff73bf-0000-1000-80ff-ffffffffffff + all | Selects all devices + -w, --watch INTERVAL Reprint the command in a loop of INTERVAL seconds + -W, --watch_time TIME The total TIME to watch the given command + -i, --iterations ITERATIONS Total number of ITERATIONS to loop on the given command + -G, --general pid, process name, memory usage + -e, --engine All engine usages + -p, --pid PID Gets all process information about the specified process based on Process ID + -n, --name NAME Gets all process information about the specified process based on Process Name. + If multiple processes have the same name information is returned for all of them. Command Modifiers: - --json Displays output in JSON format (human readable by default). - --csv Displays output in CSV format (human readable by default). - --file FILE Saves output into a file on the provided path (stdout by default). - --loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL} Set the logging level for the parser commands (ERROR by default). + --json Displays output in JSON format (human readable by default). + --csv Displays output in CSV format (human readable by default). + --file FILE Saves output into a file on the provided path (stdout by default). + --loglevel LEVEL Set the logging level from the possible choices: + DEBUG, INFO, WARNING, ERROR, CRITICAL ``` ```bash -amd-smi topology --help -usage: amd-smi topology [-h] [--json | --csv] [--file FILE] - [--loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL}] +~$ amd-smi event --help +usage: amd-smi event [-h] [--json | --csv] [--file FILE] [--loglevel LEVEL] + [-g GPU [GPU ...]] + +If no GPU is specified, returns event information for all GPUs on the system. + +Event Arguments: + -h, --help show this help message and exit + -g, --gpu GPU [GPU ...] Select a GPU ID, BDF, or UUID from the possible choices: + ID:0 | BDF:0000:23:00.0 | UUID:ffff73bf-0000-1000-80ff-ffffffffffff + all | Selects all devices + +Command Modifiers: + --json Displays output in JSON format (human readable by default). + --csv Displays output in CSV format (human readable by default). + --file FILE Saves output into a file on the provided path (stdout by default). + --loglevel LEVEL Set the logging level from the possible choices: + DEBUG, INFO, WARNING, ERROR, CRITICAL +``` + +```bash +~$ amd-smi topology --help +usage: amd-smi topology [-h] [--json | --csv] [--file FILE] [--loglevel LEVEL] [-g GPU [GPU ...]] [-a] [-w] [-o] [-t] [-b] If no GPU is specified, returns information for all GPUs on the system. If no topology argument is provided all topology information will be displayed. Topology arguments: - -h, --help show this help message and exit - -g GPU [GPU ...], --gpu GPU [GPU ...] Select a GPU ID, BDF, or UUID from the possible choices: - ID:0 | BDF:0000:23:00.0 | UUID:c4ff73bf-0000-1000-80ff-ffffffffffff - all | Selects all devices - -a, --access Displays link accessibility between GPUs - -w, --weight Displays relative weight between GPUs - -o, --hops Displays the number of hops between GPUs - -t, --link-type Displays the link type between GPUs - -b, --numa-bw Display max and min bandwidth between nodes + -h, --help show this help message and exit + -g, --gpu GPU [GPU ...] Select a GPU ID, BDF, or UUID from the possible choices: + ID:0 | BDF:0000:23:00.0 | UUID:ffff73bf-0000-1000-80ff-ffffffffffff + all | Selects all devices + -a, --access Displays link accessibility between GPUs + -w, --weight Displays relative weight between GPUs + -o, --hops Displays the number of hops between GPUs + -t, --link-type Displays the link type between GPUs + -b, --numa-bw Display max and min bandwidth between nodes Command Modifiers: - --json Displays output in JSON format (human readable by default). - --csv Displays output in CSV format (human readable by default). - --file FILE Saves output into a file on the provided path (stdout by default). - --loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL} Set the logging level for the parser commands (ERROR by default). + --json Displays output in JSON format (human readable by default). + --csv Displays output in CSV format (human readable by default). + --file FILE Saves output into a file on the provided path (stdout by default). + --loglevel LEVEL Set the logging level from the possible choices: + DEBUG, INFO, WARNING, ERROR, CRITICAL + ``` ```bash -amd-smi set --help -usage: amd-smi set [-h] [--json | --csv] [--file FILE] - [--loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL}] -g GPU [GPU ...] +~$ amd-smi set --help +usage: amd-smi set [-h] [--json | --csv] [--file FILE] [--loglevel LEVEL] -g GPU [GPU ...] [-f %] [-l LEVEL] [-P SETPROFILE] [-d SCLKMAX] [-C PARTITION] [-M PARTITION] @@ -322,52 +353,55 @@ A GPU must be specified to set a configuration. A set argument must be provided; Multiple set arguments are accepted Set Arguments: - -h, --help show this help message and exit - -g GPU [GPU ...], --gpu GPU [GPU ...] Select a GPU ID, BDF, or UUID from the possible choices: - ID:0 | BDF:0000:23:00.0 | UUID:c4ff73bf-0000-1000-80ff-ffffffffffff - all | Selects all devices - -f %, --fan % Sets GPU fan speed (0-255 or 0-100%) - -l LEVEL, --perf-level LEVEL Sets performance level - -P SETPROFILE, --profile SETPROFILE Set power profile level (#) or a quoted string of custom profile attributes - -d SCLKMAX, --perf-determinism SCLKMAX Sets GPU clock frequency limit and performance level to determinism to get minimal performance variation - -C PARTITION, --compute-partition PARTITION Sets compute partition mode - -M PARTITION, --memory-partition PARTITION Sets memory partition mode + -h, --help show this help message and exit + -g, --gpu GPU [GPU ...] Select a GPU ID, BDF, or UUID from the possible choices: + ID: 0 | BDF: 0000:23:00.0 | UUID: c4ff73bf-0000-1000-802e-0812b504ed69 + all | Selects all devices + -f, --fan % Set GPU fan speed (0-255 or 0-100%) + -l, --perf-level LEVEL Set performance level + -P, --profile SETPROFILE Set power profile level (#) or a quoted string of custom profile attributes + -d, --perf-determinism SCLKMAX Set GPU clock frequency limit and performance level to determinism to get minimal performance variation + -C, --compute-partition PARTITION Set one of the following the compute partition modes: + CPX, SPX, DPX, TPX, QPX + -M, --memory-partition PARTITION Set one of the following the memory partition modes: + NPS1, NPS2, NPS4, NPS8 Command Modifiers: - --json Displays output in JSON format (human readable by default). - --csv Displays output in CSV format (human readable by default). - --file FILE Saves output into a file on the provided path (stdout by default). - --loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL} Set the logging level for the parser commands (ERROR by default). + --json Displays output in JSON format (human readable by default). + --csv Displays output in CSV format (human readable by default). + --file FILE Saves output into a file on the provided path (stdout by default). + --loglevel LEVEL Set the logging level from the possible choices: + DEBUG, INFO, WARNING, ERROR, CRITICAL ``` ```bash -amd-smi reset --help -usage: amd-smi reset [-h] [--json | --csv] [--file FILE] - [--loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL}] -g GPU [GPU ...] - [-G] [-c] [-f] [-p] [-x] [-d] [-C] [-M] +~$ amd-smi reset --help +usage: amd-smi reset [-h] [--json | --csv] [--file FILE] [--loglevel LEVEL] -g GPU + [GPU ...] [-G] [-c] [-f] [-p] [-x] [-d] [-C] [-M] A GPU must be specified to reset a configuration. A reset argument must be provided; Multiple reset arguments are accepted Reset Arguments: - -h, --help show this help message and exit - -g GPU [GPU ...], --gpu GPU [GPU ...] Select a GPU ID, BDF, or UUID from the possible choices: - ID:0 | BDF:0000:23:00.0 | UUID:c4ff73bf-0000-1000-80ff-ffffffffffff - all | Selects all devices - -G, --gpureset Reset the specified GPU - -c, --clocks Reset clocks and overdrive to default - -f, --fans Reset fans to automatic (driver) control - -p, --profile Reset power profile back to default - -x, --xgmierr Reset XGMI error counts - -d, --perf-determinism Disable performance determinism - -C, --compute-partition Reset compute partitions on the specified GPU - -M, --memory-partition Reset memory partitions on the specified GPU + -h, --help show this help message and exit + -g, --gpu GPU [GPU ...] Select a GPU ID, BDF, or UUID from the possible choices: + ID: 0 | BDF: 0000:23:00.0 | UUID: c4ff73bf-0000-1000-802e-0812b504ed69 + all | Selects all devices + -G, --gpureset Reset the specified GPU + -c, --clocks Reset clocks and overdrive to default + -f, --fans Reset fans to automatic (driver) control + -p, --profile Reset power profile back to default + -x, --xgmierr Reset XGMI error counts + -d, --perf-determinism Disable performance determinism + -C, --compute-partition Reset compute partitions on the specified GPU + -M, --memory-partition Reset memory partitions on the specified GPU Command Modifiers: - --json Displays output in JSON format (human readable by default). - --csv Displays output in CSV format (human readable by default). - --file FILE Saves output into a file on the provided path (stdout by default). - --loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL} Set the logging level for the parser commands (ERROR by default). + --json Displays output in JSON format (human readable by default). + --csv Displays output in CSV format (human readable by default). + --file FILE Saves output into a file on the provided path (stdout by default). + --loglevel LEVEL Set the logging level from the possible choices: + DEBUG, INFO, WARNING, ERROR, CRITICAL ``` ### Example output from amd-smi static @@ -375,16 +409,17 @@ Command Modifiers: Here is some example output from the tool: ```bash -amd-smi static +~$ amd-smi static GPU: 0 ASIC: MARKET_NAME: 0x73bf VENDOR_ID: 0x1002 - VENDOR_NAME: Advanced Micro Devices, Inc. [AMD/ATI] + VENDOR_NAME: Advanced Micro Devices Inc. [AMD/ATI] SUBVENDOR_ID: 0 DEVICE_ID: 0x73bf REV_ID: 0xc3 ASIC_SERIAL: 0xffffffffffffffff + XGMI_PHYSICAL_ID: N/A BUS: BDF: 0000:23:00.0 MAX_PCIE_SPEED: 16 GT/s @@ -397,9 +432,11 @@ VBIOS: PART_NUMBER: 113-D4120900-101 VERSION: 020.001.000.038.015720 BOARD: - SERIAL_NUMBER: 0xffffffffffffffff - MODEL_NUMBER: ffffffffffffffff - PRODUCT_NAME: ffffffffffffffff + MODEL_NUMBER: N/A + PRODUCT_SERIAL: 0 + FRU_ID: N/A + MANUFACTURER_NAME: N/A + PRODUCT_NAME: N/A LIMIT: MAX_POWER: 203 W CURRENT_POWER: 203 W @@ -410,16 +447,30 @@ LIMIT: SHUTDOWN_HOTSPOT_TEMPERATURE: 115 °C SHUTDOWN_VRAM_TEMPERATURE: 105 °C DRIVER: + DRIVER_NAME: amdgpu DRIVER_VERSION: 6.1.10 DRIVER_DATE: 2015/01/01 00:00 -RAS: N/A VRAM: - VRAM_TYPE: MAX + VRAM_TYPE: GDDR6 VRAM_VENDOR: SAMSUNG VRAM_SIZE_MB: 16368 MB +CACHE: + CACHE 0: + CACHE_SIZE: 16 KB + CACHE_LEVEL: 1 +RAS: + EEPROM_VERSION: N/A + PARITY_SCHEMA: N/A + SINGLE_BIT_SCHEMA: N/A + DOUBLE_BIT_SCHEMA: N/A + POISON_SCHEMA: N/A + ECC_BLOCK_STATE: N/A +PARTITION: + COMPUTE_PARTITION: N/A + MEMORY_PARTITION: N/A NUMA: NODE: 0 - AFFINITY: -1 + AFFINITY: NONE ``` ## Disclaimer diff --git a/projects/amdsmi/amdsmi_cli/__init__.py b/projects/amdsmi/amdsmi_cli/__init__.py index 457ded273b..608c46bbe2 100644 --- a/projects/amdsmi/amdsmi_cli/__init__.py +++ b/projects/amdsmi/amdsmi_cli/__init__.py @@ -1 +1 @@ -__version__ = "23.3.1.0" +__version__ = "23.4.0.0" diff --git a/projects/amdsmi/amdsmi_cli/_version.py b/projects/amdsmi/amdsmi_cli/_version.py index 457ded273b..608c46bbe2 100644 --- a/projects/amdsmi/amdsmi_cli/_version.py +++ b/projects/amdsmi/amdsmi_cli/_version.py @@ -1 +1 @@ -__version__ = "23.3.1.0" +__version__ = "23.4.0.0" diff --git a/projects/amdsmi/docs/doxygen/Doxyfile b/projects/amdsmi/docs/doxygen/Doxyfile index b90d176126..ca3cf2603d 100644 --- a/projects/amdsmi/docs/doxygen/Doxyfile +++ b/projects/amdsmi/docs/doxygen/Doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = AMD SMI # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = "23.3.1.0" +PROJECT_NUMBER = "23.4.0.0" # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/projects/amdsmi/include/amd_smi/amdsmi.h b/projects/amdsmi/include/amd_smi/amdsmi.h index 4199547127..c8da0b4502 100644 --- a/projects/amdsmi/include/amd_smi/amdsmi.h +++ b/projects/amdsmi/include/amd_smi/amdsmi.h @@ -100,10 +100,10 @@ typedef enum { #define AMDSMI_LIB_VERSION_YEAR 23 //! Major version should be changed for every header change (adding/deleting APIs, changing names, fields of structures, etc.) -#define AMDSMI_LIB_VERSION_MAJOR 3 +#define AMDSMI_LIB_VERSION_MAJOR 4 //! Minor version should be updated for each API change, but without changing headers -#define AMDSMI_LIB_VERSION_MINOR 1 +#define AMDSMI_LIB_VERSION_MINOR 0 //! Release version should be set to 0 as default and can be updated by the PMs for each CSP point release #define AMDSMI_LIB_VERSION_RELEASE 0 diff --git a/projects/amdsmi/py-interface/pyproject.toml b/projects/amdsmi/py-interface/pyproject.toml index 17ba948c13..fa2cb5d040 100644 --- a/projects/amdsmi/py-interface/pyproject.toml +++ b/projects/amdsmi/py-interface/pyproject.toml @@ -10,7 +10,7 @@ name = "amdsmi" authors = [ {name = "AMD", email = "amd-smi.support@amd.com"}, ] -version = "23.3.1.0" +version = "23.4.0.0" license = {file = "amdsmi/LICENSE"} readme = {file = "amdsmi/README.md", content-type = "text/markdown"} description = "AMDSMI Python LIB - AMD GPU Monitoring Library" diff --git a/projects/amdsmi/src/CMakeLists.txt b/projects/amdsmi/src/CMakeLists.txt index 3e22f52ffe..7e5d043e75 100644 --- a/projects/amdsmi/src/CMakeLists.txt +++ b/projects/amdsmi/src/CMakeLists.txt @@ -60,7 +60,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("${${AMD_SMI_LIBS_TARGET}_VERSION_MAJOR}.${${AMD_SMI_LIBS_TARGET}_VERSION_MINOR}.0.0" ${SO_VERSION_GIT_TAG_PREFIX} GIT) # VERSION_* variables should be set by get_version_from_tag if(${ROCM_PATCH_VERSION})