Merge amd-dev into amd-master 20230803
Change-Id: I423a2f56df33d8f9c26fcde7f5562e8d759c13d9 Signed-off-by: Galantsev, Dmitrii <dmitrii.galantsev@amd.com>
此提交包含在:
+2
-4
@@ -4,10 +4,8 @@
|
||||
# top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
# Unix-style newlines with a newline ending every file and no stray whitespaces
|
||||
[*]
|
||||
end_of_line = lf
|
||||
trim_trailing_whitespace = true
|
||||
[*.py]
|
||||
indent_style = space
|
||||
|
||||
# Matches multiple files with brace expansion notation
|
||||
# Set default charset
|
||||
|
||||
@@ -11,66 +11,6 @@ AMD SMI library can run on AMD ROCm supported platforms, please refer to [List o
|
||||
To run the AMD SMI library, the amdgpu driver needs to be installed. Optionally, the libdrm can be
|
||||
installed to query firmware information and hardware IPs.
|
||||
|
||||
## Building AMD SMI
|
||||
|
||||
### Additional Required software for building
|
||||
|
||||
In order to build the AMD SMI library, the following components are required. Note that the software versions listed are what was used in development. Earlier versions are not guaranteed to work:
|
||||
|
||||
* CMake (v3.11.0) - `pip3 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`
|
||||
|
||||
In order to build the latest documentation, the following are required:
|
||||
|
||||
* DOxygen (1.8.11)
|
||||
* latex (pdfTeX 3.14159265-2.6-1.40.16)
|
||||
|
||||
The source code for AMD SMI is available on Github.
|
||||
|
||||
After the AMD SMI library git repository has been cloned to a local Linux machine, the Default location for the library and headers is /opt/rocm. Before installation, the old rocm directories should be deleted:
|
||||
/opt/rocm
|
||||
/opt/rocm-{number}
|
||||
|
||||
Building the library is achieved by following the typical CMake build sequence (run as root user or use 'sudo' before 'make install' command), specifically:
|
||||
|
||||
```bash
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake ..
|
||||
make -j $(nproc)
|
||||
make install
|
||||
```
|
||||
|
||||
The built library will appear in the `build` folder.
|
||||
|
||||
To build the rpm and deb packages follow the above steps with:
|
||||
|
||||
```bash
|
||||
make package
|
||||
```
|
||||
|
||||
### Building the Tests
|
||||
|
||||
In order to verify the build and capability of AMD SMI on your system and to see an example of how AMD SMI can be used, you may build and run the tests that are available in the repo. To build the tests, follow these steps:
|
||||
|
||||
```bash
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake -DBUILD_TESTS=ON ..
|
||||
make -j $(nproc)
|
||||
```
|
||||
|
||||
### Run the Tests
|
||||
|
||||
To run the test, execute the program `amdsmitst` that is built from the steps above.
|
||||
Path to the program `amdsmitst`: build/tests/amd_smi_test/
|
||||
|
||||
## Usage Basics
|
||||
|
||||
### Device/Socket handles
|
||||
@@ -192,20 +132,26 @@ For additional details, see the [ROCm Contributing Guide](https://rocm.docs.amd.
|
||||
|
||||
### Installation
|
||||
|
||||
Before instalation, check if the old python amdsmi package is accidentally installed using pip:
|
||||
```bash
|
||||
sudo pip3 list
|
||||
sudo pip3 uninstall amdsmi
|
||||
```
|
||||
Follow user permissions best practices if installing AMDSMI as any user than root.
|
||||
|
||||
* Install amdgpu driver
|
||||
* Install amd-smi-lib package through package manager
|
||||
* cd /opt/rocm/share/amd_smi
|
||||
* python3 -m pip install --upgrade pip
|
||||
* python3 -m pip install --user .
|
||||
* /opt/rocm/bin/amd-smi --help
|
||||
|
||||
Add /opt/rocm/bin to your shell's path to access amd-smi via the cmdline
|
||||
Before amd-smi install, uninstall current versions of amdsmi using pip:
|
||||
|
||||
```bash
|
||||
pip3 list | grep amd
|
||||
pip3 uninstall amdsmi
|
||||
```
|
||||
|
||||
```bash
|
||||
cd /opt/rocm/share/amd_smi
|
||||
python3 -m pip install --upgrade pip
|
||||
python3 -m pip install --user .
|
||||
/opt/rocm/bin/amd-smi --help
|
||||
```
|
||||
|
||||
after installing amd-smi-lib, amd-smi is also available as a binary in /opt/rocm/bin
|
||||
|
||||
### Rebuilding Python wrapper
|
||||
|
||||
@@ -224,6 +170,66 @@ Note: To be able to re-generate python wrapper you need several tools installed
|
||||
|
||||
Note: python_wrapper is NOT automatically re-generated. You must run `cmake` with `-DBUILD_WRAPPER=on` argument.
|
||||
|
||||
## Building AMD SMI
|
||||
|
||||
### Additional Required software for building
|
||||
|
||||
In order to build the AMD SMI library, the following components are required. Note that the software versions listed are what was used in development. Earlier versions are not guaranteed to work:
|
||||
|
||||
* CMake (v3.11.0) - `pip3 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`
|
||||
|
||||
In order to build the latest documentation, the following are required:
|
||||
|
||||
* DOxygen (1.8.11)
|
||||
* latex (pdfTeX 3.14159265-2.6-1.40.16)
|
||||
|
||||
The source code for AMD SMI is available on Github.
|
||||
|
||||
After the AMD SMI library git repository has been cloned to a local Linux machine, the Default location for the library and headers is /opt/rocm. Before installation, the old rocm directories should be deleted:
|
||||
/opt/rocm
|
||||
/opt/rocm-{number}
|
||||
|
||||
Building the library is achieved by following the typical CMake build sequence (run as root user or use 'sudo' before 'make install' command), specifically:
|
||||
|
||||
```bash
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake ..
|
||||
make -j $(nproc)
|
||||
make install
|
||||
```
|
||||
|
||||
The built library will appear in the `build` folder.
|
||||
|
||||
To build the rpm and deb packages follow the above steps with:
|
||||
|
||||
```bash
|
||||
make package
|
||||
```
|
||||
|
||||
### Building the Tests
|
||||
|
||||
In order to verify the build and capability of AMD SMI on your system and to see an example of how AMD SMI can be used, you may build and run the tests that are available in the repo. To build the tests, follow these steps:
|
||||
|
||||
```bash
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake -DBUILD_TESTS=ON ..
|
||||
make -j $(nproc)
|
||||
```
|
||||
|
||||
### Run the Tests
|
||||
|
||||
To run the test, execute the program `amdsmitst` that is built from the steps above.
|
||||
Path to the program `amdsmitst`: build/tests/amd_smi_test/
|
||||
|
||||
## DISCLAIMER
|
||||
|
||||
The information contained herein is for informational purposes only, and is subject to change without notice. In addition, any stated support is planned and is also subject to change. While every precaution has been taken in the preparation of this document, it may contain technical inaccuracies, omissions and typographical errors, and AMD is under no obligation to update or otherwise correct this information. Advanced Micro Devices, Inc. makes no representations or warranties with respect to the accuracy or completeness of the contents of this document, and assumes no liability of any kind, including the implied warranties of noninfringement, merchantability or fitness for particular purposes, with respect to the operation or use of AMD hardware, software or other products described herein.
|
||||
|
||||
+5
-24
@@ -54,7 +54,7 @@ amd-smi will report the version and current platform detected when running the c
|
||||
amd-smi
|
||||
usage: amd-smi [-h] ...
|
||||
|
||||
AMD System Management Interface | Version: 23.0.1.0 | Platform: Linux Baremetal
|
||||
AMD System Management Interface | Version: 23.2.1.0 | Platform: Linux Baremetal
|
||||
|
||||
optional arguments:
|
||||
-h, --help show this help message and exit
|
||||
@@ -185,8 +185,8 @@ 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] [-u]
|
||||
[-b] [-p] [-c] [-t] [-e] [-P] [-V] [-f] [-C] [-o] [-M] [-l] [-r]
|
||||
[-x] [-E] [-m]
|
||||
[-b] [-p] [-c] [-t] [-e] [-P] [-f] [-C] [-o] [-l] [-r] [-x]
|
||||
[-E] [-m]
|
||||
|
||||
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.
|
||||
@@ -205,11 +205,9 @@ Metric arguments:
|
||||
-t, --temperature Current temperatures
|
||||
-e, --ecc Number of ECC errors
|
||||
-P, --pcie Current PCIe speed and width
|
||||
-V, --voltage Current GPU voltages
|
||||
-f, --fan Current fan speed
|
||||
-C, --voltage-curve Display voltage curve
|
||||
-o, --overdrive Current GPU clock overdrive level
|
||||
-M, --mem-overdrive Current memory clock overdrive level
|
||||
-l, --perf-level Current DPM performance level
|
||||
-r, --replay-count PCIe replay count
|
||||
-x, --xgmi-err XGMI error information since last read
|
||||
@@ -283,11 +281,7 @@ Command Modifiers:
|
||||
amd-smi set --help
|
||||
usage: amd-smi set [-h] [--json | --csv] [--file FILE]
|
||||
[--loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL}] -g GPU [GPU ...]
|
||||
[-c CLK_TYPE [CLK_LEVELS ...]] [-s CLK_LEVELS [CLK_LEVELS ...]]
|
||||
[-m CLK_LEVELS [CLK_LEVELS ...]] [-p CLK_LEVELS [CLK_LEVELS ...]]
|
||||
[-S SCLKLEVEL SCLK] [-M MCLKLEVEL MCLK] [-V POINT SCLK SVOLT]
|
||||
[-r SCLKMIN SCLKMAX] [-R MCLKMIN MCLKMAX] [-f %] [-l LEVEL] [-o %]
|
||||
[-O %] [-w WATTS] [-P SETPROFILE] [-d SCLKMAX]
|
||||
[-f %] [-l LEVEL] [-P SETPROFILE] [-d SCLKMAX]
|
||||
|
||||
A GPU must be specified to set a configuration.
|
||||
A set argument must be provided; Multiple set arguments are accepted
|
||||
@@ -296,20 +290,8 @@ 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:ffffffff-ffff-ffff-ffff-ffffffffffff
|
||||
-c CLK_TYPE [CLK_LEVELS ...], --clock CLK_TYPE [CLK_LEVELS ...] Sets clock frequency levels for specified clocks
|
||||
-s CLK_LEVELS [CLK_LEVELS ...], --sclk CLK_LEVELS [CLK_LEVELS ...] Sets GPU clock frequency levels
|
||||
-m CLK_LEVELS [CLK_LEVELS ...], --mclk CLK_LEVELS [CLK_LEVELS ...] Sets memory clock frequency levels
|
||||
-p CLK_LEVELS [CLK_LEVELS ...], --pcie CLK_LEVELS [CLK_LEVELS ...] Sets PCIe Bandwith
|
||||
-S SCLKLEVEL SCLK, --slevel SCLKLEVEL SCLK Change GPU clock frequency and voltage for a specific level
|
||||
-M MCLKLEVEL MCLK, --mlevel MCLKLEVEL MCLK Change GPU memory frequency and voltage for a specific level
|
||||
-V POINT SCLK SVOLT, --vc POINT SCLK SVOLT Change SCLK voltage curve for a specified point
|
||||
-r SCLKMIN SCLKMAX, --srange SCLKMIN SCLKMAX Sets min and max SCLK speed
|
||||
-R MCLKMIN MCLKMAX, --mrange MCLKMIN MCLKMAX Sets min and max MCLK speed
|
||||
-f %, --fan % Sets GPU fan speed (0-255 or 0-100%)
|
||||
-l LEVEL, --perflevel LEVEL Sets performance level
|
||||
-o %, --overdrive % Set GPU overdrive (0-20%) ***DEPRECATED IN NEWER KERNEL VERSIONS (use --slevel instead)***
|
||||
-O %, --memoverdrive % Set memory overclock overdrive level ***DEPRECATED IN NEWER KERNEL VERSIONS (use --mlevel instead)***
|
||||
-w WATTS, --poweroverdrive WATTS Set the maximum GPU power using power overdrive in Watts
|
||||
-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
|
||||
|
||||
@@ -324,7 +306,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] [-o] [-x] [-d]
|
||||
[-G] [-c] [-f] [-p] [-x] [-d]
|
||||
|
||||
A GPU must be specified to reset a configuration.
|
||||
A reset argument must be provided; Multiple reset arguments are accepted
|
||||
@@ -337,7 +319,6 @@ Reset Arguments:
|
||||
-c, --clocks Reset clocks and overdrive to default
|
||||
-f, --fans Reset fans to automatic (driver) control
|
||||
-p, --profile Reset power profile back to default
|
||||
-o, --poweroverdrive Set the maximum GPU power back to the device default state
|
||||
-x, --xgmierr Reset XGMI error counts
|
||||
-d, --perfdeterminism Disable performance determinism
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
__version__ = "23.2.1.0"
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
__version__ = "23.0.1.1"
|
||||
__version__ = "23.2.1.0"
|
||||
|
||||
+132
-401
@@ -57,16 +57,10 @@ class AMDSMICommands():
|
||||
Args:
|
||||
args (Namespace): Namespace containing the parsed CLI args
|
||||
"""
|
||||
|
||||
try:
|
||||
amdsmi_lib_version = amdsmi_interface.amdsmi_get_lib_version()
|
||||
amdsmi_lib_version_str = amdsmi_interface.amdsmi_get_lib_version()["build"]
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
amdsmi_lib_version = e.get_error_info()
|
||||
|
||||
major = amdsmi_lib_version["major"]
|
||||
minor = amdsmi_lib_version["minor"]
|
||||
patch = amdsmi_lib_version["patch"]
|
||||
amdsmi_lib_version_str = f'{major}.{minor}.{patch}'
|
||||
amdsmi_lib_version_str = e.get_error_info()
|
||||
|
||||
self.logger.output['tool'] = 'AMDSMI Tool'
|
||||
self.logger.output['version'] = f'{__version__}'
|
||||
@@ -221,11 +215,34 @@ class AMDSMICommands():
|
||||
|
||||
try:
|
||||
bus_info = amdsmi_interface.amdsmi_get_pcie_link_caps(args.gpu)
|
||||
pcie_speed_GTs_value = round(bus_info['pcie_speed'] / 1000, 1) if bus_info['pcie_speed'] % 1000 != 0 else round(bus_info['pcie_speed'] / 1000)
|
||||
bus_info['pcie_speed'] = pcie_speed_GTs_value
|
||||
if bus_info['max_pcie_speed'] % 1000 != 0:
|
||||
pcie_speed_GTs_value = round(bus_info['max_pcie_speed'] / 1000, 1)
|
||||
else:
|
||||
pcie_speed_GTs_value = round(bus_info['max_pcie_speed'] / 1000)
|
||||
|
||||
bus_info['max_pcie_speed'] = pcie_speed_GTs_value
|
||||
|
||||
try:
|
||||
pcie_slot_type = amdsmi_interface.amdsmi_topo_get_link_type(args.gpu, args.gpu)['type']
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
pcie_slot_type = e.get_error_info()
|
||||
|
||||
if self.logger.is_human_readable_format():
|
||||
unit ='GT/s'
|
||||
bus_info['pcie_speed'] = f"{bus_info['pcie_speed']} {unit}"
|
||||
bus_info['max_pcie_speed'] = f"{bus_info['max_pcie_speed']} {unit}"
|
||||
|
||||
if bus_info['pcie_interface_version'] > 0:
|
||||
bus_info['pcie_interface_version'] = f"Gen {bus_info['pcie_interface_version']}"
|
||||
|
||||
bus_info['pcie_slot_type'] = 'XXXX'
|
||||
if isinstance(pcie_slot_type, int):
|
||||
if pcie_slot_type == amdsmi_interface.amdsmi_wrapper.AMDSMI_IOLINK_TYPE_UNDEFINED:
|
||||
bus_info['pcie_slot_type'] = "UNKNOWN"
|
||||
elif pcie_slot_type == amdsmi_interface.amdsmi_wrapper.AMDSMI_IOLINK_TYPE_PCIEXPRESS:
|
||||
bus_info['pcie_slot_type'] = "PCIE"
|
||||
elif pcie_slot_type == amdsmi_interface.amdsmi_wrapper.AMDSMI_IOLINK_TYPE_XGMI:
|
||||
bus_info['pcie_slot_type'] = "XGMI"
|
||||
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
bus_info = e.get_error_info()
|
||||
if not self.all_arguments:
|
||||
@@ -259,9 +276,10 @@ class AMDSMICommands():
|
||||
board_info = amdsmi_interface.amdsmi_get_gpu_board_info(args.gpu)
|
||||
board_info['serial_number'] = hex(board_info['serial_number'])
|
||||
board_info['model_number'] = board_info['model_number'].strip()
|
||||
board_info['product_serial'] = '0x' + board_info['product_serial']
|
||||
board_info['product_name'] = board_info['product_name'].strip()
|
||||
board_info['manufacturer_name'] = board_info['manufacturer_name'].strip()
|
||||
board_info.pop('product_serial')
|
||||
board_info.pop('manufacturer_name')
|
||||
|
||||
static_dict['board'] = board_info
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
@@ -270,44 +288,60 @@ class AMDSMICommands():
|
||||
raise e
|
||||
if args.limit:
|
||||
try:
|
||||
power_limit_error = False
|
||||
power_limit = amdsmi_interface.amdsmi_get_power_info(args.gpu)['power_limit']
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
power_limit_error = True
|
||||
power_limit = e.get_error_info()
|
||||
if not self.all_arguments:
|
||||
raise e
|
||||
|
||||
try:
|
||||
temp_edge_limit_error = False
|
||||
temp_edge_limit = amdsmi_interface.amdsmi_get_temp_metric(args.gpu,
|
||||
amdsmi_interface.AmdSmiTemperatureType.EDGE, amdsmi_interface.AmdSmiTemperatureMetric.CRITICAL)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
temp_edge_limit_error = True
|
||||
temp_edge_limit = e.get_error_info()
|
||||
if not self.all_arguments:
|
||||
raise e
|
||||
|
||||
if temp_edge_limit == 0:
|
||||
temp_edge_limit_error = True
|
||||
temp_edge_limit = 'N/A'
|
||||
|
||||
try:
|
||||
temp_junction_limit_error = False
|
||||
temp_junction_limit = amdsmi_interface.amdsmi_get_temp_metric(args.gpu,
|
||||
amdsmi_interface.AmdSmiTemperatureType.JUNCTION, amdsmi_interface.AmdSmiTemperatureMetric.CRITICAL)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
temp_junction_limit_error = True
|
||||
temp_junction_limit = e.get_error_info()
|
||||
if not self.all_arguments:
|
||||
raise e
|
||||
|
||||
try:
|
||||
temp_vram_limit_error = False
|
||||
temp_vram_limit = amdsmi_interface.amdsmi_get_temp_metric(args.gpu,
|
||||
amdsmi_interface.AmdSmiTemperatureType.VRAM, amdsmi_interface.AmdSmiTemperatureMetric.CRITICAL)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
temp_vram_limit_error = True
|
||||
temp_vram_limit = e.get_error_info()
|
||||
if not self.all_arguments:
|
||||
raise e
|
||||
|
||||
if self.logger.is_human_readable_format():
|
||||
unit = 'W'
|
||||
power_limit = f"{power_limit} {unit}"
|
||||
if not power_limit_error:
|
||||
power_limit = f"{power_limit} {unit}"
|
||||
|
||||
unit = 'C'
|
||||
temp_edge_limit = f"{temp_edge_limit} {unit}"
|
||||
temp_junction_limit = f"{temp_junction_limit} {unit}"
|
||||
temp_vram_limit = f"{temp_vram_limit} {unit}"
|
||||
unit = '\N{DEGREE SIGN}C'
|
||||
if not temp_edge_limit_error:
|
||||
temp_edge_limit = f"{temp_edge_limit} {unit}"
|
||||
if not temp_junction_limit_error:
|
||||
temp_junction_limit = f"{temp_junction_limit} {unit}"
|
||||
if not temp_vram_limit_error:
|
||||
temp_vram_limit = f"{temp_vram_limit} {unit}"
|
||||
|
||||
limit_info = {}
|
||||
limit_info['power'] = power_limit
|
||||
@@ -519,53 +553,53 @@ class AMDSMICommands():
|
||||
bad_page_info = amdsmi_interface.amdsmi_get_gpu_bad_page_info(args.gpu)
|
||||
bad_page_error = False
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
bad_page_info = ""
|
||||
bad_page_err_output = e.get_error_info()
|
||||
bad_page_error = True
|
||||
raise e
|
||||
|
||||
if isinstance(bad_page_info, str):
|
||||
pass
|
||||
else:
|
||||
if args.retired:
|
||||
if bad_page_error:
|
||||
bad_page_info_output = bad_page_err_output
|
||||
else:
|
||||
bad_page_info_output = []
|
||||
for bad_page in bad_page_info:
|
||||
if bad_page["status"] == amdsmi_interface.AmdSmiMemoryPageStatus.RESERVED:
|
||||
bad_page_info_entry = {}
|
||||
bad_page_info_entry["page_address"] = bad_page["page_address"]
|
||||
bad_page_info_entry["page_size"] = bad_page["page_size"]
|
||||
bad_page_info_entry["status"] = bad_page["status"].name
|
||||
if bad_page_info == "No bad pages found.":
|
||||
bad_page_error = True
|
||||
bad_page_err_output = bad_page_info
|
||||
|
||||
bad_page_info_output.append(bad_page_info_entry)
|
||||
# Remove brackets if there is only one value
|
||||
if len(bad_page_info_output) == 1:
|
||||
bad_page_info_output = bad_page_info_output[0]
|
||||
if args.retired:
|
||||
if bad_page_error:
|
||||
bad_page_info_output = bad_page_err_output
|
||||
else:
|
||||
bad_page_info_output = []
|
||||
for bad_page in bad_page_info:
|
||||
if bad_page["status"] == amdsmi_interface.AmdSmiMemoryPageStatus.RESERVED:
|
||||
bad_page_info_entry = {}
|
||||
bad_page_info_entry["page_address"] = bad_page["page_address"]
|
||||
bad_page_info_entry["page_size"] = bad_page["page_size"]
|
||||
bad_page_info_entry["status"] = bad_page["status"].name
|
||||
|
||||
values_dict['retired'] = bad_page_info_output
|
||||
bad_page_info_output.append(bad_page_info_entry)
|
||||
# Remove brackets if there is only one value
|
||||
if len(bad_page_info_output) == 1:
|
||||
bad_page_info_output = bad_page_info_output[0]
|
||||
|
||||
if args.pending:
|
||||
if bad_page_error:
|
||||
bad_page_info_output = bad_page_err_output
|
||||
else:
|
||||
bad_page_info_output = []
|
||||
for bad_page in bad_page_info:
|
||||
if bad_page["status"] == amdsmi_interface.AmdSmiMemoryPageStatus.PENDING:
|
||||
bad_page_info_entry = {}
|
||||
bad_page_info_entry["page_address"] = bad_page["page_address"]
|
||||
bad_page_info_entry["page_size"] = bad_page["page_size"]
|
||||
bad_page_info_entry["status"] = bad_page["status"].name
|
||||
values_dict['retired'] = bad_page_info_output
|
||||
|
||||
bad_page_info_output.append(bad_page_info_entry)
|
||||
# Remove brackets if there is only one value
|
||||
if len(bad_page_info_output) == 1:
|
||||
bad_page_info_output = bad_page_info_output[0]
|
||||
if args.pending:
|
||||
if bad_page_error:
|
||||
bad_page_info_output = bad_page_err_output
|
||||
else:
|
||||
bad_page_info_output = []
|
||||
for bad_page in bad_page_info:
|
||||
if bad_page["status"] == amdsmi_interface.AmdSmiMemoryPageStatus.PENDING:
|
||||
bad_page_info_entry = {}
|
||||
bad_page_info_entry["page_address"] = bad_page["page_address"]
|
||||
bad_page_info_entry["page_size"] = bad_page["page_size"]
|
||||
bad_page_info_entry["status"] = bad_page["status"].name
|
||||
|
||||
values_dict['pending'] = bad_page_info_output
|
||||
bad_page_info_output.append(bad_page_info_entry)
|
||||
# Remove brackets if there is only one value
|
||||
if len(bad_page_info_output) == 1:
|
||||
bad_page_info_output = bad_page_info_output[0]
|
||||
|
||||
if args.un_res:
|
||||
values_dict['pending'] = bad_page_info_output
|
||||
|
||||
if args.un_res:
|
||||
if bad_page_error:
|
||||
bad_page_info_output = bad_page_err_output
|
||||
else:
|
||||
@@ -596,8 +630,8 @@ class AMDSMICommands():
|
||||
|
||||
def metric(self, args, multiple_devices=False, watching_output=False, gpu=None,
|
||||
usage=None, watch=None, watch_time=None, iterations=None, fb_usage=None, power=None,
|
||||
clock=None, temperature=None, ecc=None, ecc_block=None, pcie=None, voltage=None,
|
||||
fan=None, voltage_curve=None, overdrive=None, mem_overdrive=None, perf_level=None,
|
||||
clock=None, temperature=None, ecc=None, ecc_block=None, pcie=None,
|
||||
fan=None, voltage_curve=None, overdrive=None, perf_level=None,
|
||||
replay_count=None, xgmi_err=None, energy=None, mem_usage=None):
|
||||
"""Get Metric information for target gpu
|
||||
|
||||
@@ -617,11 +651,9 @@ class AMDSMICommands():
|
||||
ecc (bool, optional): Value override for args.ecc. Defaults to None.
|
||||
ecc_block (bool, optional): Value override for args.ecc. Defaults to None.
|
||||
pcie (bool, optional): Value override for args.pcie. Defaults to None.
|
||||
voltage (bool, optional): Value override for args.voltage. Defaults to None.
|
||||
fan (bool, optional): Value override for args.fan. Defaults to None.
|
||||
voltage_curve (bool, optional): Value override for args.voltage_curve. Defaults to None.
|
||||
overdrive (bool, optional): Value override for args.overdrive. Defaults to None.
|
||||
mem_overdrive (bool, optional): Value override for args.mem_overdrive. Defaults to None.
|
||||
perf_level (bool, optional): Value override for args.perf_level. Defaults to None.
|
||||
replay_count (bool, optional): Value override for args.replay_count. Defaults to None.
|
||||
xgmi_err (bool, optional): Value override for args.xgmi_err. Defaults to None.
|
||||
@@ -665,16 +697,12 @@ class AMDSMICommands():
|
||||
args.ecc_block = ecc_block
|
||||
if pcie:
|
||||
args.pcie = pcie
|
||||
if voltage:
|
||||
args.voltage = voltage
|
||||
if fan:
|
||||
args.fan = fan
|
||||
if voltage_curve:
|
||||
args.voltage_curve = voltage_curve
|
||||
if overdrive:
|
||||
args.overdrive = overdrive
|
||||
if mem_overdrive:
|
||||
args.mem_overdrive = mem_overdrive
|
||||
if perf_level:
|
||||
args.perf_level = perf_level
|
||||
if xgmi_err:
|
||||
@@ -728,12 +756,14 @@ class AMDSMICommands():
|
||||
args.fb_usage = args.replay_count = args.mem_usage = self.all_arguments = True
|
||||
|
||||
if self.helpers.is_linux() and self.helpers.is_baremetal():
|
||||
if not any([args.usage, args.fb_usage, args.power, args.clock, args.temperature, args.ecc, args.ecc_block, args.pcie, args.voltage, args.fan,
|
||||
args.voltage_curve, args.overdrive, args.mem_overdrive, args.perf_level,
|
||||
args.replay_count, args.xgmi_err, args.energy, args.mem_usage]):
|
||||
args.usage = args.fb_usage = args.power = args.clock = args.temperature = args.ecc = args.ecc_block = args.pcie = args.voltage = args.fan = \
|
||||
args.voltage_curve = args.overdrive = args.mem_overdrive = args.perf_level = \
|
||||
args.replay_count = args.xgmi_err = args.energy = args.mem_usage = self.all_arguments = True
|
||||
if not any([args.usage, args.fb_usage, args.power, args.clock, args.temperature,
|
||||
args.ecc, args.ecc_block, args.pcie, args.fan, args.voltage_curve,
|
||||
args.overdrive, args.perf_level, args.replay_count, args.xgmi_err,
|
||||
args.energy, args.mem_usage]):
|
||||
args.usage = args.fb_usage = args.power = args.clock = args.temperature = \
|
||||
args.ecc = args.ecc_block = args.pcie = args.fan = args.voltage_curve = \
|
||||
args.overdrive = args.perf_level = args.replay_count = args.xgmi_err = \
|
||||
args.energy = args.mem_usage = self.all_arguments = True
|
||||
|
||||
# Add timestamp and store values for specified arguments
|
||||
values_dict = {}
|
||||
@@ -784,19 +814,22 @@ class AMDSMICommands():
|
||||
power_dict = {'average_socket_power': power_measure['average_socket_power'],
|
||||
'gfx_voltage': power_measure['gfx_voltage'],
|
||||
'soc_voltage': amdsmi_exception.AmdSmiLibraryException(amdsmi_exception.AmdSmiRetCode.STATUS_NOT_YET_IMPLEMENTED).err_info,
|
||||
'mem_voltage': amdsmi_exception.AmdSmiLibraryException(amdsmi_exception.AmdSmiRetCode.STATUS_NOT_YET_IMPLEMENTED).err_info}
|
||||
'mem_voltage': amdsmi_exception.AmdSmiLibraryException(amdsmi_exception.AmdSmiRetCode.STATUS_NOT_YET_IMPLEMENTED).err_info,
|
||||
'power_limit': power_measure['power_limit']}
|
||||
|
||||
if self.logger.is_human_readable_format():
|
||||
power_dict['average_socket_power'] = f"{power_dict['average_socket_power']} W"
|
||||
power_dict['gfx_voltage'] = f"{power_dict['gfx_voltage']} mV"
|
||||
power_dict['soc_voltage'] = amdsmi_exception.AmdSmiLibraryException(amdsmi_exception.AmdSmiRetCode.STATUS_NOT_YET_IMPLEMENTED).err_info
|
||||
power_dict['mem_voltage'] = amdsmi_exception.AmdSmiLibraryException(amdsmi_exception.AmdSmiRetCode.STATUS_NOT_YET_IMPLEMENTED).err_info
|
||||
power_dict['power_limit'] = f"{power_dict['power_limit']} W"
|
||||
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
power_dict = {'average_socket_power': e.get_error_info(),
|
||||
'gfx_voltage': e.get_error_info(),
|
||||
'soc_voltage': e.get_error_info(),
|
||||
'mem_voltage': e.get_error_info()}
|
||||
'mem_voltage': e.get_error_info(),
|
||||
'power_limit': e.get_error_info()}
|
||||
|
||||
if not self.all_arguments:
|
||||
raise e
|
||||
@@ -840,18 +873,24 @@ class AMDSMICommands():
|
||||
try:
|
||||
temperature_edge_current = amdsmi_interface.amdsmi_get_temp_metric(
|
||||
args.gpu, amdsmi_interface.AmdSmiTemperatureType.EDGE, amdsmi_interface.AmdSmiTemperatureMetric.CURRENT)
|
||||
temperature_edge_limit = amdsmi_interface.amdsmi_get_temp_metric(
|
||||
args.gpu, amdsmi_interface.AmdSmiTemperatureType.EDGE, amdsmi_interface.AmdSmiTemperatureMetric.CRITICAL)
|
||||
temperature_junction_current = amdsmi_interface.amdsmi_get_temp_metric(
|
||||
args.gpu, amdsmi_interface.AmdSmiTemperatureType.JUNCTION, amdsmi_interface.AmdSmiTemperatureMetric.CURRENT)
|
||||
temperature_vram_current = amdsmi_interface.amdsmi_get_temp_metric(
|
||||
args.gpu, amdsmi_interface.AmdSmiTemperatureType.VRAM, amdsmi_interface.AmdSmiTemperatureMetric.CURRENT)
|
||||
|
||||
# If edge limit is reporting 0 then set the current edge temp to N/A
|
||||
if temperature_edge_limit == 0:
|
||||
temperature_edge_current = 'N/A'
|
||||
|
||||
temperatures = {'edge': temperature_edge_current,
|
||||
'hotspot': temperature_junction_current,
|
||||
'junction': temperature_junction_current,
|
||||
'mem': temperature_vram_current}
|
||||
|
||||
if self.logger.is_gpuvsmi_compatibility():
|
||||
temperatures = {'edge_temperature': temperature_edge_current,
|
||||
'hotspot_temperature': temperature_junction_current,
|
||||
'junction_temperature': temperature_junction_current,
|
||||
'mem_temperature': temperature_vram_current}
|
||||
|
||||
if self.logger.is_human_readable_format():
|
||||
@@ -907,38 +946,30 @@ class AMDSMICommands():
|
||||
values_dict['ecc_block'] = e.get_error_info()
|
||||
if not self.all_arguments:
|
||||
raise e
|
||||
|
||||
if args.pcie:
|
||||
try:
|
||||
pcie_link_status = amdsmi_interface.amdsmi_get_pcie_link_caps(args.gpu)
|
||||
pcie_speed_GTs_value = round(pcie_link_status['pcie_speed'] / 1000, 1) if pcie_link_status['pcie_speed'] % 1000 != 0 else round(pcie_link_status['pcie_speed'] / 1000)
|
||||
pcie_link_status = amdsmi_interface.amdsmi_get_pcie_link_status(args.gpu)
|
||||
|
||||
if pcie_link_status['pcie_speed'] % 1000 != 0:
|
||||
pcie_speed_GTs_value = round(pcie_link_status['pcie_speed'] / 1000, 1)
|
||||
else:
|
||||
pcie_speed_GTs_value = round(pcie_link_status['pcie_speed'] / 1000)
|
||||
|
||||
pcie_link_status['pcie_speed'] = pcie_speed_GTs_value
|
||||
# The interface version should not be displayed as it is based on the current speed
|
||||
del pcie_link_status['pcie_interface_version']
|
||||
|
||||
if self.logger.is_human_readable_format():
|
||||
unit ='GT/s'
|
||||
unit = 'GT/s'
|
||||
pcie_link_status['pcie_speed'] = f"{pcie_link_status['pcie_speed']} {unit}"
|
||||
if self.logger.is_gpuvsmi_compatibility():
|
||||
pcie_link_status['current_width'] = pcie_link_status.pop('pcie_lanes')
|
||||
pcie_link_status['current_speed'] = pcie_link_status.pop('pcie_speed')
|
||||
|
||||
values_dict['pcie'] = pcie_link_status
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
values_dict['pcie'] = e.get_error_info()
|
||||
if not self.all_arguments:
|
||||
raise e
|
||||
|
||||
if args.voltage:
|
||||
try:
|
||||
volt_metric = amdsmi_interface.amdsmi_get_gpu_volt_metric(
|
||||
args.gpu, amdsmi_interface.AmdSmiVoltageType.VDDGFX, amdsmi_interface.AmdSmiVoltageMetric.CURRENT)
|
||||
|
||||
if self.logger.is_human_readable_format():
|
||||
unit = 'mV'
|
||||
volt_metric = f"{volt_metric} {unit}"
|
||||
|
||||
values_dict['voltage'] = volt_metric
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
values_dict['voltage'] = e.get_error_info()
|
||||
if not self.all_arguments:
|
||||
raise e
|
||||
if args.fan:
|
||||
try:
|
||||
fan_speed = amdsmi_interface.amdsmi_get_gpu_fan_speed(args.gpu, 0)
|
||||
@@ -1002,8 +1033,6 @@ class AMDSMICommands():
|
||||
values_dict['overdrive'] = e.get_error_info()
|
||||
if not self.all_arguments:
|
||||
raise e
|
||||
if args.mem_overdrive:
|
||||
values_dict['mem_overdrive'] = amdsmi_exception.AmdSmiLibraryException(amdsmi_exception.AmdSmiRetCode.STATUS_NOT_YET_IMPLEMENTED).err_info
|
||||
if args.perf_level:
|
||||
try:
|
||||
perf_level = amdsmi_interface.amdsmi_get_gpu_perf_level(args.gpu)
|
||||
@@ -1405,18 +1434,17 @@ class AMDSMICommands():
|
||||
dest_gpu_key = f'gpu_{dest_gpu_id}'
|
||||
|
||||
if src_gpu == dest_gpu:
|
||||
src_gpu_link_type[dest_gpu_key] = 0
|
||||
src_gpu_link_type[dest_gpu_key] = "SELF"
|
||||
continue
|
||||
|
||||
try:
|
||||
link_type = amdsmi_interface.amdsmi_topo_get_link_type(src_gpu, dest_gpu)['type']
|
||||
if isinstance(link_type, int):
|
||||
if link_type == 1:
|
||||
if link_type == amdsmi_interface.amdsmi_wrapper.AMDSMI_IOLINK_TYPE_UNDEFINED:
|
||||
src_gpu_link_type[dest_gpu_key] = "UNKNOWN"
|
||||
elif link_type == amdsmi_interface.amdsmi_wrapper.AMDSMI_IOLINK_TYPE_PCIEXPRESS:
|
||||
src_gpu_link_type[dest_gpu_key] = "PCIE"
|
||||
elif link_type == 2:
|
||||
src_gpu_link_type[dest_gpu_key] = "XMGI"
|
||||
else:
|
||||
src_gpu_link_type[dest_gpu_key] = "XXXX"
|
||||
elif link_type == amdsmi_interface.amdsmi_wrapper.AMDSMI_IOLINK_TYPE_XGMI:
|
||||
src_gpu_link_type[dest_gpu_key] = "XGMI"
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
src_gpu_link_type[dest_gpu_key] = e.get_error_info()
|
||||
|
||||
@@ -1464,30 +1492,16 @@ class AMDSMICommands():
|
||||
self.logger.print_output(multiple_device_enabled=True)
|
||||
|
||||
|
||||
def set_value(self, args, multiple_devices=False, gpu=None, clock=None, sclk=None, mclk=None,
|
||||
pcie=None, slevel=None, mlevel=None, vc=None, srange=None, mrange=None,
|
||||
fan=None, perflevel=None, overdrive=None, memoverdrive=None,
|
||||
poweroverdrive=None, profile=None, perfdeterminism=None):
|
||||
def set_value(self, args, multiple_devices=False, gpu=None, fan=None, perflevel=None,
|
||||
profile=None, perfdeterminism=None):
|
||||
"""Issue reset commands to target gpu(s)
|
||||
|
||||
Args:
|
||||
args (Namespace): Namespace containing the parsed CLI args
|
||||
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.
|
||||
clock ((amdsmi_interface.AmdSmiClkType, int), optional): Value override for args.clock. Defaults to None.
|
||||
sclk (int, optional): Value override for args.sclk. Defaults to None.
|
||||
mclk (int, optional): Value override for args.mclk. Defaults to None.
|
||||
pcie (int, optional): Value override for args.pcie. Defaults to None.
|
||||
slevel ((amdsmi_interface.AmdSmiFreqInd), int), optional): Value override for args.slevel. Defaults to None.
|
||||
mlevel ((amdsmi_interface.AmdSmiFreqInd), optional): Value override for args.mlevel. Defaults to None.
|
||||
vc ((int, int, int), optional): Value override for args.vc. Defaults to None.
|
||||
srange ((int, int), optional): Value override for args.srange. Defaults to None.
|
||||
mrange ((int, int), optional): Value override for args.mrange. 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.
|
||||
overdrive (int, optional): Value override for args.overdrive. Defaults to None.
|
||||
memoverdrive (int, optional): Value override for args.memoverdrive. Defaults to None.
|
||||
poweroverdrive (int, optional): Value override for args.poweroverdrive. 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.
|
||||
|
||||
@@ -1501,34 +1515,10 @@ class AMDSMICommands():
|
||||
# Set args.* to passed in arguments
|
||||
if gpu:
|
||||
args.gpu = gpu
|
||||
if clock:
|
||||
args.clock = clock
|
||||
if sclk:
|
||||
args.sclk = sclk
|
||||
if mclk:
|
||||
args.mclk = mclk
|
||||
if pcie:
|
||||
args.pcie = pcie
|
||||
if slevel:
|
||||
args.slevel = slevel
|
||||
if mlevel:
|
||||
args.mlevel = mlevel
|
||||
if vc:
|
||||
args.vc = vc
|
||||
if srange:
|
||||
args.srange = srange
|
||||
if mrange:
|
||||
args.mrange = mrange
|
||||
if fan:
|
||||
args.fan = fan
|
||||
if perflevel:
|
||||
args.perflevel = perflevel
|
||||
if overdrive:
|
||||
args.overdrive = overdrive
|
||||
if memoverdrive:
|
||||
args.memoverdrive = memoverdrive
|
||||
if poweroverdrive:
|
||||
args.poweroverdrive = poweroverdrive
|
||||
if profile:
|
||||
args.profile = profile
|
||||
if perfdeterminism:
|
||||
@@ -1557,178 +1547,6 @@ class AMDSMICommands():
|
||||
gpu_string = f"GPU ID: {gpu_id} BDF:{gpu_bdf}"
|
||||
|
||||
# Handle args
|
||||
if args.clock:
|
||||
clock_type, freq_bitmask = args.clock
|
||||
|
||||
# Check if the performance level is manual, if not then set it to manual
|
||||
try:
|
||||
perf_level = amdsmi_interface.amdsmi_get_gpu_perf_level(args.gpu)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.get_error_code() == amdsmi_exception.AmdSmiRetCode.STATUS_NO_PERM:
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
raise ValueError(f"Unable to get performance level of {gpu_string}") from e
|
||||
|
||||
if 'manual' in perf_level.lower():
|
||||
try:
|
||||
amdsmi_interface.amdsmi_set_gpu_perf_level(args.gpu, amdsmi_interface.AmdSmiDevPerfLevel.MANUAL)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.get_error_code() == amdsmi_exception.AmdSmiRetCode.STATUS_NO_PERM:
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
raise ValueError(f"Unable to set the performance level of {gpu_string} to manual") from e
|
||||
|
||||
if clock_type != amdsmi_interface.AmdSmiClkType.PCIE:
|
||||
try:
|
||||
amdsmi_interface.amdsmi_set_clk_freq(args.gpu, clock_type, freq_bitmask)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.get_error_code() == amdsmi_exception.AmdSmiRetCode.STATUS_NO_PERM:
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
raise ValueError(f"Unable to set the {clock_type} clock frequency on {gpu_string}") from e
|
||||
else:
|
||||
try:
|
||||
amdsmi_interface.amdsmi_set_gpu_pci_bandwidth(args.gpu, freq_bitmask)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.get_error_code() == amdsmi_exception.AmdSmiRetCode.STATUS_NO_PERM:
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
raise ValueError(f"Unable to set the {clock_type} clock frequency on {gpu_string}") from e
|
||||
|
||||
self.logger.store_output(args.gpu, 'clock', f'Successfully set clock frequency bitmask for {clock_type}')
|
||||
if isinstance(args.sclk, int):
|
||||
freq_bitmask = args.sclk
|
||||
clock_type = amdsmi_interface.AmdSmiClkType.SYS
|
||||
# Check if the performance level is manual, if not then set it to manual
|
||||
try:
|
||||
perf_level = amdsmi_interface.amdsmi_get_gpu_perf_level(args.gpu)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.get_error_code() == amdsmi_exception.AmdSmiRetCode.STATUS_NO_PERM:
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
raise ValueError(f"Unable to get performance level of {gpu_string}") from e
|
||||
|
||||
if 'manual' in perf_level.lower():
|
||||
try:
|
||||
amdsmi_interface.amdsmi_set_gpu_perf_level(args.gpu, amdsmi_interface.AmdSmiDevPerfLevel.MANUAL)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.get_error_code() == amdsmi_exception.AmdSmiRetCode.STATUS_NO_PERM:
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
raise ValueError(f"Unable to set the performance level of {gpu_string} to manual") from e
|
||||
|
||||
try:
|
||||
amdsmi_interface.amdsmi_set_clk_freq(args.gpu, clock_type, freq_bitmask)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.get_error_code() == amdsmi_exception.AmdSmiRetCode.STATUS_NO_PERM:
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
raise ValueError(f"Unable to set the {clock_type} clock frequency on {gpu_string}") from e
|
||||
|
||||
self.logger.store_output(args.gpu, 'sclk', 'Successfully set clock frequency bitmask')
|
||||
if isinstance(args.mclk, int):
|
||||
freq_bitmask = args.mclk
|
||||
clock_type = amdsmi_interface.AmdSmiClkType.MEM
|
||||
# Check if the performance level is manual, if not then set it to manual
|
||||
try:
|
||||
perf_level = amdsmi_interface.amdsmi_get_gpu_perf_level(args.gpu)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.get_error_code() == amdsmi_exception.AmdSmiRetCode.STATUS_NO_PERM:
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
raise ValueError(f"Unable to get performance level of {gpu_string}") from e
|
||||
|
||||
if 'manual' in perf_level.lower():
|
||||
try:
|
||||
amdsmi_interface.amdsmi_set_gpu_perf_level(args.gpu, amdsmi_interface.AmdSmiDevPerfLevel.MANUAL)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.get_error_code() == amdsmi_exception.AmdSmiRetCode.STATUS_NO_PERM:
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
raise ValueError(f"Unable to set the performance level of {gpu_string} to manual") from e
|
||||
|
||||
try:
|
||||
amdsmi_interface.amdsmi_set_clk_freq(args.gpu, clock_type, freq_bitmask)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.get_error_code() == amdsmi_exception.AmdSmiRetCode.STATUS_NO_PERM:
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
raise ValueError(f"Unable to set the {clock_type} clock frequency on {gpu_string}") from e
|
||||
|
||||
self.logger.store_output(args.gpu, 'mclk', 'Successfully set clock frequency bitmask')
|
||||
if isinstance(args.pcie, int):
|
||||
freq_bitmask = args.pcie
|
||||
clock_type = amdsmi_interface.AmdSmiClkType.PCIE
|
||||
# Check if the performance level is manual, if not then set it to manual
|
||||
try:
|
||||
perf_level = amdsmi_interface.amdsmi_get_gpu_perf_level(args.gpu)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.get_error_code() == amdsmi_exception.AmdSmiRetCode.STATUS_NO_PERM:
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
raise ValueError(f"Unable to get performance level of {gpu_string}") from e
|
||||
|
||||
if 'manual' in perf_level.lower():
|
||||
try:
|
||||
amdsmi_interface.amdsmi_set_gpu_perf_level(args.gpu, amdsmi_interface.AmdSmiDevPerfLevel.MANUAL)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.get_error_code() == amdsmi_exception.AmdSmiRetCode.STATUS_NO_PERM:
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
raise ValueError(f"Unable to set the performance level of {gpu_string} to manual") from e
|
||||
try:
|
||||
amdsmi_interface.amdsmi_set_gpu_pci_bandwidth(args.gpu, freq_bitmask)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.get_error_code() == amdsmi_exception.AmdSmiRetCode.STATUS_NO_PERM:
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
raise ValueError(f"Unable to set the {clock_type} clock frequency on {gpu_string}") from e
|
||||
|
||||
self.logger.store_output(args.gpu, 'pcie', 'Successfully set clock frequency bitmask')
|
||||
if isinstance(args.slevel, int):
|
||||
|
||||
level, value = args.slevel
|
||||
level = amdsmi_interface.AmdSmiFreqInd(level)
|
||||
clock_type = amdsmi_interface.AmdSmiClkType.SYS
|
||||
try:
|
||||
amdsmi_interface.amdsmi_set_gpu_od_clk_info(args.gpu, level, value, clock_type)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.get_error_code() == amdsmi_exception.AmdSmiRetCode.STATUS_NO_PERM:
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
raise ValueError(f"Unable to change the {clock_type} clock frequency in the PowerPlay table on {gpu_string}") from e
|
||||
|
||||
self.logger.store_output(args.gpu, 'slevel', 'Successfully changed clock frequency')
|
||||
if isinstance(args.mlevel, int):
|
||||
level, value = args.mlevel
|
||||
level = amdsmi_interface.AmdSmiFreqInd(level)
|
||||
clock_type = amdsmi_interface.AmdSmiClkType.MEM
|
||||
try:
|
||||
amdsmi_interface.amdsmi_set_gpu_od_clk_info(args.gpu, level, value, clock_type)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.get_error_code() == amdsmi_exception.AmdSmiRetCode.STATUS_NO_PERM:
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
raise ValueError(f"Unable to change the {clock_type} clock frequency in the PowerPlay table on {gpu_string}") from e
|
||||
|
||||
self.logger.store_output(args.gpu, 'mlevel', 'Successfully changed clock frequency')
|
||||
if isinstance(args.vc, int):
|
||||
point, clk, volt = args.vc
|
||||
try:
|
||||
amdsmi_interface.amdsmi_set_gpu_od_volt_info(args.gpu, point, clk, volt)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.get_error_code() == amdsmi_exception.AmdSmiRetCode.STATUS_NO_PERM:
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
raise ValueError(f"Unable to set the Voltage Curve point {point} to {clk}(MHz) {volt}(mV) on {gpu_string}") from e
|
||||
|
||||
self.logger.store_output(args.gpu, 'vc', f'Successfully set voltage point {point} to {clk}(MHz) {volt}(mV)')
|
||||
if isinstance(args.srange, int):
|
||||
min_value, max_value = args.srange
|
||||
clock_type = amdsmi_interface.AmdSmiClkType.SYS
|
||||
try:
|
||||
amdsmi_interface.amdsmi_set_gpu_clk_range(args.gpu, min_value, max_value, clock_type)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.get_error_code() == amdsmi_exception.AmdSmiRetCode.STATUS_NO_PERM:
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
raise ValueError(f"Unable to set {clock_type} from {min_value}(MHz) to {max_value}(MHz) on {gpu_string}") from e
|
||||
|
||||
self.logger.store_output(args.gpu, 'srange', f"Successfully set {clock_type} from {min_value}(MHz) to {max_value}(MHz)")
|
||||
if isinstance(args.mrange, int):
|
||||
min_value, max_value = args.srange
|
||||
clock_type = amdsmi_interface.AmdSmiClkType.MEM
|
||||
try:
|
||||
amdsmi_interface.amdsmi_set_gpu_clk_range(args.gpu, min_value, max_value, clock_type)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.get_error_code() == amdsmi_exception.AmdSmiRetCode.STATUS_NO_PERM:
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
raise ValueError(f"Unable to set {clock_type} from {min_value}(MHz) to {max_value}(MHz) on {gpu_string}") from e
|
||||
|
||||
self.logger.store_output(args.gpu, 'mrange', f"Successfully set {clock_type} from {min_value}(MHz) to {max_value}(MHz)")
|
||||
if isinstance(args.fan, int):
|
||||
try:
|
||||
amdsmi_interface.amdsmi_set_gpu_fan_speed(args.gpu, 0, args.fan)
|
||||
@@ -1748,89 +1566,6 @@ class AMDSMICommands():
|
||||
raise ValueError(f"Unable to set performance level {args.perflevel} on {gpu_string}") from e
|
||||
|
||||
self.logger.store_output(args.gpu, 'perflevel', f"Successfully set performance level {args.perflevel}")
|
||||
if isinstance(args.overdrive, int):
|
||||
# Check if the performance level is manual, if not then set it to manual
|
||||
try:
|
||||
perf_level = amdsmi_interface.amdsmi_get_gpu_perf_level(args.gpu)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.get_error_code() == amdsmi_exception.AmdSmiRetCode.STATUS_NO_PERM:
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
raise ValueError(f"Unable to get performance level of {gpu_string}") from e
|
||||
|
||||
if 'manual' in perf_level.lower():
|
||||
try:
|
||||
amdsmi_interface.amdsmi_set_gpu_perf_level(args.gpu, amdsmi_interface.AmdSmiDevPerfLevel.MANUAL)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.get_error_code() == amdsmi_exception.AmdSmiRetCode.STATUS_NO_PERM:
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
raise ValueError(f"Unable to set the performance level of {gpu_string} to manual") from e
|
||||
|
||||
try:
|
||||
amdsmi_interface.amdsmi_set_gpu_overdrive_level(args.gpu, args.overdrive)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.get_error_code() == amdsmi_exception.AmdSmiRetCode.STATUS_NO_PERM:
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
raise ValueError(f"Unable to set overdrive {args.overdrive} to {gpu_string}") from e
|
||||
|
||||
self.logger.store_output(args.gpu, 'overdrive', f"Successfully to set overdrive level to {args.overdrive}")
|
||||
if isinstance(args.memoverdrive, int):
|
||||
# Check if the performance level is manual, if not then set it to manual
|
||||
try:
|
||||
perf_level = amdsmi_interface.amdsmi_get_gpu_perf_level(args.gpu)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.get_error_code() == amdsmi_exception.AmdSmiRetCode.STATUS_NO_PERM:
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
raise ValueError(f"Unable to get performance level of {gpu_string}") from e
|
||||
|
||||
if 'manual' in perf_level.lower():
|
||||
try:
|
||||
amdsmi_interface.amdsmi_set_gpu_perf_level(args.gpu, amdsmi_interface.AmdSmiDevPerfLevel.MANUAL)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.get_error_code() == amdsmi_exception.AmdSmiRetCode.STATUS_NO_PERM:
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
raise ValueError(f"Unable to set the performance level of {gpu_string} to manual") from e
|
||||
|
||||
self.logger.store_output(args.gpu, 'memoverdrive', f"Successfully to set memoverdrive level to {args.memoverdrive}")
|
||||
if isinstance(args.poweroverdrive, int):
|
||||
overdrive_power_cap = args.poweroverdrive
|
||||
try:
|
||||
power_caps = amdsmi_interface.amdsmi_get_power_cap_info(args.gpu)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.get_error_code() == amdsmi_exception.AmdSmiRetCode.STATUS_NO_PERM:
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
raise ValueError(f"Unable to get the power cap info for {gpu_string}") from e
|
||||
if overdrive_power_cap == 0:
|
||||
overdrive_power_cap = power_caps['default_power_cap']
|
||||
else:
|
||||
overdrive_power_cap *= 1000000
|
||||
|
||||
if overdrive_power_cap < power_caps['min_power_cap']:
|
||||
raise ValueError(f"Requested power cap: {overdrive_power_cap} is lower than the min power cap: {power_caps['min_power_cap']}")
|
||||
|
||||
if overdrive_power_cap > power_caps['max_power_cap']:
|
||||
raise ValueError(f"Requested power cap: {overdrive_power_cap} is greater than the max power cap: {power_caps['max_power_cap']}")
|
||||
|
||||
if overdrive_power_cap == power_caps['power_cap']:
|
||||
raise ValueError(f"Requested power cap: {overdrive_power_cap} is the same as the current power cap: {power_caps['power_cap']}")
|
||||
|
||||
try:
|
||||
amdsmi_interface.amdsmi_set_power_cap(args.gpu, 0, overdrive_power_cap)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.get_error_code() == amdsmi_exception.AmdSmiRetCode.STATUS_NO_PERM:
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
raise ValueError(f"Unable to set power cap to {overdrive_power_cap} on {gpu_string}") from e
|
||||
|
||||
try:
|
||||
power_caps = amdsmi_interface.amdsmi_get_power_cap_info(args.gpu)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
if e.get_error_code() == amdsmi_exception.AmdSmiRetCode.STATUS_NO_PERM:
|
||||
raise PermissionError('Command requires elevation') from e
|
||||
raise ValueError(f"Unable to get the power cap info for {gpu_string} post set") from e
|
||||
|
||||
if power_caps['power_cap'] == overdrive_power_cap:
|
||||
self.logger.store_output(args.gpu, 'power_cap', f"Successfully set the power cap {overdrive_power_cap}")
|
||||
else:
|
||||
raise ValueError(f"Power cap: {overdrive_power_cap} set failed on {gpu_string}")
|
||||
if args.profile:
|
||||
self.logger.store_output(args.gpu, 'profile', "Not Yet Implemented")
|
||||
if isinstance(args.perfdeterminism, int):
|
||||
@@ -1851,8 +1586,7 @@ class AMDSMICommands():
|
||||
|
||||
|
||||
def reset(self, args, multiple_devices=False, gpu=None, gpureset=None,
|
||||
clocks=None, fans=None, profile=None,
|
||||
poweroverdrive=None, xgmierr=None, perfdeterminism=None):
|
||||
clocks=None, fans=None, profile=None, xgmierr=None, perfdeterminism=None):
|
||||
"""Issue reset commands to target gpu(s)
|
||||
|
||||
Args:
|
||||
@@ -1863,7 +1597,6 @@ class AMDSMICommands():
|
||||
clocks (bool, optional): Value override for args.clocks. Defaults to None.
|
||||
fans (bool, optional): Value override for args.fans. Defaults to None.
|
||||
profile (bool, optional): Value override for args.profile. Defaults to None.
|
||||
poweroverdrive (bool, optional): Value override for args.poweroverdrive. 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.
|
||||
|
||||
@@ -1885,8 +1618,6 @@ class AMDSMICommands():
|
||||
args.fans = fans
|
||||
if profile:
|
||||
args.profile = profile
|
||||
if poweroverdrive:
|
||||
args.poweroverdrive = poweroverdrive
|
||||
if xgmierr:
|
||||
args.xgmierr = xgmierr
|
||||
if perfdeterminism:
|
||||
|
||||
@@ -25,7 +25,6 @@ import platform
|
||||
import sys
|
||||
import time
|
||||
|
||||
from pathlib import Path
|
||||
from subprocess import run
|
||||
from subprocess import PIPE, STDOUT
|
||||
|
||||
@@ -152,7 +151,7 @@ class AMDSMIHelpers():
|
||||
"UUID": uuid,
|
||||
"Device Handle": device_handle,
|
||||
}
|
||||
gpu_choices_str += f"ID:{gpu_id:<2} | BDF:{bdf} | UUID:{uuid}"
|
||||
gpu_choices_str += f"ID:{gpu_id:<2} | BDF:{bdf} | UUID:{uuid}\n"
|
||||
|
||||
return (gpu_choices, gpu_choices_str)
|
||||
|
||||
|
||||
+11
-33
@@ -127,6 +127,15 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
path.touch()
|
||||
setattr(args, self.dest, path)
|
||||
elif path.is_file():
|
||||
file_name = str(path)
|
||||
if args.json and str(path).split('.')[-1].lower() != 'json':
|
||||
file_name += ".json"
|
||||
elif args.csv and str(path).split('.')[-1].lower() != 'csv':
|
||||
file_name += ".csv"
|
||||
elif str(path).split('.')[-1].lower() != 'txt':
|
||||
file_name += ".txt"
|
||||
path = Path(file_name)
|
||||
path.touch()
|
||||
setattr(args, self.dest, path)
|
||||
else:
|
||||
raise amdsmi_cli_exceptions.AmdSmiInvalidFilePathException(path, CheckOutputFilePath.outputformat)
|
||||
@@ -415,13 +424,11 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
ecc_help = "Number of ECC errors"
|
||||
ecc_block_help = "Number of ECC errors per block"
|
||||
pcie_help = "Current PCIe speed and width"
|
||||
voltage_help = "Current GPU voltages"
|
||||
|
||||
# Help text for Arguments only on Linux Baremetal platforms
|
||||
fan_help = "Current fan speed"
|
||||
vc_help = "Display voltage curve"
|
||||
overdrive_help = "Current GPU clock overdrive level"
|
||||
mo_help = "Current memory clock overdrive level"
|
||||
perf_level_help = "Current DPM performance level"
|
||||
replay_count_help = "PCIe replay count"
|
||||
xgmi_err_help = "XGMI error information since last read"
|
||||
@@ -450,7 +457,6 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
if self.helpers.is_virtual_os() or self.helpers.is_baremetal():
|
||||
metric_parser.add_argument('-b', '--fb-usage', action='store_true', required=False, help=fb_usage_help)
|
||||
metric_parser.add_argument('-m', '--mem-usage', action='store_true', required=False, help=mem_usage_help)
|
||||
metric_parser.add_argument('-r', '--replay-count', action='store_true', required=False, help=replay_count_help)
|
||||
|
||||
# Optional Args for Hypervisors and Baremetal systems
|
||||
if self.helpers.is_hypervisor() or self.helpers.is_baremetal():
|
||||
@@ -459,9 +465,8 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
metric_parser.add_argument('-t', '--temperature', action='store_true', required=False, help=temperature_help)
|
||||
metric_parser.add_argument('-e', '--ecc', action='store_true', required=False, help=ecc_help)
|
||||
metric_parser.add_argument('-k', '--ecc-block', action='store_true', required=False, help=ecc_block_help)
|
||||
|
||||
metric_parser.add_argument('-r', '--replay-count', action='store_true', required=False, help=replay_count_help)
|
||||
metric_parser.add_argument('-P', '--pcie', action='store_true', required=False, help=pcie_help)
|
||||
metric_parser.add_argument('-V', '--voltage', action='store_true', required=False, help=voltage_help)
|
||||
metric_parser.add_argument('-u', '--usage', action='store_true', required=False, help=usage_help)
|
||||
|
||||
# Optional Args for Linux Baremetal Systems
|
||||
@@ -469,7 +474,6 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
metric_parser.add_argument('-f', '--fan', action='store_true', required=False, help=fan_help)
|
||||
metric_parser.add_argument('-C', '--voltage-curve', action='store_true', required=False, help=vc_help)
|
||||
metric_parser.add_argument('-o', '--overdrive', action='store_true', required=False, help=overdrive_help)
|
||||
metric_parser.add_argument('-M', '--mem-overdrive', action='store_true', required=False, help=mo_help)
|
||||
metric_parser.add_argument('-l', '--perf-level', action='store_true', required=False, help=perf_level_help)
|
||||
metric_parser.add_argument('-x', '--xgmi-err', action='store_true', required=False, help=xgmi_err_help)
|
||||
metric_parser.add_argument('-E', '--energy', action='store_true', required=False, help=energy_help)
|
||||
@@ -544,7 +548,7 @@ 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 BareMetal & Linux Hypervisors, NOT Linux Guest
|
||||
# This subparser only applies to Linux Hypervisors, NOT Linux Guest
|
||||
return
|
||||
|
||||
# Subparser help text
|
||||
@@ -611,20 +615,8 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
set_value_optionals_title = "Set Arguments"
|
||||
|
||||
# Help text for Arguments only on Guest and BM platforms
|
||||
set_clock_help = "Sets clock frequency levels for specified clocks"
|
||||
set_sclk_help = "Sets GPU clock frequency levels"
|
||||
set_mclk_help = "Sets memory clock frequency levels"
|
||||
set_pcie_help = "Sets PCIe Bandwith"
|
||||
set_slevel_help = "Change GPU clock frequency and voltage for a specific level"
|
||||
set_mlevel_help = "Change GPU memory frequency and voltage for a specific level"
|
||||
set_vc_help = "Change SCLK voltage curve for a specified point"
|
||||
set_srange_help = "Sets min and max SCLK speed"
|
||||
set_mrange_help = "Sets min and max MCLK speed"
|
||||
set_fan_help = "Sets GPU fan speed (0-255 or 0-100%%)"
|
||||
set_perf_level_help = "Sets performance level"
|
||||
set_overdrive_help = "Set GPU overdrive (0-20%%) ***DEPRECATED IN NEWER KERNEL VERSIONS (use --slevel instead)***"
|
||||
set_mem_overdrive_help = "Set memory overclock overdrive level ***DEPRECATED IN NEWER KERNEL VERSIONS (use --mlevel instead)***"
|
||||
set_power_overdrive_help = "Set the maximum GPU power using power overdrive in Watts"
|
||||
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"
|
||||
|
||||
@@ -639,20 +631,8 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
self._add_device_arguments(set_value_parser, required=True)
|
||||
|
||||
# Optional Args
|
||||
set_value_parser.add_argument('-c', '--clock', action=self._validate_set_clock(True), nargs='+', required=False, help=set_clock_help, metavar=('CLK_TYPE', 'CLK_LEVELS'))
|
||||
set_value_parser.add_argument('-s', '--sclk', action=self._validate_set_clock(False), nargs='+', type=self._positive_int, required=False, help=set_sclk_help, metavar='CLK_LEVELS')
|
||||
set_value_parser.add_argument('-m', '--mclk', action=self._validate_set_clock(False), nargs='+', type=self._positive_int, required=False, help=set_mclk_help, metavar='CLK_LEVELS')
|
||||
set_value_parser.add_argument('-p', '--pcie', action=self._validate_set_clock(False), nargs='+', type=self._positive_int, required=False, help=set_pcie_help, metavar='CLK_LEVELS')
|
||||
set_value_parser.add_argument('-S', '--slevel', action=self._prompt_spec_warning(), nargs=2, type=self._positive_int, required=False, help=set_slevel_help, metavar=('SCLKLEVEL', 'SCLK'))
|
||||
set_value_parser.add_argument('-M', '--mlevel', action=self._prompt_spec_warning(), nargs=2, type=self._positive_int, required=False, help=set_mlevel_help, metavar=('MCLKLEVEL', 'MCLK'))
|
||||
set_value_parser.add_argument('-V', '--vc', action=self._prompt_spec_warning(), nargs=3, type=self._positive_int, required=False, help=set_vc_help, metavar=('POINT', 'SCLK', 'SVOLT'))
|
||||
set_value_parser.add_argument('-r', '--srange', action=self._prompt_spec_warning(), nargs=2, type=self._positive_int, required=False, help=set_srange_help, metavar=('SCLKMIN', 'SCLKMAX'))
|
||||
set_value_parser.add_argument('-R', '--mrange', action=self._prompt_spec_warning(), nargs=2, type=self._positive_int, required=False, help=set_mrange_help, metavar=('MCLKMIN', 'MCLKMAX'))
|
||||
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('-o', '--overdrive', action=self._validate_overdrive_percent(), required=False, help=set_overdrive_help, metavar='%')
|
||||
set_value_parser.add_argument('-O', '--memoverdrive', action=self._validate_overdrive_percent(), required=False, help=set_mem_overdrive_help, metavar='%')
|
||||
set_value_parser.add_argument('-w', '--poweroverdrive', action=self._prompt_spec_warning(), type=self._positive_int, required=False, help=set_power_overdrive_help, metavar="WATTS")
|
||||
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')
|
||||
|
||||
@@ -766,7 +746,6 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
resetclocks_help = "Reset clocks and overdrive to default"
|
||||
resetfans_help = "Reset fans to automatic (driver) control"
|
||||
resetprofile_help = "Reset power profile back to default"
|
||||
resetpoweroverdrive_help = "Set the maximum GPU power back to the device default state"
|
||||
resetxgmierr_help = "Reset XGMI error counts"
|
||||
resetperfdet_help = "Disable performance determinism"
|
||||
|
||||
@@ -785,7 +764,6 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
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('-o', '--poweroverdrive', action='store_true', required=False, help=resetpoweroverdrive_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)
|
||||
|
||||
|
||||
+1
-1
@@ -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.1.1.0"
|
||||
PROJECT_NUMBER = "23.2.1.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
|
||||
|
||||
@@ -27,3 +27,10 @@ set(SMI_NODRM_EXAMPLE_EXE "amd_smi_nodrm_ex")
|
||||
add_executable(${SMI_NODRM_EXAMPLE_EXE} "amd_smi_nodrm_example.cc")
|
||||
target_link_libraries(${SMI_NODRM_EXAMPLE_EXE} ${AMD_SMI_TARGET})
|
||||
add_dependencies(${SMI_NODRM_EXAMPLE_EXE} ${AMD_SMI_TARGET})
|
||||
|
||||
if(ENABLE_ESMI_LIB)
|
||||
set(ESMI_SAMPLE_EXE "amd_smi_esmi_ex")
|
||||
add_executable(${ESMI_SAMPLE_EXE} "amdsmi_esmi_intg_example.cc")
|
||||
target_link_libraries(${ESMI_SAMPLE_EXE} ${AMD_SMI_TARGET})
|
||||
add_dependencies(${ESMI_SAMPLE_EXE} ${AMD_SMI_TARGET})
|
||||
endif()
|
||||
|
||||
@@ -21,3 +21,6 @@ link_libraries(amd_smi)
|
||||
# compile example files but do not install
|
||||
add_executable(amd_smi_drm_ex "amd_smi_drm_example.cc")
|
||||
add_executable(amd_smi_nodrm_ex "amd_smi_nodrm_example.cc")
|
||||
if(ENABLE_ESMI_LIB)
|
||||
add_executable(amd_smi_esmi_ex "amdsmi_esmi_intg_example.cc")
|
||||
endif()
|
||||
|
||||
@@ -377,6 +377,7 @@ int main() {
|
||||
printf(" Output of amdsmi_get_pcie_link_status:\n");
|
||||
printf("\tPCIe lanes: %d\n", pcie_info.pcie_lanes);
|
||||
printf("\tPCIe speed: %d\n\n", pcie_info.pcie_speed);
|
||||
printf("\tPCIe Interface Version: %d\n\n", pcie_info.pcie_interface_version);
|
||||
|
||||
// Get PCIe caps
|
||||
amdsmi_pcie_info_t pcie_caps_info = {};
|
||||
@@ -385,6 +386,7 @@ int main() {
|
||||
printf(" Output of amdsmi_get_pcie_link_caps:\n");
|
||||
printf("\tPCIe max lanes: %d\n", pcie_caps_info.pcie_lanes);
|
||||
printf("\tPCIe max speed: %d\n\n", pcie_caps_info.pcie_speed);
|
||||
printf("\tPCIe Interface Version: %d\n\n", pcie_caps_info.pcie_interface_version);
|
||||
|
||||
// Get VRAM temperature limit
|
||||
int64_t temperature = 0;
|
||||
|
||||
@@ -0,0 +1,313 @@
|
||||
/*
|
||||
* =============================================================================
|
||||
* The University of Illinois/NCSA
|
||||
* Open Source License (NCSA)
|
||||
*
|
||||
* Copyright (c) 2022, Advanced Micro Devices, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Developed by:
|
||||
*
|
||||
* AMD Research and AMD ROC Software Development
|
||||
*
|
||||
* Advanced Micro Devices, Inc.
|
||||
*
|
||||
* www.amd.com
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal with the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimers.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimers in
|
||||
* the documentation and/or other materials provided with the distribution.
|
||||
* - Neither the names of <Name of Development Group, Name of Institution>,
|
||||
* nor the names of its contributors may be used to endorse or promote
|
||||
* products derived from this Software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS WITH THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <bitset>
|
||||
#include <iomanip>
|
||||
#include "amd_smi/amdsmi.h"
|
||||
#include <cstring>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define SHOWLINESZ 256
|
||||
|
||||
#define CHK_AMDSMI_RET(RET) \
|
||||
{ \
|
||||
if (RET != AMDSMI_STATUS_SUCCESS) { \
|
||||
const char *err_str; \
|
||||
std::cout << "AMDSMI call returned " << RET << " at line " \
|
||||
<< __LINE__ << std::endl; \
|
||||
amdsmi_status_code_to_string(RET, &err_str); \
|
||||
std::cout << err_str << std::endl; \
|
||||
return RET; \
|
||||
} \
|
||||
}
|
||||
|
||||
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);
|
||||
CHK_AMDSMI_RET(ret)
|
||||
|
||||
// Get all sockets
|
||||
uint32_t socket_count = 0;
|
||||
|
||||
ret = amdsmi_get_cpusocket_handles(&socket_count, nullptr);
|
||||
CHK_AMDSMI_RET(ret)
|
||||
|
||||
// Allocate the memory for the sockets
|
||||
std::vector<amdsmi_cpusocket_handle> sockets(socket_count);
|
||||
|
||||
// Get the sockets of the system
|
||||
ret = amdsmi_get_cpusocket_handles(&socket_count, &sockets[0]);
|
||||
CHK_AMDSMI_RET(ret)
|
||||
|
||||
std::cout << "Total Socket: " << socket_count << std::endl;
|
||||
|
||||
// For each socket, get identifier and cores
|
||||
for (uint32_t i = 0; i < socket_count; i++) {
|
||||
// Get Socket info
|
||||
uint32_t socket_info;
|
||||
ret = amdsmi_get_cpusocket_info(sockets[i], socket_info);
|
||||
CHK_AMDSMI_RET(ret)
|
||||
std::cout << "Socket " << socket_info << std::endl;
|
||||
|
||||
// Get the core count available for the socket.
|
||||
uint32_t core_count = 0;
|
||||
ret = amdsmi_get_cpucore_handles(sockets[i], &core_count, nullptr);
|
||||
CHK_AMDSMI_RET(ret)
|
||||
|
||||
// Allocate the memory for the cpu core handles on the socket
|
||||
std::vector<amdsmi_processor_handle> processor_handles(core_count);
|
||||
// Get all cores of the socket
|
||||
ret = amdsmi_get_cpucore_handles(sockets[i],
|
||||
&core_count, &processor_handles[0]);
|
||||
CHK_AMDSMI_RET(ret)
|
||||
std::cout << "core_count=" << core_count << std::endl;
|
||||
|
||||
ret = amdsmi_get_hsmp_proto_ver(&proto_ver);
|
||||
CHK_AMDSMI_RET(ret)
|
||||
|
||||
cout<<"\n------------------------------------------";
|
||||
cout<<"\n| HSMP Proto Version | "<< proto_ver <<"\t\t |"<< endl;
|
||||
cout<<"------------------------------------------\n";
|
||||
|
||||
ret = amdsmi_get_smu_fw_version(&smu_fw);
|
||||
CHK_AMDSMI_RET(ret)
|
||||
|
||||
cout<<"\n------------------------------------------";
|
||||
cout<<"\n| SMU FW Version | "
|
||||
<<(unsigned)smu_fw.major<<"."
|
||||
<<(unsigned)smu_fw.minor<<"."
|
||||
<<(unsigned)smu_fw.debug
|
||||
<<"\t\t |"<<endl;
|
||||
cout<<"------------------------------------------\n";
|
||||
|
||||
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<<setprecision(3)<<" Socket "<<i<<"\t|";
|
||||
}
|
||||
cout<<"\n-------------------------------------------------";
|
||||
cout<<"\n| Energy (K Joules)\t\t | ";
|
||||
|
||||
ret = amdsmi_get_cpu_socket_energy(sockets[i], i, &pkg_input);
|
||||
CHK_AMDSMI_RET(ret)
|
||||
|
||||
if (!ret) {
|
||||
cout<<setprecision(7)<<static_cast<double>(pkg_input)/1000000000<<"\t|";
|
||||
} else {
|
||||
err_bits |= 1 << ret;
|
||||
cout<<" NA (Err:" <<ret<<" |";
|
||||
}
|
||||
cout<<"\n-------------------------------------------------\n";
|
||||
|
||||
err_bits = 0;
|
||||
uint32_t prochot;
|
||||
cout<<"\n-------------------------------------------------";
|
||||
cout<<"\n| Sensor Name\t\t\t |";
|
||||
for (uint32_t i = 0; i < socket_count; i++) {
|
||||
cout<<setprecision(3)<<" Socket "<<i<<"\t|";
|
||||
}
|
||||
cout<<"\n-------------------------------------------------";
|
||||
cout<<"\n| ProchotStatus:\t\t |";
|
||||
ret = amdsmi_get_cpu_prochot_status(sockets[i], i, &prochot);
|
||||
CHK_AMDSMI_RET(ret)
|
||||
if (!ret) {
|
||||
cout<<setprecision(7)<< (prochot ? "active" : "inactive")<<"\t|";
|
||||
} else {
|
||||
err_bits |= 1 << ret;
|
||||
cout<<" NA (Err:" <<ret<<" |";
|
||||
}
|
||||
cout<<"\n-------------------------------------------------\n";
|
||||
|
||||
size_t len;
|
||||
char str[SHOWLINESZ] = {};
|
||||
int retVal = 0;
|
||||
cout<<"\n-------------------------------------------------";
|
||||
cout<<"\n| Sensor Name\t\t\t |";
|
||||
for (uint32_t i = 0; i < socket_count; i++) {
|
||||
cout<<setprecision(3)<<" Socket "<<i<<"\t|";
|
||||
}
|
||||
cout<<"\n-------------------------------------------------";
|
||||
cout<<"\n| fclk (Mhz)\t\t\t |";
|
||||
retVal = snprintf(str, SHOWLINESZ, "\n| mclk (Mhz)\t\t\t |");
|
||||
|
||||
len = strlen(str);
|
||||
uint32_t fclk, mclk, cclk;
|
||||
err_bits = 0;
|
||||
ret = amdsmi_get_cpu_fclk_mclk(sockets[i], i, &fclk, &mclk);
|
||||
CHK_AMDSMI_RET(ret)
|
||||
if (!ret) {
|
||||
cout<<setprecision(7)<<" "<<fclk<<"\t\t|";
|
||||
retVal = snprintf(str + len, SHOWLINESZ - len, " %d\t\t|", mclk);
|
||||
} else {
|
||||
err_bits |= 1 << ret;
|
||||
cout<<" NA (Err: "<<setprecision(2)<<ret<<" |";
|
||||
retVal = snprintf(str + len, SHOWLINESZ - len, " NA (Err: %-2d) |", ret);
|
||||
}
|
||||
if (retVal > 0 && retVal < SHOWLINESZ)
|
||||
cout << str;
|
||||
else
|
||||
cout <<"error writing to buffer" << endl;
|
||||
|
||||
cout<<"\n-------------------------------------------------\n";
|
||||
cout<<"-----------------------------------------------------------------";
|
||||
ret = amdsmi_get_cpu_cclk_limit(sockets[i], i, &cclk);
|
||||
CHK_AMDSMI_RET(ret)
|
||||
cout<<"\n| SOCKET["<<i<<"] core clock current frequency limit (MHz) : "<<cclk<<"\t|\n";
|
||||
cout<<"-----------------------------------------------------------------\n";
|
||||
|
||||
uint64_t core_input = 0;
|
||||
ret = amdsmi_get_cpu_core_energy(processor_handles[i], i, &core_input);
|
||||
CHK_AMDSMI_RET(ret)
|
||||
cout<<"\n-------------------------------------------------";
|
||||
cout<<"\n| core["<<i<<"] energy | "<<setprecision(7)
|
||||
<<static_cast<double>(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"<<j<<"] :";
|
||||
else
|
||||
cout<<"\n| cpu ["<<j<<"] :";
|
||||
}
|
||||
cout<<setw(8)<<right<<fixed<<setprecision(3)<<static_cast<double>(core_input)/1000000<<" ";
|
||||
if (j % 8 == 7)
|
||||
cout<<"\t|";
|
||||
}
|
||||
cout<<"\n-------------------------------------------------\n";
|
||||
|
||||
#if 0
|
||||
uint32_t c_clk = 0;
|
||||
ret = amdsmi_get_cpu_core_current_freq_limit(processor_handles[i], i, &c_clk);
|
||||
CHK_AMDSMI_RET(ret)
|
||||
|
||||
cout<<"--------------------------------------------------------------";
|
||||
cout<<"\n| CPU["<<i<<"] core clock current frequency limit (MHz) : "<<c_clk<<"\t|\n";
|
||||
cout<<"--------------------------------------------------------------\n";
|
||||
#endif
|
||||
|
||||
uint32_t power;
|
||||
cout<<"\n-------------------------------------------------";
|
||||
cout<<"\n| Sensor Name\t\t\t |";
|
||||
for (uint32_t i = 0; i < socket_count; i++) {
|
||||
cout<<setprecision(3)<<" Socket "<<i<<"\t|";
|
||||
}
|
||||
cout<<"\n-------------------------------------------------";
|
||||
cout<<"\n| Power (Watts)\t\t\t | ";
|
||||
|
||||
ret = amdsmi_get_cpu_socket_power(sockets[i], i, &power);
|
||||
CHK_AMDSMI_RET(ret)
|
||||
|
||||
if (!ret) {
|
||||
cout<<fixed<<setprecision(3)<<static_cast<double>(power)/1000<<"\t|";
|
||||
} else {
|
||||
err_bits |= 1 << ret;
|
||||
cout<<" NA (Err:" <<ret<<" |";
|
||||
}
|
||||
|
||||
uint32_t powerlimit;
|
||||
cout<<"\n| PowerLimit (Watts)\t\t | ";
|
||||
|
||||
ret = amdsmi_get_cpu_socket_power_cap(sockets[i], i, &powerlimit);
|
||||
CHK_AMDSMI_RET(ret)
|
||||
|
||||
if (!ret) {
|
||||
cout<<fixed<<setprecision(3)<<static_cast<double>(powerlimit)/1000<<"\t|";
|
||||
} else {
|
||||
err_bits |= 1 << ret;
|
||||
cout<<" NA (Err:" <<ret<<" |";
|
||||
}
|
||||
|
||||
uint32_t powermax;
|
||||
cout<<"\n| PowerLimitMax (Watts)\t\t | ";
|
||||
|
||||
ret = amdsmi_get_cpu_socket_power_cap_max(sockets[i], i, &powermax);
|
||||
CHK_AMDSMI_RET(ret)
|
||||
|
||||
if (!ret) {
|
||||
cout<<fixed<<setprecision(3)<<static_cast<double>(powermax)/1000<<"\t|";
|
||||
} else {
|
||||
err_bits |= 1 << ret;
|
||||
cout<<" NA (Err:" <<ret<<" |";
|
||||
}
|
||||
cout<<"\n-------------------------------------------------\n";
|
||||
#if 0
|
||||
uint32_t svi_power;
|
||||
cout<<"\n| SVI Power Telemetry (mWatts) \t |";
|
||||
|
||||
ret = amdsmi_get_cpu_pwr_svi_telemetry_all_rails(sockets[i], i, &svi_power);
|
||||
CHK_AMDSMI_RET(ret)
|
||||
|
||||
if (!ret) {
|
||||
cout<<fixed<<setprecision(3)<<static_cast<double>(svi_power)/1000<<"\t|";
|
||||
} else {
|
||||
err_bits |= 1 << ret;
|
||||
cout<<" NA (Err:" <<ret<<" |";
|
||||
}
|
||||
cout<<"\n-------------------------------------------------\n";
|
||||
#endif
|
||||
}
|
||||
// Clean up resources allocated at amdsmi_init
|
||||
ret = amdsmi_shut_down();
|
||||
CHK_AMDSMI_RET(ret)
|
||||
|
||||
return 0;
|
||||
}
|
||||
+7
-6
@@ -99,7 +99,7 @@ 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 1
|
||||
#define AMDSMI_LIB_VERSION_MAJOR 2
|
||||
|
||||
//! Minor version should be updated for each API change, but without changing headers
|
||||
#define AMDSMI_LIB_VERSION_MINOR 1
|
||||
@@ -392,7 +392,7 @@ typedef struct {
|
||||
char market_name[AMDSMI_MAX_STRING_LENGTH];
|
||||
uint32_t vendor_id; //< Use 32 bit to be compatible with other platform.
|
||||
uint32_t subvendor_id; //< The subsystem vendor id
|
||||
uint64_t device_id; //< The unique id of a GPU
|
||||
uint64_t device_id; //< The device id of a GPU
|
||||
uint32_t rev_id;
|
||||
char asic_serial[AMDSMI_NORMAL_STRING_LENGTH];
|
||||
uint32_t reserved[3];
|
||||
@@ -938,11 +938,11 @@ typedef struct {
|
||||
* @brief This structure holds version information.
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t year; //!< Last 2 digits of the Year released
|
||||
uint32_t major; //!< Major version
|
||||
uint32_t minor; //!< Minor version
|
||||
uint32_t patch; //!< Patch, build or stepping version
|
||||
const char *build; //!< Build string
|
||||
uint32_t reserved[4];
|
||||
uint32_t release; //!< Patch, build or stepping version
|
||||
const char *build; //!< Full Build version string
|
||||
} amdsmi_version_t;
|
||||
|
||||
/**
|
||||
@@ -1105,7 +1105,8 @@ typedef struct {
|
||||
typedef struct {
|
||||
uint16_t pcie_lanes;
|
||||
uint32_t pcie_speed;
|
||||
uint32_t reserved[6];
|
||||
uint32_t reserved[5];
|
||||
uint32_t pcie_interface_version;
|
||||
} amdsmi_pcie_info_t;
|
||||
/**
|
||||
* @brief This structure contains information specific to a process.
|
||||
|
||||
@@ -76,6 +76,35 @@ const std::map<rsmi_status_t, amdsmi_status_t> rsmi_status_map = {
|
||||
|
||||
amdsmi_status_t rsmi_to_amdsmi_status(rsmi_status_t status);
|
||||
|
||||
#ifdef ENABLE_ESMI_LIB
|
||||
// Define a map of esmi status codes to amdsmi status codes
|
||||
const std::map<esmi_status_t, amdsmi_status_t> esmi_status_map = {
|
||||
{ESMI_SUCCESS, AMDSMI_STATUS_SUCCESS},
|
||||
{ESMI_INITIALIZED, AMDSMI_STATUS_SUCCESS},
|
||||
{ESMI_INVALID_INPUT, AMDSMI_STATUS_INVAL},
|
||||
{ESMI_NOT_SUPPORTED, AMDSMI_STATUS_NOT_SUPPORTED},
|
||||
{ESMI_PERMISSION, AMDSMI_STATUS_NO_PERM},
|
||||
{ESMI_INTERRUPTED, AMDSMI_STATUS_INTERRUPT},
|
||||
{ESMI_IO_ERROR, AMDSMI_STATUS_IO},
|
||||
{ESMI_FILE_ERROR, AMDSMI_STATUS_FILE_ERROR},
|
||||
{ESMI_NO_MEMORY, AMDSMI_STATUS_OUT_OF_RESOURCES},
|
||||
{ESMI_DEV_BUSY, AMDSMI_STATUS_BUSY},
|
||||
{ESMI_NOT_INITIALIZED, AMDSMI_STATUS_NOT_INIT},
|
||||
{ESMI_UNEXPECTED_SIZE, AMDSMI_STATUS_UNEXPECTED_SIZE},
|
||||
{ESMI_UNKNOWN_ERROR, AMDSMI_STATUS_UNKNOWN_ERROR},
|
||||
{ESMI_NO_ENERGY_DRV, AMDSMI_NO_ENERGY_DRV},
|
||||
{ESMI_NO_MSR_DRV, AMDSMI_NO_MSR_DRV},
|
||||
{ESMI_NO_HSMP_DRV, AMDSMI_NO_HSMP_DRV},
|
||||
{ESMI_NO_HSMP_SUP, AMDSMI_NO_HSMP_SUP},
|
||||
{ESMI_NO_DRV, AMDSMI_NO_DRV},
|
||||
{ESMI_FILE_NOT_FOUND, AMDSMI_FILE_NOT_FOUND},
|
||||
{ESMI_ARG_PTR_NULL, AMDSMI_ARG_PTR_NULL},
|
||||
{ESMI_HSMP_TIMEOUT, AMDSMI_HSMP_TIMEOUT},
|
||||
{ESMI_NO_HSMP_MSG_SUP, AMDSMI_NO_HSMP_MSG_SUP},
|
||||
};
|
||||
|
||||
amdsmi_status_t esmi_to_amdsmi_status(esmi_status_t status);
|
||||
#endif
|
||||
} // namespace smi
|
||||
} // namespace amd
|
||||
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* =============================================================================
|
||||
* The University of Illinois/NCSA
|
||||
* Open Source License (NCSA)
|
||||
*
|
||||
* Copyright (c) 2022, Advanced Micro Devices, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Developed by:
|
||||
*
|
||||
* AMD Research and AMD ROC Software Development
|
||||
*
|
||||
* Advanced Micro Devices, Inc.
|
||||
*
|
||||
* www.amd.com
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal with the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimers.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimers in
|
||||
* the documentation and/or other materials provided with the distribution.
|
||||
* - Neither the names of <Name of Development Group, Name of Institution>,
|
||||
* nor the names of its contributors may be used to endorse or promote
|
||||
* products derived from this Software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS WITH THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef AMD_SMI_INCLUDE_AMD_SMI_CPU_CORE_H_
|
||||
#define AMD_SMI_INCLUDE_AMD_SMI_CPU_CORE_H_
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include "amd_smi/amdsmi.h"
|
||||
#include "amd_smi/impl/amd_smi_processor.h"
|
||||
|
||||
namespace amd {
|
||||
namespace smi {
|
||||
|
||||
/*Subclass CPU Core*/
|
||||
class AMDSmiCpuCore : public AMDSmiProcessor {
|
||||
public:
|
||||
explicit AMDSmiCpuCore(const uint32_t& core_idx):AMDSmiProcessor(AMD_CPU_CORE),core_idx_(core_idx) {}
|
||||
|
||||
virtual ~AMDSmiCpuCore() {}
|
||||
|
||||
void add_processor(AMDSmiProcessor* processor) { processors_.push_back(processor); }
|
||||
std::vector<AMDSmiProcessor*>& get_processors() { return processors_;}
|
||||
amdsmi_status_t get_processor_count(uint32_t* processor_count) const;
|
||||
|
||||
private:
|
||||
uint32_t core_idx_;
|
||||
//uint64_t input;
|
||||
//uint32_t idx;
|
||||
std::vector<AMDSmiProcessor*> processors_;
|
||||
};
|
||||
|
||||
} // namespace smi
|
||||
} // namespace amd
|
||||
|
||||
#endif // AMD_SMI_INCLUDE_AMD_SMI_CPU_CORE_H_
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* =============================================================================
|
||||
* The University of Illinois/NCSA
|
||||
* Open Source License (NCSA)
|
||||
*
|
||||
* Copyright (c) 2022, Advanced Micro Devices, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Developed by:
|
||||
*
|
||||
* AMD Research and AMD ROC Software Development
|
||||
*
|
||||
* Advanced Micro Devices, Inc.
|
||||
*
|
||||
* www.amd.com
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal with the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimers.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimers in
|
||||
* the documentation and/or other materials provided with the distribution.
|
||||
* - Neither the names of <Name of Development Group, Name of Institution>,
|
||||
* nor the names of its contributors may be used to endorse or promote
|
||||
* products derived from this Software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS WITH THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef AMD_SMI_INCLUDE_AMD_SMI_CPU_SOCKET_H_
|
||||
#define AMD_SMI_INCLUDE_AMD_SMI_CPU_SOCKET_H_
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include "amd_smi/amdsmi.h"
|
||||
#include "amd_smi/impl/amd_smi_processor.h"
|
||||
#include "amd_smi/impl/amd_smi_cpu_core.h"
|
||||
|
||||
namespace amd {
|
||||
namespace smi {
|
||||
|
||||
/*Subclass CPU Socket*/
|
||||
class AMDSmiCpuSocket : public AMDSmiProcessor {
|
||||
public:
|
||||
explicit AMDSmiCpuSocket(const uint32_t& id):AMDSmiProcessor(AMD_CPU),socket_identifier_(id) {}
|
||||
|
||||
virtual ~AMDSmiCpuSocket() {}
|
||||
|
||||
amdsmi_status_t get_cpu_vendor() { return AMDSMI_STATUS_SUCCESS; }
|
||||
uint32_t get_cpu_id() const { return cpu_id_; }
|
||||
const uint32_t& get_socket_id() const { return socket_identifier_; }
|
||||
|
||||
void add_processor(AMDSmiProcessor* processor) { processors_.push_back(processor); }
|
||||
std::vector<AMDSmiProcessor*>& get_processors() { return processors_;}
|
||||
amdsmi_status_t get_processor_count(uint32_t* processor_count) const;
|
||||
|
||||
private:
|
||||
uint32_t cpu_id_;
|
||||
uint32_t socket_identifier_;
|
||||
std::vector<AMDSmiProcessor*> processors_;
|
||||
};
|
||||
|
||||
} // namespace smi
|
||||
} // namespace amd
|
||||
|
||||
#endif // AMD_SMI_INCLUDE_AMD_SMI_CPU_SOCKET_H_
|
||||
@@ -50,6 +50,9 @@
|
||||
#include "amd_smi/impl/amd_smi_socket.h"
|
||||
#include "amd_smi/impl/amd_smi_processor.h"
|
||||
#include "amd_smi/impl/amd_smi_drm.h"
|
||||
#ifdef ENABLE_ESMI_LIB
|
||||
#include "amd_smi/impl/amd_smi_cpu_socket.h"
|
||||
#endif
|
||||
|
||||
namespace amd {
|
||||
namespace smi {
|
||||
@@ -75,6 +78,25 @@ class AMDSmiSystem {
|
||||
amdsmi_status_t gpu_index_to_handle(uint32_t gpu_index,
|
||||
amdsmi_processor_handle* processor_handle);
|
||||
|
||||
#ifdef ENABLE_ESMI_LIB
|
||||
std::vector<AMDSmiCpuSocket*>& get_cpu_sockets() {return cpu_sockets_;}
|
||||
|
||||
amdsmi_status_t handle_to_cpusocket(amdsmi_cpusocket_handle cpusock_handle,
|
||||
AMDSmiCpuSocket** cpu_socket);
|
||||
|
||||
amdsmi_status_t cpu_index_to_handle(uint32_t cpu_index,
|
||||
amdsmi_cpusocket_handle* cpusock_handle);
|
||||
|
||||
amdsmi_status_t get_cpu_sockets(uint32_t socks);
|
||||
|
||||
amdsmi_status_t get_cpu_cores(uint32_t cpus);
|
||||
|
||||
amdsmi_status_t get_threads_per_core(uint32_t threads);
|
||||
|
||||
amdsmi_status_t get_cpu_family(uint32_t family);
|
||||
|
||||
amdsmi_status_t get_cpu_model(uint32_t model);
|
||||
#endif
|
||||
private:
|
||||
AMDSmiSystem() : init_flag_(AMDSMI_INIT_AMD_GPUS) {}
|
||||
amdsmi_status_t get_gpu_bdf_by_index(uint32_t index, std::string& bdf);
|
||||
@@ -83,6 +105,15 @@ class AMDSmiSystem {
|
||||
AMDSmiDrm drm_;
|
||||
std::vector<AMDSmiSocket*> sockets_;
|
||||
std::set<AMDSmiProcessor*> processors_; // Track valid processors
|
||||
#ifdef ENABLE_ESMI_LIB
|
||||
amdsmi_status_t populate_amd_cpus();
|
||||
std::vector<AMDSmiCpuSocket*> cpu_sockets_;
|
||||
static uint32_t sockets;
|
||||
static uint32_t cpus;
|
||||
static uint32_t threads;
|
||||
static uint32_t family;
|
||||
static uint32_t model;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -679,6 +679,7 @@ Field | Description
|
||||
---|---
|
||||
`pcie_lanes`| pcie lanes in use
|
||||
`pcie_speed`| current pcie speed
|
||||
`pcie_interface_version`| current pcie generation
|
||||
|
||||
Exceptions that can be thrown by `amdsmi_get_pcie_link_status` function:
|
||||
|
||||
@@ -698,6 +699,7 @@ try:
|
||||
pcie_link_status = amdsmi_get_pcie_link_status(device)
|
||||
print(pcie_link_status["pcie_lanes"])
|
||||
print(pcie_link_status["pcie_speed"])
|
||||
print(pcie_link_status["pcie_interface_version"])
|
||||
except AmdSmiException as e:
|
||||
print(e)
|
||||
```
|
||||
|
||||
@@ -1019,8 +1019,9 @@ def amdsmi_get_pcie_link_status(
|
||||
)
|
||||
)
|
||||
|
||||
return {"pcie_lanes": pcie_info.pcie_lanes, "pcie_speed": pcie_info.pcie_speed}
|
||||
|
||||
return {"pcie_speed": pcie_info.pcie_speed,
|
||||
"pcie_lanes": pcie_info.pcie_lanes,
|
||||
"pcie_interface_version": pcie_info.pcie_interface_version}
|
||||
|
||||
def amdsmi_get_pcie_link_caps(
|
||||
processor_handle: amdsmi_wrapper.amdsmi_processor_handle,
|
||||
@@ -1036,7 +1037,9 @@ def amdsmi_get_pcie_link_caps(
|
||||
processor_handle, ctypes.byref(pcie_info))
|
||||
)
|
||||
|
||||
return {"pcie_speed": pcie_info.pcie_speed, "pcie_lanes": pcie_info.pcie_lanes}
|
||||
return {"max_pcie_speed": pcie_info.pcie_speed,
|
||||
"max_pcie_lanes": pcie_info.pcie_lanes,
|
||||
"pcie_interface_version": pcie_info.pcie_interface_version}
|
||||
|
||||
|
||||
def amdsmi_get_processor_handle_from_bdf(bdf):
|
||||
@@ -1143,10 +1146,11 @@ def amdsmi_get_lib_version():
|
||||
_check_res(amdsmi_wrapper.amdsmi_get_lib_version(ctypes.byref(version)))
|
||||
|
||||
return {
|
||||
"year": version.year,
|
||||
"major": version.major,
|
||||
"minor": version.minor,
|
||||
"patch": version.patch,
|
||||
"build": version.build.contents.value.decode("utf-8"),
|
||||
"release": version.release,
|
||||
"build": version.build.contents.value.decode("utf-8")
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1246,12 +1246,12 @@ class struct_c__SA_amdsmi_version_t(Structure):
|
||||
|
||||
struct_c__SA_amdsmi_version_t._pack_ = 1 # source:False
|
||||
struct_c__SA_amdsmi_version_t._fields_ = [
|
||||
('year', ctypes.c_uint32),
|
||||
('major', ctypes.c_uint32),
|
||||
('minor', ctypes.c_uint32),
|
||||
('patch', ctypes.c_uint32),
|
||||
('PADDING_0', ctypes.c_ubyte * 4),
|
||||
('release', ctypes.c_uint32),
|
||||
('build', ctypes.POINTER(ctypes.c_char)),
|
||||
('reserved', ctypes.c_uint32 * 4),
|
||||
('reserved', ctypes.c_ubyte * 4),
|
||||
]
|
||||
|
||||
amdsmi_version_t = struct_c__SA_amdsmi_version_t
|
||||
@@ -1368,7 +1368,8 @@ struct_c__SA_amdsmi_pcie_info_t._fields_ = [
|
||||
('pcie_lanes', ctypes.c_uint16),
|
||||
('PADDING_0', ctypes.c_ubyte * 2),
|
||||
('pcie_speed', ctypes.c_uint32),
|
||||
('reserved', ctypes.c_uint32 * 6),
|
||||
('reserved', ctypes.c_uint32 * 5),
|
||||
('pcie_interface_version', ctypes.c_uint32),
|
||||
]
|
||||
|
||||
amdsmi_pcie_info_t = struct_c__SA_amdsmi_pcie_info_t
|
||||
|
||||
@@ -10,14 +10,14 @@ name = "amdsmi"
|
||||
authors = [
|
||||
{name = "AMD", email = "amd-smi.support@amd.com"},
|
||||
]
|
||||
version = '23.0.1.1'
|
||||
version = "23.2.1.0"
|
||||
license = {file = "amdsmi/LICENSE"}
|
||||
readme = {file = "amdsmi/README.md", content-type = "text/markdown"}
|
||||
description = "SMI LIB - AMD GPU Monitoring Library"
|
||||
description = "AMDSMI Python LIB - AMD GPU Monitoring Library"
|
||||
requires-python = ">=3.7"
|
||||
dependencies = [
|
||||
'PyYAML >= 5.0',
|
||||
'clang >= 14.0'
|
||||
"PyYAML >= 5.0",
|
||||
"clang >= 14.0"
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
|
||||
@@ -15,13 +15,17 @@ LD_LIBRARY_PATH should be set to the folder containing librocm_smi64.
|
||||
|
||||
|
||||
### Version
|
||||
|
||||
The SMI will report a "version" which is the version of the kernel installed:
|
||||
|
||||
```shell
|
||||
AMD ROCm System Management Interface v$(uname)
|
||||
```
|
||||
|
||||
For ROCk installations, this will be the AMDGPU module version (e.g. 5.0.71)
|
||||
For non-ROCk or monolithic ROCk installations, this will be the kernel version,
|
||||
which will be equivalent to the following bash command:
|
||||
|
||||
```shell
|
||||
$(uname -a) | cut -d ' ' -f 3)
|
||||
```
|
||||
@@ -34,6 +38,7 @@ For detailed and up to date usage information, we recommend consulting the help:
|
||||
```
|
||||
|
||||
For convenience purposes, following is the output from the -h flag:
|
||||
|
||||
```shell
|
||||
|
||||
usage: rocmSmiLib_cli.py [-h] [-d DEVICE [DEVICE ...]] [--alldevices] [--showhw] [-a] [-i] [-v] [--showdriverversion]
|
||||
|
||||
+583
-15
@@ -67,6 +67,11 @@
|
||||
#include "rocm_smi/rocm_smi_common.h"
|
||||
#include "amd_smi/impl/amdgpu_drm.h"
|
||||
#include "amd_smi/impl/amd_smi_utils.h"
|
||||
#include "amd_smi/impl/amd_smi_processor.h"
|
||||
#ifdef ENABLE_ESMI_LIB
|
||||
#include "amd_smi/impl/amd_smi_cpu_socket.h"
|
||||
#include "amd_smi/impl/amd_smi_cpu_core.h"
|
||||
#endif
|
||||
|
||||
static bool initialized_lib = false;
|
||||
|
||||
@@ -97,6 +102,49 @@ static amdsmi_status_t get_gpu_device_from_handle(amdsmi_processor_handle proces
|
||||
return AMDSMI_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_ESMI_LIB
|
||||
static amdsmi_status_t get_cpu_socket_from_handle(amdsmi_cpusocket_handle socket_handle,
|
||||
amd::smi::AMDSmiCpuSocket** cpusocket) {
|
||||
|
||||
AMDSMI_CHECK_INIT();
|
||||
|
||||
if (socket_handle == nullptr || cpusocket == nullptr)
|
||||
return AMDSMI_STATUS_INVAL;
|
||||
|
||||
amd::smi::AMDSmiCpuSocket* socket = nullptr;
|
||||
amdsmi_status_t r = amd::smi::AMDSmiSystem::getInstance()
|
||||
.handle_to_cpusocket(socket_handle, &socket);
|
||||
if (r != AMDSMI_STATUS_SUCCESS) return r;
|
||||
|
||||
if (socket->get_processor_type() == AMD_CPU) {
|
||||
*cpusocket = static_cast<amd::smi::AMDSmiCpuSocket*>(socket_handle);
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
return AMDSMI_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
static amdsmi_status_t get_cpu_core_from_handle(amdsmi_processor_handle processor_handle,
|
||||
amd::smi::AMDSmiCpuCore** cpucore) {
|
||||
|
||||
AMDSMI_CHECK_INIT();
|
||||
if (processor_handle == nullptr || cpucore == nullptr)
|
||||
return AMDSMI_STATUS_INVAL;
|
||||
|
||||
amd::smi::AMDSmiProcessor* core = nullptr;
|
||||
amdsmi_status_t r = amd::smi::AMDSmiSystem::getInstance()
|
||||
.handle_to_processor(processor_handle, &core);
|
||||
if (r != AMDSMI_STATUS_SUCCESS) return r;
|
||||
|
||||
if (core->get_processor_type() == AMD_CPU_CORE) {
|
||||
*cpucore = static_cast<amd::smi::AMDSmiCpuCore*>(processor_handle);
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
return AMDSMI_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename F, typename ...Args>
|
||||
amdsmi_status_t rsmi_wrapper(F && f,
|
||||
amdsmi_processor_handle processor_handle, Args &&... args) {
|
||||
@@ -114,6 +162,24 @@ amdsmi_status_t rsmi_wrapper(F && f,
|
||||
return amd::smi::rsmi_to_amdsmi_status(rstatus);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_ESMI_LIB
|
||||
template <typename F, typename ...Args>
|
||||
amdsmi_status_t esmi_wrapper(F && f,
|
||||
amdsmi_processor_handle processor_handle, Args &&... args) {
|
||||
|
||||
AMDSMI_CHECK_INIT();
|
||||
|
||||
amd::smi::AMDSmiCpuSocket* cpu_socket = nullptr;
|
||||
amdsmi_status_t r = get_cpu_socket_from_handle(processor_handle, &cpu_socket);
|
||||
if (r != AMDSMI_STATUS_SUCCESS) return r;
|
||||
|
||||
uint32_t cpu_index = cpu_socket->get_cpu_id();
|
||||
auto estatus = std::forward<F>(f)(cpu_index,
|
||||
std::forward<Args>(args)...);
|
||||
return amd::smi::esmi_to_amdsmi_status(estatus);
|
||||
}
|
||||
#endif
|
||||
|
||||
amdsmi_status_t
|
||||
amdsmi_init(uint64_t flags) {
|
||||
if (initialized_lib)
|
||||
@@ -165,6 +231,37 @@ amdsmi_status_code_to_string(amdsmi_status_t status, const char **status_string)
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_ESMI_LIB
|
||||
amdsmi_status_t amdsmi_get_cpusocket_handles(uint32_t *socket_count,
|
||||
amdsmi_cpusocket_handle* socket_handles) {
|
||||
|
||||
AMDSMI_CHECK_INIT();
|
||||
if (socket_count == nullptr) {
|
||||
return AMDSMI_STATUS_INVAL;
|
||||
}
|
||||
|
||||
std::vector<amd::smi::AMDSmiCpuSocket*>& sockets
|
||||
= amd::smi::AMDSmiSystem::getInstance().get_cpu_sockets();
|
||||
uint32_t socket_size = static_cast<uint32_t>(sockets.size());
|
||||
|
||||
// Get the socket size
|
||||
if (socket_handles == nullptr) {
|
||||
*socket_count = socket_size;
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// If the socket_handles can hold all sockets, return all of them.
|
||||
*socket_count = *socket_count >= socket_size ? socket_size : *socket_count;
|
||||
|
||||
// Copy the cpu socket handles
|
||||
for (uint32_t i = 0; i < *socket_count; i++) {
|
||||
socket_handles[i] = reinterpret_cast<amdsmi_cpusocket_handle>(sockets[i]);
|
||||
}
|
||||
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
amdsmi_status_t amdsmi_get_socket_handles(uint32_t *socket_count,
|
||||
amdsmi_socket_handle* socket_handles) {
|
||||
|
||||
@@ -214,6 +311,27 @@ amdsmi_status_t amdsmi_get_socket_info(
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_ESMI_LIB
|
||||
amdsmi_status_t amdsmi_get_cpusocket_info(
|
||||
amdsmi_cpusocket_handle socket_handle,
|
||||
uint32_t sock_id) {
|
||||
AMDSMI_CHECK_INIT();
|
||||
|
||||
if (socket_handle == nullptr) {
|
||||
return AMDSMI_STATUS_INVAL;
|
||||
}
|
||||
|
||||
amd::smi::AMDSmiCpuSocket* socket = nullptr;
|
||||
amdsmi_status_t r = amd::smi::AMDSmiSystem::getInstance()
|
||||
.handle_to_cpusocket(socket_handle, &socket);
|
||||
if (r != AMDSMI_STATUS_SUCCESS) return r;
|
||||
|
||||
sock_id = socket->get_socket_id();
|
||||
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
amdsmi_status_t amdsmi_get_processor_handles(amdsmi_socket_handle socket_handle,
|
||||
uint32_t* processor_count,
|
||||
amdsmi_processor_handle* processor_handles) {
|
||||
@@ -249,6 +367,44 @@ amdsmi_status_t amdsmi_get_processor_handles(amdsmi_socket_handle socket_handle,
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_ESMI_LIB
|
||||
amdsmi_status_t amdsmi_get_cpucore_handles(amdsmi_cpusocket_handle socket_handle,
|
||||
uint32_t* processor_count,
|
||||
amdsmi_processor_handle* processor_handles) {
|
||||
AMDSMI_CHECK_INIT();
|
||||
|
||||
if (processor_count == nullptr) {
|
||||
return AMDSMI_STATUS_INVAL;
|
||||
}
|
||||
|
||||
// Get the socket object via socket handle.
|
||||
amd::smi::AMDSmiCpuSocket* socket = nullptr;
|
||||
amdsmi_status_t r = amd::smi::AMDSmiSystem::getInstance()
|
||||
.handle_to_cpusocket(socket_handle, &socket);
|
||||
if (r != AMDSMI_STATUS_SUCCESS) return r;
|
||||
|
||||
|
||||
std::vector<amd::smi::AMDSmiProcessor*>& processors = socket->get_processors();
|
||||
uint32_t processor_size = static_cast<uint32_t>(processors.size());
|
||||
|
||||
// Get the processor count only
|
||||
if (processor_handles == nullptr) {
|
||||
*processor_count = processor_size;
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// If the processor_handles can hold all processors, return all of them.
|
||||
*processor_count = *processor_count >= processor_size ? processor_size : *processor_count;
|
||||
|
||||
// Copy the processor handles
|
||||
for (uint32_t i = 0; i < *processor_count; i++) {
|
||||
processor_handles[i] = reinterpret_cast<amdsmi_processor_handle>(processors[i]);
|
||||
}
|
||||
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
amdsmi_status_t amdsmi_get_processor_type(amdsmi_processor_handle processor_handle ,
|
||||
processor_type_t* processor_type) {
|
||||
|
||||
@@ -512,8 +668,9 @@ amdsmi_get_gpu_asic_info(amdsmi_processor_handle processor_handle, amdsmi_asic_i
|
||||
}
|
||||
// For other sysfs related information, get from rocm-smi
|
||||
else {
|
||||
status = rsmi_wrapper(rsmi_dev_serial_number_get, processor_handle,
|
||||
info->asic_serial, AMDSMI_NORMAL_STRING_LENGTH);
|
||||
uint64_t dv_uid = 0;
|
||||
status = rsmi_wrapper(rsmi_dev_unique_id_get, processor_handle, &dv_uid);
|
||||
if (status == AMDSMI_STATUS_SUCCESS) snprintf(info->asic_serial, sizeof(info->asic_serial), "%d", dv_uid);
|
||||
|
||||
status = rsmi_wrapper(rsmi_dev_brand_get, processor_handle,
|
||||
info->market_name, AMDSMI_NORMAL_STRING_LENGTH);
|
||||
@@ -1126,9 +1283,13 @@ amdsmi_status_t amdsmi_get_lib_version(amdsmi_version_t *version) {
|
||||
if (version == nullptr)
|
||||
return AMDSMI_STATUS_INVAL;
|
||||
|
||||
auto rstatus = rsmi_version_get(
|
||||
reinterpret_cast<rsmi_version_t*>(version));
|
||||
return amd::smi::rsmi_to_amdsmi_status(rstatus);
|
||||
version->year = AMDSMI_LIB_VERSION_YEAR;
|
||||
version->major = AMDSMI_LIB_VERSION_MAJOR;
|
||||
version->minor = AMDSMI_LIB_VERSION_MINOR;
|
||||
version->release = AMDSMI_LIB_VERSION_RELEASE;
|
||||
version->build = AMDSMI_LIB_VERSION_STRING;
|
||||
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
amdsmi_status_t
|
||||
@@ -1224,12 +1385,14 @@ amdsmi_get_clock_info(amdsmi_processor_handle processor_handle, amdsmi_clk_type_
|
||||
return status;
|
||||
}
|
||||
int max_freq;
|
||||
int min_freq;
|
||||
status = smi_amdgpu_get_ranges(gpu_device, clk_type,
|
||||
&max_freq, NULL, NULL);
|
||||
&max_freq, &min_freq, NULL);
|
||||
if (status != AMDSMI_STATUS_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
info->max_clk = max_freq;
|
||||
info->min_clk = min_freq;
|
||||
|
||||
switch (clk_type) {
|
||||
case CLK_TYPE_GFX:
|
||||
@@ -1531,7 +1694,31 @@ amdsmi_get_pcie_link_status(amdsmi_processor_handle processor_handle, amdsmi_pci
|
||||
return status;
|
||||
|
||||
info->pcie_lanes = metric_info.pcie_link_width;
|
||||
status = smi_amdgpu_get_pcie_speed_from_pcie_type(metric_info.pcie_link_speed, &info->pcie_speed); // mapping to MT/s
|
||||
// gpu metrics returns pcie link speed in .1 GT/s ex. 160 vs 16
|
||||
info->pcie_speed = (metric_info.pcie_link_speed / 10) * 1000;
|
||||
|
||||
switch (info->pcie_speed) {
|
||||
case 2500:
|
||||
info->pcie_interface_version = 1;
|
||||
break;
|
||||
case 5000:
|
||||
info->pcie_interface_version = 2;
|
||||
break;
|
||||
case 8000:
|
||||
info->pcie_interface_version = 3;
|
||||
break;
|
||||
case 16000:
|
||||
info->pcie_interface_version = 4;
|
||||
break;
|
||||
case 32000:
|
||||
info->pcie_interface_version = 5;
|
||||
break;
|
||||
case 64000:
|
||||
info->pcie_interface_version = 6;
|
||||
break;
|
||||
default:
|
||||
info->pcie_interface_version = 0;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -1555,7 +1742,6 @@ amdsmi_status_t amdsmi_get_pcie_link_caps(amdsmi_processor_handle processor_hand
|
||||
FILE* fp;
|
||||
double pcie_speed = 0;
|
||||
unsigned pcie_width = 0;
|
||||
amdsmi_asic_info_t asic_info = {};
|
||||
|
||||
memset((void *)info, 0, sizeof(*info));
|
||||
|
||||
@@ -1582,15 +1768,32 @@ amdsmi_status_t amdsmi_get_pcie_link_caps(amdsmi_processor_handle processor_hand
|
||||
return AMDSMI_STATUS_API_FAILED;
|
||||
}
|
||||
|
||||
status = amdsmi_get_gpu_asic_info(processor_handle, &asic_info);
|
||||
if (status != AMDSMI_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
if (pcie_speed == 0 && asic_info.device_id == 29538)
|
||||
pcie_speed = 16;
|
||||
|
||||
// pcie speed in sysfs returns in GT/s
|
||||
info->pcie_speed = pcie_speed * 1000;
|
||||
|
||||
switch (info->pcie_speed) {
|
||||
case 2500:
|
||||
info->pcie_interface_version = 1;
|
||||
break;
|
||||
case 5000:
|
||||
info->pcie_interface_version = 2;
|
||||
break;
|
||||
case 8000:
|
||||
info->pcie_interface_version = 3;
|
||||
break;
|
||||
case 16000:
|
||||
info->pcie_interface_version = 4;
|
||||
break;
|
||||
case 32000:
|
||||
info->pcie_interface_version = 5;
|
||||
break;
|
||||
case 64000:
|
||||
info->pcie_interface_version = 6;
|
||||
break;
|
||||
default:
|
||||
info->pcie_interface_version = 0;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -1646,3 +1849,368 @@ amdsmi_status_t amdsmi_get_processor_handle_from_bdf(amdsmi_bdf_t bdf,
|
||||
|
||||
return AMDSMI_STATUS_API_FAILED;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_ESMI_LIB
|
||||
amdsmi_status_t amdsmi_get_hsmp_proto_ver(uint32_t *proto_ver)
|
||||
{
|
||||
amdsmi_status_t status;
|
||||
uint32_t hsmp_proto_ver;
|
||||
|
||||
if (proto_ver == nullptr)
|
||||
return AMDSMI_STATUS_INVAL;
|
||||
|
||||
status = static_cast<amdsmi_status_t>(esmi_hsmp_proto_ver_get(&hsmp_proto_ver));
|
||||
*proto_ver = hsmp_proto_ver;
|
||||
|
||||
if (status != AMDSMI_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
amdsmi_status_t amdsmi_get_smu_fw_version(amdsmi_smu_fw_version_t *amdsmi_smu_fw)
|
||||
{
|
||||
amdsmi_status_t status;
|
||||
struct smu_fw_version smu_fw;
|
||||
|
||||
if (amdsmi_smu_fw == nullptr)
|
||||
return AMDSMI_STATUS_INVAL;
|
||||
|
||||
status = static_cast<amdsmi_status_t>(esmi_smu_fw_version_get(&smu_fw));
|
||||
|
||||
amdsmi_smu_fw->major = smu_fw.major;
|
||||
amdsmi_smu_fw->minor = smu_fw.minor;
|
||||
amdsmi_smu_fw->debug = smu_fw.debug;
|
||||
|
||||
if (status != AMDSMI_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
amdsmi_status_t amdsmi_get_cpu_core_energy(amdsmi_processor_handle processor_handle,
|
||||
uint32_t core_ind, uint64_t *penergy)
|
||||
{
|
||||
amdsmi_status_t status;
|
||||
uint64_t core_input;
|
||||
|
||||
if (processor_handle == nullptr)
|
||||
return AMDSMI_STATUS_INVAL;
|
||||
|
||||
amd::smi::AMDSmiCpuCore* core = nullptr;
|
||||
amdsmi_status_t r = get_cpu_core_from_handle(processor_handle, &core);
|
||||
if (r != AMDSMI_STATUS_SUCCESS)
|
||||
return r;
|
||||
|
||||
status = static_cast<amdsmi_status_t>(esmi_core_energy_get(core_ind, &core_input));
|
||||
*penergy = core_input;
|
||||
|
||||
if (status != AMDSMI_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
amdsmi_status_t amdsmi_get_cpu_socket_energy(amdsmi_cpusocket_handle socket_handle,
|
||||
uint32_t sock_ind, uint64_t *penergy)
|
||||
{
|
||||
amdsmi_status_t status;
|
||||
uint64_t pkg_input;
|
||||
|
||||
if (socket_handle == nullptr)
|
||||
return AMDSMI_STATUS_INVAL;
|
||||
|
||||
amd::smi::AMDSmiCpuSocket* socket = nullptr;
|
||||
amdsmi_status_t r = get_cpu_socket_from_handle(socket_handle, &socket);
|
||||
if (r != AMDSMI_STATUS_SUCCESS)
|
||||
return r;
|
||||
|
||||
status = static_cast<amdsmi_status_t>(esmi_socket_energy_get(sock_ind, &pkg_input));
|
||||
*penergy = pkg_input;
|
||||
|
||||
if (status != AMDSMI_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
amdsmi_status_t amdsmi_get_cpu_prochot_status(amdsmi_cpusocket_handle socket_handle,
|
||||
uint32_t sock_ind, uint32_t *prochot)
|
||||
{
|
||||
amdsmi_status_t status;
|
||||
uint32_t phot;
|
||||
|
||||
if (socket_handle == nullptr)
|
||||
return AMDSMI_STATUS_INVAL;
|
||||
|
||||
amd::smi::AMDSmiCpuSocket* socket = nullptr;
|
||||
amdsmi_status_t r = get_cpu_socket_from_handle(socket_handle, &socket);
|
||||
if (r != AMDSMI_STATUS_SUCCESS)
|
||||
return r;
|
||||
|
||||
status = static_cast<amdsmi_status_t>(esmi_prochot_status_get(sock_ind, &phot));
|
||||
*prochot = phot;
|
||||
|
||||
if (status != AMDSMI_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
amdsmi_status_t amdsmi_get_cpu_fclk_mclk(amdsmi_cpusocket_handle socket_handle,
|
||||
uint32_t sock_ind, uint32_t *fclk, uint32_t *mclk)
|
||||
{
|
||||
amdsmi_status_t status;
|
||||
uint32_t f_clk, m_clk;
|
||||
|
||||
if (socket_handle == nullptr)
|
||||
return AMDSMI_STATUS_INVAL;
|
||||
|
||||
amd::smi::AMDSmiCpuSocket* socket = nullptr;
|
||||
amdsmi_status_t r = get_cpu_socket_from_handle(socket_handle, &socket);
|
||||
if (r != AMDSMI_STATUS_SUCCESS)
|
||||
return r;
|
||||
|
||||
status = static_cast<amdsmi_status_t>(esmi_fclk_mclk_get(sock_ind, &f_clk, &m_clk));
|
||||
*fclk = f_clk;
|
||||
*mclk = m_clk;
|
||||
|
||||
if (status != AMDSMI_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
amdsmi_status_t amdsmi_get_cpu_cclk_limit(amdsmi_cpusocket_handle socket_handle,
|
||||
uint32_t sock_ind, uint32_t *cclk)
|
||||
{
|
||||
amdsmi_status_t status;
|
||||
uint32_t c_clk;
|
||||
|
||||
if (socket_handle == nullptr)
|
||||
return AMDSMI_STATUS_INVAL;
|
||||
|
||||
amd::smi::AMDSmiCpuSocket* socket = nullptr;
|
||||
amdsmi_status_t r = get_cpu_socket_from_handle(socket_handle, &socket);
|
||||
if (r != AMDSMI_STATUS_SUCCESS)
|
||||
return r;
|
||||
|
||||
status = static_cast<amdsmi_status_t>(esmi_cclk_limit_get(sock_ind, &c_clk));
|
||||
*cclk = c_clk;
|
||||
|
||||
if (status != AMDSMI_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
amdsmi_status_t amdsmi_get_cpu_socket_current_active_freq_limit(amdsmi_cpusocket_handle socket_handle,
|
||||
uint32_t sock_ind, uint16_t *freq, char **src_type)
|
||||
{
|
||||
amdsmi_status_t status;
|
||||
uint16_t limit;
|
||||
|
||||
if (socket_handle == nullptr)
|
||||
return AMDSMI_STATUS_INVAL;
|
||||
|
||||
amd::smi::AMDSmiCpuSocket* socket = nullptr;
|
||||
amdsmi_status_t r = get_cpu_socket_from_handle(socket_handle, &socket);
|
||||
if (r != AMDSMI_STATUS_SUCCESS)
|
||||
return r;
|
||||
|
||||
status = static_cast<amdsmi_status_t>(esmi_socket_current_active_freq_limit_get(sock_ind, &limit, src_type));
|
||||
*freq = limit;
|
||||
|
||||
if (status != AMDSMI_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
amdsmi_status_t amdsmi_get_cpu_socket_freq_range(amdsmi_cpusocket_handle socket_handle,
|
||||
uint32_t sock_ind, uint16_t *fmax, uint16_t *fmin)
|
||||
{
|
||||
amdsmi_status_t status;
|
||||
uint16_t f_max;
|
||||
uint16_t f_min;
|
||||
|
||||
if (socket_handle == nullptr)
|
||||
return AMDSMI_STATUS_INVAL;
|
||||
|
||||
amd::smi::AMDSmiCpuSocket* socket = nullptr;
|
||||
amdsmi_status_t r = get_cpu_socket_from_handle(socket_handle, &socket);
|
||||
if (r != AMDSMI_STATUS_SUCCESS)
|
||||
return r;
|
||||
|
||||
status = static_cast<amdsmi_status_t>(esmi_socket_freq_range_get(sock_ind, &f_max, &f_min));
|
||||
*fmax = f_max;
|
||||
*fmin = f_min;
|
||||
|
||||
if (status != AMDSMI_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
amdsmi_status_t amdsmi_get_cpu_core_current_freq_limit(amdsmi_processor_handle processor_handle,
|
||||
uint32_t core_ind, uint32_t *freq)
|
||||
{
|
||||
amdsmi_status_t status;
|
||||
uint32_t c_clk;
|
||||
|
||||
if (processor_handle == nullptr)
|
||||
return AMDSMI_STATUS_INVAL;
|
||||
|
||||
amd::smi::AMDSmiCpuCore* core = nullptr;
|
||||
amdsmi_status_t r = get_cpu_core_from_handle(processor_handle, &core);
|
||||
if (r != AMDSMI_STATUS_SUCCESS)
|
||||
return r;
|
||||
|
||||
status = static_cast<amdsmi_status_t>(esmi_current_freq_limit_core_get(core_ind, &c_clk));
|
||||
*freq = c_clk;
|
||||
|
||||
if (status != AMDSMI_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
amdsmi_status_t amdsmi_get_cpu_socket_power(amdsmi_cpusocket_handle socket_handle,
|
||||
uint32_t sock_ind, uint32_t *ppower)
|
||||
{
|
||||
amdsmi_status_t status;
|
||||
uint32_t avg_power;
|
||||
|
||||
if (socket_handle == nullptr)
|
||||
return AMDSMI_STATUS_INVAL;
|
||||
|
||||
amd::smi::AMDSmiCpuSocket* socket = nullptr;
|
||||
amdsmi_status_t r = get_cpu_socket_from_handle(socket_handle, &socket);
|
||||
if (r != AMDSMI_STATUS_SUCCESS)
|
||||
return r;
|
||||
|
||||
status = static_cast<amdsmi_status_t>(esmi_socket_power_get(sock_ind, &avg_power));
|
||||
*ppower = avg_power;
|
||||
|
||||
if (status != AMDSMI_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
amdsmi_status_t amdsmi_get_cpu_socket_power_cap(amdsmi_cpusocket_handle socket_handle,
|
||||
uint32_t sock_ind, uint32_t *pcap)
|
||||
{
|
||||
amdsmi_status_t status;
|
||||
uint32_t p_cap;
|
||||
|
||||
if (socket_handle == nullptr)
|
||||
return AMDSMI_STATUS_INVAL;
|
||||
|
||||
amd::smi::AMDSmiCpuSocket* socket = nullptr;
|
||||
amdsmi_status_t r = get_cpu_socket_from_handle(socket_handle, &socket);
|
||||
if (r != AMDSMI_STATUS_SUCCESS)
|
||||
return r;
|
||||
|
||||
status = static_cast<amdsmi_status_t>(esmi_socket_power_cap_get(sock_ind, &p_cap));
|
||||
*pcap = p_cap;
|
||||
|
||||
if (status != AMDSMI_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
amdsmi_status_t amdsmi_get_cpu_socket_power_cap_max(amdsmi_cpusocket_handle socket_handle,
|
||||
uint32_t sock_ind, uint32_t *pmax)
|
||||
{
|
||||
amdsmi_status_t status;
|
||||
uint32_t p_max;
|
||||
|
||||
if (socket_handle == nullptr)
|
||||
return AMDSMI_STATUS_INVAL;
|
||||
|
||||
amd::smi::AMDSmiCpuSocket* socket = nullptr;
|
||||
amdsmi_status_t r = get_cpu_socket_from_handle(socket_handle, &socket);
|
||||
if (r != AMDSMI_STATUS_SUCCESS)
|
||||
return r;
|
||||
|
||||
status = static_cast<amdsmi_status_t>(esmi_socket_power_cap_max_get(sock_ind, &p_max));
|
||||
*pmax = p_max;
|
||||
|
||||
if (status != AMDSMI_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
amdsmi_status_t amdsmi_get_cpu_pwr_svi_telemetry_all_rails(amdsmi_cpusocket_handle socket_handle,
|
||||
uint32_t sock_ind, uint32_t *power)
|
||||
{
|
||||
amdsmi_status_t status;
|
||||
uint32_t pow;
|
||||
|
||||
if (socket_handle == nullptr)
|
||||
return AMDSMI_STATUS_INVAL;
|
||||
|
||||
amd::smi::AMDSmiCpuSocket* socket = nullptr;
|
||||
amdsmi_status_t r = get_cpu_socket_from_handle(socket_handle, &socket);
|
||||
if (r != AMDSMI_STATUS_SUCCESS)
|
||||
return r;
|
||||
|
||||
status = static_cast<amdsmi_status_t>(esmi_pwr_svi_telemetry_all_rails_get(sock_ind, &pow));
|
||||
*power = pow;
|
||||
|
||||
if (status != AMDSMI_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
amdsmi_status_t amdsmi_get_number_of_cpu_sockets(uint32_t sockets)
|
||||
{
|
||||
amdsmi_status_t status = amd::smi::AMDSmiSystem::getInstance().get_cpu_sockets(sockets);
|
||||
if (status != AMDSMI_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
amdsmi_status_t amdsmi_get_number_of_cpu_cores(uint32_t cpus)
|
||||
{
|
||||
amdsmi_status_t status = amd::smi::AMDSmiSystem::getInstance().get_cpu_cores(cpus);
|
||||
if (status != AMDSMI_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
amdsmi_status_t amdsmi_get_cpu_threads_per_core(uint32_t threads)
|
||||
{
|
||||
amdsmi_status_t status = amd::smi::AMDSmiSystem::getInstance().get_threads_per_core(threads);
|
||||
if (status != AMDSMI_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
amdsmi_status_t amdsmi_get_cpu_family(uint32_t family)
|
||||
{
|
||||
amdsmi_status_t status = amd::smi::AMDSmiSystem::getInstance().get_cpu_family(family);
|
||||
if (status != AMDSMI_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
amdsmi_status_t amdsmi_get_cpu_model(uint32_t model)
|
||||
{
|
||||
amdsmi_status_t status = amd::smi::AMDSmiSystem::getInstance().get_cpu_model(model);
|
||||
if (status != AMDSMI_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -63,5 +63,21 @@ amdsmi_status_t rsmi_to_amdsmi_status(rsmi_status_t status) {
|
||||
return amdsmi_status;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_ESMI_LIB
|
||||
amdsmi_status_t esmi_to_amdsmi_status(esmi_status_t status) {
|
||||
amdsmi_status_t amdsmi_status = AMDSMI_STATUS_MAP_ERROR;
|
||||
|
||||
// Look for it in the map
|
||||
// If found: use the mapped value
|
||||
// If not found: return the map error established above
|
||||
auto search = amd::smi::esmi_status_map.find(status);
|
||||
if (search != amd::smi::esmi_status_map.end()) {
|
||||
amdsmi_status = search->second;
|
||||
}
|
||||
|
||||
return amdsmi_status;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace smi
|
||||
} // namespace amd
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* =============================================================================
|
||||
* The University of Illinois/NCSA
|
||||
* Open Source License (NCSA)
|
||||
*
|
||||
* Copyright (c) 2022, Advanced Micro Devices, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Developed by:
|
||||
*
|
||||
* AMD Research and AMD ROC Software Development
|
||||
*
|
||||
* Advanced Micro Devices, Inc.
|
||||
*
|
||||
* www.amd.com
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal with the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimers.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimers in
|
||||
* the documentation and/or other materials provided with the distribution.
|
||||
* - Neither the names of <Name of Development Group, Name of Institution>,
|
||||
* nor the names of its contributors may be used to endorse or promote
|
||||
* products derived from this Software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS WITH THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <functional>
|
||||
#include "amd_smi/impl/amd_smi_cpu_core.h"
|
||||
|
||||
namespace amd {
|
||||
namespace smi {
|
||||
AMDSmiCpuCore::~AMDSmiCpuCore() {
|
||||
for (uint32_t i = 0; i < processors_.size(); i++) {
|
||||
delete processors_[i];
|
||||
}
|
||||
processors_.clear();
|
||||
}
|
||||
|
||||
amdsmi_status_t AMDSmiCpuCore::get_processor_count(uint32_t* processor_count) const {
|
||||
*processor_count = static_cast<uint32_t>(processors_.size());
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
} // namespace smi
|
||||
} // namespace amd
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* =============================================================================
|
||||
* The University of Illinois/NCSA
|
||||
* Open Source License (NCSA)
|
||||
*
|
||||
* Copyright (c) 2022, Advanced Micro Devices, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Developed by:
|
||||
*
|
||||
* AMD Research and AMD ROC Software Development
|
||||
*
|
||||
* Advanced Micro Devices, Inc.
|
||||
*
|
||||
* www.amd.com
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal with the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimers.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimers in
|
||||
* the documentation and/or other materials provided with the distribution.
|
||||
* - Neither the names of <Name of Development Group, Name of Institution>,
|
||||
* nor the names of its contributors may be used to endorse or promote
|
||||
* products derived from this Software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS WITH THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <functional>
|
||||
#include "amd_smi/impl/amd_smi_cpu_socket.h"
|
||||
#include <cpuid.h>
|
||||
|
||||
namespace amd {
|
||||
namespace smi {
|
||||
|
||||
AMDSmiCpuSocket::~AMDSmiCpuSocket() {}
|
||||
|
||||
amdsmi_status_t AMDSmiCpuSocket::set_socket_id(uint32_t idx, uint32_t socket_id) {
|
||||
socket_id = idx;
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
amdsmi_status_t AMDSmiCpuSocket::get_cpu_vendor() {
|
||||
uint32_t eax, ebx, ecx, edx;
|
||||
|
||||
if (!__get_cpuid(0, &eax, &ebx, &ecx, &edx))
|
||||
return AMDSMI_STATUS_IO;
|
||||
|
||||
/* check if the value in ebx, ecx, edx matches "AuthenticAMD" string */
|
||||
if (ebx != 0x68747541 || ecx != 0x444d4163 || edx != 0x69746e65)
|
||||
return AMDSMI_STATUS_NON_AMD_CPU;
|
||||
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
} // namespace smi
|
||||
} // namespace amd
|
||||
+191
-2
@@ -47,11 +47,20 @@
|
||||
#include "amd_smi/impl/amd_smi_common.h"
|
||||
#include "rocm_smi/rocm_smi.h"
|
||||
#include "rocm_smi/rocm_smi_main.h"
|
||||
#include <fstream>
|
||||
|
||||
|
||||
namespace amd {
|
||||
namespace smi {
|
||||
|
||||
#ifdef ENABLE_ESMI_LIB
|
||||
uint32_t AMDSmiSystem::sockets = 0;
|
||||
uint32_t AMDSmiSystem::cpus = 0;
|
||||
uint32_t AMDSmiSystem::threads = 0;
|
||||
uint32_t AMDSmiSystem::family = 0;
|
||||
uint32_t AMDSmiSystem::model = 0;
|
||||
#endif
|
||||
|
||||
#define AMD_SMI_INIT_FLAG_RESRV_TEST1 0x800000000000000 //!< Reserved for test
|
||||
|
||||
amdsmi_status_t AMDSmiSystem::init(uint64_t flags) {
|
||||
@@ -62,12 +71,141 @@ amdsmi_status_t AMDSmiSystem::init(uint64_t flags) {
|
||||
amd_smi_status = populate_amd_gpu_devices();
|
||||
if (amd_smi_status != AMDSMI_STATUS_SUCCESS)
|
||||
return amd_smi_status;
|
||||
} else { // Currently only support AMD GPU
|
||||
#ifdef ENABLE_ESMI_LIB
|
||||
}
|
||||
else if(flags & AMDSMI_INIT_AMD_CPUS) {
|
||||
amd_smi_status = populate_amd_cpus();
|
||||
if (amd_smi_status != AMDSMI_STATUS_SUCCESS)
|
||||
return amd_smi_status;
|
||||
#endif
|
||||
} else {
|
||||
return AMDSMI_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_ESMI_LIB
|
||||
amdsmi_status_t AMDSmiSystem::populate_amd_cpus() {
|
||||
amdsmi_status_t amd_smi_status;
|
||||
amd::smi::AMDSmiCpuSocket *cpu_instance = nullptr;
|
||||
|
||||
/* detect if its an AMD cpu */
|
||||
amd_smi_status = cpu_instance->get_cpu_vendor();
|
||||
/* esmi is for AMD cpus, if its not AMD CPU, we are not going to initialise esmi */
|
||||
if (!amd_smi_status) {
|
||||
amd_smi_status = static_cast<amdsmi_status_t>(esmi_init());
|
||||
if (amd_smi_status != AMDSMI_STATUS_SUCCESS){
|
||||
std::cout<<"\tESMI Not initialized, drivers not found " << std::endl;
|
||||
return amd_smi_status;
|
||||
}
|
||||
}
|
||||
|
||||
amd_smi_status = get_cpu_sockets(sockets);
|
||||
amd_smi_status = get_cpu_cores(cpus);
|
||||
amd_smi_status = get_threads_per_core(threads);
|
||||
amd_smi_status = get_cpu_family(family);
|
||||
amd_smi_status = get_cpu_model(model);
|
||||
std::cout << "\n***********************EPYC METRICS***********************" << std::endl;
|
||||
std::cout <<"| NR_SOCKETS | "<<sockets<<"\t\t|" << std::endl;
|
||||
std::cout <<"| NR_CPUS | "<<cpus<<"\t\t|" << std::endl;
|
||||
|
||||
if (threads > 1) {
|
||||
std::cout <<"| THREADS PER CORE | "<<threads<<" (SMT ON)\t|" << std::endl;
|
||||
} else {
|
||||
std::cout <<"| THREADS PER CORE | "<<threads<<" (SMT OFF)\t|" << std::endl;
|
||||
}
|
||||
std::cout <<"| CPU Family | 0x"<<std::hex<<family<<"("<<std::dec<<family<<")\t|" << std::endl;
|
||||
std::cout <<"| CPU Model | 0x"<<std::hex<<model<<"("<<std::dec<<model<<")\t|" << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
for(uint32_t i = 0; i < sockets; i++) {
|
||||
uint32_t cpu_socket_id = i;
|
||||
|
||||
// Multiple cores may share the same socket
|
||||
AMDSmiCpuSocket* socket = nullptr;
|
||||
for (uint32_t j = 0; j < cpu_sockets_.size(); j++) {
|
||||
if (cpu_sockets_[j]->get_socket_id() == cpu_socket_id) {
|
||||
socket = cpu_sockets_[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (socket == nullptr) {
|
||||
socket = new AMDSmiCpuSocket(cpu_socket_id);
|
||||
cpu_sockets_.push_back(socket);
|
||||
}
|
||||
|
||||
for (uint32_t k = 0; k < cpus/threads; k++) {
|
||||
AMDSmiCpuCore* core = new AMDSmiCpuCore(k);
|
||||
socket->add_processor(core);
|
||||
processors_.insert(core);
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
amdsmi_status_t AMDSmiSystem::get_cpu_sockets(uint32_t num_socks) {
|
||||
amdsmi_status_t ret;
|
||||
ret = static_cast<amdsmi_status_t>(esmi_number_of_sockets_get(&num_socks));
|
||||
sockets = num_socks;
|
||||
|
||||
if (ret != AMDSMI_STATUS_SUCCESS) {
|
||||
std::cout << "Failed to get number of sockets, Err["<<ret<<"]" << std::endl;
|
||||
return ret;
|
||||
}
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
amdsmi_status_t AMDSmiSystem::get_cpu_cores(uint32_t num_cpus) {
|
||||
amdsmi_status_t ret;
|
||||
ret = static_cast<amdsmi_status_t>(esmi_number_of_cpus_get(&num_cpus));
|
||||
cpus = num_cpus;
|
||||
|
||||
if (ret != AMDSMI_STATUS_SUCCESS) {
|
||||
std::cout << "Failed to get number of cpus, Err["<<ret<<"]" << std::endl;
|
||||
return ret;
|
||||
}
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
amdsmi_status_t AMDSmiSystem::get_threads_per_core(uint32_t threads_per_core) {
|
||||
amdsmi_status_t ret;
|
||||
ret = static_cast<amdsmi_status_t>(esmi_threads_per_core_get(&threads_per_core));
|
||||
threads = threads_per_core;
|
||||
|
||||
if (ret != AMDSMI_STATUS_SUCCESS) {
|
||||
std::cout << "Failed to get threads per core, Err["<<ret<<"]" << std::endl;
|
||||
return ret;
|
||||
}
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
amdsmi_status_t AMDSmiSystem::get_cpu_family(uint32_t cpu_family) {
|
||||
amdsmi_status_t ret;
|
||||
ret = static_cast<amdsmi_status_t>(esmi_cpu_family_get(&cpu_family));
|
||||
family = cpu_family;
|
||||
|
||||
if (ret != AMDSMI_STATUS_SUCCESS) {
|
||||
std::cout << "Failed to get cpu family, Err["<<ret<<"]" << std::endl;
|
||||
return ret;
|
||||
}
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
amdsmi_status_t AMDSmiSystem::get_cpu_model(uint32_t cpu_model) {
|
||||
amdsmi_status_t ret;
|
||||
ret = static_cast<amdsmi_status_t>(esmi_cpu_model_get(&cpu_model));
|
||||
model = cpu_model;
|
||||
|
||||
if (ret != AMDSMI_STATUS_SUCCESS) {
|
||||
std::cout << "Failed to get cpu model, Err["<<ret<<"]" << std::endl;
|
||||
return ret;
|
||||
}
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
amdsmi_status_t AMDSmiSystem::populate_amd_gpu_devices() {
|
||||
// init rsmi
|
||||
rsmi_status_t ret = rsmi_init(0);
|
||||
@@ -135,6 +273,18 @@ amdsmi_status_t AMDSmiSystem::get_gpu_bdf_by_index(uint32_t index,
|
||||
}
|
||||
|
||||
amdsmi_status_t AMDSmiSystem::cleanup() {
|
||||
#ifdef ENABLE_ESMI_LIB
|
||||
if(init_flag_ == AMDSMI_INIT_AMD_CPUS){
|
||||
for (uint32_t i = 0; i < cpu_sockets_.size(); i++) {
|
||||
delete cpu_sockets_[i];
|
||||
}
|
||||
cpu_sockets_.clear();
|
||||
processors_.clear();
|
||||
esmi_exit();
|
||||
init_flag_ = AMDSMI_INIT_ALL_PROCESSORS;
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
for (uint32_t i = 0; i < sockets_.size(); i++) {
|
||||
delete sockets_[i];
|
||||
}
|
||||
@@ -166,6 +316,24 @@ amdsmi_status_t AMDSmiSystem::handle_to_socket(
|
||||
return AMDSMI_STATUS_INVAL;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_ESMI_LIB
|
||||
amdsmi_status_t AMDSmiSystem::handle_to_cpusocket(
|
||||
amdsmi_cpusocket_handle socket_handle,
|
||||
AMDSmiCpuSocket** socket) {
|
||||
if (socket_handle == nullptr || socket == nullptr) {
|
||||
return AMDSMI_STATUS_INVAL;
|
||||
}
|
||||
*socket = static_cast<AMDSmiCpuSocket*>(socket_handle);
|
||||
|
||||
// double check handlers is here
|
||||
if (std::find(cpu_sockets_.begin(), cpu_sockets_.end(), *socket)
|
||||
!= cpu_sockets_.end()) {
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
return AMDSMI_STATUS_INVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
amdsmi_status_t AMDSmiSystem::handle_to_processor(
|
||||
amdsmi_processor_handle processor_handle,
|
||||
AMDSmiProcessor** processor) {
|
||||
@@ -203,7 +371,28 @@ amdsmi_status_t AMDSmiSystem::gpu_index_to_handle(uint32_t gpu_index,
|
||||
return AMDSMI_STATUS_INVAL;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_ESMI_LIB
|
||||
amdsmi_status_t AMDSmiSystem::cpu_index_to_handle(uint32_t cpu_index,
|
||||
amdsmi_cpusocket_handle* cpu_handle) {
|
||||
if (cpu_handle == nullptr)
|
||||
return AMDSMI_STATUS_INVAL;
|
||||
|
||||
auto iter = cpu_sockets_.begin();
|
||||
for (; iter != cpu_sockets_.end(); iter++) {
|
||||
auto cur_socket = (*iter);
|
||||
if (cur_socket->get_processor_type() != AMD_CPU)
|
||||
continue;
|
||||
amd::smi::AMDSmiCpuSocket* cpu_socket =
|
||||
static_cast<amd::smi::AMDSmiCpuSocket*>(cur_socket);
|
||||
uint32_t cur_cpu_index = cpu_socket->get_cpu_id();
|
||||
if (cpu_index == cur_cpu_index) {
|
||||
*cpu_handle = cur_socket;
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
return AMDSMI_STATUS_INVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace smi
|
||||
} // namespace amd
|
||||
|
||||
|
||||
@@ -217,7 +217,7 @@ amdsmi_status_t smi_amdgpu_get_ranges(amd::smi::AMDSmiGPUDevice* device, amdsmi_
|
||||
}
|
||||
|
||||
max = 0;
|
||||
min = -1;
|
||||
min = UINT_MAX;
|
||||
dpm = 0;
|
||||
for (std::string line; getline(ranges, line);) {
|
||||
unsigned int d, freq;
|
||||
|
||||
@@ -91,7 +91,7 @@ void TestSysInfoRead::Run(void) {
|
||||
uint64_t val_ui64;
|
||||
uint32_t val_ui32;
|
||||
char buffer[80];
|
||||
amdsmi_version_t ver = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, nullptr};
|
||||
amdsmi_version_t ver = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, nullptr};
|
||||
|
||||
TestBase::Run();
|
||||
if (setup_failed_) {
|
||||
@@ -177,15 +177,17 @@ void TestSysInfoRead::Run(void) {
|
||||
}
|
||||
}
|
||||
|
||||
err = amdsmi_get_lib_version(&ver);
|
||||
CHK_ERR_ASRT(err)
|
||||
err = amdsmi_get_lib_version(&ver);
|
||||
CHK_ERR_ASRT(err)
|
||||
|
||||
ASSERT_TRUE(ver.major != 0xFFFFFFFF && ver.minor != 0xFFFFFFFF &&
|
||||
ver.patch != 0xFFFFFFFF && ver.build != nullptr);
|
||||
IF_VERB(STANDARD) {
|
||||
std::cout << "\t**RocM SMI Library version: " << ver.major << "." <<
|
||||
ver.minor << "." << ver.patch << " (" << ver.build << ")" << std::endl;
|
||||
}
|
||||
ASSERT_TRUE(ver.year != 0xFFFFFFFF && ver.major != 0xFFFFFFFF &&
|
||||
ver.minor != 0xFFFFFFFF && ver.release != 0xFFFFFFFF &&
|
||||
ver.build != nullptr);
|
||||
IF_VERB(STANDARD) {
|
||||
std::cout << "\t**AMD SMI Library version: " << ver.year << "." <<
|
||||
ver.major << "." << ver.minor << "." << ver.release <<
|
||||
" (" << ver.build << ")" << std::endl;
|
||||
}
|
||||
|
||||
std::cout << std::setbase(10);
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ static const uint32_t kVerMaxStrLen = 80;
|
||||
|
||||
void TestVersionRead::Run(void) {
|
||||
amdsmi_status_t err;
|
||||
amdsmi_version_t ver = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, nullptr};
|
||||
amdsmi_version_t ver = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, nullptr};
|
||||
|
||||
TestBase::Run();
|
||||
if (setup_failed_) {
|
||||
@@ -99,10 +99,12 @@ void TestVersionRead::Run(void) {
|
||||
err = amdsmi_get_lib_version(&ver);
|
||||
CHK_ERR_ASRT(err)
|
||||
|
||||
ASSERT_TRUE(ver.major != 0xFFFFFFFF && ver.minor != 0xFFFFFFFF &&
|
||||
ver.patch != 0xFFFFFFFF && ver.build != nullptr);
|
||||
ASSERT_TRUE(ver.year != 0xFFFFFFFF && ver.major != 0xFFFFFFFF &&
|
||||
ver.minor != 0xFFFFFFFF && ver.release != 0xFFFFFFFF &&
|
||||
ver.build != nullptr);
|
||||
IF_VERB(STANDARD) {
|
||||
std::cout << "\t**AMD SMI Library version: " << ver.major << "." <<
|
||||
ver.minor << "." << ver.patch << " (" << ver.build << ")" << std::endl;
|
||||
std::cout << "\t**AMD SMI Library version: " << ver.year << "." <<
|
||||
ver.major << "." << ver.minor << "." << ver.release <<
|
||||
" (" << ver.build << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
+16
-12
@@ -111,18 +111,22 @@ libamd_smi_optrocm = Path("/opt/rocm/lib/{library_name}")
|
||||
libamd_smi_parent_dir = Path(__file__).resolve().parent / "{library_name}"
|
||||
libamd_smi_cwd = Path.cwd() / "{library_name}"
|
||||
|
||||
if libamd_smi_cpack.is_file():
|
||||
# try to find library in install directory provided by CMake
|
||||
_libraries['{library_name}'] = ctypes.CDLL(libamd_smi_cpack)
|
||||
elif libamd_smi_optrocm.is_file():
|
||||
# try /opt/rocm/lib as a fallback
|
||||
_libraries['{library_name}'] = ctypes.CDLL(libamd_smi_optrocm)
|
||||
elif libamd_smi_parent_dir.is_file():
|
||||
# try to fall back to parent directory
|
||||
_libraries['{library_name}'] = ctypes.CDLL(libamd_smi_parent_dir)
|
||||
else:
|
||||
# lastly - search in current working directory
|
||||
_libraries['{library_name}'] = ctypes.CDLL(libamd_smi_cwd)"""
|
||||
try:
|
||||
if libamd_smi_cpack.is_file():
|
||||
# try to find library in install directory provided by CMake
|
||||
_libraries['{library_name}'] = ctypes.CDLL(libamd_smi_cpack)
|
||||
elif libamd_smi_optrocm.is_file():
|
||||
# try /opt/rocm/lib as a fallback
|
||||
_libraries['{library_name}'] = ctypes.CDLL(libamd_smi_optrocm)
|
||||
elif libamd_smi_parent_dir.is_file():
|
||||
# try to fall back to parent directory
|
||||
_libraries['{library_name}'] = ctypes.CDLL(libamd_smi_parent_dir)
|
||||
else:
|
||||
# lastly - search in current working directory
|
||||
_libraries['{library_name}'] = ctypes.CDLL(libamd_smi_cwd)
|
||||
except OSError as error:
|
||||
print(error)
|
||||
print("Unable to find amdsmi library try installing amd-smi-lib from your package manager")"""
|
||||
else:
|
||||
print("Unknown operating system. It is only supporing Linux and Windows.")
|
||||
return
|
||||
|
||||
新增問題並參考
封鎖使用者