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:
@@ -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**.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user