SWDEV-417124 - Implement Power Management
Signed-off-by: Maisam Arif <maisarif@amd.com>
Change-Id: Ib0d37038e49cec61d5415076a46a5666d95dcea2
[ROCm/amdsmi commit: e4fac177c1]
このコミットが含まれているのは:
@@ -850,28 +850,37 @@ class AMDSMICommands():
|
||||
|
||||
if self.helpers.is_linux() and self.helpers.is_baremetal():
|
||||
if args.power:
|
||||
power_dict = {}
|
||||
power_dict = {'average_socket_power': "N/A",
|
||||
'gfx_voltage': "N/A",
|
||||
'soc_voltage': "N/A",
|
||||
'mem_voltage': "N/A",
|
||||
'power_limit': "N/A",
|
||||
'power_management': "N/A"}
|
||||
|
||||
try:
|
||||
is_power_management_enabled = amdsmi_interface.amdsmi_is_gpu_power_management_enabled(args.gpu)
|
||||
if is_power_management_enabled:
|
||||
power_dict['power_management'] = "ENABLED"
|
||||
else:
|
||||
power_dict['power_management'] = "DISABLED"
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
logging.debug("Failed to get power management status for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
|
||||
try:
|
||||
power_measure = amdsmi_interface.amdsmi_get_power_info(args.gpu)
|
||||
power_dict = {'average_socket_power': power_measure['average_socket_power'],
|
||||
'gfx_voltage': power_measure['gfx_voltage'],
|
||||
'soc_voltage': power_measure['soc_voltage'],
|
||||
'mem_voltage': power_measure['mem_voltage'],
|
||||
'power_limit': power_measure['power_limit']}
|
||||
power_dict['average_socket_power'] = power_measure['average_socket_power']
|
||||
power_dict['gfx_voltage'] = power_measure['gfx_voltage']
|
||||
power_dict['soc_voltage'] = power_measure['soc_voltage']
|
||||
power_dict['mem_voltage'] = power_measure['mem_voltage']
|
||||
power_dict['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'] = f"{power_dict['soc_voltage']} mV"
|
||||
power_dict['mem_voltage'] = f"{power_dict['mem_voltage']} mV"
|
||||
power_dict['power_limit'] = f"{power_dict['power_limit']} W"
|
||||
|
||||
power_dict['average_socket_power'] = f"{power_measure['average_socket_power']} W"
|
||||
power_dict['gfx_voltage'] = f"{power_measure['gfx_voltage']} mV"
|
||||
power_dict['soc_voltage'] = f"{power_measure['soc_voltage']} mV"
|
||||
power_dict['mem_voltage'] = f"{power_measure['mem_voltage']} mV"
|
||||
power_dict['power_limit'] = f"{power_measure['power_limit']} W"
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
power_dict = {'average_socket_power': "N/A",
|
||||
'gfx_voltage': "N/A",
|
||||
'soc_voltage': "N/A",
|
||||
'mem_voltage': "N/A",
|
||||
'power_limit': "N/A"}
|
||||
logging.debug("Failed to get power info for gpu %s | %s", args.gpu, e.get_error_info())
|
||||
|
||||
if self.logger.is_gpuvsmi_compatibility():
|
||||
|
||||
@@ -3591,6 +3591,18 @@ amdsmi_get_gpu_activity(amdsmi_processor_handle processor_handle, amdsmi_engine_
|
||||
amdsmi_status_t
|
||||
amdsmi_get_power_info(amdsmi_processor_handle processor_handle, amdsmi_power_info_t *info);
|
||||
|
||||
/**
|
||||
* @brief Returns is power management enabled
|
||||
*
|
||||
* @param[in] processor_handle PF of a processor for which to query
|
||||
*
|
||||
* @param[out] status Reference to bool. Must be allocated by user.
|
||||
*
|
||||
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
|
||||
*/
|
||||
amdsmi_status_t
|
||||
amdsmi_is_gpu_power_management_enabled(amdsmi_processor_handle processor_handle, bool *enabled);
|
||||
|
||||
/**
|
||||
* @brief Returns the measurements of the clocks in the GPU
|
||||
* for the GFX and multimedia engines and Memory. This call
|
||||
|
||||
@@ -43,5 +43,6 @@ amdsmi_status_t smi_amdgpu_get_ecc_error_count(amd::smi::AMDSmiGPUDevice* device
|
||||
amdsmi_status_t smi_amdgpu_get_driver_version(amd::smi::AMDSmiGPUDevice* device, int *length, char *version);
|
||||
amdsmi_status_t smi_amdgpu_get_pcie_speed_from_pcie_type(uint16_t pcie_type, uint32_t *pcie_speed);
|
||||
amdsmi_status_t smi_amdgpu_get_market_name_from_dev_id(uint32_t device_id, char *market_name);
|
||||
amdsmi_status_t smi_amdgpu_is_gpu_power_management_enabled(amd::smi::AMDSmiGPUDevice* device, bool *enabled);
|
||||
|
||||
#endif //
|
||||
|
||||
@@ -1641,6 +1641,33 @@ except AmdSmiException as e:
|
||||
print(e)
|
||||
```
|
||||
|
||||
## amdsmi_is_gpu_power_management_enabled
|
||||
Description: Returns is power management enabled
|
||||
|
||||
Input parameters:
|
||||
* `processor_handle` GPU device which to query
|
||||
|
||||
Output: Bool true if power management enabled else false
|
||||
|
||||
Exceptions that can be thrown by `amdsmi_is_gpu_power_management_enabled` function:
|
||||
* `AmdSmiLibraryException`
|
||||
* `AmdSmiRetryException`
|
||||
* `AmdSmiParameterException`
|
||||
|
||||
Example:
|
||||
```python
|
||||
try:
|
||||
processors = amdsmi_get_processor_handles()
|
||||
if len(processors) == 0:
|
||||
print("No GPUs on machine")
|
||||
else:
|
||||
for processor in processors:
|
||||
is_power_management_enabled = amdsmi_is_gpu_power_management_enabled(processor)
|
||||
print(is_power_management_enabled)
|
||||
except AmdSmiException as e:
|
||||
print(e)
|
||||
```
|
||||
|
||||
### amdsmi_get_temp_metric
|
||||
|
||||
Description: Get the temperature metric value for the specified metric, from the
|
||||
|
||||
@@ -99,7 +99,7 @@ from .amdsmi_interface import amdsmi_get_clk_freq
|
||||
from .amdsmi_interface import amdsmi_get_gpu_od_volt_info
|
||||
from .amdsmi_interface import amdsmi_get_gpu_metrics_info
|
||||
from .amdsmi_interface import amdsmi_get_gpu_od_volt_curve_regions
|
||||
from .amdsmi_interface import amdsmi_get_gpu_power_profile_presets
|
||||
from .amdsmi_interface import amdsmi_is_gpu_power_management_enabled
|
||||
|
||||
# # Performance Counters
|
||||
from .amdsmi_interface import amdsmi_gpu_counter_group_supported
|
||||
|
||||
@@ -962,12 +962,28 @@ def amdsmi_get_power_info(
|
||||
return {
|
||||
"average_socket_power": power_measure.average_socket_power,
|
||||
"gfx_voltage": power_measure.gfx_voltage,
|
||||
'soc_voltage': power_measure.soc_voltage,
|
||||
'mem_voltage': power_measure.mem_voltage,
|
||||
"soc_voltage": power_measure.soc_voltage,
|
||||
"mem_voltage": power_measure.mem_voltage,
|
||||
"power_limit" : power_measure.power_limit,
|
||||
}
|
||||
|
||||
|
||||
def amdsmi_is_gpu_power_management_enabled(
|
||||
processor_handle: amdsmi_wrapper.amdsmi_processor_handle
|
||||
) -> bool:
|
||||
if not isinstance(processor_handle, amdsmi_wrapper.amdsmi_processor_handle):
|
||||
raise AmdSmiParameterException(processor_handle, amdsmi_wrapper.amdsmi_processor_handle)
|
||||
|
||||
is_power_management_enabled = ctypes.c_bool()
|
||||
_check_res(
|
||||
amdsmi_wrapper.amdsmi_is_gpu_power_management_enabled(
|
||||
processor_handle, ctypes.byref(is_power_management_enabled)
|
||||
)
|
||||
)
|
||||
|
||||
return is_power_management_enabled.value
|
||||
|
||||
|
||||
def amdsmi_get_fw_info(
|
||||
processor_handle: amdsmi_wrapper.amdsmi_processor_handle
|
||||
) -> List[Dict[str, Any]]:
|
||||
|
||||
@@ -276,6 +276,7 @@ amdsmi_status_t__enumvalues = {
|
||||
31: 'AMDSMI_STATUS_NOT_FOUND',
|
||||
32: 'AMDSMI_STATUS_NOT_INIT',
|
||||
33: 'AMDSMI_STATUS_NO_SLOT',
|
||||
34: 'AMDSMI_STATUS_DRIVER_NOT_LOADED',
|
||||
40: 'AMDSMI_STATUS_NO_DATA',
|
||||
41: 'AMDSMI_STATUS_INSUFFICIENT_SIZE',
|
||||
42: 'AMDSMI_STATUS_UNEXPECTED_SIZE',
|
||||
@@ -317,6 +318,7 @@ AMDSMI_STATUS_BUSY = 30
|
||||
AMDSMI_STATUS_NOT_FOUND = 31
|
||||
AMDSMI_STATUS_NOT_INIT = 32
|
||||
AMDSMI_STATUS_NO_SLOT = 33
|
||||
AMDSMI_STATUS_DRIVER_NOT_LOADED = 34
|
||||
AMDSMI_STATUS_NO_DATA = 40
|
||||
AMDSMI_STATUS_INSUFFICIENT_SIZE = 41
|
||||
AMDSMI_STATUS_UNEXPECTED_SIZE = 42
|
||||
@@ -1712,6 +1714,9 @@ amdsmi_get_gpu_activity.argtypes = [amdsmi_processor_handle, ctypes.POINTER(stru
|
||||
amdsmi_get_power_info = _libraries['libamd_smi.so'].amdsmi_get_power_info
|
||||
amdsmi_get_power_info.restype = amdsmi_status_t
|
||||
amdsmi_get_power_info.argtypes = [amdsmi_processor_handle, ctypes.POINTER(struct_amdsmi_power_info_t)]
|
||||
amdsmi_is_gpu_power_management_enabled = _libraries['libamd_smi.so'].amdsmi_is_gpu_power_management_enabled
|
||||
amdsmi_is_gpu_power_management_enabled.restype = amdsmi_status_t
|
||||
amdsmi_is_gpu_power_management_enabled.argtypes = [amdsmi_processor_handle, ctypes.POINTER(ctypes.c_bool)]
|
||||
amdsmi_get_clock_info = _libraries['libamd_smi.so'].amdsmi_get_clock_info
|
||||
amdsmi_get_clock_info.restype = amdsmi_status_t
|
||||
amdsmi_get_clock_info.argtypes = [amdsmi_processor_handle, amdsmi_clk_type_t, ctypes.POINTER(struct_amdsmi_clk_info_t)]
|
||||
@@ -1794,7 +1799,8 @@ __all__ = \
|
||||
'AMDSMI_RAS_ERR_STATE_PARITY', 'AMDSMI_RAS_ERR_STATE_POISON',
|
||||
'AMDSMI_RAS_ERR_STATE_SING_C', 'AMDSMI_STATUS_ADDRESS_FAULT',
|
||||
'AMDSMI_STATUS_API_FAILED', 'AMDSMI_STATUS_BUSY',
|
||||
'AMDSMI_STATUS_DRM_ERROR', 'AMDSMI_STATUS_FAIL_LOAD_MODULE',
|
||||
'AMDSMI_STATUS_DRIVER_NOT_LOADED', 'AMDSMI_STATUS_DRM_ERROR',
|
||||
'AMDSMI_STATUS_FAIL_LOAD_MODULE',
|
||||
'AMDSMI_STATUS_FAIL_LOAD_SYMBOL', 'AMDSMI_STATUS_FILE_ERROR',
|
||||
'AMDSMI_STATUS_INIT_ERROR', 'AMDSMI_STATUS_INPUT_OUT_OF_BOUNDS',
|
||||
'AMDSMI_STATUS_INSUFFICIENT_SIZE',
|
||||
@@ -1936,6 +1942,7 @@ __all__ = \
|
||||
'amdsmi_gpu_read_counter', 'amdsmi_gpu_xgmi_error_status',
|
||||
'amdsmi_init', 'amdsmi_init_flags_t',
|
||||
'amdsmi_init_gpu_event_notification', 'amdsmi_is_P2P_accessible',
|
||||
'amdsmi_is_gpu_power_management_enabled',
|
||||
'amdsmi_memory_page_status_t', 'amdsmi_memory_type_t',
|
||||
'amdsmi_mm_ip_t', 'amdsmi_od_vddc_point_t',
|
||||
'amdsmi_od_volt_curve_t', 'amdsmi_od_volt_freq_data_t',
|
||||
|
||||
@@ -1439,6 +1439,24 @@ amdsmi_get_gpu_activity(amdsmi_processor_handle processor_handle, amdsmi_engine_
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
amdsmi_status_t amdsmi_is_gpu_power_management_enabled(amdsmi_processor_handle processor_handle, bool *enabled) {
|
||||
if (enabled == nullptr) {
|
||||
return AMDSMI_STATUS_INVAL;
|
||||
}
|
||||
*enabled = false;
|
||||
|
||||
amd::smi::AMDSmiGPUDevice * gpu_device = nullptr;
|
||||
amdsmi_status_t status;
|
||||
|
||||
status = get_gpu_device_from_handle(processor_handle, &gpu_device);
|
||||
if (status != AMDSMI_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
status = smi_amdgpu_is_gpu_power_management_enabled(gpu_device, enabled);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
amdsmi_status_t
|
||||
amdsmi_get_clock_info(amdsmi_processor_handle processor_handle, amdsmi_clk_type_t clk_type, amdsmi_clk_info_t *info) {
|
||||
AMDSMI_CHECK_INIT();
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -36,10 +35,10 @@
|
||||
#include <random>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <regex>
|
||||
#include <sstream>
|
||||
#include <sys/ioctl.h>
|
||||
#include <algorithm>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "amd_smi/impl/amd_smi_utils.h"
|
||||
@@ -499,3 +498,35 @@ amdsmi_status_t smi_amdgpu_get_market_name_from_dev_id(uint32_t device_id, char
|
||||
}
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
amdsmi_status_t smi_amdgpu_is_gpu_power_management_enabled(amd::smi::AMDSmiGPUDevice *device,
|
||||
bool *enabled) {
|
||||
if (!device->check_if_drm_is_supported()) {
|
||||
return AMDSMI_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (enabled == nullptr) {
|
||||
return AMDSMI_STATUS_API_FAILED;
|
||||
}
|
||||
|
||||
SMIGPUDEVICE_MUTEX(device->get_mutex())
|
||||
std::string fullpath = "/sys/class/drm/" + device->get_gpu_path() + std::string("/device/pp_features");
|
||||
std::ifstream fs(fullpath.c_str());
|
||||
|
||||
if (fs.fail()) {
|
||||
return AMDSMI_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
// ANY line must end with "enabled" and have space before it
|
||||
const std::regex regex(R"(.*\senabled$)");
|
||||
std::string line;
|
||||
while (std::getline(fs, line)) {
|
||||
// match the whole line against regex, not just substrings
|
||||
if (std::regex_match(line, regex)) {
|
||||
*enabled = true;
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
*enabled = false;
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
新しいイシューから参照
ユーザーをブロックする