Implement PTL support (#1957)
* Implement PTL support Signed-off-by: adapryor <Adam.pryor@amd.com> (cherry picked from commit 45bc31292e7940a3b8fca044ef7df22047b95733) Signed-off-by: Maisam Arif <Maisam.Arif@amd.com> --------- Signed-off-by: adapryor <Adam.pryor@amd.com> Signed-off-by: Maisam Arif <Maisam.Arif@amd.com> Co-authored-by: Maisam Arif <Maisam.Arif@amd.com>
Este commit está contenido en:
@@ -78,6 +78,18 @@ Full documentation for amd_smi_lib is available at [https://rocm.docs.amd.com/pr
|
||||
- amdsmi_set_power_cap()
|
||||
- See the Changed section for changes made to the `set` and `static` commands regarding support for PPT1.
|
||||
|
||||
- **Added PTL Support to `amd-smi static` and `amd-smi set`**
|
||||
- `amd-smi set` now support --ptl-status 0|1 and --ptl-format FORMAT1,FORMAT2
|
||||
- `amd-smi static -l` shows current state and format of PTL
|
||||
|
||||
```console
|
||||
$ amd-smi static -l
|
||||
GPU: 0
|
||||
LIMIT:
|
||||
PTL_STATE: Enabled
|
||||
PTL_FORMAT: I8,F64
|
||||
```
|
||||
|
||||
### Changed
|
||||
|
||||
- **The `amd-smi` command now shows hsmp rather than amd_hsmp**.
|
||||
|
||||
@@ -721,6 +721,26 @@ class AMDSMICommands():
|
||||
shutdown_temp_vram_limit = "N/A"
|
||||
logging.debug("Failed to get vram temperature shutdown metrics for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
# PTL
|
||||
try:
|
||||
ptl_state = amdsmi_interface.amdsmi_get_gpu_ptl_state(args.gpu)
|
||||
ptl_state = "Enabled" if ptl_state else "Disabled"
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
ptl_state = "N/A"
|
||||
logging.debug("Failed to get PTL state for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
try:
|
||||
ptl_format1, ptl_format2 = amdsmi_interface.amdsmi_get_gpu_ptl_formats(args.gpu)
|
||||
fmt1_name = amdsmi_interface.amdsmi_wrapper.amdsmi_ptl_data_format_t__enumvalues.get(ptl_format1)
|
||||
fmt2_name = amdsmi_interface.amdsmi_wrapper.amdsmi_ptl_data_format_t__enumvalues.get(ptl_format2)
|
||||
|
||||
fmt1_short = fmt1_name.replace("AMDSMI_PTL_DATA_FORMAT_", "") if fmt1_name else "UNKNOWN"
|
||||
fmt2_short = fmt2_name.replace("AMDSMI_PTL_DATA_FORMAT_", "") if fmt2_name else "UNKNOWN"
|
||||
|
||||
ptl_format = f"{fmt1_short},{fmt2_short}"
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
ptl_format = "N/A"
|
||||
logging.debug("Failed to get PTL state for gpu %s | %s", gpu_id, e.get_error_info())
|
||||
|
||||
# Assign units
|
||||
power_unit = 'W'
|
||||
@@ -773,6 +793,11 @@ class AMDSMICommands():
|
||||
limit_info['shutdown_edge_temperature'] = shutdown_temp_edge_limit
|
||||
limit_info['shutdown_hotspot_temperature'] = shutdown_temp_hotspot_limit
|
||||
limit_info['shutdown_vram_temperature'] = shutdown_temp_vram_limit
|
||||
|
||||
# PTL
|
||||
limit_info['ptl_state'] = ptl_state
|
||||
limit_info['ptl_format'] = ptl_format
|
||||
|
||||
static_dict['limit'] = limit_info
|
||||
if args.driver:
|
||||
driver_info_dict = {"name" : "N/A",
|
||||
@@ -4499,7 +4524,7 @@ class AMDSMICommands():
|
||||
def set_gpu(self, args, multiple_devices=False, gpu=None, fan=None, perf_level=None,
|
||||
profile=None, perf_determinism=None, compute_partition=None,
|
||||
memory_partition=None, power_cap=None, soc_pstate=None, xgmi_plpd = None,
|
||||
process_isolation=None, clk_limit=None, clk_level=None):
|
||||
process_isolation=None, clk_limit=None, clk_level=None, ptl_status=None, ptl_format=None):
|
||||
"""Issue reset commands to target gpu(s)
|
||||
|
||||
Args:
|
||||
@@ -4516,6 +4541,8 @@ class AMDSMICommands():
|
||||
soc_pstate (int, optional): Value override for args.soc_pstate. Defaults to None.
|
||||
xgmi_plpd (int, optional): Value override for args.xgmi_plpd. Defaults to None.
|
||||
process_isolation (int, optional): Value override for args.process_isolation. Defaults to None.
|
||||
ptl_status (int, optional): Value override for args.ptl_status. Defaults to None.
|
||||
ptl_format(string, optional): Value override for args.ptl_format. Defaults to None.
|
||||
Raises:
|
||||
ValueError: Value error if no gpu value is provided
|
||||
IndexError: Index error if gpu list is empty
|
||||
@@ -4550,6 +4577,10 @@ class AMDSMICommands():
|
||||
args.clk_limit = clk_limit
|
||||
if clk_level:
|
||||
args.clk_level = clk_level
|
||||
if ptl_status:
|
||||
args.ptl_status = ptl_status
|
||||
if ptl_format:
|
||||
args.ptl_format = ptl_format
|
||||
|
||||
# Handle No GPU passed
|
||||
if args.gpu == None:
|
||||
@@ -4579,6 +4610,8 @@ class AMDSMICommands():
|
||||
args.xgmi_plpd is not None,
|
||||
args.clk_level is not None,
|
||||
args.clk_limit is not None,
|
||||
args.ptl_status is not None,
|
||||
args.ptl_format is not None,
|
||||
args.process_isolation is not None]):
|
||||
command = " ".join(sys.argv[1:])
|
||||
raise AmdSmiRequiredCommandException(command, self.logger.format)
|
||||
@@ -4898,6 +4931,55 @@ class AMDSMICommands():
|
||||
self.logger.print_output()
|
||||
self.logger.clear_multiple_devices_output()
|
||||
return
|
||||
if isinstance(args.ptl_status, int):
|
||||
status_string = "Enabled" if args.ptl_status else "Disabled"
|
||||
result = f"Requested PTL status to {status_string}" # This should not print out
|
||||
try:
|
||||
current_state = amdsmi_interface.amdsmi_get_gpu_ptl_state(args.gpu)
|
||||
if current_state == args.ptl_status:
|
||||
result = f"PTL state is already {status_string}"
|
||||
else:
|
||||
amdsmi_interface.amdsmi_set_gpu_ptl_state(args.gpu, args.ptl_status)
|
||||
result = f"Successfully set PTL state to {status_string}"
|
||||
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
|
||||
self.logger.store_output(args.gpu, 'ptlstatus', f"[{e.get_error_info(detailed=False)}] Unable to set ptl status to {args.ptl_status}")
|
||||
self.logger.print_output()
|
||||
self.logger.clear_multiple_devices_output()
|
||||
return
|
||||
self.logger.store_output(args.gpu, 'ptlstatus', result)
|
||||
self.logger.print_output()
|
||||
self.logger.clear_multiple_devices_output()
|
||||
return
|
||||
if isinstance(args.ptl_format, tuple):
|
||||
requested_fmt1_enum, requested_fmt2_enum = args.ptl_format
|
||||
requested_str = f"{requested_fmt1_enum.name},{requested_fmt2_enum.name}"
|
||||
|
||||
result = f"Requested PTL status to {requested_str}" # This should not print out
|
||||
try:
|
||||
# Get current formats as ints
|
||||
cur1_code, cur2_code = amdsmi_interface.amdsmi_get_gpu_ptl_formats(args.gpu)
|
||||
cur1_enum = amdsmi_interface.AmdSmiPtlData(cur1_code)
|
||||
cur2_enum = amdsmi_interface.AmdSmiPtlData(cur2_code)
|
||||
current_str = f"{cur1_enum.name},{cur2_enum.name}"
|
||||
if (cur1_enum, cur2_enum) == (requested_fmt1_enum, requested_fmt2_enum):
|
||||
result = f"PTL format is already {current_str}"
|
||||
else:
|
||||
amdsmi_interface.amdsmi_set_gpu_ptl_formats(args.gpu, requested_fmt1_enum, requested_fmt2_enum)
|
||||
result = f"Successfully set PTL format to {requested_str}"
|
||||
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
|
||||
self.logger.store_output(args.gpu, 'ptlformat', f"[{e.get_error_info(detailed=False)}] Unable to set PTL format to {requested_str}")
|
||||
self.logger.print_output()
|
||||
self.logger.clear_multiple_devices_output()
|
||||
return
|
||||
self.logger.store_output(args.gpu, 'ptlformat', result)
|
||||
self.logger.print_output()
|
||||
self.logger.clear_multiple_devices_output()
|
||||
return
|
||||
|
||||
# Universal args
|
||||
if isinstance(args.power_cap, tuple):
|
||||
pwr_type = args.power_cap.pwr_type
|
||||
@@ -5053,7 +5135,7 @@ class AMDSMICommands():
|
||||
cpu_pwr_eff_mode=None, cpu_gmi3_link_width=None, cpu_pcie_link_rate=None,
|
||||
cpu_df_pstate_range=None, cpu_enable_apb=None, cpu_disable_apb=None,
|
||||
soc_boost_limit=None, core=None, core_boost_limit=None, soc_pstate=None, xgmi_plpd=None,
|
||||
process_isolation=None, clk_limit=None, clk_level=None):
|
||||
process_isolation=None, clk_limit=None, clk_level=None, ptl_status=None, ptl_format=None):
|
||||
"""Issue reset commands to target gpu(s)
|
||||
|
||||
Args:
|
||||
@@ -5105,7 +5187,7 @@ class AMDSMICommands():
|
||||
gpu_args_enabled = False
|
||||
gpu_attributes = ["fan", "perf_level", "profile", "perf_determinism", "compute_partition",
|
||||
"memory_partition", "power_cap", "soc_pstate", "xgmi_plpd",
|
||||
"process_isolation", "clk_limit", "clk_level"]
|
||||
"process_isolation", "clk_limit", "clk_level", "ptl_status", "ptl_format"]
|
||||
for attr in gpu_attributes:
|
||||
if hasattr(args, attr):
|
||||
if getattr(args, attr) is not None:
|
||||
@@ -5150,6 +5232,8 @@ class AMDSMICommands():
|
||||
args.xgmi_plpd is not None,
|
||||
args.clk_limit is not None,
|
||||
args.clk_level is not None,
|
||||
args.ptl_status is not None,
|
||||
args.ptl_format is not None,
|
||||
args.process_isolation is not None
|
||||
])
|
||||
except AttributeError:
|
||||
@@ -5232,7 +5316,7 @@ class AMDSMICommands():
|
||||
self.set_gpu(args, multiple_devices, gpu, fan, perf_level,
|
||||
profile, perf_determinism, compute_partition,
|
||||
memory_partition, power_cap, soc_pstate, xgmi_plpd,
|
||||
process_isolation, clk_limit, clk_level)
|
||||
process_isolation, clk_limit, clk_level, ptl_status, ptl_format)
|
||||
elif self.helpers.is_amd_hsmp_initialized(): # Only CPU is initialized
|
||||
if args.cpu == None and args.core == None:
|
||||
raise ValueError('No CPU or CORE provided, specific target(s) are needed')
|
||||
@@ -5252,7 +5336,7 @@ class AMDSMICommands():
|
||||
self.set_gpu(args, multiple_devices, gpu, fan, perf_level,
|
||||
profile, perf_determinism, compute_partition,
|
||||
memory_partition, power_cap, soc_pstate, xgmi_plpd,
|
||||
process_isolation, clk_limit, clk_level)
|
||||
process_isolation, clk_limit, clk_level, ptl_status, ptl_format)
|
||||
|
||||
|
||||
def reset(self, args, multiple_devices=False, gpu=None, gpureset=None,
|
||||
|
||||
@@ -781,6 +781,10 @@ class AMDSMIHelpers():
|
||||
perf_levels_int = list(set(clock.value for clock in amdsmi_interface.AmdSmiDevPerfLevel))
|
||||
return perf_levels_str, perf_levels_int
|
||||
|
||||
def get_ptl_values(self):
|
||||
ptl_values_str = [ptl.name for ptl in amdsmi_interface.AmdSmiPtlData]
|
||||
ptl_values_int = list(set(ptl.name for ptl in amdsmi_interface.AmdSmiPtlData))
|
||||
return ptl_values_str,ptl_values_int
|
||||
|
||||
def get_accelerator_partition_profile_config(self):
|
||||
device_handles = amdsmi_interface.amdsmi_get_processor_handles()
|
||||
|
||||
@@ -649,6 +649,59 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
raise argparse.ArgumentError(self, f"Invalid argument: '{values}' needs to be 0-20 or 0-20%")
|
||||
return _ValidateOverdrivePercent
|
||||
|
||||
def _validate_ptl_format(self):
|
||||
"""Validate and normalize --ptl-format FRMT1,FRMT2."""
|
||||
valid_names = [name for name in amdsmi_interface.AmdSmiPtlData.__members__ if name != 'INVALID']
|
||||
|
||||
class _ValidatePtlFormat(argparse.Action):
|
||||
def __call__(self, parser, args, values, option_string=None):
|
||||
if not isinstance(values, str):
|
||||
raise argparse.ArgumentError(
|
||||
self,
|
||||
f"Invalid argument for {option_string}: '{values}' "
|
||||
f"(expected string like I8,F32)"
|
||||
)
|
||||
|
||||
parts = values.split(',')
|
||||
if len(parts) != 2:
|
||||
raise argparse.ArgumentError(
|
||||
self,
|
||||
f"{option_string} expects exactly two comma-separated formats, "
|
||||
f"e.g. I8,F32 (got '{values}')"
|
||||
)
|
||||
|
||||
enums = []
|
||||
for raw in parts:
|
||||
token = raw.strip().upper()
|
||||
if token == '':
|
||||
raise argparse.ArgumentError(
|
||||
self,
|
||||
f"Empty PTL format in '{values}'. Expected formats like I8,F32."
|
||||
)
|
||||
try:
|
||||
enum_val = amdsmi_interface.AmdSmiPtlData[token]
|
||||
except KeyError:
|
||||
raise argparse.ArgumentError(
|
||||
self,
|
||||
f"Invalid PTL format '{raw}'. Valid formats are: "
|
||||
+ ", ".join(valid_names)
|
||||
)
|
||||
if enum_val == amdsmi_interface.AmdSmiPtlData.INVALID:
|
||||
raise argparse.ArgumentError(
|
||||
self,
|
||||
f"INVALID is not a usable PTL format."
|
||||
)
|
||||
enums.append(enum_val)
|
||||
|
||||
if enums[0] == enums[1]:
|
||||
raise argparse.ArgumentError(
|
||||
self,
|
||||
f"PTL formats must be different (got '{values}')."
|
||||
)
|
||||
|
||||
setattr(args, self.dest, (enums[0], enums[1]))
|
||||
|
||||
return _ValidatePtlFormat
|
||||
|
||||
### Building parsers ###
|
||||
def _add_device_arguments(self, subcommand_parser: argparse.ArgumentParser, required=False):
|
||||
@@ -1263,6 +1316,9 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
xgmi_plpd_help_info = ", ".join(self.helpers.get_xgmi_plpd_policies())
|
||||
set_xgmi_plpd_help = f"Set the GPU XGMI per-link power down policy using policy id, an integer. Valid id's include:\n\t{xgmi_plpd_help_info}"
|
||||
set_clock_freq_help = "Set one or more sclk (aka gfxclk), mclk, fclk, pcie, or socclk frequency levels.\n\tUse `amd-smi static --clock` to find acceptable levels.\n\tUse `amd-smi static --bus` to find acceptable pcie levels."
|
||||
set_ptl_status_help = "Enable or disable the PTL on a GPU processor:\n 0 for disable and 1 for enable."
|
||||
ptl_format_help_choices_str = ", ".join(self.helpers.get_ptl_values()[0][0:-1])
|
||||
set_ptl_format_help = f"Set the PTL format on a GPU processor. For example, --ptl-format I8,F32\n\tSet to one of the following PTL formats: {ptl_format_help_choices_str}"
|
||||
ppt0_power_cap_min, ppt0_power_cap_max, ppt1_power_cap_min, ppt1_power_cap_max = self.helpers.get_power_caps()
|
||||
set_power_cap_help = f"Set either PPT0 or PPT1 power capacity limit:\n\tEx: `amd-smi set -o ppt0 1300`\n\tPPT0 min cap: {ppt0_power_cap_min}, PPT0 max cap: {ppt0_power_cap_max}\n\tPPT1 min cap: {ppt1_power_cap_min}, PPT1 max cap: {ppt1_power_cap_max}"
|
||||
set_clk_limit_help = "Sets the sclk (aka gfxclk) or mclk minimum and maximum frequencies. \n\tex: amd-smi set -L (sclk | mclk) (min | max) value"
|
||||
@@ -1308,6 +1364,8 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
set_value_exclusive_group.add_argument('-p', '--soc-pstate', action='store', required=False, type=lambda value: self._not_negative_int(value, '--soc-pstate'), help=set_soc_pstate_help, metavar='POLICY_ID')
|
||||
set_value_exclusive_group.add_argument('-x', '--xgmi-plpd', action='store', required=False, type=lambda value: self._not_negative_int(value, '--xgmi-plpd'), help=set_xgmi_plpd_help, metavar='POLICY_ID')
|
||||
set_value_exclusive_group.add_argument('-c', '--clk-level', action=self._level_select(), nargs='+', required=False, help=set_clock_freq_help, metavar=('CLK_TYPE', 'PERF_LEVELS'))
|
||||
set_value_exclusive_group.add_argument('-S', '--ptl-status', action='store', choices=[0,1], type=lambda value: self._not_negative_int(value, '--ptl-status'), required=False, help=set_ptl_status_help, metavar=('STATUS'))
|
||||
set_value_exclusive_group.add_argument('-F', '--ptl-format', action=self._validate_ptl_format(), required=False, help=set_ptl_format_help, metavar=('FRMT1,FRMT2'))
|
||||
|
||||
set_value_exclusive_group.add_argument('-L', '--clk-limit', action=self._limit_select(), nargs=3, required=False, help=set_clk_limit_help, metavar=('CLK_TYPE', 'LIM_TYPE', 'VALUE'))
|
||||
set_value_exclusive_group.add_argument('-R', '--process-isolation', action='store', choices=[0,1], type=lambda value: self._not_negative_int(value, '--process-isolation'), required=False, help=set_process_isolation_help, metavar='STATUS')
|
||||
|
||||
@@ -580,6 +580,8 @@ Set Arguments:
|
||||
-L, --clk-limit CLK_TYPE LIM_TYPE VALUE Sets the sclk (aka gfxclk) or mclk minimum and maximum frequencies.
|
||||
ex: amd-smi set -L (sclk | mclk) (min | max) value
|
||||
-R, --process-isolation STATUS Enable or disable the GPU process isolation on a per partition basis: 0 for disable and 1 for enable.
|
||||
--ptl-status STATUS Enable or disable the PTL on a GPU processor: 0 for disable and 1 for enable
|
||||
--ptl-format FRMT1,FRMT2 Set the PTL format on a GPU processor. For example, --ptl-format I8,F32
|
||||
|
||||
CPU Arguments:
|
||||
--cpu-pwr-limit PWR_LIMIT Set power limit for the given socket. Input parameter is power limit value.
|
||||
|
||||
@@ -473,7 +473,7 @@ typedef enum {
|
||||
|
||||
// GPU Board Node temperature
|
||||
AMDSMI_TEMPERATURE_TYPE_GPUBOARD_NODE_FIRST = 100,
|
||||
AMDSMI_TEMPERATURE_TYPE_GPUBOARD_NODE_RETIMER_X
|
||||
AMDSMI_TEMPERATURE_TYPE_GPUBOARD_NODE_RETIMER_X
|
||||
= AMDSMI_TEMPERATURE_TYPE_GPUBOARD_NODE_FIRST, //!< Retimer X temperature
|
||||
AMDSMI_TEMPERATURE_TYPE_GPUBOARD_NODE_OAM_X_IBC, //!< OAM X IBC temperature
|
||||
AMDSMI_TEMPERATURE_TYPE_GPUBOARD_NODE_OAM_X_IBC_2, //!< OAM X IBC 2 temperature
|
||||
@@ -482,7 +482,7 @@ typedef enum {
|
||||
AMDSMI_TEMPERATURE_TYPE_GPUBOARD_NODE_OAM_X_04_HBM_D_VR, //!< OAM X 0.4V HBM D voltage regulator temperature
|
||||
AMDSMI_TEMPERATURE_TYPE_GPUBOARD_NODE_LAST = 149,
|
||||
|
||||
// GPU Board VR (Voltage Regulator) temperature
|
||||
// GPU Board VR (Voltage Regulator) temperature
|
||||
AMDSMI_TEMPERATURE_TYPE_GPUBOARD_VR_FIRST = 150,
|
||||
AMDSMI_TEMPERATURE_TYPE_GPUBOARD_VDDCR_VDD0
|
||||
= AMDSMI_TEMPERATURE_TYPE_GPUBOARD_VR_FIRST, //!< VDDCR VDD0 voltage regulator temperature
|
||||
@@ -500,7 +500,7 @@ typedef enum {
|
||||
AMDSMI_TEMPERATURE_TYPE_GPUBOARD_VDDIO_11_E32, //!< VDDIO 1.1V E32 voltage regulator temperature
|
||||
AMDSMI_TEMPERATURE_TYPE_GPUBOARD_VR_LAST = 199,
|
||||
|
||||
// Baseboard System temperature
|
||||
// Baseboard System temperature
|
||||
AMDSMI_TEMPERATURE_TYPE_BASEBOARD_FIRST = 200,
|
||||
AMDSMI_TEMPERATURE_TYPE_BASEBOARD_UBB_FPGA = AMDSMI_TEMPERATURE_TYPE_BASEBOARD_FIRST, //!< UBB FPGA temperature
|
||||
AMDSMI_TEMPERATURE_TYPE_BASEBOARD_UBB_FRONT, //!< UBB front temperature
|
||||
@@ -2169,6 +2169,22 @@ typedef struct {
|
||||
uint64_t reserved[6];
|
||||
} amdsmi_npm_info_t;
|
||||
|
||||
/**
|
||||
* @brief PTL (Peak Tops Limiter) data format types
|
||||
* These correspond to the hardware data types used in matrix operations.
|
||||
* Only F8 and XF32 are always supported at full performance. From the remaining
|
||||
* five types, only two can be supported at peak performance simultaneously.
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
AMDSMI_PTL_DATA_FORMAT_I8 = 0x0, //!< Integer 8-bit format
|
||||
AMDSMI_PTL_DATA_FORMAT_F16 = 0x1, //!< Float 16-bit format
|
||||
AMDSMI_PTL_DATA_FORMAT_BF16 = 0x2, //!< Brain Float 16-bit format
|
||||
AMDSMI_PTL_DATA_FORMAT_F32 = 0x3, //!< Float 32-bit format
|
||||
AMDSMI_PTL_DATA_FORMAT_F64 = 0x4, //!< Float 64-bit format
|
||||
AMDSMI_PTL_DATA_FORMAT_INVALID = 0xFFFFFFFF //!< Invalid format
|
||||
} amdsmi_ptl_data_format_t;
|
||||
|
||||
#ifdef ENABLE_ESMI_LIB
|
||||
|
||||
/**
|
||||
@@ -2406,7 +2422,7 @@ typedef struct {
|
||||
* @platform{guest_mvf} @platform{guest_windows}
|
||||
*
|
||||
* @details This function initializes the library and the internal data structures,
|
||||
* including those corresponding to sources of information that SMI provides.
|
||||
* including those corresponding to sources of information that SMI provides.
|
||||
* Singleton Design, requires the same number of inits as shutdowns.
|
||||
*
|
||||
* The @p init_flags decides which type of processor
|
||||
@@ -2654,7 +2670,7 @@ amdsmi_status_t amdsmi_get_processor_handles(amdsmi_socket_handle socket_handle,
|
||||
amdsmi_processor_handle* processor_handles);
|
||||
|
||||
/**
|
||||
* @brief Get the node handle associated with processor handle.
|
||||
* @brief Get the node handle associated with processor handle.
|
||||
*
|
||||
* @ingroup tagProcDiscovery
|
||||
*
|
||||
@@ -2664,7 +2680,7 @@ amdsmi_status_t amdsmi_get_processor_handles(amdsmi_socket_handle socket_handle,
|
||||
* @p processor_handle must be provided for the processor.
|
||||
* Currently, only AMD GPUs are supported.
|
||||
*
|
||||
* @param[in] processor_handle A pointer to a ::amdsmi_processor_handle, this
|
||||
* @param[in] processor_handle A pointer to a ::amdsmi_processor_handle, this
|
||||
* is required to be OAM ID 0 otherwise the API will fail. OAM ID is sourced
|
||||
* from amdsmi_get_gpu_asic_info API.
|
||||
*
|
||||
@@ -3356,7 +3372,7 @@ amdsmi_set_gpu_power_profile(amdsmi_processor_handle processor_handle, uint32_t
|
||||
*
|
||||
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail.
|
||||
*/
|
||||
amdsmi_status_t
|
||||
amdsmi_status_t
|
||||
amdsmi_get_supported_power_cap(amdsmi_processor_handle processor_handle, uint32_t *sensor_count,
|
||||
uint32_t *sensor_inds, amdsmi_power_cap_type_t *sensor_types);
|
||||
|
||||
@@ -6571,23 +6587,23 @@ amdsmi_get_gpu_process_list(amdsmi_processor_handle processor_handle, uint32_t *
|
||||
* https://docs.kernel.org/admin-guide/sysctl/kernel.html#modprobe
|
||||
* with no extra parameters as specified in
|
||||
* https://docs.kernel.org/gpu/amdgpu/module-parameters.html.
|
||||
*
|
||||
*
|
||||
* Use this function with caution, as it will unload and reload the AMD GPU
|
||||
* driver: `modprobe -r amdgpu && modprobe amdgpu`.
|
||||
*
|
||||
* driver: `modprobe -r amdgpu && modprobe amdgpu`.
|
||||
*
|
||||
* Any process or workload using the AMD GPU driver is REQUIRED to be
|
||||
* stopped before calling this function. Otherwise, function will return
|
||||
* ::AMDSMI_STATUS_AMDGPU_RESTART_ERR could not successfully restart
|
||||
* the amdgpu driver.
|
||||
*
|
||||
*
|
||||
* User is REQUIRED to have root/admin privileges to call this function.
|
||||
* Otherwise, this function will return ::AMDSMI_STATUS_NO_PERM.
|
||||
*
|
||||
*
|
||||
* This API will take time to complete, as we are checking the driver's
|
||||
* loading status to confirm it reloaded properly. If
|
||||
* ::AMDSMI_STATUS_AMDGPU_RESTART_ERR is returned, it means the driver
|
||||
* did not reload properly and the user should check dmesg logs.
|
||||
*
|
||||
*
|
||||
* This function has been created in order to conviently reload the
|
||||
* AMD GPU driver once `amdsmi_set_gpu_memory_partition()` or
|
||||
* `amdsmi_set_gpu_memory_partition_mode()` successfully has been changed
|
||||
@@ -6608,6 +6624,111 @@ amdsmi_status_t amdsmi_gpu_driver_reload(void);
|
||||
|
||||
/** @} End tagDriverControl */
|
||||
|
||||
/*****************************************************************************/
|
||||
/** @defgroup tagPTL Peak Tops Limiter
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Get PTL enable/disable state
|
||||
*
|
||||
* @ingroup tagPTL
|
||||
*
|
||||
* @platform{gpu_bm_linux} @platform{host}
|
||||
*
|
||||
* @details This function retrieves whether PTL (Peak Tops Limiter) is currently
|
||||
* enabled or disabled for the specified processor. This is a simple state query
|
||||
* that returns the current PTL operational state without detailed configuration.
|
||||
*
|
||||
* @param[in] processor_handle Device which to query
|
||||
*
|
||||
* @param[out] enabled Pointer to boolean that will be set to true if PTL is
|
||||
* enabled, false if PTL is disabled
|
||||
*
|
||||
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success,
|
||||
* ::AMDSMI_STATUS_NOT_SUPPORTED if PTL is not supported on this device,
|
||||
* non-zero on other failures
|
||||
*/
|
||||
amdsmi_status_t
|
||||
amdsmi_get_gpu_ptl_state(amdsmi_processor_handle processor_handle, bool *enabled);
|
||||
|
||||
/**
|
||||
* @brief Set PTL enable/disable state
|
||||
*
|
||||
* @ingroup tagPTL
|
||||
*
|
||||
* @platform{gpu_bm_linux} @platform{host}
|
||||
*
|
||||
* @details This function enables or disables PTL (Peak Tops Limiter) operation.
|
||||
* Use amdsmi_set_gpu_ptl_enable_with_formats()
|
||||
* for more control over the preferred data formats when enabling.
|
||||
*
|
||||
* @param[in] processor_handle Device to configure
|
||||
*
|
||||
* @param[in] enable Boolean flag: true to enable PTL with default formats,
|
||||
* false to disable PTL
|
||||
*
|
||||
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
|
||||
*/
|
||||
amdsmi_status_t amdsmi_set_gpu_ptl_state(amdsmi_processor_handle processor_handle, bool enable);
|
||||
|
||||
/**
|
||||
* @brief Get PTL (Peak Tops Limiter) formats for the processor
|
||||
*
|
||||
* @ingroup tagPTL
|
||||
*
|
||||
* @platform{gpu_bm_linux} @platform{host}
|
||||
*
|
||||
* @details This function retrieves the current PTL fromats
|
||||
* for the specified processor. PTL constrains the product to never deliver more
|
||||
* than a specified TOPS/second.
|
||||
*
|
||||
* @param[in] processor_handle Device which to query
|
||||
*
|
||||
* @param[out] data_format1 Pointer to first preferred data format that receives peak performance
|
||||
*
|
||||
* @param[out] data_format2 Pointer to second preferred data format that receives peak performance
|
||||
*
|
||||
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success,
|
||||
* ::AMDSMI_STATUS_NOT_SUPPORTED if PTL is not supported on this device,
|
||||
* non-zero on other failures
|
||||
*/
|
||||
amdsmi_status_t
|
||||
amdsmi_get_gpu_ptl_formats(amdsmi_processor_handle processor_handle,
|
||||
amdsmi_ptl_data_format_t *data_format1,
|
||||
amdsmi_ptl_data_format_t *data_format2);
|
||||
|
||||
/**
|
||||
* @brief Set PTL with specified preferred data formats
|
||||
*
|
||||
* @ingroup tagPTL
|
||||
*
|
||||
* @platform{gpu_bm_linux} @platform{host}
|
||||
*
|
||||
* @details This function sets PTL with the specified preferred data format pair.
|
||||
* PTL must be enabled first before calling this function using amdsmi_set_gpu_ptl_state.
|
||||
* The two specified formats will receive accurate performance monitoring and peak
|
||||
* performance. F8 and XF32 formats always receive peak performance regardless of this setting.
|
||||
*
|
||||
* @param[in] processor_handle Device to configure
|
||||
*
|
||||
* @param[in] data_format1 First preferred data format (must be from the limited set:
|
||||
* I8, F16, BF16, F32, F64)
|
||||
*
|
||||
* @param[in] data_format2 Second preferred data format (must be from the limited set:
|
||||
* I8, F16, BF16, F32, F64, and different from data_format1)
|
||||
*
|
||||
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success,
|
||||
* ::AMDSMI_STATUS_NOT_SUPPORTED if PTL is not supported on this device,
|
||||
* non-zero on other failures
|
||||
**/
|
||||
amdsmi_status_t
|
||||
amdsmi_set_gpu_ptl_formats(amdsmi_processor_handle processor_handle,
|
||||
amdsmi_ptl_data_format_t data_format1,
|
||||
amdsmi_ptl_data_format_t data_format2);
|
||||
|
||||
/** @} End tagPTL */
|
||||
|
||||
#ifdef ENABLE_ESMI_LIB
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
@@ -57,6 +57,7 @@ amdsmi_status_t smi_amdgpu_get_pcie_speed_from_pcie_type(uint16_t pcie_type, uin
|
||||
amdsmi_status_t smi_amdgpu_get_market_name_from_dev_id(amd::smi::AMDSmiGPUDevice* device, char *market_name);
|
||||
amdsmi_status_t smi_amdgpu_is_gpu_power_management_enabled(amd::smi::AMDSmiGPUDevice* device, bool *enabled);
|
||||
std::string smi_split_string(std::string str, char delim);
|
||||
std::vector<std::string> split_string(const std::string& line, char delim);
|
||||
std::string smi_amdgpu_get_status_string(amdsmi_status_t ret, bool fullStatus);
|
||||
amdsmi_status_t smi_clear_char_and_reinitialize(char buffer[], uint32_t len,
|
||||
std::string newString);
|
||||
|
||||
@@ -266,6 +266,12 @@ from .amdsmi_interface import amdsmi_get_gpu_pm_metrics_info
|
||||
# # Virtualization Mode Detection
|
||||
from .amdsmi_interface import amdsmi_get_gpu_virtualization_mode
|
||||
|
||||
# # PTL implementation
|
||||
from .amdsmi_interface import amdsmi_get_gpu_ptl_state
|
||||
from .amdsmi_interface import amdsmi_set_gpu_ptl_state
|
||||
from .amdsmi_interface import amdsmi_get_gpu_ptl_formats
|
||||
from .amdsmi_interface import amdsmi_set_gpu_ptl_formats
|
||||
|
||||
# # Functions where library initialization is not needed
|
||||
# # Version information
|
||||
from .amdsmi_interface import amdsmi_get_lib_version
|
||||
@@ -306,6 +312,7 @@ from .amdsmi_interface import AmdSmiProcessorType
|
||||
from .amdsmi_interface import AmdSmiVirtualizationMode
|
||||
from .amdsmi_interface import AmdSmiVramType
|
||||
from .amdsmi_interface import AmdSmiAffinityScope
|
||||
from .amdsmi_interface import AmdSmiPtlData
|
||||
|
||||
# Exceptions
|
||||
from .amdsmi_exception import AmdSmiLibraryException
|
||||
|
||||
@@ -604,6 +604,13 @@ class AmdSmiAffinityScope(IntEnum):
|
||||
NUMA_SCOPE = amdsmi_wrapper.AMDSMI_AFFINITY_SCOPE_NODE
|
||||
SOCKET_SCOPE = amdsmi_wrapper.AMDSMI_AFFINITY_SCOPE_SOCKET
|
||||
|
||||
class AmdSmiPtlData(IntEnum):
|
||||
I8 = amdsmi_wrapper.AMDSMI_PTL_DATA_FORMAT_I8
|
||||
F16 = amdsmi_wrapper.AMDSMI_PTL_DATA_FORMAT_F16
|
||||
BF16 = amdsmi_wrapper.AMDSMI_PTL_DATA_FORMAT_BF16
|
||||
F32 = amdsmi_wrapper.AMDSMI_PTL_DATA_FORMAT_F32
|
||||
F64 = amdsmi_wrapper.AMDSMI_PTL_DATA_FORMAT_F64
|
||||
INVALID = amdsmi_wrapper.AMDSMI_PTL_DATA_FORMAT_INVALID
|
||||
|
||||
class AmdSmiPowerCapType(IntEnum):
|
||||
PPT0 = amdsmi_wrapper.AMDSMI_POWER_CAP_TYPE_PPT0
|
||||
@@ -5540,6 +5547,75 @@ def amdsmi_get_gpu_virtualization_mode(
|
||||
"mode": AmdSmiVirtualizationMode(mode.value)
|
||||
}
|
||||
|
||||
def amdsmi_get_gpu_ptl_state(
|
||||
processor_handle: processor_handle_t
|
||||
) -> bool:
|
||||
if not isinstance(processor_handle, amdsmi_wrapper.amdsmi_processor_handle):
|
||||
raise AmdSmiParameterException(processor_handle, amdsmi_wrapper.amdsmi_processor_handle)
|
||||
|
||||
is_ptl_enabled = ctypes.c_bool()
|
||||
_check_res(
|
||||
amdsmi_wrapper.amdsmi_get_gpu_ptl_state(
|
||||
processor_handle, ctypes.byref(is_ptl_enabled)
|
||||
)
|
||||
)
|
||||
|
||||
return is_ptl_enabled.value
|
||||
|
||||
def amdsmi_set_gpu_ptl_state(
|
||||
processor_handle: processor_handle_t,
|
||||
state: int
|
||||
) -> None:
|
||||
if not isinstance(processor_handle, amdsmi_wrapper.amdsmi_processor_handle):
|
||||
raise AmdSmiParameterException(
|
||||
processor_handle, amdsmi_wrapper.amdsmi_processor_handle
|
||||
)
|
||||
_check_res(
|
||||
amdsmi_wrapper.amdsmi_set_gpu_ptl_state(
|
||||
processor_handle, state
|
||||
)
|
||||
)
|
||||
|
||||
def amdsmi_get_gpu_ptl_formats(
|
||||
processor_handle: processor_handle_t
|
||||
) -> tuple[int, int]:
|
||||
if not isinstance(processor_handle, amdsmi_wrapper.amdsmi_processor_handle):
|
||||
raise AmdSmiParameterException(processor_handle, amdsmi_wrapper.amdsmi_processor_handle)
|
||||
data_format1 = amdsmi_wrapper.amdsmi_ptl_data_format_t()
|
||||
data_format2 = amdsmi_wrapper.amdsmi_ptl_data_format_t()
|
||||
|
||||
_check_res(
|
||||
amdsmi_wrapper.amdsmi_get_gpu_ptl_formats(
|
||||
processor_handle, ctypes.byref(data_format1), ctypes.byref(data_format2)
|
||||
)
|
||||
)
|
||||
|
||||
return int(data_format1.value), int(data_format2.value)
|
||||
|
||||
def amdsmi_set_gpu_ptl_formats(
|
||||
processor_handle: processor_handle_t,
|
||||
fmt1: AmdSmiPtlData,
|
||||
fmt2: AmdSmiPtlData,
|
||||
) -> None:
|
||||
if not isinstance(processor_handle, amdsmi_wrapper.amdsmi_processor_handle):
|
||||
raise AmdSmiParameterException(
|
||||
processor_handle, amdsmi_wrapper.amdsmi_processor_handle
|
||||
)
|
||||
|
||||
for fmt in (fmt1, fmt2):
|
||||
if not isinstance(fmt, AmdSmiPtlData):
|
||||
raise AmdSmiParameterException(fmt, AmdSmiPtlData)
|
||||
if fmt is AmdSmiPtlData.INVALID:
|
||||
raise AmdSmiParameterException(fmt, "A valid PTL data format (not INVALID)")
|
||||
|
||||
c_fmt1 = amdsmi_wrapper.amdsmi_ptl_data_format_t(int(fmt1))
|
||||
c_fmt2 = amdsmi_wrapper.amdsmi_ptl_data_format_t(int(fmt2))
|
||||
|
||||
_check_res(
|
||||
amdsmi_wrapper.amdsmi_set_gpu_ptl_formats(
|
||||
processor_handle, c_fmt1, c_fmt2)
|
||||
)
|
||||
|
||||
### Non C-Lib APIs ###
|
||||
|
||||
def amdsmi_get_rocm_version()-> Tuple[bool, str]:
|
||||
|
||||
@@ -2281,6 +2281,22 @@ struct_amdsmi_npm_info_t._fields_ = [
|
||||
]
|
||||
|
||||
amdsmi_npm_info_t = struct_amdsmi_npm_info_t
|
||||
# values for enumeration 'amdsmi_ptl_data_format_t'
|
||||
amdsmi_ptl_data_format_t__enumvalues = {
|
||||
0: 'AMDSMI_PTL_DATA_FORMAT_I8',
|
||||
1: 'AMDSMI_PTL_DATA_FORMAT_F16',
|
||||
2: 'AMDSMI_PTL_DATA_FORMAT_BF16',
|
||||
3: 'AMDSMI_PTL_DATA_FORMAT_F32',
|
||||
4: 'AMDSMI_PTL_DATA_FORMAT_F64',
|
||||
4294967295: 'AMDSMI_PTL_DATA_FORMAT_INVALID',
|
||||
}
|
||||
AMDSMI_PTL_DATA_FORMAT_I8 = 0
|
||||
AMDSMI_PTL_DATA_FORMAT_F16 = 1
|
||||
AMDSMI_PTL_DATA_FORMAT_BF16 = 2
|
||||
AMDSMI_PTL_DATA_FORMAT_F32 = 3
|
||||
AMDSMI_PTL_DATA_FORMAT_F64 = 4
|
||||
AMDSMI_PTL_DATA_FORMAT_INVALID = 4294967295
|
||||
amdsmi_ptl_data_format_t = ctypes.c_uint32 # enum
|
||||
class struct_amdsmi_smu_fw_version_t(Structure):
|
||||
pass
|
||||
|
||||
@@ -2997,6 +3013,18 @@ amdsmi_get_gpu_process_list.argtypes = [amdsmi_processor_handle, ctypes.POINTER(
|
||||
amdsmi_gpu_driver_reload = _libraries['libamd_smi.so'].amdsmi_gpu_driver_reload
|
||||
amdsmi_gpu_driver_reload.restype = amdsmi_status_t
|
||||
amdsmi_gpu_driver_reload.argtypes = []
|
||||
amdsmi_get_gpu_ptl_state = _libraries['libamd_smi.so'].amdsmi_get_gpu_ptl_state
|
||||
amdsmi_get_gpu_ptl_state.restype = amdsmi_status_t
|
||||
amdsmi_get_gpu_ptl_state.argtypes = [amdsmi_processor_handle, ctypes.POINTER(ctypes.c_bool)]
|
||||
amdsmi_set_gpu_ptl_state = _libraries['libamd_smi.so'].amdsmi_set_gpu_ptl_state
|
||||
amdsmi_set_gpu_ptl_state.restype = amdsmi_status_t
|
||||
amdsmi_set_gpu_ptl_state.argtypes = [amdsmi_processor_handle, ctypes.c_bool]
|
||||
amdsmi_get_gpu_ptl_formats = _libraries['libamd_smi.so'].amdsmi_get_gpu_ptl_formats
|
||||
amdsmi_get_gpu_ptl_formats.restype = amdsmi_status_t
|
||||
amdsmi_get_gpu_ptl_formats.argtypes = [amdsmi_processor_handle, ctypes.POINTER(amdsmi_ptl_data_format_t), ctypes.POINTER(amdsmi_ptl_data_format_t)]
|
||||
amdsmi_set_gpu_ptl_formats = _libraries['libamd_smi.so'].amdsmi_set_gpu_ptl_formats
|
||||
amdsmi_set_gpu_ptl_formats.restype = amdsmi_status_t
|
||||
amdsmi_set_gpu_ptl_formats.argtypes = [amdsmi_processor_handle, amdsmi_ptl_data_format_t, amdsmi_ptl_data_format_t]
|
||||
amdsmi_get_cpu_core_energy = _libraries['libamd_smi.so'].amdsmi_get_cpu_core_energy
|
||||
amdsmi_get_cpu_core_energy.restype = amdsmi_status_t
|
||||
amdsmi_get_cpu_core_energy.argtypes = [amdsmi_processor_handle, ctypes.POINTER(ctypes.c_uint64)]
|
||||
@@ -3267,7 +3295,10 @@ __all__ = \
|
||||
'AMDSMI_PROCESSOR_TYPE_AMD_GPU',
|
||||
'AMDSMI_PROCESSOR_TYPE_NON_AMD_CPU',
|
||||
'AMDSMI_PROCESSOR_TYPE_NON_AMD_GPU',
|
||||
'AMDSMI_PROCESSOR_TYPE_UNKNOWN',
|
||||
'AMDSMI_PROCESSOR_TYPE_UNKNOWN', 'AMDSMI_PTL_DATA_FORMAT_BF16',
|
||||
'AMDSMI_PTL_DATA_FORMAT_F16', 'AMDSMI_PTL_DATA_FORMAT_F32',
|
||||
'AMDSMI_PTL_DATA_FORMAT_F64', 'AMDSMI_PTL_DATA_FORMAT_I8',
|
||||
'AMDSMI_PTL_DATA_FORMAT_INVALID',
|
||||
'AMDSMI_PWR_PROF_PRST_3D_FULL_SCR_MASK',
|
||||
'AMDSMI_PWR_PROF_PRST_BOOTUP_DEFAULT',
|
||||
'AMDSMI_PWR_PROF_PRST_COMPUTE_MASK',
|
||||
@@ -3485,6 +3516,7 @@ __all__ = \
|
||||
'amdsmi_get_gpu_pm_metrics_info',
|
||||
'amdsmi_get_gpu_power_profile_presets',
|
||||
'amdsmi_get_gpu_process_isolation', 'amdsmi_get_gpu_process_list',
|
||||
'amdsmi_get_gpu_ptl_formats', 'amdsmi_get_gpu_ptl_state',
|
||||
'amdsmi_get_gpu_ras_block_features_enabled',
|
||||
'amdsmi_get_gpu_ras_feature_info',
|
||||
'amdsmi_get_gpu_reg_table_info', 'amdsmi_get_gpu_revision',
|
||||
@@ -3538,11 +3570,12 @@ __all__ = \
|
||||
'amdsmi_power_info_t', 'amdsmi_power_profile_preset_masks_t',
|
||||
'amdsmi_power_profile_status_t', 'amdsmi_proc_info_t',
|
||||
'amdsmi_process_handle_t', 'amdsmi_process_info_t',
|
||||
'amdsmi_processor_handle', 'amdsmi_range_t',
|
||||
'amdsmi_ras_err_state_t', 'amdsmi_ras_feature_t',
|
||||
'amdsmi_reg_type_t', 'amdsmi_reset_gpu', 'amdsmi_reset_gpu_fan',
|
||||
'amdsmi_reset_gpu_xgmi_error', 'amdsmi_retired_page_record_t',
|
||||
'amdsmi_set_clk_freq', 'amdsmi_set_cpu_core_boostlimit',
|
||||
'amdsmi_processor_handle', 'amdsmi_ptl_data_format_t',
|
||||
'amdsmi_range_t', 'amdsmi_ras_err_state_t',
|
||||
'amdsmi_ras_feature_t', 'amdsmi_reg_type_t', 'amdsmi_reset_gpu',
|
||||
'amdsmi_reset_gpu_fan', 'amdsmi_reset_gpu_xgmi_error',
|
||||
'amdsmi_retired_page_record_t', 'amdsmi_set_clk_freq',
|
||||
'amdsmi_set_cpu_core_boostlimit',
|
||||
'amdsmi_set_cpu_df_pstate_range',
|
||||
'amdsmi_set_cpu_gmi3_link_width_range',
|
||||
'amdsmi_set_cpu_pcie_link_rate',
|
||||
@@ -3560,7 +3593,8 @@ __all__ = \
|
||||
'amdsmi_set_gpu_overdrive_level', 'amdsmi_set_gpu_pci_bandwidth',
|
||||
'amdsmi_set_gpu_perf_determinism_mode',
|
||||
'amdsmi_set_gpu_perf_level', 'amdsmi_set_gpu_power_profile',
|
||||
'amdsmi_set_gpu_process_isolation', 'amdsmi_set_power_cap',
|
||||
'amdsmi_set_gpu_process_isolation', 'amdsmi_set_gpu_ptl_formats',
|
||||
'amdsmi_set_gpu_ptl_state', 'amdsmi_set_power_cap',
|
||||
'amdsmi_set_soc_pstate', 'amdsmi_set_xgmi_plpd',
|
||||
'amdsmi_shut_down', 'amdsmi_smu_fw_version_t',
|
||||
'amdsmi_sock_info_t', 'amdsmi_socket_handle',
|
||||
|
||||
@@ -109,7 +109,7 @@ typedef enum {
|
||||
//!< being used
|
||||
RSMI_STATUS_REFCOUNT_OVERFLOW, //!< An internal reference counter
|
||||
//!< exceeded INT32_MAX
|
||||
RSMI_STATUS_DIRECTORY_NOT_FOUND, //!< Error when a directory is not
|
||||
RSMI_STATUS_DIRECTORY_NOT_FOUND, //!< Error when a directory is not
|
||||
//!< found, maps to ENOTDIR
|
||||
RSMI_STATUS_SETTING_UNAVAILABLE, //!< Requested setting is unavailable
|
||||
//!< for the current device
|
||||
@@ -1474,6 +1474,22 @@ typedef enum {
|
||||
RSMI_REG_USR1,
|
||||
} rsmi_reg_type_t;
|
||||
|
||||
/**
|
||||
* @brief PTL (Peak Tops Limiter) data format types
|
||||
* These correspond to the hardware data types used in matrix operations.
|
||||
* Only F8 and XF32 are always supported at full performance. From the remaining
|
||||
* five types, only two can be supported at peak performance simultaneously.
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
RSMI_PTL_DATA_FORMAT_I8 = 0x0, //!< Integer 8-bit format
|
||||
RSMI_PTL_DATA_FORMAT_F16 = 0x1, //!< Float 16-bit format
|
||||
RSMI_PTL_DATA_FORMAT_BF16 = 0x2, //!< Brain Float 16-bit format
|
||||
RSMI_PTL_DATA_FORMAT_F32 = 0x3, //!< Float 32-bit format
|
||||
RSMI_PTL_DATA_FORMAT_F64 = 0x4, //!< Float 64-bit format
|
||||
RSMI_PTL_DATA_FORMAT_INVALID = 0xFFFFFFFF //!< Invalid format
|
||||
} rsmi_ptl_data_format_t;
|
||||
|
||||
/**
|
||||
* @brief This structure holds error counts.
|
||||
*/
|
||||
@@ -2666,7 +2682,7 @@ rsmi_dev_power_profile_set(uint32_t dv_ind, uint32_t reserved,
|
||||
*
|
||||
* @return ::rsmi_status_t | ::RSMI_STATUS_SUCCESS on success, non-zero on fail.
|
||||
*/
|
||||
rsmi_status_t
|
||||
rsmi_status_t
|
||||
rsmi_dev_supported_power_cap_get(uint32_t dv_ind, uint32_t *sensor_count,
|
||||
uint32_t *sensor_inds, rsmi_power_cap_type_t *sensor_types);
|
||||
/** @} */ // end of PowerCont
|
||||
@@ -5097,7 +5113,7 @@ rsmi_dev_compute_partition_xcp_config_set(uint32_t dv_ind,
|
||||
* @param[in] dv_ind a device index
|
||||
*
|
||||
* @param[in] type a pointer to a requested resource using enum ::rsmi_accelerator_partition_resource_type_t
|
||||
*
|
||||
*
|
||||
* @param[inout] profile a pointer to the requested rsmi_accelerator_partition_resource_profile_t details
|
||||
*
|
||||
* @retval ::RSMI_STATUS_SUCCESS call was successful
|
||||
@@ -5600,6 +5616,96 @@ rsmi_dev_metrics_header_info_get(uint32_t dv_ind, metrics_table_header_t* header
|
||||
rsmi_status_t
|
||||
rsmi_dev_metrics_xcd_counter_get(uint32_t dv_ind, uint16_t* xcd_counter_value);
|
||||
|
||||
/**
|
||||
* @brief Check if ptl enabled for device
|
||||
*
|
||||
* @details Given a device index @p dv_ind and a pointer to a bool in which
|
||||
* the status will stored
|
||||
*
|
||||
* @param[in] dv_ind a device index
|
||||
*
|
||||
* @param[inout] enabled a pointer to bool to which the status will be stored
|
||||
*
|
||||
* @retval ::RSMI_STATUS_SUCCESS is returned upon successful call.
|
||||
* ::RSMI_STATUS_NOT_SUPPORTED is returned in case the sysfs fails
|
||||
*
|
||||
*/
|
||||
rsmi_status_t
|
||||
rsmi_get_gpu_ptl_state(uint32_t dv_ind, bool* enabled);
|
||||
|
||||
/**
|
||||
* @brief Set PTL enable/disable state
|
||||
*
|
||||
* @ingroup tagPTL
|
||||
*
|
||||
* @platform{gpu_bm_linux} @platform{host}
|
||||
*
|
||||
* @details This function enables or disables PTL (Peak Tops Limiter) operation.
|
||||
* Use rsmi_set_gpu_ptl_enable_with_formats()
|
||||
* for more control over the preferred data formats when enabling.
|
||||
*
|
||||
* @param[in] processor_handle Device to configure
|
||||
*
|
||||
* @param[in] enable Boolean flag: true to enable PTL with default formats,
|
||||
* false to disable PTL
|
||||
*
|
||||
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
|
||||
*/
|
||||
rsmi_status_t
|
||||
rsmi_set_gpu_ptl_state(uint32_t dv_ind, bool enabled);
|
||||
|
||||
/**
|
||||
* @brief Get ptl data formats
|
||||
*
|
||||
* @details Given a device index @p dv_ind and string pointers to store ptl data
|
||||
*
|
||||
* @param[in] dv_ind a device index
|
||||
*
|
||||
* @param[inout] format a pointer to data format to which the raw format string will be stored
|
||||
*
|
||||
* @param[in] len the length of the caller provided buffer @p name.
|
||||
*
|
||||
* @retval ::RSMI_STATUS_SUCCESS is returned upon successful call.
|
||||
* ::RSMI_STATUS_NOT_SUPPORTED is returned in case the sysfs fails
|
||||
*
|
||||
*/
|
||||
rsmi_status_t
|
||||
rsmi_get_gpu_ptl_formats(uint32_t dv_ind, char* format, size_t len);
|
||||
|
||||
/**
|
||||
* @brief Set ptl data formats
|
||||
*
|
||||
* @details Given a device index @p dv_ind and raw string poitner in which to set ptl format
|
||||
*
|
||||
* @param[in] dv_ind a device index
|
||||
*
|
||||
* @param[inout] format string pointer format to set ptl level to
|
||||
*
|
||||
* @retval ::RSMI_STATUS_SUCCESS is returned upon successful call.
|
||||
* ::RSMI_STATUS_NOT_SUPPORTED is returned in case the sysfs fails
|
||||
*
|
||||
*/
|
||||
rsmi_status_t
|
||||
rsmi_set_gpu_ptl_formats(uint32_t dv_ind, const char* format);
|
||||
|
||||
/**
|
||||
* @brief Get supported ptl formats
|
||||
*
|
||||
* @details Given a device index @p dv_ind and string pointer return supported ptl formats
|
||||
*
|
||||
* @param[in] dv_ind a device index
|
||||
*
|
||||
* @param[inout] supported string pointer to return supported ptl formats
|
||||
*
|
||||
* @param[in] len the length of the caller provided buffer @p name.
|
||||
*
|
||||
* @retval ::RSMI_STATUS_SUCCESS is returned upon successful call.
|
||||
* ::RSMI_STATUS_NOT_SUPPORTED is returned in case the sysfs fails
|
||||
*
|
||||
*/
|
||||
rsmi_status_t
|
||||
rsmi_read_supported_ptl_formats(uint32_t dv_ind, char* supported, size_t length);
|
||||
|
||||
/**
|
||||
* @brief Get the log from the GPU metrics associated with the device
|
||||
*
|
||||
@@ -5631,23 +5737,23 @@ rsmi_dev_metrics_log_get(uint32_t dv_ind);
|
||||
* https://docs.kernel.org/admin-guide/sysctl/kernel.html#modprobe
|
||||
* with no extra parameters as specified in
|
||||
* https://docs.kernel.org/gpu/amdgpu/module-parameters.html.
|
||||
*
|
||||
*
|
||||
* Use this function with caution, as it will unload and reload the AMD GPU
|
||||
* driver: `modprobe -r amdgpu && modprobe amdgpu`.
|
||||
*
|
||||
* driver: `modprobe -r amdgpu && modprobe amdgpu`.
|
||||
*
|
||||
* Any process or workload using the AMD GPU driver is REQUIRED to be
|
||||
* stopped before calling this function. Otherwise, function will return
|
||||
* ::RSMI_STATUS_AMDGPU_RESTART_ERR could not successfully restart
|
||||
* the amdgpu driver.
|
||||
*
|
||||
*
|
||||
* User is REQUIRED to have root/admin privileges to call this function.
|
||||
* Otherwise, this function will return ::RSMI_STATUS_PERMISSION.
|
||||
*
|
||||
*
|
||||
* This API will take time to complete, as we are checking the driver's
|
||||
* loading status to confirm it reloaded properly. If
|
||||
* ::RSMI_STATUS_AMDGPU_RESTART_ERR is returned, it means the driver
|
||||
* did not reload properly and the user should check dmesg logs.
|
||||
*
|
||||
*
|
||||
* This function has been created in order to conviently reload the
|
||||
* AMD GPU driver once `rsmi_dev_memory_partition_set()`
|
||||
* successfully has been changed on Baremetal systems.
|
||||
|
||||
@@ -187,6 +187,11 @@ enum DevInfoTypes {
|
||||
* Possible xcp config resources end
|
||||
*/
|
||||
|
||||
// PTL
|
||||
kDevPtlSupported,
|
||||
kDevPtlStatus,
|
||||
kDevPtlFormat,
|
||||
|
||||
// The information read from pci core sysfs
|
||||
kDevPCieTypeStart = 1000,
|
||||
kDevPCieVendorID = kDevPCieTypeStart,
|
||||
|
||||
@@ -269,6 +269,7 @@ static rsmi_status_t get_dev_value_str(amd::smi::DevInfoTypes type,
|
||||
|
||||
return amd::smi::ErrnoToRsmiStatus(ret);
|
||||
}
|
||||
|
||||
static rsmi_status_t read_dev_port_map_file(amd::smi::DevInfoTypes type, uint32_t dv_ind, std::string *val_str) {
|
||||
assert(val_str != nullptr);
|
||||
if (val_str == nullptr) {
|
||||
@@ -320,6 +321,14 @@ static rsmi_status_t set_dev_value(amd::smi::DevInfoTypes type,
|
||||
return amd::smi::ErrnoToRsmiStatus(ret);
|
||||
}
|
||||
|
||||
static rsmi_status_t set_dev_value(amd::smi::DevInfoTypes type,
|
||||
uint32_t dv_ind, const char* val) {
|
||||
GET_DEV_FROM_INDX
|
||||
|
||||
int ret = dev->writeDevInfo(type, val);
|
||||
return amd::smi::ErrnoToRsmiStatus(ret);
|
||||
}
|
||||
|
||||
static rsmi_status_t get_dev_mon_value(amd::smi::MonitorTypes type,
|
||||
uint32_t dv_ind, uint32_t sensor_ind, int64_t *val) {
|
||||
assert(val != nullptr);
|
||||
@@ -7888,6 +7897,140 @@ rsmi_dev_metrics_xcd_counter_get(uint32_t dv_ind, uint16_t* xcd_counter_value)
|
||||
CATCH
|
||||
}
|
||||
|
||||
// Internal only helper
|
||||
rsmi_status_t
|
||||
rsmi_read_supported_ptl_formats(uint32_t dv_ind, char* supported, size_t length){
|
||||
TRY
|
||||
std::ostringstream ss;
|
||||
ss << __PRETTY_FUNCTION__ << " | ======= start ======="
|
||||
<< " | dv_ind=" << dv_ind;
|
||||
LOG_TRACE(ss);
|
||||
|
||||
if (supported == nullptr) {
|
||||
return RSMI_STATUS_INVALID_ARGS;
|
||||
}
|
||||
|
||||
std::string line;
|
||||
DEVICE_MUTEX
|
||||
rsmi_status_t ret = get_dev_value_line(amd::smi::kDevPtlSupported, dv_ind, &line);
|
||||
if (ret != RSMI_STATUS_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (line.size() + 1 > length) {
|
||||
return RSMI_STATUS_UNEXPECTED_SIZE;
|
||||
}
|
||||
|
||||
std::strncpy(supported, line.c_str(), length);
|
||||
supported[length - 1] = '\0';
|
||||
return RSMI_STATUS_SUCCESS;
|
||||
CATCH
|
||||
}
|
||||
|
||||
rsmi_status_t
|
||||
rsmi_get_gpu_ptl_state(uint32_t dv_ind, bool *enabled)
|
||||
{
|
||||
TRY
|
||||
std::string val_str;
|
||||
std::ostringstream ss;
|
||||
ss << __PRETTY_FUNCTION__ << "| ======= start =======";
|
||||
LOG_TRACE(ss);
|
||||
|
||||
DEVICE_MUTEX
|
||||
if (!enabled) {
|
||||
return RSMI_STATUS_INVALID_ARGS;
|
||||
}
|
||||
|
||||
rsmi_status_t ret = get_dev_value_str(amd::smi::kDevPtlStatus, dv_ind,
|
||||
&val_str);
|
||||
if (ret != RSMI_STATUS_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (val_str == "enabled") { *enabled = true; return RSMI_STATUS_SUCCESS; }
|
||||
if (val_str == "disabled") { *enabled = false; return RSMI_STATUS_SUCCESS; }
|
||||
|
||||
// unexpected value
|
||||
return RSMI_STATUS_UNEXPECTED_DATA;
|
||||
CATCH
|
||||
}
|
||||
|
||||
rsmi_status_t
|
||||
rsmi_set_gpu_ptl_state(uint32_t dv_ind, bool enable) {
|
||||
TRY
|
||||
std::ostringstream ss;
|
||||
ss << __PRETTY_FUNCTION__ << " | ======= start ======="
|
||||
<< " | dv_ind=" << dv_ind
|
||||
<< " | enable=" << enable;
|
||||
LOG_TRACE(ss);
|
||||
REQUIRE_ROOT_ACCESS
|
||||
|
||||
DEVICE_MUTEX
|
||||
return set_dev_value(amd::smi::kDevPtlStatus, dv_ind, enable);
|
||||
CATCH
|
||||
}
|
||||
|
||||
rsmi_status_t
|
||||
rsmi_get_gpu_ptl_formats(uint32_t dv_ind, char* format, size_t length)
|
||||
{
|
||||
TRY
|
||||
std::ostringstream ss;
|
||||
ss << __PRETTY_FUNCTION__ << " | ======= start ======="
|
||||
<< " | dv_ind=" << dv_ind;
|
||||
LOG_TRACE(ss);
|
||||
|
||||
if (format == nullptr) {
|
||||
return RSMI_STATUS_INVALID_ARGS;
|
||||
}
|
||||
|
||||
std::string line;
|
||||
DEVICE_MUTEX
|
||||
rsmi_status_t ret = get_dev_value_line(amd::smi::kDevPtlFormat, dv_ind, &line);
|
||||
if (ret != RSMI_STATUS_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (line.size() + 1 > length) {
|
||||
return RSMI_STATUS_UNEXPECTED_SIZE;
|
||||
}
|
||||
|
||||
std::strncpy(format, line.c_str(), length);
|
||||
format[length - 1] = '\0';
|
||||
return RSMI_STATUS_SUCCESS;
|
||||
CATCH
|
||||
}
|
||||
|
||||
rsmi_status_t
|
||||
rsmi_set_gpu_ptl_formats(uint32_t dv_ind, const char* format)
|
||||
{
|
||||
TRY
|
||||
std::ostringstream ss;
|
||||
ss << __PRETTY_FUNCTION__ << " | ======= start ======="
|
||||
<< " | dv_ind=" << dv_ind
|
||||
<< " | format=" << format;
|
||||
LOG_TRACE(ss);
|
||||
|
||||
REQUIRE_ROOT_ACCESS
|
||||
DEVICE_MUTEX
|
||||
rsmi_status_t ret = set_dev_value(amd::smi::kDevPtlFormat, dv_ind, format);
|
||||
if (ret != RSMI_STATUS_SUCCESS) {
|
||||
ss << __PRETTY_FUNCTION__
|
||||
<< " | Failed to write PTL format to sysfs"
|
||||
<< " | format='" << format << "'"
|
||||
<< " | ret=" << getRSMIStatusString(ret);
|
||||
LOG_ERROR(ss);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ss << __PRETTY_FUNCTION__
|
||||
<< " | PTL set formats success"
|
||||
<< " | format='" << format << "'";
|
||||
LOG_DEBUG(ss);
|
||||
|
||||
return RSMI_STATUS_SUCCESS;
|
||||
CATCH
|
||||
}
|
||||
|
||||
rsmi_status_t
|
||||
rsmi_dev_metrics_log_get(uint32_t dv_ind)
|
||||
{
|
||||
|
||||
@@ -119,6 +119,9 @@ static const char *kDevPmMetricsFName = "pm_metrics"; // PM log
|
||||
static const char *kDevRegMetricsFName = "reg_state"; // register table
|
||||
static const char *kDevBaseBoardTempMetricsFName = "board/baseboard_temp";
|
||||
static const char *kDevGpuBoardTempMetricsFName = "board/gpuboard_temp";
|
||||
static const char *kDevPtlSupportedFName = "ptl/ptl_supported_formats"; // Only used internally for verification
|
||||
static const char *kDevPtlStatusFName = "ptl/ptl_enable";
|
||||
static const char *kDevPtlFormatFName = "ptl/ptl_format";
|
||||
|
||||
static const char *kDevAvailableComputePartitionFName =
|
||||
"available_compute_partition";
|
||||
@@ -331,6 +334,9 @@ static const std::map<DevInfoTypes, const char *> kDevAttribNameMap = {
|
||||
{kDevRegMetrics, kDevRegMetricsFName},
|
||||
{kDevBaseBoardTempMetrics, kDevBaseBoardTempMetricsFName},
|
||||
{kDevGpuBoardTempMetrics, kDevGpuBoardTempMetricsFName},
|
||||
{kDevPtlSupported, kDevPtlSupportedFName},
|
||||
{kDevPtlStatus, kDevPtlStatusFName},
|
||||
{kDevPtlFormat, kDevPtlFormatFName},
|
||||
{kDevGpuReset, kDevGpuResetFName},
|
||||
{kDevAvailableComputePartition, kDevAvailableComputePartitionFName},
|
||||
{kDevComputePartition, kDevComputePartitionFName},
|
||||
@@ -605,6 +611,10 @@ static const std::map<const char *, dev_depends_t> kDevFuncDependsMap = {
|
||||
{"rsmi_dev_compute_partition_set", {{kDevComputePartitionFName}, {}}},
|
||||
{"rsmi_dev_memory_partition_get", {{kDevMemoryPartitionFName}, {}}},
|
||||
{"rsmi_dev_memory_partition_set", {{kDevMemoryPartitionFName}, {}}},
|
||||
{"rsmi_get_gpu_ptl_state", {{kDevPtlStatusFName}, {}}},
|
||||
{"rsmi_set_gpu_ptl_state", {{kDevPtlStatusFName}, {}}},
|
||||
{"rsmi_get_gpu_ptl_formats", {{kDevPtlFormatFName}, {}}},
|
||||
{"rsmi_set_gpu_ptl_formats", {{kDevPtlFormatFName}, {}}},
|
||||
|
||||
// These functions with variants, but no sensors/units. (May or may not
|
||||
// have mandatory dependencies.)
|
||||
@@ -1035,6 +1045,7 @@ int Device::writeDevInfo(DevInfoTypes type, uint64_t val) {
|
||||
case kDevOverDriveLevel: // integer between 0 and 20
|
||||
case kDevPowerODVoltage:
|
||||
case kDevPowerProfileMode:
|
||||
case kDevPtlStatus:
|
||||
return writeDevInfoStr(type, std::to_string(val));
|
||||
break;
|
||||
|
||||
@@ -1066,6 +1077,7 @@ int Device::writeDevInfo(DevInfoTypes type, std::string val) {
|
||||
case kDevPCIEClk:
|
||||
case kDevPowerODVoltage:
|
||||
case kDevSOCClk:
|
||||
case kDevPtlFormat:
|
||||
return writeDevInfoStr(type, val);
|
||||
case kDevComputePartition:
|
||||
case kDevMemoryPartition:
|
||||
@@ -1521,6 +1533,9 @@ int Device::readDevInfo(DevInfoTypes type, std::string *val) {
|
||||
case kDevJpegShared:
|
||||
case kDevXccInst:
|
||||
case kDevXccShared:
|
||||
case kDevPtlSupported:
|
||||
case kDevPtlStatus:
|
||||
case kDevPtlFormat:
|
||||
return readDevInfoStr(type, val);
|
||||
break;
|
||||
|
||||
|
||||
@@ -5251,6 +5251,202 @@ amdsmi_get_gpu_virtualization_mode(amdsmi_processor_handle processor_handle,
|
||||
return status;
|
||||
}
|
||||
|
||||
// PTL
|
||||
|
||||
bool amdsmi_is_supported_format(
|
||||
const std::vector<amdsmi_ptl_data_format_t> &supported,
|
||||
amdsmi_ptl_data_format_t fmt) {
|
||||
return std::find(supported.begin(), supported.end(), fmt) != supported.end();
|
||||
}
|
||||
|
||||
amdsmi_status_t
|
||||
amdsmi_get_gpu_ptl_state(amdsmi_processor_handle processor_handle, bool *enabled) {
|
||||
return rsmi_wrapper(rsmi_get_gpu_ptl_state, processor_handle, 0, enabled);
|
||||
}
|
||||
|
||||
amdsmi_status_t
|
||||
amdsmi_set_gpu_ptl_state(amdsmi_processor_handle processor_handle, bool enable) {
|
||||
return rsmi_wrapper(rsmi_set_gpu_ptl_state, processor_handle, 0, enable);
|
||||
}
|
||||
|
||||
// Mapping for PTL string <-> enum
|
||||
struct PtlFormatMapEntry {
|
||||
const char* token;
|
||||
amdsmi_ptl_data_format_t fmt;
|
||||
};
|
||||
|
||||
PtlFormatMapEntry kPtlFormatMap[] = {
|
||||
{"I8", AMDSMI_PTL_DATA_FORMAT_I8},
|
||||
{"F16", AMDSMI_PTL_DATA_FORMAT_F16},
|
||||
{"BF16", AMDSMI_PTL_DATA_FORMAT_BF16},
|
||||
{"F32", AMDSMI_PTL_DATA_FORMAT_F32},
|
||||
{"F64", AMDSMI_PTL_DATA_FORMAT_F64},
|
||||
};
|
||||
static constexpr size_t kPtlFormatMapSize =
|
||||
sizeof(kPtlFormatMap) / sizeof(kPtlFormatMap[0]);
|
||||
|
||||
// Given string, return ptl data format enum
|
||||
amdsmi_ptl_data_format_t token_to_amdsmi_fmt(std::string token) {
|
||||
token = amd::smi::trim(token);
|
||||
if (token.empty()) {
|
||||
return AMDSMI_PTL_DATA_FORMAT_INVALID;
|
||||
}
|
||||
|
||||
// Ensure upper case for comparison
|
||||
for (auto &c : token) {
|
||||
c = std::toupper(static_cast<unsigned char>(c));
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < kPtlFormatMapSize; ++i) {
|
||||
if (token == kPtlFormatMap[i].token) {
|
||||
return kPtlFormatMap[i].fmt;
|
||||
}
|
||||
}
|
||||
return AMDSMI_PTL_DATA_FORMAT_INVALID;
|
||||
}
|
||||
|
||||
// Given ptl format, return string representation
|
||||
const char* amdsmi_fmt_to_token(amdsmi_ptl_data_format_t fmt) {
|
||||
for (size_t i = 0; i < kPtlFormatMapSize; ++i) {
|
||||
if (kPtlFormatMap[i].fmt == fmt) {
|
||||
return kPtlFormatMap[i].token;
|
||||
}
|
||||
}
|
||||
return "N/A";
|
||||
}
|
||||
|
||||
// Internal only helper to create supported ptl formats
|
||||
amdsmi_status_t amdsmi_read_supported_ptl_formats(
|
||||
amdsmi_processor_handle processor_handle,
|
||||
std::vector<amdsmi_ptl_data_format_t> &out) {
|
||||
|
||||
out.clear();
|
||||
|
||||
std::string line;
|
||||
{
|
||||
char buf[AMDSMI_MAX_STRING_LENGTH] = {0};
|
||||
amdsmi_status_t st = rsmi_wrapper(
|
||||
rsmi_read_supported_ptl_formats, processor_handle, 0, buf, AMDSMI_MAX_STRING_LENGTH);
|
||||
|
||||
if (st != AMDSMI_STATUS_SUCCESS) {
|
||||
return st;
|
||||
}
|
||||
line.assign(buf);
|
||||
}
|
||||
|
||||
line = amd::smi::trim(line);
|
||||
auto tokens = split_string(line, ',');
|
||||
if (tokens.empty()) {
|
||||
return AMDSMI_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
for (const auto &t : tokens) {
|
||||
amdsmi_ptl_data_format_t f = token_to_amdsmi_fmt(t);
|
||||
if (f == AMDSMI_PTL_DATA_FORMAT_INVALID) {
|
||||
return AMDSMI_STATUS_UNEXPECTED_DATA;
|
||||
}
|
||||
out.push_back(f);
|
||||
}
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
amdsmi_status_t
|
||||
amdsmi_get_gpu_ptl_formats(amdsmi_processor_handle processor_handle,
|
||||
amdsmi_ptl_data_format_t *data_format1,
|
||||
amdsmi_ptl_data_format_t *data_format2)
|
||||
{
|
||||
|
||||
if (data_format1 == nullptr || data_format2 == nullptr) {
|
||||
return AMDSMI_STATUS_ARG_PTR_NULL;
|
||||
}
|
||||
*data_format1 = AMDSMI_PTL_DATA_FORMAT_INVALID;
|
||||
*data_format2 = AMDSMI_PTL_DATA_FORMAT_INVALID;
|
||||
|
||||
// Ensure PTL enabled
|
||||
bool enabled = false;
|
||||
amdsmi_status_t st = amdsmi_get_gpu_ptl_state(processor_handle, &enabled);
|
||||
if (st != AMDSMI_STATUS_SUCCESS) {
|
||||
return st;
|
||||
}
|
||||
if (!enabled) {
|
||||
return AMDSMI_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
// Read ptl sysfs
|
||||
std::string line;
|
||||
{
|
||||
char buf[AMDSMI_MAX_STRING_LENGTH] = {0};
|
||||
st = rsmi_wrapper(rsmi_get_gpu_ptl_formats, processor_handle, 0, buf, AMDSMI_MAX_STRING_LENGTH);
|
||||
if (st != AMDSMI_STATUS_SUCCESS) {
|
||||
return st;
|
||||
}
|
||||
line.assign(buf);
|
||||
}
|
||||
|
||||
line = amd::smi::trim(line);
|
||||
auto tokens = split_string(line, ',');
|
||||
if (tokens.empty() || tokens.size() != 2) {
|
||||
return AMDSMI_STATUS_UNEXPECTED_SIZE; // malformed sysfs content
|
||||
}
|
||||
|
||||
// Parse tokens
|
||||
amdsmi_ptl_data_format_t f1 = token_to_amdsmi_fmt(tokens[0]);
|
||||
if (f1 == AMDSMI_PTL_DATA_FORMAT_INVALID) {
|
||||
return AMDSMI_STATUS_UNEXPECTED_DATA;
|
||||
}
|
||||
|
||||
amdsmi_ptl_data_format_t f2 = token_to_amdsmi_fmt(tokens[1]);
|
||||
if (f2 == AMDSMI_PTL_DATA_FORMAT_INVALID) {
|
||||
return AMDSMI_STATUS_UNEXPECTED_DATA;
|
||||
}
|
||||
|
||||
*data_format1 = f1;
|
||||
*data_format2 = f2;
|
||||
return AMDSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
amdsmi_status_t
|
||||
amdsmi_set_gpu_ptl_formats(amdsmi_processor_handle processor_handle,
|
||||
amdsmi_ptl_data_format_t data_format1,
|
||||
amdsmi_ptl_data_format_t data_format2)
|
||||
{
|
||||
|
||||
if (data_format1 == AMDSMI_PTL_DATA_FORMAT_INVALID ||
|
||||
data_format2 == AMDSMI_PTL_DATA_FORMAT_INVALID ||
|
||||
data_format1 == data_format2) {
|
||||
return AMDSMI_STATUS_UNEXPECTED_DATA;
|
||||
}
|
||||
|
||||
// Ensure PTL enabled
|
||||
bool enabled = false;
|
||||
amdsmi_status_t st = amdsmi_get_gpu_ptl_state(processor_handle, &enabled);
|
||||
if (st != AMDSMI_STATUS_SUCCESS) {
|
||||
return st;
|
||||
}
|
||||
if (!enabled) {
|
||||
return AMDSMI_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
// Read supported formats and check both are allowed
|
||||
std::vector<amdsmi_ptl_data_format_t> supported;
|
||||
st = amdsmi_read_supported_ptl_formats(processor_handle, supported);
|
||||
if (st != AMDSMI_STATUS_SUCCESS) {
|
||||
return st;
|
||||
}
|
||||
|
||||
if (!amdsmi_is_supported_format(supported, data_format1) ||
|
||||
!amdsmi_is_supported_format(supported, data_format2)) {
|
||||
return AMDSMI_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
// Convert enums to string
|
||||
std::string format =
|
||||
std::string(amdsmi_fmt_to_token(data_format1)) + "," +
|
||||
amdsmi_fmt_to_token(data_format2);
|
||||
|
||||
return rsmi_wrapper(rsmi_set_gpu_ptl_formats, processor_handle, 0, format.c_str());
|
||||
}
|
||||
|
||||
amdsmi_status_t amdsmi_get_cpu_affinity_with_scope(amdsmi_processor_handle processor_handle,
|
||||
uint32_t cpu_set_size, uint64_t *cpu_set, amdsmi_affinity_scope_t scope)
|
||||
{
|
||||
|
||||
@@ -793,6 +793,25 @@ std::string smi_amdgpu_split_string(std::string str, char delim) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// Split string at delimiter and return strings in vector
|
||||
std::vector<std::string> split_string(const std::string& line, char delim) {
|
||||
std::vector<std::string> out;
|
||||
std::size_t start = 0;
|
||||
|
||||
while (start < line.size()) {
|
||||
auto pos = line.find(delim, start);
|
||||
if (pos == std::string::npos) {
|
||||
pos = line.size();
|
||||
}
|
||||
std::string token = trim(line.substr(start, pos - start));
|
||||
if (!token.empty()) {
|
||||
out.push_back(token);
|
||||
}
|
||||
start = pos + 1;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
// wrapper to return string expression of a rsmi_status_t return
|
||||
// rsmi_status_t ret - return value of RSMI API function
|
||||
// bool fullStatus - defaults to true, set to false to chop off description
|
||||
|
||||
Referencia en una nueva incidencia
Block a user