Merge amd-dev into amd-master 20241107

Signed-off-by: Zhang Ava <niandong.zhang@amd.com>
Change-Id: I06979911d0e335c142eea73f95dc3801611ac275


[ROCm/amdsmi commit: e0b913b30d]
This commit is contained in:
Zhang Ava
2024-11-08 10:57:45 +08:00
10 changed files with 113 additions and 60 deletions
+2
View File
@@ -591,6 +591,8 @@ GPU: 0
### Resolved issues
- **Fixed `amd-smi reset` commands showing an AttributeError**.
- **Improved Offline install process & lowered dependency for PyYAML**.
- **Fixed CPX not showing total number of logical GPUs**.
+11
View File
@@ -24,6 +24,9 @@ installed to query firmware information and hardware IPs.
### Requirements
* python 3.6.8+ 64-bit
- prerequisite modules:
- python3-wheel
- python3-setuptools
* amdgpu driver must be loaded for amdsmi_init() to pass
### Installation
@@ -91,6 +94,14 @@ Type "help", "copyright", "credits" or "license" for more information.
>>>
```
### Installing the Python Prerequisite Modules
Python3-setuptools and python3-wheel can both be installed through the pip installer as shown below:
```bash
python3 -m pip install setuptools wheel
```
## Usage Basics for the C Library
### Device/Socket handles
+51 -44
View File
@@ -4270,7 +4270,7 @@ class AMDSMICommands():
# Error if no subcommand args are passed
if self.helpers.is_baremetal():
if not any([args.gpureset, args.clocks, args.fans, args.profile, args.xgmierr, \
args.perf_determinism, args.compute_partition, args.memory_partition, \
args.perf_determinism, \
args.power_cap, args.clean_local_data]):
command = " ".join(sys.argv[1:])
raise AmdSmiRequiredCommandException(command, self.logger.format)
@@ -4337,8 +4337,8 @@ class AMDSMICommands():
logging.debug("Failed to reset fans on gpu %s | %s", gpu_id, e.get_error_info())
self.logger.store_output(args.gpu, 'reset_fans', result)
if args.profile:
reset_profile_results = {'power_profile' : '',
'performance_level': ''}
reset_profile_results = {'power_profile' : 'N/A',
'performance_level': 'N/A'}
try:
power_profile_mask = amdsmi_interface.AmdSmiPowerProfilePresetMasks.BOOTUP_DEFAULT
amdsmi_interface.amdsmi_set_gpu_power_profile(args.gpu, 0, power_profile_mask)
@@ -4349,48 +4349,48 @@ class AMDSMICommands():
reset_profile_results['power_profile'] = "N/A"
logging.debug("Failed to reset power profile on gpu %s | %s", gpu_id, e.get_error_info())
try:
level_auto = amdsmi_interface.AmdSmiDevPerfLevel.AUTO
amdsmi_interface.amdsmi_set_gpu_perf_level(args.gpu, level_auto)
reset_profile_results['performance_level'] = 'Successfully reset Performance Level'
except amdsmi_exception.AmdSmiLibraryException as e:
if e.get_error_code() == amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NO_PERM:
raise PermissionError('Command requires elevation') from e
reset_profile_results['performance_level'] = "N/A"
logging.debug("Failed to reset perf level on gpu %s | %s", gpu_id, e.get_error_info())
try:
level_auto = amdsmi_interface.AmdSmiDevPerfLevel.AUTO
amdsmi_interface.amdsmi_set_gpu_perf_level(args.gpu, level_auto)
reset_profile_results['performance_level'] = 'Successfully reset Performance Level'
except amdsmi_exception.AmdSmiLibraryException as e:
if e.get_error_code() == amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NO_PERM:
raise PermissionError('Command requires elevation') from e
reset_profile_results['performance_level'] = "N/A"
logging.debug("Failed to reset perf level on gpu %s | %s", gpu_id, e.get_error_info())
self.logger.store_output(args.gpu, 'reset_profile', reset_profile_results)
if args.xgmierr:
try:
amdsmi_interface.amdsmi_reset_gpu_xgmi_error(args.gpu)
result = 'Successfully reset XGMI Error count'
except amdsmi_exception.AmdSmiLibraryException as e:
if e.get_error_code() == amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NO_PERM:
raise PermissionError('Command requires elevation') from e
result = "N/A"
logging.debug("Failed to reset xgmi error count on gpu %s | %s", gpu_id, e.get_error_info())
self.logger.store_output(args.gpu, 'reset_xgmi_err', result)
if args.perf_determinism:
try:
level_auto = amdsmi_interface.AmdSmiDevPerfLevel.AUTO
amdsmi_interface.amdsmi_set_gpu_perf_level(args.gpu, level_auto)
result = 'Successfully disabled performance determinism'
except amdsmi_exception.AmdSmiLibraryException as e:
if e.get_error_code() == amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NO_PERM:
raise PermissionError('Command requires elevation') from e
result = "N/A"
logging.debug("Failed to set perf level on gpu %s | %s", gpu_id, e.get_error_info())
self.logger.store_output(args.gpu, 'reset_perf_determinism', result)
if args.power_cap:
try:
power_cap_info = amdsmi_interface.amdsmi_get_power_cap_info(args.gpu)
logging.debug(f"Power cap info for gpu {gpu_id} | {power_cap_info}")
default_power_cap_in_w = power_cap_info["default_power_cap"]
default_power_cap_in_w = self.helpers.convert_SI_unit(default_power_cap_in_w, AMDSMIHelpers.SI_Unit.MICRO)
current_power_cap_in_w = power_cap_info["power_cap"]
current_power_cap_in_w = self.helpers.convert_SI_unit(current_power_cap_in_w, AMDSMIHelpers.SI_Unit.MICRO)
except amdsmi_exception.AmdSmiLibraryException as e:
raise ValueError(f"Unable to get power cap info from {gpu_id}") from e
self.logger.store_output(args.gpu, 'reset_profile', reset_profile_results)
if args.xgmierr:
try:
amdsmi_interface.amdsmi_reset_gpu_xgmi_error(args.gpu)
result = 'Successfully reset XGMI Error count'
except amdsmi_exception.AmdSmiLibraryException as e:
if e.get_error_code() == amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NO_PERM:
raise PermissionError('Command requires elevation') from e
result = "N/A"
logging.debug("Failed to reset xgmi error count on gpu %s | %s", gpu_id, e.get_error_info())
self.logger.store_output(args.gpu, 'reset_xgmi_err', result)
if args.perf_determinism:
try:
level_auto = amdsmi_interface.AmdSmiDevPerfLevel.AUTO
amdsmi_interface.amdsmi_set_gpu_perf_level(args.gpu, level_auto)
result = 'Successfully disabled performance determinism'
except amdsmi_exception.AmdSmiLibraryException as e:
if e.get_error_code() == amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NO_PERM:
raise PermissionError('Command requires elevation') from e
result = "N/A"
logging.debug("Failed to set perf level on gpu %s | %s", gpu_id, e.get_error_info())
self.logger.store_output(args.gpu, 'reset_perf_determinism', result)
if args.power_cap:
try:
power_cap_info = amdsmi_interface.amdsmi_get_power_cap_info(args.gpu)
logging.debug(f"Power cap info for gpu {gpu_id} | {power_cap_info}")
default_power_cap_in_w = power_cap_info["default_power_cap"]
default_power_cap_in_w = self.helpers.convert_SI_unit(default_power_cap_in_w, AMDSMIHelpers.SI_Unit.MICRO)
current_power_cap_in_w = power_cap_info["power_cap"]
current_power_cap_in_w = self.helpers.convert_SI_unit(current_power_cap_in_w, AMDSMIHelpers.SI_Unit.MICRO)
except amdsmi_exception.AmdSmiLibraryException as e:
raise ValueError(f"Unable to get power cap info from {gpu_id}") from e
if current_power_cap_in_w == default_power_cap_in_w:
self.logger.store_output(args.gpu, 'powercap', f"Power cap is already set to {default_power_cap_in_w}")
@@ -5239,6 +5239,9 @@ class AMDSMICommands():
current_mem_cap = "N/A"
logging.debug("Failed to get current memory partition capabilties for GPU %s | %s", gpu_id, e.get_error_info())
if profile_type == 0:
profile_type = "N/A"
tabular_output_dict = {"gpu_id": gpu_id,
"memory": current_mem_cap,
"accelerator_type": profile_type,
@@ -5298,6 +5301,7 @@ class AMDSMICommands():
self.logger.store_multiple_device_output()
self.logger.print_output(multiple_device_enabled=True)
self.logger.clear_multiple_devices_ouput()
if args.accelerator:
self.logger.table_header = ''.rjust(7)
current_header = "GPU_ID".ljust(13) + \
@@ -5361,6 +5365,9 @@ class AMDSMICommands():
mem_caps_str = "N/A"
logging.debug("Failed to get accelerator partition profile for GPU %s | %s", gpu_id, e.get_error_info())
if profile_type == 0:
profile_type = "N/A"
tabular_output_dict = {"gpu_id": gpu_id,
"profile_index": profile_index,
"memory_partition_caps": mem_caps_str,
+2 -2
View File
@@ -691,11 +691,11 @@ typedef union {
typedef struct {
amdsmi_accelerator_partition_type_t profile_type; // SPX, DPX, QPX, CPX and so on
uint32_t num_partitions; // On MI300X, SPX: 1, DPX: 2, QPX: 4, CPX: 8, length of resources array
uint32_t profile_index;
amdsmi_nps_caps_t memory_caps; // Possible memory partition capabilities
uint32_t profile_index;
uint32_t num_resources; // length of index_of_resources_profile
uint32_t resources[AMDSMI_MAX_ACCELERATOR_PARTITIONS][AMDSMI_MAX_CP_PROFILE_RESOURCES];
uint64_t reserved[6];
uint64_t reserved[13];
} amdsmi_accelerator_partition_profile_t;
typedef enum {
@@ -82,6 +82,7 @@ int SameFile(const std::string fileA, const std::string fileB);
bool FileExists(char const *filename);
std::vector<std::string> globFilesExist(const std::string& filePattern);
int isRegularFile(std::string fname, bool *is_reg);
int isReadOnlyForAll(const std::string& fname, bool *is_read_only);
int ReadSysfsStr(std::string path, std::string *retStr);
int WriteSysfsStr(std::string path, std::string val);
bool IsInteger(const std::string & n_str);
@@ -71,14 +71,17 @@ validClockNames.sort()
def driverInitialized():
""" Returns true if amdgpu is found in the list of initialized modules
"""
driverInitialized = ''
try:
driverInitialized = str(subprocess.check_output("cat /sys/module/amdgpu/initstate |grep live", shell=True))
except subprocess.CalledProcessError:
pass
if len(driverInitialized) > 0:
return True
return False
driverInitialized = False
if os.path.exists("/sys/module/amdgpu") :
if os.path.exists("/sys/module/amdgpu/initstate"):
# amdgpu is loadable module
with open("/sys/module/amdgpu/initstate") as initstate:
if 'live' in initstate.read():
driverInitialized = True
else:
# amdgpu is built into the kernel
driverInitialized = True
return driverInitialized
def formatJson(device, log):
+14 -3
View File
@@ -2054,7 +2054,7 @@ rsmi_dev_gpu_clk_freq_set(uint32_t dv_ind,
return ret;
}
int ret_i;
rsmi_status_t status;
amd::smi::DevInfoTypes dev_type;
const auto & clk_type_it = kClkTypeMap.find(clk_type);
@@ -2064,9 +2064,20 @@ rsmi_dev_gpu_clk_freq_set(uint32_t dv_ind,
return RSMI_STATUS_INVALID_ARGS;
}
ret_i = dev->writeDevInfo(dev_type, freq_enable_str);
return amd::smi::ErrnoToRsmiStatus(ret_i);
status = amd::smi::ErrnoToRsmiStatus(dev->writeDevInfo(dev_type, freq_enable_str));
// If an operation is not supported, the dev file, ie /sys/class/drm/card1/device/pp_dpm_pcie
// will have read-only perms, and the OS will deny access, before the request hits the driver level
if (status == RSMI_STATUS_PERMISSION){
bool read_only = false;
int perms = amd::smi::isReadOnlyForAll(dev->path(), &read_only);
if(read_only){
return RSMI_STATUS_NOT_SUPPORTED;
}
}
return status;
CATCH
}
@@ -173,6 +173,24 @@ int isRegularFile(std::string fname, bool *is_reg) {
return 0;
}
int isReadOnlyForAll(const std::string& fname, bool *is_read_only){
struct stat file_stat;
int ret;
ret = stat(fname.c_str(), &file_stat);
if (ret) {
return errno;
}
if (is_read_only != nullptr) {
*is_read_only = (file_stat.st_mode & (S_IRUSR | S_IRGRP | S_IROTH)) && !(file_stat.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH));
} else {
ret = 1;
}
return ret;
}
int WriteSysfsStr(std::string path, std::string val) {
// On success, zero is returned. On error, -1 is returned, and
// errno is set to indicate the error.
+1 -1
View File
@@ -576,7 +576,7 @@ amdsmi_status_t smi_amdgpu_get_market_name_from_dev_id(uint32_t device_id, char
break;
case 0x74a1:
case 0x74b5:
strcpy(market_name, "MI300X-O");
strcpy(market_name, "AMD Instinct MI300X");
break;
case 0x74a2:
case 0x74b6:
@@ -4,7 +4,7 @@ option(INSTALL_GTEST "Install GTest (only useful if GTest is not already install
# Help tests find libraries at runtime
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--enable-new-dtags")
set(CMAKE_INSTALL_RPATH
"\$ORIGIN:\$ORIGIN/../../../lib"
"\$ORIGIN:\$ORIGIN/../../../lib:CPACK_PACKAGING_INSTALL_PREFIX/lib"
CACHE STRING "RUNPATH for tests. Helps find libgtest.so and libamd_smi.so")
# Download and compile googletest
@@ -76,6 +76,6 @@ install(
# Install googletest libraries with tests
install(TARGETS gtest gtest_main
DESTINATION ${SHARE_INSTALL_PREFIX}/tests
DESTINATION ${CPACK_PACKAGING_INSTALL_PREFIX}/lib
COMPONENT ${TESTS_COMPONENT})