diff --git a/projects/amdsmi/CHANGELOG.md b/projects/amdsmi/CHANGELOG.md index 1f25879de8..d5089c5077 100644 --- a/projects/amdsmi/CHANGELOG.md +++ b/projects/amdsmi/CHANGELOG.md @@ -34,6 +34,50 @@ Full documentation for amd_smi_lib is available at [https://rocm.docs.amd.com/pr ### Added +- **Added support for get and set option for CPUISOFreqPolicy control API and DFCState Control API**. + - Users can now able to set the CPU ISO frequency policy using `amd-smi set --cpu-railisofreq-policy (0-1)`. + - Users can now able to read the CPU ISO frequency policy using `amd-smi metric --cpu-railisofreq-policy`. + - Users can now able to set the Data Fabric C-state control status using `amd-smi set --cpu-dfcstate-ctrl (0-1)`. + - Users can now able to read the Data Fabric C-state control status using `amd-smi metric --cpu-dfcstate-ctrl`. + + ```console + $amd-smi set --cpu-railisofreq-policy 0 + CPU: 0 + CPURAILISO: + STATE: Set CPU ISO frequency policy operation successful + + CPU: 1 + CPURAILISO: + STATE: Set CPU ISO frequency policy operation successful + + $amd-smi metric --cpu-railisofreq-policy + CPU: 0 + CPURAILISO: + CPURAILISOFREQ_POLICY: 0 + + CPU: 1 + CPURAILISO: + CPURAILISOFREQ_POLICY: 0 + + $amd-smi set --cpu-dfcstate-ctrl 0 + CPU: 0 + DFCSTATECTRL: + STATE: DFCState control operation successful + + CPU: 1 + DFCSTATECTRL: + STATE: DFCState control operation successful + + $amd-smi metric --cpu-dfcstate-ctrl + CPU: 0 + DFCSTATE: + DFCSTATECTRL_STATUS: 0 + + CPU: 1 + DFCSTATE: + DFCSTATECTRL_STATUS: 0 + ``` + - **Added GPU and base board temperature `amd-smi monitor` CLI support**. - Added `--gpu-board-temps` option to `amd-smi monitor` command for GPU board temperature sensors - Added `--base-board-temps` option to `amd-smi monitor` command for base board temperature sensors diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_commands.py b/projects/amdsmi/amdsmi_cli/amdsmi_commands.py index c546328182..df0eca53c5 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_commands.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_commands.py @@ -2771,7 +2771,8 @@ class AMDSMICommands(): cpu_pwr_svi_telemetry_rails=None, cpu_io_bandwidth=None, cpu_xgmi_bandwidth=None, cpu_metrics_ver=None, cpu_metrics_table=None, cpu_socket_energy=None, cpu_ddr_bandwidth=None, cpu_temp=None, cpu_dimm_temp_range_rate=None, - cpu_dimm_pow_consumption=None, cpu_dimm_thermal_sensor=None): + cpu_dimm_pow_consumption=None, cpu_dimm_thermal_sensor=None, + cpu_dfcstate_ctrl=None, cpu_railisofreq_policy=None): """Get Metric information for target cpu Args: @@ -2794,6 +2795,8 @@ class AMDSMICommands(): cpu_dimm_temp_range_rate (list, optional): Dimm address. Value override for args.cpu_dimm_temp_range_rate. Defaults to None cpu_dimm_pow_consumption (list, optional): Dimm address. Value override for args.cpu_dimm_pow_consumption. Defaults to None cpu_dimm_thermal_sensor (list, optional): Dimm address. Value override for args.cpu_dimm_thermal_sensor. Defaults to None + cpu_dfcstate_ctrl (bool, optional): Value override for args.cpu_dfcstate_ctrl. Defaults to None + cpu_railisofreq_policy (bool, optional): Value override for args.cpu_railisofreq_policy. Defaults to None Returns: None: Print output via AMDSMILogger to destination @@ -2833,6 +2836,10 @@ class AMDSMICommands(): args.cpu_dimm_pow_consumption = cpu_dimm_pow_consumption if cpu_dimm_thermal_sensor: args.cpu_dimm_thermal_sensor = cpu_dimm_thermal_sensor + if cpu_dfcstate_ctrl: + args.cpu_dfcstate_ctrl = cpu_dfcstate_ctrl + if cpu_railisofreq_policy: + args.cpu_railisofreq_policy = cpu_railisofreq_policy #store cpu args that are applicable to the current platform curr_platform_cpu_args = ["cpu_power_metrics", "cpu_prochot", "cpu_freq_metrics", @@ -2840,13 +2847,13 @@ class AMDSMICommands(): "cpu_io_bandwidth", "cpu_xgmi_bandwidth", "cpu_metrics_ver", "cpu_metrics_table", "cpu_socket_energy", "cpu_ddr_bandwidth", "cpu_temp", "cpu_dimm_temp_range_rate", "cpu_dimm_pow_consumption", - "cpu_dimm_thermal_sensor"] + "cpu_dimm_thermal_sensor", "cpu_dfcstate_ctrl", "cpu_railisofreq_policy"] curr_platform_cpu_values = [args.cpu_power_metrics, args.cpu_prochot, args.cpu_freq_metrics, args.cpu_c0_res, args.cpu_lclk_dpm_level, args.cpu_pwr_svi_telemetry_rails, args.cpu_io_bandwidth, args.cpu_xgmi_bandwidth, args.cpu_metrics_ver, args.cpu_metrics_table, args.cpu_socket_energy, args.cpu_ddr_bandwidth, args.cpu_temp, args.cpu_dimm_temp_range_rate, args.cpu_dimm_pow_consumption, - args.cpu_dimm_thermal_sensor] + args.cpu_dimm_thermal_sensor, args.cpu_dfcstate_ctrl, args.cpu_railisofreq_policy] # Handle No CPU passed (fall back as this should be defined in metric()) if args.cpu == None: @@ -3051,6 +3058,22 @@ class AMDSMICommands(): except amdsmi_exception.AmdSmiLibraryException as e: static_dict["dimm_thermal_sensor"]["response"] = "N/A" logging.debug("Failed to get dimm temperature range and refresh rate for cpu %s | %s", cpu_id, e.get_error_info()) + if args.cpu_dfcstate_ctrl: + static_dict["dfcstate"] = {} + try: + dfcstatectrl_status = amdsmi_interface.amdsmi_get_dfc_ctrl(args.cpu) + static_dict["dfcstate"]["dfcstatectrl_status"] = dfcstatectrl_status + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["dfcstate"]["dfcstatectrl_status"] = "N/A" + logging.debug("Failed to get dfcstate control status for cpu %s | %s", cpu_id, e.get_error_info()) + if args.cpu_railisofreq_policy: + static_dict["cpurailiso"] = {} + try: + cpurailisofreq_policy = amdsmi_interface.amdsmi_get_cpu_rail_isofreq_policy(args.cpu) + static_dict["cpurailiso"]["cpurailisofreq_policy"] = cpurailisofreq_policy + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["cpurailiso"]["cpurailisofreq_policy"] = "N/A" + logging.debug("Failed to get cpurailiso frequency policy for cpu %s | %s", cpu_id, e.get_error_info()) multiple_devices_csv_override = False if not self.logger.is_json_format(): @@ -3161,7 +3184,7 @@ class AMDSMICommands(): cpu_io_bandwidth=None, cpu_xgmi_bandwidth=None, cpu_metrics_ver=None, cpu_metrics_table=None, cpu_socket_energy=None, cpu_ddr_bandwidth=None, cpu_temp=None, cpu_dimm_temp_range_rate=None, cpu_dimm_pow_consumption=None, - cpu_dimm_thermal_sensor=None, + cpu_dimm_thermal_sensor=None, cpu_dfcstate_ctrl=None, cpu_railisofreq_policy=None, core=None, core_boost_limit=None, core_curr_active_freq_core_limit=None, core_energy=None, throttle=None, base_board=None, gpu_board=None): """Get Metric information for target gpu @@ -3212,6 +3235,8 @@ class AMDSMICommands(): cpu_dimm_temp_range_rate (list, optional): Dimm address. Value override for args.cpu_dimm_temp_range_rate. Defaults to None cpu_dimm_pow_consumption (list, optional): Dimm address. Value override for args.cpu_dimm_pow_consumption. Defaults to None cpu_dimm_thermal_sensor (list, optional): Dimm address. Value override for args.cpu_dimm_thermal_sensor. Defaults to None + cpu_dfcstate_ctrl (bool, optional): Value override for args.cpu_dfcstate_ctrl. Defaults to None + cpu_railisofreq_policy (bool, optional): Value override for args.cpu_railisofreq_policy. Defaults to None core (device_handle, optional): device_handle for target core. Defaults to None. core_boost_limit (bool, optional): Value override for args.core_boost_limit. Defaults to None @@ -3251,7 +3276,8 @@ class AMDSMICommands(): "cpu_lclk_dpm_level", "cpu_pwr_svi_telemetry_rails", "cpu_io_bandwidth", "cpu_xgmi_bandwidth", "cpu_metrics_ver", "cpu_metrics_table", "cpu_socket_energy", "cpu_ddr_bandwidth", "cpu_temp", "cpu_dimm_temp_range_rate", - "cpu_dimm_pow_consumption", "cpu_dimm_thermal_sensor"] + "cpu_dimm_pow_consumption", "cpu_dimm_thermal_sensor", + "cpu_dfcstate_ctrl", "cpu_railisofreq_policy"] for attr in cpu_attributes: if hasattr(args, attr): if getattr(args, attr): @@ -3297,7 +3323,8 @@ class AMDSMICommands(): cpu_pwr_svi_telemetry_rails, cpu_io_bandwidth, cpu_xgmi_bandwidth, cpu_metrics_ver, cpu_metrics_table, cpu_socket_energy, cpu_ddr_bandwidth, cpu_temp, cpu_dimm_temp_range_rate, - cpu_dimm_pow_consumption, cpu_dimm_thermal_sensor) + cpu_dimm_pow_consumption, cpu_dimm_thermal_sensor, + cpu_dfcstate_ctrl, cpu_railisofreq_policy) if args.core: self.logger.output = {} self.logger.clear_multiple_devices_output() @@ -3331,7 +3358,8 @@ class AMDSMICommands(): cpu_pwr_svi_telemetry_rails, cpu_io_bandwidth, cpu_xgmi_bandwidth, cpu_metrics_ver, cpu_metrics_table, cpu_socket_energy, cpu_ddr_bandwidth, cpu_temp, cpu_dimm_temp_range_rate, - cpu_dimm_pow_consumption, cpu_dimm_thermal_sensor) + cpu_dimm_pow_consumption, cpu_dimm_thermal_sensor, + cpu_dfcstate_ctrl, cpu_railisofreq_policy) if args.core: self.logger.output = {} self.logger.clear_multiple_devices_output() @@ -4358,7 +4386,8 @@ class AMDSMICommands(): def set_cpu(self, args, multiple_devices=False, cpu=None, cpu_pwr_limit=None, cpu_xgmi_link_width=None, cpu_lclk_dpm_level=None, 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): + cpu_enable_apb=None, cpu_disable_apb=None, soc_boost_limit=None, + cpu_dfcstate_ctrl=None, cpu_railisofreq_policy=None): """Issue set commands to target cpu(s) Args: @@ -4375,6 +4404,8 @@ class AMDSMICommands(): cpu_enable_apb (bool, optional): Value override for args.cpu_enable_apb. Defaults to None. cpu_disable_apb (int, optional): Value override for args.cpu_disable_apb. Defaults to None. soc_boost_limit (int, optional): Value override for args.soc_boost_limit. Defaults to None. + cpu_dfcstate_ctrl (int, optional): Value override for args.cpu_dfcstate_ctrl. Defaults to None. + cpu_railisofreq_policy (int, optional): Value override for args.cpu_railisofreq_policy. Defaults to None. Raises: ValueError: Value error if no cpu value is provided @@ -4405,6 +4436,10 @@ class AMDSMICommands(): args.cpu_disable_apb = cpu_disable_apb if soc_boost_limit: args.soc_boost_limit = soc_boost_limit + if cpu_dfcstate_ctrl: + args.cpu_dfcstate_ctrl = cpu_dfcstate_ctrl + if cpu_railisofreq_policy: + args.cpu_railisofreq_policy = cpu_railisofreq_policy if args.cpu == None: raise ValueError('No CPU provided, specific CPU targets(S) are needed') @@ -4419,7 +4454,7 @@ class AMDSMICommands(): if not any([args.cpu_pwr_limit, args.cpu_xgmi_link_width, args.cpu_lclk_dpm_level, args.cpu_pwr_eff_mode, args.cpu_gmi3_link_width, args.cpu_pcie_link_rate, args.cpu_df_pstate_range, args.cpu_enable_apb, args.cpu_disable_apb, - args.soc_boost_limit]): + args.soc_boost_limit, args.cpu_dfcstate_ctrl, args.cpu_railisofreq_policy]): command = " ".join(sys.argv[1:]) raise AmdSmiRequiredCommandException(command, self.logger.format) @@ -4532,6 +4567,23 @@ class AMDSMICommands(): #static_dict["set_soc_boost_limit"]["Response"] = "N/A" static_dict["set_soc_boost_limit"]["Response"] = f"Error occurred for CPU {cpu_id} - {e.get_error_info()}" logging.debug("Failed to set socket boost limit for cpu %s | %s", cpu_id, e.get_error_info()) + if args.cpu_dfcstate_ctrl: + static_dict["dfcstatectrl"] = {} + try: + amdsmi_interface.amdsmi_set_dfc_ctrl(args.cpu, args.cpu_dfcstate_ctrl[0][0]) + static_dict["dfcstatectrl"]["state"] = "DFCState control operation successful" + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["dfcstatectrl"]["state"] = f"Error occurred for CPU {cpu_id} - {e.get_error_info()}" + logging.debug("Failed to set dfcstate control for cpu %s | %s", cpu_id, e.get_error_info()) + + if args.cpu_railisofreq_policy: + static_dict["cpurailiso"] = {} + try: + amdsmi_interface.amdsmi_set_cpu_rail_isofreq_policy(args.cpu, args.cpu_railisofreq_policy[0][0]) + static_dict["cpurailiso"]["state"] = "Set CPU ISO frequency policy operation successful" + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["cpurailiso"]["state"] = f"Error occurred for CPU {cpu_id} - {e.get_error_info()}" + logging.debug("Failed to set ISO frequency policy for cpu %s | %s", cpu_id, e.get_error_info()) multiple_devices_csv_override = False self.logger.store_cpu_output(args.cpu, 'values', static_dict) @@ -5148,7 +5200,8 @@ 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, ptl_status=None, ptl_format=None): + process_isolation=None, clk_limit=None, clk_level=None, cpu_dfcstate_ctrl=None, + cpu_railisofreq_policy=None, ptl_status=None, ptl_format=None): """Issue reset commands to target gpu(s) Args: @@ -5174,6 +5227,8 @@ class AMDSMICommands(): cpu_enable_apb (bool, optional): Value override for args.cpu_enable_apb. Defaults to None. cpu_disable_apb (int, optional): Value override for args.cpu_disable_apb. Defaults to None. soc_boost_limit (int, optional): Value override for args.soc_boost_limit. Defaults to None. + cpu_dfcstate_ctrl (int, optional): Value override for args.cpu_dfcstate_ctrl. Defaults to None. + cpu_railisofreq_policy (int, optional): Value override for args.cpu_railisofreq_policy. Defaults to None. core (device_handle, optional): device_handle for target core. Defaults to None. core_boost_limit (int, optional): Value override for args.core_boost_limit. Defaults to None @@ -5210,7 +5265,8 @@ class AMDSMICommands(): cpu_args_enabled = False cpu_attributes = ["cpu_pwr_limit", "cpu_xgmi_link_width", "cpu_lclk_dpm_level", "cpu_pwr_eff_mode", "cpu_gmi3_link_width", "cpu_pcie_link_rate", "cpu_df_pstate_range", - "cpu_enable_apb", "cpu_disable_apb", "soc_boost_limit"] + "cpu_enable_apb", "cpu_disable_apb", "soc_boost_limit", + "cpu_dfcstate_ctrl", "cpu_railisofreq_policy"] for attr in cpu_attributes: if hasattr(args, attr): if getattr(args, attr) not in [None, False]: @@ -5265,7 +5321,9 @@ class AMDSMICommands(): args.cpu_df_pstate_range is not None, args.cpu_enable_apb, args.cpu_disable_apb is not None, - args.soc_boost_limit is not None + args.soc_boost_limit is not None, + args.cpu_dfcstate_ctrl is not None, + args.cpu_railisofreq_policy is not None ]) except AttributeError: # If attribute error for cpu, then we could be another subcommand @@ -5318,7 +5376,8 @@ class AMDSMICommands(): self.set_cpu(args, multiple_devices, cpu, cpu_pwr_limit, cpu_xgmi_link_width, cpu_lclk_dpm_level, cpu_pwr_eff_mode, cpu_gmi3_link_width, cpu_pcie_link_rate, cpu_df_pstate_range, - cpu_enable_apb, cpu_disable_apb, soc_boost_limit) + cpu_enable_apb, cpu_disable_apb, soc_boost_limit, + cpu_dfcstate_ctrl, cpu_railisofreq_policy) if args.core: self.logger.output = {} self.logger.clear_multiple_devices_output() @@ -5337,7 +5396,8 @@ class AMDSMICommands(): self.set_cpu(args, multiple_devices, cpu, cpu_pwr_limit, cpu_xgmi_link_width, cpu_lclk_dpm_level, cpu_pwr_eff_mode, cpu_gmi3_link_width, cpu_pcie_link_rate, cpu_df_pstate_range, - cpu_enable_apb, cpu_disable_apb, soc_boost_limit) + cpu_enable_apb, cpu_disable_apb, soc_boost_limit, + cpu_dfcstate_ctrl, cpu_railisofreq_policy) if args.core: self.logger.output = {} self.logger.clear_multiple_devices_output() diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_parser.py b/projects/amdsmi/amdsmi_cli/amdsmi_parser.py index 2a7433ea75..83b4ea20c4 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_parser.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_parser.py @@ -1097,6 +1097,8 @@ class AMDSMIParser(argparse.ArgumentParser): cpu_dimm_temp_range_rate_help = "Displays dimm temperature range and refresh rate" cpu_dimm_pow_consumption_help = "Displays dimm power consumption" cpu_dimm_thermal_sensor_help = "Displays dimm thermal sensor" + cpu_dfcstate_ctrl_help = "Displays DFCState control status" + cpu_railisofreq_policy_help = "Displays CPU ISO frequency policy" # Help text for core options core_energy_help = "Displays core energy for the selected core" @@ -1177,6 +1179,8 @@ class AMDSMIParser(argparse.ArgumentParser): nargs=1, metavar=("DIMM_ADDR"), help=cpu_dimm_pow_consumption_help) cpu_group.add_argument('--cpu-dimm-thermal-sensor', action='append', required=False, type=lambda x: int(x, 0), nargs=1, metavar=("DIMM_ADDR"), help=cpu_dimm_thermal_sensor_help) + cpu_group.add_argument('--cpu-dfcstate-ctrl', action='store_true', required=False, help=cpu_dfcstate_ctrl_help) + cpu_group.add_argument('--cpu-railisofreq-policy', action='store_true', required=False, help=cpu_railisofreq_policy_help) # Optional Args for CPU cores core_group = metric_parser.add_argument_group("CPU Core Arguments") @@ -1371,6 +1375,8 @@ class AMDSMIParser(argparse.ArgumentParser): set_cpu_enable_apb_help = "Enables the DF p-state performance boost algorithm" set_cpu_disable_apb_help = "Disables the DF p-state performance boost algorithm. Input parameter is DFPstate (0-3)" set_soc_boost_limit_help = "Sets the boost limit for the given socket. Input parameter is socket BOOST_LIMIT value" + set_cpu_dfcstate_ctrl_help = "Sets the DFCState control. Input parameter is value (0-1)" + set_cpu_railisofreq_policy_help = "Sets the CPU ISO frequency policy. Input parameter is value (0-1)" # Help text for CPU Core set options set_core_boost_limit_help = "Sets the boost limit for the given core. Input parameter is core BOOST_LIMIT value" @@ -1419,7 +1425,8 @@ class AMDSMIParser(argparse.ArgumentParser): cpu_group.add_argument('--cpu-enable-apb', action='store_true', required=False, help=set_cpu_enable_apb_help) cpu_group.add_argument('--cpu-disable-apb', action='append', required=False, type=self._not_negative_int, nargs=1, metavar=("DF_PSTATE"), help=set_cpu_disable_apb_help) cpu_group.add_argument('--soc-boost-limit', action='append', required=False, type=self._positive_int, nargs=1, metavar=("BOOST_LIMIT"), help=set_soc_boost_limit_help) - + cpu_group.add_argument('--cpu-dfcstate-ctrl', action='append', required=False, type=self._not_negative_int, nargs=1, metavar=("VALUE"), help=set_cpu_dfcstate_ctrl_help) + cpu_group.add_argument('--cpu-railisofreq-policy', action='append', required=False, type=self._not_negative_int, nargs=1, metavar=("VALUE"), help=set_cpu_railisofreq_policy_help) # Optional CPU Core Args core_group = set_value_parser.add_argument_group("CPU Core Arguments") core_group.add_argument('--core-boost-limit', action='append', required=False, type=self._positive_int, nargs=1, metavar=("BOOST_LIMIT"), help=set_core_boost_limit_help) diff --git a/projects/amdsmi/docs/how-to/amdsmi-cli-tool.md b/projects/amdsmi/docs/how-to/amdsmi-cli-tool.md index 979796156d..3378959f07 100644 --- a/projects/amdsmi/docs/how-to/amdsmi-cli-tool.md +++ b/projects/amdsmi/docs/how-to/amdsmi-cli-tool.md @@ -358,6 +358,8 @@ CPU Arguments: --cpu-dimm-temp-range-rate DIMM_ADDR Displays dimm temperature range and refresh rate --cpu-dimm-pow-consumption DIMM_ADDR Displays dimm power consumption --cpu-dimm-thermal-sensor DIMM_ADDR Displays dimm thermal sensor + --cpu-dfcstate-ctrl Displays DFCState control status + --cpu-railisofreq-policy Displays CPU ISO frequency policy CPU Core Arguments: --core-boost-limit Get boost limit for the selected cores @@ -550,7 +552,7 @@ usage: amd-smi set [-h] (-g GPU [GPU ...] | -U CPU [CPU ...] | -O CORE [CORE ... [--cpu-df-pstate-range MAX_PSTATE MIN_PSTATE] [--cpu-enable-apb] [--cpu-disable-apb DF_PSTATE] [--soc-boost-limit BOOST_LIMIT] [--core-boost-limit BOOST_LIMIT] [--json | --csv] [--file FILE] - [--loglevel LEVEL] + [--loglevel LEVEL] [--cpu-dfcstate-ctrl VALUE] [--cpu-railisofreq-policy VALUE] If no GPU is specified, will select all GPUs on the system. A set argument must be provided; Multiple set arguments are accepted. @@ -595,6 +597,8 @@ CPU Arguments: --cpu-enable-apb Enables the DF p-state performance boost algorithm --cpu-disable-apb DF_PSTATE Disables the DF p-state performance boost algorithm. Input parameter is DFPstate (0-3) --soc-boost-limit BOOST_LIMIT Sets the boost limit for the given socket. Input parameter is socket BOOST_LIMIT value + --cpu-dfcstate-ctrl VALUE Sets the DFCState control for the given socket. Input parameter is VALUE (0-1) + --cpu-railisofreq-policy VALUE Sets the CPU ISO frequency policy. Input parameter is VALUE (0-1) CPU Core Arguments: --core-boost-limit BOOST_LIMIT Sets the boost limit for the given core. Input parameter is core BOOST_LIMIT value diff --git a/projects/amdsmi/docs/reference/amdsmi-py-api.md b/projects/amdsmi/docs/reference/amdsmi-py-api.md index 3f5edd6136..156282e326 100644 --- a/projects/amdsmi/docs/reference/amdsmi-py-api.md +++ b/projects/amdsmi/docs/reference/amdsmi-py-api.md @@ -6754,3 +6754,177 @@ try: except AmdSmiException as e: print(e) ``` + +### amdsmi_set_cpu_rail_isofreq_policy + +Description: Set the CPU Rail Isofrequency Policy. This function configures the frequency policy for CPU power rails. + +Input parameters: +- `processor_handle` (amdsmi_processor_handle): CPU socket handle to query +- `value` (int): Input policy value indicating the isofrequency setting: + - 0: Independent control enabled (each rail has an independent frequency limit) + - 1: Independent control disabled (all cores on both rails or each rail - have the same frequency limit) + +Output: `None` + +Exceptions that can be thrown by `amdsmi_set_cpu_rail_isofreq_policy` function: + +* `AmdSmiLibraryException` + +#### Possible Library Exceptions + +- `AMDSMI_STATUS_NOT_SUPPORTED` - Feature not supported +- `AMDSMI_STATUS_NOT_YET_IMPLEMENTED` - Feature not yet implemented +- `AMDSMI_STATUS_NO_HSMP_MSG_SUP` - HSMP message/feature not supported +- `AMDSMI_STATUS_INVAL` - Invalid parameters +- `AMDSMI_STATUS_TIMEOUT` - Timeout in API call + +Example: + +```python +from amdsmi import * +try: + ret = amdsmi_init(AmdSmiInitFlags.INIT_AMD_CPUS) + processor_handles = amdsmi_get_cpusocket_handles() + if len(processor_handles) == 0: + print("No CPUs on machine") + else: + for processor in processor_handles: + # Set independent control mode (0) + amdsmi_set_cpu_rail_isofreq_policy(processor, 0) + print("CPU rail isofrequency policy: set to each rail has independent frequency limit") +except AmdSmiException as e: + print(e) +``` + +### amdsmi_get_cpu_rail_isofreq_policy + +Description: Get the CPU Rail Isofrequency Policy. This function retrieves the current frequency policy configuration for CPU power rails. + +Input parameters: +- `processor_handle` (amdsmi_processor_handle): CPU socket handle to query + +Output: Integer representing the CPU rail isofrequency policy: + - 0: Independent control enabled (each rail has an independent frequency limit) + - 1: Independent control disabled (all cores on both rails or each rail - have the same frequency limit) + +Exceptions that can be thrown by `amdsmi_get_cpu_rail_isofreq_policy` function: + +* `AmdSmiLibraryException` + +#### Possible Library Exceptions + +- `AMDSMI_STATUS_NOT_SUPPORTED` - Feature not supported +- `AMDSMI_STATUS_NOT_YET_IMPLEMENTED` - Feature not yet implemented +- `AMDSMI_STATUS_NO_HSMP_MSG_SUP` - HSMP message/feature not supported +- `AMDSMI_STATUS_INVAL` - Invalid parameters +- `AMDSMI_STATUS_TIMEOUT` - Timeout in API call + +Example: + +```python +from amdsmi import * +try: + ret = amdsmi_init(AmdSmiInitFlags.INIT_AMD_CPUS) + processor_handles = amdsmi_get_cpusocket_handles() + if len(processor_handles) == 0: + print("No CPUs on machine") + else: + for processor in processor_handles: + policy = amdsmi_get_cpu_rail_isofreq_policy(processor) + if policy == 0: + print("CPU rail isofrequency policy: Each rail has independent frequency limit") + elif policy == 1: + print("CPU rail isofrequency policy: Both rail have same frequency limit") + else: + print("CPU rail isofrequency policy: Unknown value {policy}") +except AmdSmiException as e: + print(e) +``` + +### amdsmi_set_dfc_ctrl + +Description: Set the DFCState enabling control. DFCState is a low power state used for I/O Die (IOD). + +Input parameters: +- `processor_handle` (amdsmi_processor_handle): CPU socket handle to query +- `value` (int): DFCState control value: + - 0: Disable DFCState control + - 1: Enable DFCState control + +Output: `None` + +Exceptions that can be thrown by `amdsmi_set_dfc_ctrl` function: + +* `AmdSmiLibraryException` + +#### Possible Library Exceptions + +- `AMDSMI_STATUS_NOT_SUPPORTED` - Feature not supported +- `AMDSMI_STATUS_NOT_YET_IMPLEMENTED` - Feature not yet implemented +- `AMDSMI_STATUS_NO_HSMP_MSG_SUP` - HSMP message/feature not supported +- `AMDSMI_STATUS_INVAL` - Invalid parameters +- `AMDSMI_STATUS_TIMEOUT` - Timeout in API call + +Example: + +```python +from amdsmi import * +try: + ret = amdsmi_init(AmdSmiInitFlags.INIT_AMD_CPUS) + processor_handles = amdsmi_get_cpusocket_handles() + if len(processor_handles) == 0: + print("No CPUs on machine") + else: + for processor in processor_handles: + # Enable DFCState control + amdsmi_set_dfc_ctrl(processor, 1) + print("DFCState control enabled") +except AmdSmiException as e: + print(e) +``` + +### amdsmi_get_dfc_ctrl + +Description: Get the current DFCState enabling control status. DFCState is a low power state used for I/O Die (IOD). + +Input parameters: +- `processor_handle` (amdsmi_processor_handle): CPU socket handle to query + +Output: Integer representing the DFCState control status: + - 0: DFCState control is disabled + - 1: DFCState control is enabled + +Exceptions that can be thrown by `amdsmi_get_dfc_ctrl` function: + +* `AmdSmiLibraryException` + +#### Possible Library Exceptions + +- `AMDSMI_STATUS_NOT_SUPPORTED` - Feature not supported +- `AMDSMI_STATUS_NOT_YET_IMPLEMENTED` - Feature not yet implemented +- `AMDSMI_STATUS_NO_HSMP_MSG_SUP` - HSMP message/feature not supported +- `AMDSMI_STATUS_INVAL` - Invalid parameters +- `AMDSMI_STATUS_TIMEOUT` - Timeout in API call + +Example: + +```python +from amdsmi import * +try: + ret = amdsmi_init(AmdSmiInitFlags.INIT_AMD_CPUS) + processor_handles = amdsmi_get_cpusocket_handles() + if len(processor_handles) == 0: + print("No CPUs on machine") + else: + for processor in processor_handles: + dfc_status = amdsmi_get_dfc_ctrl(processor) + if dfc_status == 0: + print("DFCState control is disabled") + elif dfc_status == 1: + print("DFCState control is enabled") + else: + print(f"DFCState control: Unknown status {dfc_status}") +except AmdSmiException as e: + print(e) +``` diff --git a/projects/amdsmi/include/amd_smi/amdsmi.h b/projects/amdsmi/include/amd_smi/amdsmi.h index aa43d2e5dd..dbc480b462 100644 --- a/projects/amdsmi/include/amd_smi/amdsmi.h +++ b/projects/amdsmi/include/amd_smi/amdsmi.h @@ -7756,6 +7756,114 @@ amdsmi_status_t amdsmi_get_cpu_socket_count(uint32_t *sock_count); /** @} End tagCPUAuxillary */ +/** + * @brief Set the CPU Rail Isofrequency Policy + * + * This API configures the frequency policy for CPU power rails. + * - If a socket-wide limit (e.g., PPT) is setting the core clock frequency, this setting has no effect. + * - For other limiters specific to CPU power rails (e.g., TDC), + * this policy enables or disables independent core clocks per rail (VDDCR_CPU0 or VDDCR_CPU1). + * + * Policy values: + * - 0: Disable independent control (all cores on both rails have the same frequency limit) + * - 1: Enable independent control (each rail has an independent frequency limit) + * + * @ingroup tagCpuISOFreqPolicy + * + * @platform{cpu_bm} + * + * @param[in] processor_handle Cpu socket which to query + * + * @param[in] input Input policy value indicating the isofrequency setting: + * - 0: Enable independent control - each rail has its own independent frequency limit. + * - 1: Disable independent control - all cores on both rails share the same frequency limit. + * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail + */ +amdsmi_status_t amdsmi_set_cpu_rail_isofreq_policy(amdsmi_processor_handle processor_handle, + uint8_t input); + +/** + * @brief Get the CPU Rail Isofrequency Policy. + * + * This API retrieves the current frequency policy configuration for CPU power rails. + * - If a socket-wide limit (e.g., PPT) is setting the core clock frequency, the effective policy may be overridden. + * - For other limiters specific to CPU power rails (e.g., TDC), + * this policy indicates whether independent core clocks per rail (VDDCR_CPU0 or VDDCR_CPU1) are enabled or disabled. + * + * Cpu rail iso policy values returned: + * - 0: Independent control disabled (all cores on both rails have the same frequency limit) + * - 1: Independent control enabled (each rail has an independent frequency limit) + * + * @ingroup tagCpuISOFreqPolicy + * + * @platform{cpu_bm} + * + * @param[in] processor_handle Cpu socket which to query + * + * @param[in,out] cpurailiso to receive the current policy state + * + * @return ::amdsmi_status_t + * ::AMDSMI_STATUS_SUCCESS on success, non-zero on failure + */ +amdsmi_status_t amdsmi_get_cpu_rail_isofreq_policy(amdsmi_processor_handle processor_handle, + uint8_t *cpurailiso); + +/** @} End tagCpuISOFreqPolicy */ + +/** + * @brief Set the DFCState enabling control. + * + * DFCState is a low power state used for I/O Die (IOD). + * + * Note: + * - This feature cannot be enabled unless it was enabled by the BIOS during POST. + * - Use this API to enable or disable DFCState control. + * + * DFCState control values for setting: + * - 0: Disable DFC control + * - 1: Enable DFC control + * + * @ingroup tagDFCEnableControl + * + * @platform{cpu_bm} + * + * @param[in] processor_handle Cpu socket handle to query + * + * @param[in] dfc_ctrl indicating whether to enable (1) or disable (0) DFC control + * + * @return ::amdsmi_status_t + * ::AMDSMI_STATUS_SUCCESS on success, non-zero on failure + */ +amdsmi_status_t amdsmi_set_dfc_ctrl(amdsmi_processor_handle processor_handle, bool dfc_ctrl); + +/** + * @brief Get the current DFCState enabling control status. + * + * DFCState is a low power state used for I/O Die (IOD). + * + * Note: + * - This feature can only be enabled if it was enabled by the BIOS during POST. + * - This API retrieves whether DFC control is currently enabled or disabled. + * + * Returned DFCState control values: + * - 0: DFC control is disabled + * - 1: DFC control is enabled + * + * @ingroup tagDFCEnableControl + * + * @platform{cpu_bm} + * + * @param[in] processor_handle Cpu socket handle to query + * + * @param[in,out] dfc_ctrl to receive the current DFCState control status + * + * @return ::amdsmi_status_t + * ::AMDSMI_STATUS_SUCCESS on success, non-zero on failure + */ +amdsmi_status_t amdsmi_get_dfc_ctrl(amdsmi_processor_handle processor_handle, uint8_t *dfc_ctrl); + +/** @} End tagDFCEnableControl */ + #endif #ifdef __cplusplus diff --git a/projects/amdsmi/py-interface/__init__.py b/projects/amdsmi/py-interface/__init__.py index b5aa300658..8295178d8b 100644 --- a/projects/amdsmi/py-interface/__init__.py +++ b/projects/amdsmi/py-interface/__init__.py @@ -81,6 +81,10 @@ try: from .amdsmi_interface import amdsmi_get_cpu_model from .amdsmi_interface import amdsmi_get_cpu_model_name from .amdsmi_interface import amdsmi_get_cpu_handles + from .amdsmi_interface import amdsmi_get_dfc_ctrl + from .amdsmi_interface import amdsmi_set_dfc_ctrl + from .amdsmi_interface import amdsmi_get_cpu_rail_isofreq_policy + from .amdsmi_interface import amdsmi_set_cpu_rail_isofreq_policy except AttributeError: pass diff --git a/projects/amdsmi/py-interface/amdsmi_interface.py b/projects/amdsmi/py-interface/amdsmi_interface.py index babb9990c5..90d8e5be06 100644 --- a/projects/amdsmi/py-interface/amdsmi_interface.py +++ b/projects/amdsmi/py-interface/amdsmi_interface.py @@ -1788,6 +1788,63 @@ def amdsmi_get_hsmp_metrics_table_version( return metric_tbl_version.value +def amdsmi_set_cpu_rail_isofreq_policy( + processor_handle: processor_handle_t, + value: int): + 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_cpu_rail_isofreq_policy(processor_handle, value) + ) + +def amdsmi_get_cpu_rail_isofreq_policy( + processor_handle: processor_handle_t, +) -> int: + if not isinstance(processor_handle, amdsmi_wrapper.amdsmi_processor_handle): + raise AmdSmiParameterException( + processor_handle, amdsmi_wrapper.amdsmi_processor_handle + ) + + cpurailiso = ctypes.c_uint8() + _check_res( + amdsmi_wrapper.amdsmi_get_cpu_rail_isofreq_policy( + processor_handle, ctypes.byref(cpurailiso) + ) + ) + + return cpurailiso.value + +def amdsmi_get_dfc_ctrl( + processor_handle: processor_handle_t, +) -> int: + if not isinstance(processor_handle, amdsmi_wrapper.amdsmi_processor_handle): + raise AmdSmiParameterException( + processor_handle, amdsmi_wrapper.amdsmi_processor_handle + ) + + dfc_ctrl = ctypes.c_uint8() + _check_res( + amdsmi_wrapper.amdsmi_get_dfc_ctrl( + processor_handle, ctypes.byref(dfc_ctrl) + ) + ) + + return dfc_ctrl.value + +def amdsmi_set_dfc_ctrl( + processor_handle: processor_handle_t, + value: int): + 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_dfc_ctrl(processor_handle, value) + ) # Get 2's complement of 32 bit unsigned integer def check_msb_32(num): diff --git a/projects/amdsmi/py-interface/amdsmi_wrapper.py b/projects/amdsmi/py-interface/amdsmi_wrapper.py index f9298a5f10..c45b5fa915 100644 --- a/projects/amdsmi/py-interface/amdsmi_wrapper.py +++ b/projects/amdsmi/py-interface/amdsmi_wrapper.py @@ -3248,6 +3248,18 @@ amdsmi_get_cpu_cores_per_socket.argtypes = [uint32_t, ctypes.POINTER(struct_amds amdsmi_get_cpu_socket_count = _libraries['libamd_smi.so'].amdsmi_get_cpu_socket_count amdsmi_get_cpu_socket_count.restype = amdsmi_status_t amdsmi_get_cpu_socket_count.argtypes = [ctypes.POINTER(ctypes.c_uint32)] +amdsmi_set_cpu_rail_isofreq_policy = _libraries['libamd_smi.so'].amdsmi_set_cpu_rail_isofreq_policy +amdsmi_set_cpu_rail_isofreq_policy.restype = amdsmi_status_t +amdsmi_set_cpu_rail_isofreq_policy.argtypes = [amdsmi_processor_handle, uint8_t] +amdsmi_get_cpu_rail_isofreq_policy = _libraries['libamd_smi.so'].amdsmi_get_cpu_rail_isofreq_policy +amdsmi_get_cpu_rail_isofreq_policy.restype = amdsmi_status_t +amdsmi_get_cpu_rail_isofreq_policy.argtypes = [amdsmi_processor_handle, ctypes.POINTER(ctypes.c_uint8)] +amdsmi_set_dfc_ctrl = _libraries['libamd_smi.so'].amdsmi_set_dfc_ctrl +amdsmi_set_dfc_ctrl.restype = amdsmi_status_t +amdsmi_set_dfc_ctrl.argtypes = [amdsmi_processor_handle, ctypes.c_bool] +amdsmi_get_dfc_ctrl = _libraries['libamd_smi.so'].amdsmi_get_dfc_ctrl +amdsmi_get_dfc_ctrl.restype = amdsmi_status_t +amdsmi_get_dfc_ctrl.argtypes = [amdsmi_processor_handle, ctypes.POINTER(ctypes.c_uint8)] __all__ = \ ['AGG_BW0', 'AMDSMI_ACCELERATOR_DECODER', 'AMDSMI_ACCELERATOR_DMA', 'AMDSMI_ACCELERATOR_ENCODER', @@ -3585,8 +3597,9 @@ __all__ = \ 'amdsmi_get_cpu_socket_power', 'amdsmi_get_cpu_socket_power_cap', 'amdsmi_get_cpu_socket_power_cap_max', 'amdsmi_get_cpu_socket_temperature', 'amdsmi_get_cpucore_handles', - 'amdsmi_get_cpusocket_handles', 'amdsmi_get_energy_count', - 'amdsmi_get_esmi_err_msg', 'amdsmi_get_fw_info', + 'amdsmi_get_energy_count', 'amdsmi_get_esmi_err_msg', + 'amdsmi_get_fw_info', 'amdsmi_get_dfc_ctrl', 'amdsmi_set_dfc_ctrl', + 'amdsmi_get_cpu_rail_isofreq_policy', 'amdsmi_set_cpu_rail_isofreq_policy', 'amdsmi_get_gpu_accelerator_partition_profile', 'amdsmi_get_gpu_accelerator_partition_profile_config', 'amdsmi_get_gpu_activity', 'amdsmi_get_gpu_asic_info', diff --git a/projects/amdsmi/src/amd_smi/amd_smi.cc b/projects/amdsmi/src/amd_smi/amd_smi.cc index b4c5f8194d..4e2c060508 100644 --- a/projects/amdsmi/src/amd_smi/amd_smi.cc +++ b/projects/amdsmi/src/amd_smi/amd_smi.cc @@ -6843,4 +6843,107 @@ amdsmi_status_t amdsmi_get_esmi_err_msg(amdsmi_status_t status, const char **sta return AMDSMI_STATUS_SUCCESS; } +amdsmi_status_t amdsmi_set_cpu_rail_isofreq_policy(amdsmi_processor_handle processor_handle, + uint8_t input) +{ + amdsmi_status_t status; + uint8_t sock_ind; + bool val; + + AMDSMI_CHECK_INIT(); + + if (processor_handle == nullptr ) + return AMDSMI_STATUS_INVAL; + + amdsmi_status_t r = amdsmi_get_processor_info(processor_handle, SIZE, proc_id); + if (r != AMDSMI_STATUS_SUCCESS) + return r; + + sock_ind = (uint8_t)std::stoi(proc_id, NULL, 0); + + val = (bool)input; + status = static_cast(esmi_cpurail_isofreq_policy_set(sock_ind, &val)); + if (status != AMDSMI_STATUS_SUCCESS) + return amdsmi_errno_to_esmi_status(status); + + return AMDSMI_STATUS_SUCCESS; +} + +amdsmi_status_t amdsmi_get_cpu_rail_isofreq_policy(amdsmi_processor_handle processor_handle, + uint8_t *cpurailiso) +{ + amdsmi_status_t status; + uint8_t sock_ind; + bool cpurailisofreq; + + AMDSMI_CHECK_INIT(); + + if (processor_handle == nullptr || cpurailiso == nullptr) + return AMDSMI_STATUS_INVAL; + + amdsmi_status_t r = amdsmi_get_processor_info(processor_handle, SIZE, proc_id); + if (r != AMDSMI_STATUS_SUCCESS) + return r; + + sock_ind = (uint8_t)std::stoi(proc_id, NULL, 0); + + status = static_cast(esmi_cpurail_isofreq_policy_get(sock_ind, &cpurailisofreq)); + if (status != AMDSMI_STATUS_SUCCESS) + return amdsmi_errno_to_esmi_status(status); + + *cpurailiso = (uint8_t) cpurailisofreq; + return AMDSMI_STATUS_SUCCESS; +} + +amdsmi_status_t amdsmi_set_dfc_ctrl(amdsmi_processor_handle processor_handle, + bool dfc_ctrl) +{ + amdsmi_status_t status; + uint8_t sock_ind; + + AMDSMI_CHECK_INIT(); + + if (processor_handle == nullptr) + return AMDSMI_STATUS_INVAL; + + amdsmi_status_t r = amdsmi_get_processor_info(processor_handle, SIZE, proc_id); + if (r != AMDSMI_STATUS_SUCCESS) + return r; + + sock_ind = (uint8_t)std::stoi(proc_id, NULL, 0); + + status = static_cast(esmi_dfc_enable_set(sock_ind, &dfc_ctrl)); + if (status != AMDSMI_STATUS_SUCCESS) + return amdsmi_errno_to_esmi_status(status); + + return AMDSMI_STATUS_SUCCESS; +} + +amdsmi_status_t amdsmi_get_dfc_ctrl(amdsmi_processor_handle processor_handle, + uint8_t *dfc_ctrl) +{ + amdsmi_status_t status; + uint8_t sock_ind; + bool dfcctrl; + + AMDSMI_CHECK_INIT(); + + if (processor_handle == nullptr || dfc_ctrl == nullptr) + return AMDSMI_STATUS_INVAL; + + amdsmi_status_t r = amdsmi_get_processor_info(processor_handle, SIZE, proc_id); + if (r != AMDSMI_STATUS_SUCCESS) + return r; + + sock_ind = (uint8_t)std::stoi(proc_id, NULL, 0); + + status = static_cast(esmi_dfc_ctrl_setting_get(sock_ind, &dfcctrl)); + if (status != AMDSMI_STATUS_SUCCESS) + return amdsmi_errno_to_esmi_status(status); + + *dfc_ctrl = (uint8_t)dfcctrl; + + return AMDSMI_STATUS_SUCCESS; +} + #endif