diff --git a/CMakeLists.txt b/CMakeLists.txt index ef5b8756d2..c4b9421130 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,8 +39,8 @@ set(${AMD_SMI_LIBS_TARGET}_VERSION_BUILD "0") # ABI breaks (update MAJOR and MINOR), and ABI/API additions (update MINOR). # Until ABI stabilizes VERSION_MAJOR will be 0. This should be over-ridden # by git tags (through "git describe") when they are present. -set(PKG_VERSION_MAJOR 1) -set(PKG_VERSION_MINOR 0) +set(PKG_VERSION_MAJOR "${VERSION_MAJOR}") +set(PKG_VERSION_MINOR "${VERSION_MINOR}") set(PKG_VERSION_PATCH 0) set(PKG_VERSION_NUM_COMMIT 0) @@ -139,6 +139,7 @@ set(CMN_INC_LIST "${ROCM_INC_DIR}/rocm_smi_common.h" "${ROCM_INC_DIR}/rocm_smi_counters.h" "${ROCM_INC_DIR}/rocm_smi_device.h" + "${ROCM_INC_DIR}/rocm_smi_gpu_metrics.h" "${ROCM_INC_DIR}/rocm_smi_exception.h" "${ROCM_INC_DIR}/rocm_smi_io_link.h" "${ROCM_INC_DIR}/rocm_smi_kfd.h" diff --git a/amdsmi_cli/amdsmi_commands.py b/amdsmi_cli/amdsmi_commands.py index 9c5aa09f3e..b598a15d5c 100644 --- a/amdsmi_cli/amdsmi_commands.py +++ b/amdsmi_cli/amdsmi_commands.py @@ -209,7 +209,8 @@ class AMDSMICommands(): asic_info['rev_id'] = hex(asic_info['rev_id']) if asic_info['asic_serial'] != '': asic_info['asic_serial'] = hex(int(asic_info['asic_serial'], base=16)) - + if asic_info['xgmi_physical_id'] == 0xFFFF: # uint 16 max + asic_info['xgmi_physical_id'] = "N/A" static_dict['asic'] = asic_info except amdsmi_exception.AmdSmiLibraryException as e: static_dict['asic'] = "N/A" @@ -436,11 +437,25 @@ class AMDSMICommands(): if self.helpers.is_hypervisor() or self.helpers.is_baremetal(): if args.ras: + ras_dict = {"eeprom_version": "N/A", + "parity_schema" : "N/A", + "single_bit_schema" : "N/A", + "double_bit_schema" : "N/A", + "poison_schema" : "N/A", + "ecc_block_state": "N/A"} + try: - static_dict['ras'] = amdsmi_interface.amdsmi_get_gpu_ras_block_features_enabled(args.gpu) + ras_info = amdsmi_interface.amdsmi_get_gpu_ras_feature_info(args.gpu) + ras_dict.update(ras_info) + except amdsmi_exception.AmdSmiLibraryException as e: + logging.debug("Failed to get ras info for gpu %s | %s", gpu_id, e.get_error_info()) + + try: + ras_dict["ecc_block_state"] = amdsmi_interface.amdsmi_get_gpu_ras_block_features_enabled(args.gpu) except amdsmi_exception.AmdSmiLibraryException as e: - static_dict['ras'] = "N/A" logging.debug("Failed to get ras block features for gpu %s | %s", gpu_id, e.get_error_info()) + + static_dict["ras"] = ras_dict if self.helpers.is_linux() and self.helpers.is_baremetal(): if args.numa: try: @@ -466,11 +481,11 @@ class AMDSMICommands(): if self.logger.is_csv_format(): # expand if ras blocks are populated if self.helpers.is_linux() and self.helpers.is_baremetal() and args.ras: - if isinstance(static_dict['ras'], list): - ras_dicts = static_dict.pop('ras') + if isinstance(static_dict['ras']['ecc_block_state'], list): + ecc_block_dicts = static_dict['ras'].pop('ecc_block_state') multiple_devices_csv_override = True - for ras_dict in ras_dicts: - for key, value in ras_dict.items(): + for ecc_block_dict in ecc_block_dicts: + for key, value in ecc_block_dict.items(): self.logger.store_output(args.gpu, key, value) self.logger.store_output(args.gpu, 'values', static_dict) self.logger.store_multiple_device_output() @@ -1003,19 +1018,22 @@ class AMDSMICommands(): values_dict['ecc'] = ecc_count if args.ecc_block: ecc_dict = {} + uncountable_blocks = ["ATHUB", "DF", "SMN", "SEM", "MP0", "MP1", "FUSE"] try: ras_states = amdsmi_interface.amdsmi_get_gpu_ras_block_features_enabled(args.gpu) for state in ras_states: if state['status'] == amdsmi_interface.AmdSmiRasErrState.ENABLED.name: gpu_block = amdsmi_interface.AmdSmiGpuBlock[state['block']] - try: - ecc_count = amdsmi_interface.amdsmi_get_gpu_ecc_count(args.gpu, gpu_block) - ecc_dict[state['block']] = {'correctable' : ecc_count['correctable_count'], - 'uncorrectable': ecc_count['uncorrectable_count']} - except amdsmi_exception.AmdSmiLibraryException as e: - ecc_dict[state['block']] = {'correctable' : "N/A", - 'uncorrectable': "N/A"} - logging.debug("Failed to get ecc count for gpu %s at block %s | %s", gpu_id, gpu_block, e.get_error_info()) + # if the blocks are uncountable do not add them at all. + if gpu_block.name not in uncountable_blocks: + try: + ecc_count = amdsmi_interface.amdsmi_get_gpu_ecc_count(args.gpu, gpu_block) + ecc_dict[state['block']] = {'correctable' : ecc_count['correctable_count'], + 'uncorrectable': ecc_count['uncorrectable_count']} + except amdsmi_exception.AmdSmiLibraryException as e: + ecc_dict[state['block']] = {'correctable' : "N/A", + 'uncorrectable': "N/A"} + logging.debug("Failed to get ecc count for gpu %s at block %s | %s", gpu_id, gpu_block, e.get_error_info()) values_dict['ecc_block'] = ecc_dict except amdsmi_exception.AmdSmiLibraryException as e: diff --git a/amdsmi_cli/amdsmi_parser.py b/amdsmi_cli/amdsmi_parser.py index ab54554dae..85fda61d6f 100644 --- a/amdsmi_cli/amdsmi_parser.py +++ b/amdsmi_cli/amdsmi_parser.py @@ -413,7 +413,7 @@ class AMDSMIParser(argparse.ArgumentParser): power_help = "Current power usage" clock_help = "Average, max, and current clock frequencies" temperature_help = "Current temperatures" - ecc_help = "Number of ECC errors" + ecc_help = "Total number of ECC errors" ecc_block_help = "Number of ECC errors per block" pcie_help = "Current PCIe speed, width, and replay count" diff --git a/include/amd_smi/amdsmi.h b/include/amd_smi/amdsmi.h index 5b85077f4c..5546bc46c7 100644 --- a/include/amd_smi/amdsmi.h +++ b/include/amd_smi/amdsmi.h @@ -418,7 +418,7 @@ typedef struct { typedef struct { uint32_t num_cache_types; - struct { + struct cache_ { uint32_t cache_size_kb; /* In KB */ uint32_t cache_level; uint32_t reserved[3]; @@ -897,7 +897,7 @@ typedef enum { AMDSMI_IOLINK_TYPE_XGMI = 2, //!< XGMI AMDSMI_IOLINK_TYPE_NUMIOLINKTYPES, //!< Number of IO Link types AMDSMI_IOLINK_TYPE_SIZE = 0xFFFFFFFF //!< Max of IO Link types -} AMDSMI_IO_LINK_TYPE; +} amdsmi_io_link_type_t; /** * @brief The utilization counter type @@ -908,13 +908,22 @@ typedef enum { AMDSMI_COARSE_GRAIN_GFX_ACTIVITY = AMDSMI_UTILIZATION_COUNTER_FIRST, AMDSMI_COARSE_GRAIN_MEM_ACTIVITY, //!< Memory Activity AMDSMI_UTILIZATION_COUNTER_LAST = AMDSMI_COARSE_GRAIN_MEM_ACTIVITY -} AMDSMI_UTILIZATION_COUNTER_TYPE; +} amdsmi_utilization_counter_type_t; + +/** + * @brief Power types + */ +typedef enum { + AMDSMI_AVERAGE_POWER = 0, //!< Average Power + AMDSMI_CURRENT_POWER, //!< Current / Instant Power + AMDSMI_INVALID_POWER = 0xFFFFFFFF //!< Invalid / Undetected Power +} amdsmi_power_type_t; /** * @brief The utilization counter data */ typedef struct { - AMDSMI_UTILIZATION_COUNTER_TYPE type; //!< Utilization counter type + amdsmi_utilization_counter_type_t type; //!< Utilization counter type uint64_t value; //!< Utilization counter value } amdsmi_utilization_counter_t; @@ -3303,7 +3312,7 @@ amdsmi_status_t amdsmi_status_t amdsmi_topo_get_link_type(amdsmi_processor_handle processor_handle_src, amdsmi_processor_handle processor_handle_dst, - uint64_t *hops, AMDSMI_IO_LINK_TYPE *type); + uint64_t *hops, amdsmi_io_link_type_t *type); /** * @brief Return P2P availability status between 2 GPUs diff --git a/py-interface/README.md b/py-interface/README.md index 72f9f843fd..8147ba1b6d 100644 --- a/py-interface/README.md +++ b/py-interface/README.md @@ -351,6 +351,7 @@ Field | Content `device_id` | device id `rev_id` | revision id `asic_serial` | asic serial +`xgmi_physical_id` | xgmi physical id Exceptions that can be thrown by `amdsmi_get_gpu_asic_info` function: @@ -370,9 +371,11 @@ try: asic_info = amdsmi_get_gpu_asic_info(device) print(asic_info['market_name']) print(hex(asic_info['vendor_id'])) + print(asic_info['vendor_name']) print(hex(asic_info['device_id'])) print(hex(asic_info['rev_id'])) print(asic_info['asic_serial']) + print(asic_info['xgmi_physical_id']) except AmdSmiException as e: print(e) ``` @@ -939,6 +942,46 @@ except AmdSmiException as e: print(e) ``` +### amdsmi_get_gpu_ras_feature_info + +Description: Returns RAS version and schema information +It is not supported on virtual machine guest + +Input parameters: + +* `processor_handle` device which to query + +Output: List containing dictionaries with fields + +Field | Description +---|--- +`eeprom_version` | eeprom version +`parity_schema` | parity schema +`single_bit_schema` | single bit schema +`double_bit_schema` | double bit schema +`poison_schema` | poison schema + +Exceptions that can be thrown by `amdsmi_get_gpu_ras_feature_info` function: + +* `AmdSmiLibraryException` +* `AmdSmiRetryException` +* `AmdSmiParameterException` + +Example: + +```python +try: + devices = amdsmi_get_processor_handles() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + ras_info = amdsmi_get_gpu_ras_feature_info(device) + print(ras_info) +except AmdSmiException as e: + print(e) +``` + ### amdsmi_get_gpu_ras_block_features_enabled Description: Returns status of each RAS block for the given GPU. diff --git a/py-interface/__init__.py b/py-interface/__init__.py index 6be5f36436..22a13f7c95 100644 --- a/py-interface/__init__.py +++ b/py-interface/__init__.py @@ -66,6 +66,7 @@ from .amdsmi_interface import amdsmi_get_gpu_total_ecc_count from .amdsmi_interface import amdsmi_get_gpu_board_info # # Ras Information +from .amdsmi_interface import amdsmi_get_gpu_ras_feature_info from .amdsmi_interface import amdsmi_get_gpu_ras_block_features_enabled # # Unsupported Functions In Virtual Environment diff --git a/py-interface/amdsmi_interface.py b/py-interface/amdsmi_interface.py index 9c439e3104..98907c2708 100644 --- a/py-interface/amdsmi_interface.py +++ b/py-interface/amdsmi_interface.py @@ -644,6 +644,7 @@ def amdsmi_get_gpu_asic_info( "device_id": asic_info.device_id, "rev_id": asic_info.rev_id, "asic_serial": asic_info.asic_serial.decode("utf-8"), + "xgmi_physical_id": asic_info.xgmi_physical_id } @@ -831,9 +832,26 @@ def amdsmi_get_gpu_board_info( } -def amdsmi_get_gpu_ras_block_features_enabled( +def amdsmi_get_gpu_ras_feature_info( processor_handle: amdsmi_wrapper.amdsmi_processor_handle, ) -> Dict[str, Any]: + if not isinstance(processor_handle, amdsmi_wrapper.amdsmi_processor_handle): + raise AmdSmiParameterException( + processor_handle, amdsmi_wrapper.amdsmi_processor_handle + ) + # Dummy data waiting on population + ras_info = {"eeprom_version": "N/A", + "parity_schema" : "N/A", + "single_bit_schema" : "N/A", + "double_bit_schema" : "N/A", + "poison_schema" : "N/A"} + + return ras_info + + +def amdsmi_get_gpu_ras_block_features_enabled( + processor_handle: amdsmi_wrapper.amdsmi_processor_handle, +) -> List[Dict[str, Any]]: if not isinstance(processor_handle, amdsmi_wrapper.amdsmi_processor_handle): raise AmdSmiParameterException( processor_handle, amdsmi_wrapper.amdsmi_processor_handle diff --git a/py-interface/amdsmi_wrapper.py b/py-interface/amdsmi_wrapper.py index 2d2e8bde27..1e48cf7636 100644 --- a/py-interface/amdsmi_wrapper.py +++ b/py-interface/amdsmi_wrapper.py @@ -718,6 +718,27 @@ struct_amdsmi_vbios_info_t._fields_ = [ ] amdsmi_vbios_info_t = struct_amdsmi_vbios_info_t +class struct_amdsmi_gpu_cache_info_t(Structure): + pass + +class struct_cache_(Structure): + pass + +struct_cache_._pack_ = 1 # source:False +struct_cache_._fields_ = [ + ('cache_size_kb', ctypes.c_uint32), + ('cache_level', ctypes.c_uint32), + ('reserved', ctypes.c_uint32 * 3), +] + +struct_amdsmi_gpu_cache_info_t._pack_ = 1 # source:False +struct_amdsmi_gpu_cache_info_t._fields_ = [ + ('num_cache_types', ctypes.c_uint32), + ('cache', struct_cache_ * 10), + ('reserved', ctypes.c_uint32 * 15), +] + +amdsmi_gpu_cache_info_t = struct_amdsmi_gpu_cache_info_t class struct_amdsmi_fw_info_t(Structure): pass @@ -840,16 +861,6 @@ amdsmi_process_handle_t = ctypes.c_uint32 class struct_amdsmi_proc_info_t(Structure): pass -class struct_engine_usage_(Structure): - pass - -struct_engine_usage_._pack_ = 1 # source:False -struct_engine_usage_._fields_ = [ - ('gfx', ctypes.c_uint64), - ('enc', ctypes.c_uint64), - ('reserved', ctypes.c_uint32 * 12), -] - class struct_memory_usage_(Structure): pass @@ -861,6 +872,16 @@ struct_memory_usage_._fields_ = [ ('reserved', ctypes.c_uint32 * 10), ] +class struct_engine_usage_(Structure): + pass + +struct_engine_usage_._pack_ = 1 # source:False +struct_engine_usage_._fields_ = [ + ('gfx', ctypes.c_uint64), + ('enc', ctypes.c_uint64), + ('reserved', ctypes.c_uint32 * 12), +] + struct_amdsmi_proc_info_t._pack_ = 1 # source:False struct_amdsmi_proc_info_t._fields_ = [ ('name', ctypes.c_char * 32), @@ -1221,8 +1242,8 @@ AMDSMI_MEM_PAGE_STATUS_PENDING = 1 AMDSMI_MEM_PAGE_STATUS_UNRESERVABLE = 2 amdsmi_memory_page_status_t = ctypes.c_uint32 # enum -# values for enumeration 'AMDSMI_IO_LINK_TYPE' -AMDSMI_IO_LINK_TYPE__enumvalues = { +# values for enumeration 'amdsmi_io_link_type_t' +amdsmi_io_link_type_t__enumvalues = { 0: 'AMDSMI_IOLINK_TYPE_UNDEFINED', 1: 'AMDSMI_IOLINK_TYPE_PCIEXPRESS', 2: 'AMDSMI_IOLINK_TYPE_XGMI', @@ -1234,10 +1255,10 @@ AMDSMI_IOLINK_TYPE_PCIEXPRESS = 1 AMDSMI_IOLINK_TYPE_XGMI = 2 AMDSMI_IOLINK_TYPE_NUMIOLINKTYPES = 3 AMDSMI_IOLINK_TYPE_SIZE = 4294967295 -AMDSMI_IO_LINK_TYPE = ctypes.c_uint32 # enum +amdsmi_io_link_type_t = ctypes.c_uint32 # enum -# values for enumeration 'AMDSMI_UTILIZATION_COUNTER_TYPE' -AMDSMI_UTILIZATION_COUNTER_TYPE__enumvalues = { +# values for enumeration 'amdsmi_utilization_counter_type_t' +amdsmi_utilization_counter_type_t__enumvalues = { 0: 'AMDSMI_UTILIZATION_COUNTER_FIRST', 0: 'AMDSMI_COARSE_GRAIN_GFX_ACTIVITY', 1: 'AMDSMI_COARSE_GRAIN_MEM_ACTIVITY', @@ -1247,13 +1268,24 @@ AMDSMI_UTILIZATION_COUNTER_FIRST = 0 AMDSMI_COARSE_GRAIN_GFX_ACTIVITY = 0 AMDSMI_COARSE_GRAIN_MEM_ACTIVITY = 1 AMDSMI_UTILIZATION_COUNTER_LAST = 1 -AMDSMI_UTILIZATION_COUNTER_TYPE = ctypes.c_uint32 # enum +amdsmi_utilization_counter_type_t = ctypes.c_uint32 # enum + +# values for enumeration 'amdsmi_power_type_t' +amdsmi_power_type_t__enumvalues = { + 0: 'AMDSMI_AVERAGE_POWER', + 1: 'AMDSMI_CURRENT_POWER', + 4294967295: 'AMDSMI_INVALID_POWER', +} +AMDSMI_AVERAGE_POWER = 0 +AMDSMI_CURRENT_POWER = 1 +AMDSMI_INVALID_POWER = 4294967295 +amdsmi_power_type_t = ctypes.c_uint32 # enum class struct_amdsmi_utilization_counter_t(Structure): pass struct_amdsmi_utilization_counter_t._pack_ = 1 # source:False struct_amdsmi_utilization_counter_t._fields_ = [ - ('type', AMDSMI_UTILIZATION_COUNTER_TYPE), + ('type', amdsmi_utilization_counter_type_t), ('PADDING_0', ctypes.c_ubyte * 4), ('value', ctypes.c_uint64), ] @@ -1563,6 +1595,9 @@ amdsmi_get_gpu_fan_speed_max.argtypes = [amdsmi_processor_handle, uint32_t, ctyp amdsmi_get_temp_metric = _libraries['libamd_smi.so'].amdsmi_get_temp_metric amdsmi_get_temp_metric.restype = amdsmi_status_t amdsmi_get_temp_metric.argtypes = [amdsmi_processor_handle, amdsmi_temperature_type_t, amdsmi_temperature_metric_t, ctypes.POINTER(ctypes.c_int64)] +amdsmi_get_gpu_cache_info = _libraries['libamd_smi.so'].amdsmi_get_gpu_cache_info +amdsmi_get_gpu_cache_info.restype = amdsmi_status_t +amdsmi_get_gpu_cache_info.argtypes = [amdsmi_processor_handle, ctypes.POINTER(struct_amdsmi_gpu_cache_info_t)] amdsmi_get_gpu_volt_metric = _libraries['libamd_smi.so'].amdsmi_get_gpu_volt_metric amdsmi_get_gpu_volt_metric.restype = amdsmi_status_t amdsmi_get_gpu_volt_metric.argtypes = [amdsmi_processor_handle, amdsmi_voltage_type_t, amdsmi_voltage_metric_t, ctypes.POINTER(ctypes.c_int64)] @@ -1685,7 +1720,7 @@ amdsmi_get_minmax_bandwidth_between_processors.restype = amdsmi_status_t amdsmi_get_minmax_bandwidth_between_processors.argtypes = [amdsmi_processor_handle, amdsmi_processor_handle, ctypes.POINTER(ctypes.c_uint64), ctypes.POINTER(ctypes.c_uint64)] amdsmi_topo_get_link_type = _libraries['libamd_smi.so'].amdsmi_topo_get_link_type amdsmi_topo_get_link_type.restype = amdsmi_status_t -amdsmi_topo_get_link_type.argtypes = [amdsmi_processor_handle, amdsmi_processor_handle, ctypes.POINTER(ctypes.c_uint64), ctypes.POINTER(AMDSMI_IO_LINK_TYPE)] +amdsmi_topo_get_link_type.argtypes = [amdsmi_processor_handle, amdsmi_processor_handle, ctypes.POINTER(ctypes.c_uint64), ctypes.POINTER(amdsmi_io_link_type_t)] amdsmi_is_P2P_accessible = _libraries['libamd_smi.so'].amdsmi_is_P2P_accessible amdsmi_is_P2P_accessible.restype = amdsmi_status_t amdsmi_is_P2P_accessible.argtypes = [amdsmi_processor_handle, amdsmi_processor_handle, ctypes.POINTER(ctypes.c_bool)] @@ -1756,10 +1791,11 @@ amdsmi_get_gpu_total_ecc_count = _libraries['libamd_smi.so'].amdsmi_get_gpu_tota amdsmi_get_gpu_total_ecc_count.restype = amdsmi_status_t amdsmi_get_gpu_total_ecc_count.argtypes = [amdsmi_processor_handle, ctypes.POINTER(struct_amdsmi_error_count_t)] __all__ = \ - ['AMDSMI_ARG_PTR_NULL', 'AMDSMI_CNTR_CMD_START', - 'AMDSMI_CNTR_CMD_STOP', 'AMDSMI_COARSE_GRAIN_GFX_ACTIVITY', - 'AMDSMI_COARSE_GRAIN_MEM_ACTIVITY', 'AMDSMI_DEV_PERF_LEVEL_AUTO', - 'AMDSMI_DEV_PERF_LEVEL_DETERMINISM', + ['AMDSMI_ARG_PTR_NULL', 'AMDSMI_AVERAGE_POWER', + 'AMDSMI_CNTR_CMD_START', 'AMDSMI_CNTR_CMD_STOP', + 'AMDSMI_COARSE_GRAIN_GFX_ACTIVITY', + 'AMDSMI_COARSE_GRAIN_MEM_ACTIVITY', 'AMDSMI_CURRENT_POWER', + 'AMDSMI_DEV_PERF_LEVEL_AUTO', 'AMDSMI_DEV_PERF_LEVEL_DETERMINISM', 'AMDSMI_DEV_PERF_LEVEL_FIRST', 'AMDSMI_DEV_PERF_LEVEL_HIGH', 'AMDSMI_DEV_PERF_LEVEL_LAST', 'AMDSMI_DEV_PERF_LEVEL_LOW', 'AMDSMI_DEV_PERF_LEVEL_MANUAL', @@ -1797,10 +1833,10 @@ __all__ = \ 'AMDSMI_HSMP_TIMEOUT', 'AMDSMI_INIT_ALL_PROCESSORS', 'AMDSMI_INIT_AMD_CPUS', 'AMDSMI_INIT_AMD_GPUS', 'AMDSMI_INIT_NON_AMD_CPUS', 'AMDSMI_INIT_NON_AMD_GPUS', - 'AMDSMI_IOLINK_TYPE_NUMIOLINKTYPES', + 'AMDSMI_INVALID_POWER', 'AMDSMI_IOLINK_TYPE_NUMIOLINKTYPES', 'AMDSMI_IOLINK_TYPE_PCIEXPRESS', 'AMDSMI_IOLINK_TYPE_SIZE', 'AMDSMI_IOLINK_TYPE_UNDEFINED', 'AMDSMI_IOLINK_TYPE_XGMI', - 'AMDSMI_IO_LINK_TYPE', 'AMDSMI_MEM_PAGE_STATUS_PENDING', + 'AMDSMI_MEM_PAGE_STATUS_PENDING', 'AMDSMI_MEM_PAGE_STATUS_RESERVED', 'AMDSMI_MEM_PAGE_STATUS_UNRESERVABLE', 'AMDSMI_MEM_TYPE_FIRST', 'AMDSMI_MEM_TYPE_GTT', 'AMDSMI_MEM_TYPE_LAST', @@ -1848,8 +1884,7 @@ __all__ = \ 'AMDSMI_TEMP_LOWEST', 'AMDSMI_TEMP_MAX', 'AMDSMI_TEMP_MAX_HYST', 'AMDSMI_TEMP_MIN', 'AMDSMI_TEMP_MIN_HYST', 'AMDSMI_TEMP_OFFSET', 'AMDSMI_UTILIZATION_COUNTER_FIRST', - 'AMDSMI_UTILIZATION_COUNTER_LAST', - 'AMDSMI_UTILIZATION_COUNTER_TYPE', 'AMDSMI_VOLT_AVERAGE', + 'AMDSMI_UTILIZATION_COUNTER_LAST', 'AMDSMI_VOLT_AVERAGE', 'AMDSMI_VOLT_CURRENT', 'AMDSMI_VOLT_FIRST', 'AMDSMI_VOLT_HIGHEST', 'AMDSMI_VOLT_LAST', 'AMDSMI_VOLT_LOWEST', 'AMDSMI_VOLT_MAX', 'AMDSMI_VOLT_MAX_CRIT', 'AMDSMI_VOLT_MIN', 'AMDSMI_VOLT_MIN_CRIT', @@ -1926,7 +1961,7 @@ __all__ = \ 'amdsmi_get_fw_info', 'amdsmi_get_gpu_activity', 'amdsmi_get_gpu_asic_info', 'amdsmi_get_gpu_available_counters', 'amdsmi_get_gpu_bad_page_info', 'amdsmi_get_gpu_bdf_id', - 'amdsmi_get_gpu_board_info', + 'amdsmi_get_gpu_board_info', 'amdsmi_get_gpu_cache_info', 'amdsmi_get_gpu_compute_process_gpus', 'amdsmi_get_gpu_compute_process_info', 'amdsmi_get_gpu_compute_process_info_by_pid', @@ -1961,12 +1996,13 @@ __all__ = \ 'amdsmi_get_socket_handles', 'amdsmi_get_socket_info', 'amdsmi_get_temp_metric', 'amdsmi_get_utilization_count', 'amdsmi_get_xgmi_info', 'amdsmi_gpu_block_t', - 'amdsmi_gpu_control_counter', + 'amdsmi_gpu_cache_info_t', 'amdsmi_gpu_control_counter', 'amdsmi_gpu_counter_group_supported', 'amdsmi_gpu_create_counter', 'amdsmi_gpu_destroy_counter', 'amdsmi_gpu_metrics_t', 'amdsmi_gpu_read_counter', 'amdsmi_gpu_xgmi_error_status', 'amdsmi_init', 'amdsmi_init_flags_t', - 'amdsmi_init_gpu_event_notification', 'amdsmi_is_P2P_accessible', + 'amdsmi_init_gpu_event_notification', 'amdsmi_io_link_type_t', + 'amdsmi_is_P2P_accessible', 'amdsmi_is_gpu_power_management_enabled', 'amdsmi_memory_page_status_t', 'amdsmi_memory_type_t', 'amdsmi_mm_ip_t', 'amdsmi_od_vddc_point_t', @@ -1974,10 +2010,10 @@ __all__ = \ 'amdsmi_pcie_bandwidth_t', 'amdsmi_pcie_info_t', 'amdsmi_pcie_slot_type_t', 'amdsmi_power_cap_info_t', '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_reset_gpu', + 'amdsmi_power_profile_status_t', 'amdsmi_power_type_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_reset_gpu', 'amdsmi_reset_gpu_fan', 'amdsmi_reset_gpu_xgmi_error', 'amdsmi_retired_page_record_t', 'amdsmi_set_clk_freq', 'amdsmi_set_gpu_clk_range', @@ -1993,7 +2029,8 @@ __all__ = \ 'amdsmi_temperature_metric_t', 'amdsmi_temperature_type_t', 'amdsmi_topo_get_link_type', 'amdsmi_topo_get_link_weight', 'amdsmi_topo_get_numa_node_number', - 'amdsmi_utilization_counter_t', 'amdsmi_vbios_info_t', + 'amdsmi_utilization_counter_t', + 'amdsmi_utilization_counter_type_t', 'amdsmi_vbios_info_t', 'amdsmi_version_t', 'amdsmi_voltage_metric_t', 'amdsmi_voltage_type_t', 'amdsmi_vram_info_t', 'amdsmi_vram_type_t', 'amdsmi_vram_usage_t', @@ -2006,8 +2043,8 @@ __all__ = \ 'struct_amdsmi_evt_notification_data_t', 'struct_amdsmi_freq_volt_region_t', 'struct_amdsmi_frequencies_t', 'struct_amdsmi_frequency_range_t', 'struct_amdsmi_fw_info_t', - 'struct_amdsmi_gpu_metrics_t', 'struct_amdsmi_od_vddc_point_t', - 'struct_amdsmi_od_volt_curve_t', + 'struct_amdsmi_gpu_cache_info_t', 'struct_amdsmi_gpu_metrics_t', + 'struct_amdsmi_od_vddc_point_t', 'struct_amdsmi_od_volt_curve_t', 'struct_amdsmi_od_volt_freq_data_t', 'struct_amdsmi_pcie_bandwidth_t', 'struct_amdsmi_pcie_info_t', 'struct_amdsmi_power_cap_info_t', 'struct_amdsmi_power_info_t', @@ -2017,6 +2054,7 @@ __all__ = \ 'struct_amdsmi_utilization_counter_t', 'struct_amdsmi_vbios_info_t', 'struct_amdsmi_version_t', 'struct_amdsmi_vram_info_t', 'struct_amdsmi_vram_usage_t', - 'struct_amdsmi_xgmi_info_t', 'struct_engine_usage_', - 'struct_fields_', 'struct_fw_info_list_', 'struct_memory_usage_', - 'uint32_t', 'uint64_t', 'union_amdsmi_bdf_t'] + 'struct_amdsmi_xgmi_info_t', 'struct_cache_', + 'struct_engine_usage_', 'struct_fields_', 'struct_fw_info_list_', + 'struct_memory_usage_', 'uint32_t', 'uint64_t', + 'union_amdsmi_bdf_t'] diff --git a/rocm_smi/example/rocm_smi_example.cc b/rocm_smi/example/rocm_smi_example.cc index 8db5c7c810..7c061ddbf0 100755 --- a/rocm_smi/example/rocm_smi_example.cc +++ b/rocm_smi/example/rocm_smi_example.cc @@ -53,14 +53,13 @@ #include #include "rocm_smi/rocm_smi.h" +#include "rocm_smi/rocm_smi_utils.h" #define PRINT_RSMI_ERR(RET) { \ if (RET != RSMI_STATUS_SUCCESS) { \ - const char *err_str; \ std::cout << "[ERROR] RSMI call returned " << (RET) \ << " at line " << __LINE__ << std::endl; \ - rsmi_status_string((RET), &err_str); \ - std::cout << err_str << std::endl; \ + std::cout << amd::smi::getRSMIStatusString(RET) << std::endl; \ } \ } @@ -100,10 +99,10 @@ } \ } else if ((RET) == RSMI_STATUS_NOT_SUPPORTED) { \ std::cout << "Not Supported." \ - << std::endl; \ + << "\n"; \ } else if ((RET) == RSMI_STATUS_NOT_YET_IMPLEMENTED) { \ std::cout << "Not Yet Implemented." \ - << std::endl; \ + << "\n"; \ } else { \ CHK_RSMI_RET(RET) \ } \ @@ -112,7 +111,7 @@ #define CHK_RSMI_NOT_SUPPORTED_RET(RET) { \ if ((RET) == RSMI_STATUS_NOT_SUPPORTED) { \ std::cout << "Not Supported." \ - << std::endl; \ + << "\n"; \ } else { \ CHK_RSMI_RET(RET) \ } \ @@ -121,10 +120,10 @@ #define CHK_RSMI_NOT_SUPPORTED_OR_UNEXPECTED_DATA_RET(RET) { \ if ((RET) == RSMI_STATUS_NOT_SUPPORTED) { \ std::cout << "Not Supported." \ - << std::endl; \ + << "\n"; \ } else if ((RET) == RSMI_STATUS_UNEXPECTED_DATA) { \ std::cout << "[ERROR] RSMI_STATUS_UNEXPECTED_DATA retrieved." \ - << std::endl; \ + << "\n"; \ } else { \ CHK_RSMI_RET(RET) \ } \ @@ -133,10 +132,10 @@ #define CHK_RSMI_NOT_SUPPORTED_OR_SETTING_UNAVAILABLE_RET(RET) {\ if ((RET) == RSMI_STATUS_NOT_SUPPORTED) { \ std::cout << "Not Supported."\ - << std::endl; \ + << "\n"; \ } else if ((RET) == RSMI_STATUS_SETTING_UNAVAILABLE) { \ std::cout << "[WARN] RSMI_STATUS_SETTING_UNAVAILABLE retrieved." \ - << std::endl; \ + << "\n"; \ } else { \ CHK_RSMI_RET(RET) \ } \ @@ -145,27 +144,27 @@ #define CHK_NOT_SUPPORTED_OR_UNEXPECTED_DATA_OR_INSUFFICIENT_SIZE_RET(RET) { \ if ((RET) == RSMI_STATUS_NOT_SUPPORTED) { \ std::cout << "Not Supported." \ - << std::endl; \ + << "\n"; \ } else if ((RET) == RSMI_STATUS_UNEXPECTED_DATA) { \ std::cout << "[WARN] RSMI_STATUS_UNEXPECTED_DATA retrieved." \ - << std::endl; \ + << "\n"; \ } else if ((RET) == RSMI_STATUS_INSUFFICIENT_SIZE) { \ std::cout << "[WARN] RSMI_STATUS_INSUFFICIENT_SIZE retrieved." \ - << std::endl; \ + << "\n"; \ } else { \ CHK_RSMI_RET(RET) \ } \ } static void print_test_header(const char *str, uint32_t dv_ind) { - std::cout << "********************************" << std::endl; - std::cout << "*** " << str << std::endl; - std::cout << "********************************" << std::endl; - std::cout << "Device index: " << dv_ind << std::endl; + std::cout << "********************************" << "\n"; + std::cout << "*** " << str << "\n"; + std::cout << "********************************" << "\n"; + std::cout << "Device index: " << dv_ind << "\n"; } static void print_mini_header(const char *str) { - std::cout << "\n>> " << str << " <<" << std::endl; + std::cout << "\n>> " << str << " <<" << "\n"; } static const char * @@ -189,7 +188,7 @@ power_profile_string(rsmi_power_profile_preset_masks_t profile) { } static const std::string -compute_partition_string(rsmi_compute_partition_type partition) { +compute_partition_string(rsmi_compute_partition_type_t partition) { switch (partition) { case RSMI_COMPUTE_PARTITION_CPX: return "CPX"; @@ -216,7 +215,7 @@ mapStringToRSMIComputePartitionTypes { }; static const std::string -nps_mode_string(rsmi_nps_mode_type_t partition) { +memory_partition_string(rsmi_memory_partition_type_t partition) { switch (partition) { case RSMI_MEMORY_PARTITION_NPS1: return "NPS1"; @@ -231,8 +230,8 @@ nps_mode_string(rsmi_nps_mode_type_t partition) { } } -static std::map -mapStringToRSMINpsModeTypes { +static std::map +mapStringToRSMIMemoryPartitionTypes { {"NPS1", RSMI_MEMORY_PARTITION_NPS1}, {"NPS2", RSMI_MEMORY_PARTITION_NPS2}, {"NPS4", RSMI_MEMORY_PARTITION_NPS4}, @@ -274,7 +273,7 @@ static bool isFileWritable(rsmi_status_t response) { bool fileWritable = true; if (isUserRunningAsSudo() && (response == RSMI_STATUS_PERMISSION)) { std::cout << "[WARN] User is running with sudo " - << "permissions, file is not writable." << std::endl; + << "permissions, file is not writable." << "\n"; fileWritable = false; } else { CHK_AND_PRINT_RSMI_ERR_RET(response) @@ -292,23 +291,23 @@ static rsmi_status_t test_power_profile(uint32_t dv_ind) { ret = rsmi_dev_power_profile_presets_get(dv_ind, 0, &status); CHK_RSMI_NOT_SUPPORTED_RET(ret) if (ret != RSMI_STATUS_SUCCESS) { - std::cout << "***Skipping Power Profile test." << std::endl; + std::cout << "***Skipping Power Profile test." << "\n"; return RSMI_STATUS_SUCCESS; } CHK_RSMI_RET(ret) - std::cout << "The available power profiles are:" << std::endl; + std::cout << "The available power profiles are:" << "\n"; uint64_t tmp = 1; while (tmp <= RSMI_PWR_PROF_PRST_LAST) { if ((tmp & status.available_profiles) == tmp) { std::cout << "\t" << - power_profile_string((rsmi_power_profile_preset_masks_t)tmp) << std::endl; + power_profile_string((rsmi_power_profile_preset_masks_t)tmp) << "\n"; } tmp = tmp << 1; } std::cout << "The current power profile is: " << - power_profile_string(status.current) << std::endl; + power_profile_string(status.current) << "\n"; // Try setting the profile to a different power profile rsmi_bit_field_t diff_profiles; @@ -326,40 +325,40 @@ static rsmi_status_t test_power_profile(uint32_t dv_ind) { } else if (diff_profiles & RSMI_PWR_PROF_PRST_3D_FULL_SCR_MASK) { new_prof = RSMI_PWR_PROF_PRST_3D_FULL_SCR_MASK; } else { - std::cout << "No other non-custom power profiles to set to" << std::endl; + std::cout << "No other non-custom power profiles to set to" << "\n"; return ret; } std::cout << "Setting power profile to " << power_profile_string(new_prof) - << "..." << std::endl; + << "..." << "\n"; ret = rsmi_dev_power_profile_set(dv_ind, 0, new_prof); CHK_RSMI_RET(ret) - std::cout << "Done." << std::endl; + std::cout << "Done." << "\n"; rsmi_dev_perf_level_t pfl; ret = rsmi_dev_perf_level_get(dv_ind, &pfl); CHK_RSMI_RET(ret) std::cout << "Performance Level is now " << - perf_level_string(pfl) << std::endl; + perf_level_string(pfl) << "\n"; ret = rsmi_dev_power_profile_presets_get(dv_ind, 0, &status); CHK_RSMI_RET(ret) std::cout << "The current power profile is: " << - power_profile_string(status.current) << std::endl; - std::cout << "Resetting perf level to auto..." << std::endl; + power_profile_string(status.current) << "\n"; + std::cout << "Resetting perf level to auto..." << "\n"; ret = rsmi_dev_perf_level_set_v1(dv_ind, RSMI_DEV_PERF_LEVEL_AUTO); CHK_RSMI_RET(ret) - std::cout << "Done." << std::endl; + std::cout << "Done." << "\n"; ret = rsmi_dev_perf_level_get(dv_ind, &pfl); CHK_RSMI_RET(ret) std::cout << "Performance Level is now " << - perf_level_string(pfl) << std::endl; + perf_level_string(pfl) << "\n"; ret = rsmi_dev_power_profile_presets_get(dv_ind, 0, &status); CHK_RSMI_RET(ret) std::cout << "The current power profile is: " << - power_profile_string(status.current) << std::endl; + power_profile_string(status.current) << "\n"; return ret; } @@ -376,12 +375,12 @@ static rsmi_status_t test_power_cap(uint32_t dv_ind) { ret = rsmi_dev_power_cap_get(dv_ind, 0, &orig); CHK_RSMI_RET(ret) - std::cout << "Original Power Cap: " << orig << " uW" << std::endl; + std::cout << "Original Power Cap: " << orig << " uW" << "\n"; std::cout << "Power Cap Range: " << max << " uW to " << min << - " uW" << std::endl; + " uW" << "\n"; new_cap = (max + min)/2; - std::cout << "Setting new cap to " << new_cap << "..." << std::endl; + std::cout << "Setting new cap to " << new_cap << "..." << "\n"; ret = rsmi_dev_power_cap_set(dv_ind, 0, new_cap); CHK_RSMI_RET(ret) @@ -389,15 +388,15 @@ static rsmi_status_t test_power_cap(uint32_t dv_ind) { ret = rsmi_dev_power_cap_get(dv_ind, 0, &new_cap); CHK_RSMI_RET(ret) - std::cout << "New Power Cap: " << new_cap << " uW" << std::endl; - std::cout << "Resetting cap to " << orig << "..." << std::endl; + std::cout << "New Power Cap: " << new_cap << " uW" << "\n"; + std::cout << "Resetting cap to " << orig << "..." << "\n"; ret = rsmi_dev_power_cap_set(dv_ind, 0, orig); CHK_RSMI_RET(ret) ret = rsmi_dev_power_cap_get(dv_ind, 0, &new_cap); CHK_RSMI_RET(ret) - std::cout << "Current Power Cap: " << new_cap << " uW" << std::endl; + std::cout << "Current Power Cap: " << new_cap << " uW" << "\n"; return ret; } @@ -407,21 +406,21 @@ static rsmi_status_t test_set_overdrive(uint32_t dv_ind) { uint32_t val; print_test_header("Overdrive Control", dv_ind); - std::cout << "Set Overdrive level to 0%..." << std::endl; + std::cout << "Set Overdrive level to 0%..." << "\n"; ret = rsmi_dev_overdrive_level_set_v1(dv_ind, 0); CHK_RSMI_RET(ret) - std::cout << "Set Overdrive level to 10%..." << std::endl; + std::cout << "Set Overdrive level to 10%..." << "\n"; ret = rsmi_dev_overdrive_level_set_v1(dv_ind, 10); CHK_RSMI_RET(ret) ret = rsmi_dev_overdrive_level_get(dv_ind, &val); CHK_RSMI_RET(ret) - std::cout << "\t**New OverDrive Level:" << std::dec << val << std::endl; - std::cout << "Reset Overdrive level to 0%..." << std::endl; + std::cout << "\t**New OverDrive Level:" << std::dec << val << "\n"; + std::cout << "Reset Overdrive level to 0%..." << "\n"; ret = rsmi_dev_overdrive_level_set_v1(dv_ind, 0); CHK_RSMI_RET(ret) ret = rsmi_dev_overdrive_level_get(dv_ind, &val); CHK_RSMI_RET(ret) - std::cout << "\t**New OverDrive Level:" << std::dec << val << std::endl; + std::cout << "\t**New OverDrive Level:" << std::dec << val << "\n"; return ret; } @@ -437,21 +436,21 @@ static rsmi_status_t test_set_fan_speed(uint32_t dv_ind) { std::cout << "Original fan speed: "; ret = rsmi_dev_fan_speed_get(dv_ind, 0, &orig_speed); if (ret == RSMI_STATUS_SUCCESS) { - std::cout << orig_speed << std::endl; + std::cout << orig_speed << "\n"; } else { CHK_RSMI_NOT_SUPPORTED_RET(ret) - std::cout << "***Skipping Fan Speed Control test." << std::endl; + std::cout << "***Skipping Fan Speed Control test." << "\n"; return RSMI_STATUS_SUCCESS; } if (orig_speed == 0) { - std::cout << "***System fan speed value is 0. Skip fan test." << std::endl; + std::cout << "***System fan speed value is 0. Skip fan test." << "\n"; return RSMI_STATUS_SUCCESS; } new_speed = 1.1 * static_cast(orig_speed); - std::cout << "Setting fan speed to " << new_speed << std::endl; + std::cout << "Setting fan speed to " << new_speed << "\n"; ret = rsmi_dev_fan_speed_set(dv_ind, 0, static_cast(new_speed)); CHK_RSMI_RET(ret) @@ -461,7 +460,7 @@ static rsmi_status_t test_set_fan_speed(uint32_t dv_ind) { ret = rsmi_dev_fan_speed_get(dv_ind, 0, &cur_spd); CHK_RSMI_RET(ret) - std::cout << "New fan speed: " << cur_spd << std::endl; + std::cout << "New fan speed: " << cur_spd << "\n"; assert( (cur_spd > static_cast(0.95 * static_cast(new_speed)) && @@ -469,7 +468,7 @@ static rsmi_status_t test_set_fan_speed(uint32_t dv_ind) { (cur_spd > static_cast(0.95 * static_cast(RSMI_MAX_FAN_SPEED)))); - std::cout << "Resetting fan control to auto..." << std::endl; + std::cout << "Resetting fan control to auto..." << "\n"; ret = rsmi_dev_fan_reset(dv_ind, 0); CHK_RSMI_RET(ret) @@ -479,7 +478,7 @@ static rsmi_status_t test_set_fan_speed(uint32_t dv_ind) { ret = rsmi_dev_fan_speed_get(dv_ind, 0, &cur_spd); CHK_RSMI_RET(ret) - std::cout << "End fan speed: " << cur_spd << std::endl; + std::cout << "End fan speed: " << cur_spd << "\n"; return ret; } @@ -494,29 +493,29 @@ static rsmi_status_t test_set_perf_level(uint32_t dv_ind) { ret = rsmi_dev_perf_level_get(dv_ind, &orig_pfl); CHK_RSMI_RET(ret) std::cout << "\t**Original Perf Level:" << perf_level_string(orig_pfl) << - std::endl; + "\n"; pfl = (rsmi_dev_perf_level_t)((orig_pfl + 1) % (RSMI_DEV_PERF_LEVEL_LAST + 1)); std::cout << "Set Performance Level to " << (uint32_t)pfl << " ..." << - std::endl; + "\n"; ret = rsmi_dev_perf_level_set_v1(dv_ind, pfl); if (ret != RSMI_STATUS_SUCCESS) { CHK_RSMI_NOT_SUPPORTED_RET(ret) - std::cout << "***Skipping Performance Level Control test." << std::endl; + std::cout << "***Skipping Performance Level Control test." << "\n"; return RSMI_STATUS_SUCCESS; } CHK_RSMI_RET(ret) ret = rsmi_dev_perf_level_get(dv_ind, &pfl); CHK_RSMI_RET(ret) - std::cout << "\t**New Perf Level:" << perf_level_string(pfl) << std::endl; - std::cout << "Reset Perf level to " << orig_pfl << " ..." << std::endl; + std::cout << "\t**New Perf Level:" << perf_level_string(pfl) << "\n"; + std::cout << "Reset Perf level to " << orig_pfl << " ..." << "\n"; ret = rsmi_dev_perf_level_set_v1(dv_ind, orig_pfl); CHK_RSMI_RET(ret) ret = rsmi_dev_perf_level_get(dv_ind, &pfl); CHK_RSMI_RET(ret) - std::cout << "\t**New Perf Level:" << perf_level_string(pfl) << std::endl; + std::cout << "\t**New Perf Level:" << perf_level_string(pfl) << "\n"; return ret; } @@ -541,7 +540,7 @@ static rsmi_status_t test_set_freq(uint32_t dv_ind) { CHK_FILE_PERMISSIONS_AND_NOT_SUPPORTED_OR_UNIMPLEMENTED(ret) std::cout << "Initial frequency for clock" << rsmi_clk << " is " << - f.current << std::endl; + f.current << "\n"; // Set clocks to something other than the usual default of the lowest // frequency. @@ -554,7 +553,7 @@ static rsmi_status_t test_set_freq(uint32_t dv_ind) { freq_bm_str.size()-1)); std::cout << "Setting frequency mask for clock " << rsmi_clk << - " to 0b" << freq_bm_str << " ..." << std::endl; + " to 0b" << freq_bm_str << " ..." << "\n"; ret = rsmi_dev_gpu_clk_freq_set(dv_ind, rsmi_clk, freq_bitmask); CHK_FILE_PERMISSIONS_AND_NOT_SUPPORTED_OR_UNIMPLEMENTED(ret) @@ -562,15 +561,15 @@ static rsmi_status_t test_set_freq(uint32_t dv_ind) { ret = rsmi_dev_gpu_clk_freq_get(dv_ind, rsmi_clk, &f); CHK_FILE_PERMISSIONS_AND_NOT_SUPPORTED_OR_UNIMPLEMENTED(ret) - std::cout << "Frequency is now index " << f.current << std::endl; - std::cout << "Resetting mask to all frequencies." << std::endl; + std::cout << "Frequency is now index " << f.current << "\n"; + std::cout << "Resetting mask to all frequencies." << "\n"; ret = rsmi_dev_gpu_clk_freq_set(dv_ind, rsmi_clk, 0xFFFFFFFF); CHK_FILE_PERMISSIONS_AND_NOT_SUPPORTED_OR_UNIMPLEMENTED(ret) ret = rsmi_dev_perf_level_set_v1(dv_ind, RSMI_DEV_PERF_LEVEL_AUTO); CHK_FILE_PERMISSIONS(ret) } - std::cout << std::endl; + std::cout << "\n"; return RSMI_STATUS_SUCCESS; } @@ -581,19 +580,19 @@ static void print_frequencies(rsmi_frequencies_t *f) { if (j == f->current) { std::cout << " *"; } - std::cout << std::endl; + std::cout << "\n"; } } static rsmi_status_t test_set_compute_partitioning(uint32_t dv_ind) { rsmi_status_t ret; - uint32_t buffer_len = 10; - char originalComputePartition[buffer_len]; + const uint32_t kLength = 10; + char originalComputePartition[kLength]; originalComputePartition[0] = '\0'; print_test_header("Compute Partitioning Control", dv_ind); ret = rsmi_dev_compute_partition_get(dv_ind, originalComputePartition, - buffer_len); + kLength); CHK_RSMI_NOT_SUPPORTED_OR_UNEXPECTED_DATA_RET(ret) if (ret == RSMI_STATUS_NOT_SUPPORTED) { return RSMI_STATUS_SUCCESS; @@ -604,99 +603,102 @@ static rsmi_status_t test_set_compute_partitioning(uint32_t dv_ind) { || ((originalComputePartition != nullptr) && (originalComputePartition[0] == '\0'))) ? "UNKNOWN" : originalComputePartition) - << std::endl << std::endl; + << "\n" << "\n"; for (int newComputePartition = RSMI_COMPUTE_PARTITION_CPX; newComputePartition <= RSMI_COMPUTE_PARTITION_QPX; newComputePartition++) { - rsmi_compute_partition_type newPartition - = static_cast(newComputePartition); + rsmi_compute_partition_type_t newPartition + = static_cast(newComputePartition); std::cout << "Attempting to set compute partition to " << compute_partition_string(newPartition) << "..." - << std::endl; + << "\n"; ret = rsmi_dev_compute_partition_set(dv_ind, newPartition); CHK_RSMI_NOT_SUPPORTED_OR_SETTING_UNAVAILABLE_RET(ret) std::cout << "Done setting compute partition to " - << compute_partition_string(newPartition) << "." << std::endl; - std::cout << std::endl << std::endl; + << compute_partition_string(newPartition) << "." << "\n"; + std::cout << "\n" << "\n"; } - std::cout << "About to initate compute partition reset..." << std::endl; + std::cout << "About to initate compute partition reset..." << "\n"; ret = rsmi_dev_compute_partition_reset(dv_ind); CHK_RSMI_NOT_SUPPORTED_RET(ret) - std::cout << "Done resetting compute partition." << std::endl; + std::cout << "Done resetting compute partition." << "\n"; std::string myComputePartition = originalComputePartition; if (myComputePartition.empty() == false) { std::cout << "Resetting back to original compute partition to " - << originalComputePartition << "... " << std::endl; + << originalComputePartition << "... " << "\n"; rsmi_compute_partition_type origComputePartitionType = mapStringToRSMIComputePartitionTypes[originalComputePartition]; ret = rsmi_dev_compute_partition_set(dv_ind, origComputePartitionType); CHK_RSMI_NOT_SUPPORTED_OR_SETTING_UNAVAILABLE_RET(ret) - std::cout << "Done" << std::endl; + std::cout << "Done" << "\n"; } return RSMI_STATUS_SUCCESS; } -static rsmi_status_t test_set_nps_mode(uint32_t dv_ind) { +static rsmi_status_t test_set_memory_partition(uint32_t dv_ind) { rsmi_status_t ret; - uint32_t buffer_len = 10; - char originalNpsMode[buffer_len]; - originalNpsMode[0] = '\0'; - print_test_header("NPS Mode Control", dv_ind); + const uint32_t kLength = 10; + char originalMemoryPartition[kLength]; + originalMemoryPartition[0] = '\0'; + print_test_header("Memory Partition Control", dv_ind); - ret = rsmi_dev_nps_mode_get(dv_ind, originalNpsMode, buffer_len); + ret = rsmi_dev_memory_partition_get(dv_ind, originalMemoryPartition, kLength); CHK_RSMI_NOT_SUPPORTED_OR_UNEXPECTED_DATA_RET(ret) if (ret == RSMI_STATUS_NOT_SUPPORTED) { return RSMI_STATUS_SUCCESS; } - std::cout << "Original NPS Mode: " - << (((originalNpsMode == nullptr) - || ((originalNpsMode != nullptr) - && (originalNpsMode[0] == '\0'))) - ? "UNKNOWN" : originalNpsMode) - << std::endl << std::endl; + std::cout << "Original Memory Partition: " + << (((originalMemoryPartition == nullptr) + || ((originalMemoryPartition != nullptr) + && (originalMemoryPartition[0] == '\0'))) + ? "UNKNOWN" : originalMemoryPartition) + << "\n\n"; - for (int newNpsMode = RSMI_MEMORY_PARTITION_NPS1; - newNpsMode <= RSMI_MEMORY_PARTITION_NPS8; - newNpsMode++) { - rsmi_nps_mode_type_t newMemoryPartition - = static_cast(newNpsMode); - std::cout << "Attempting to set NPS mode to " - << nps_mode_string(newMemoryPartition) << "..." - << std::endl; - ret = rsmi_dev_nps_mode_set(dv_ind, newMemoryPartition); + for (int newMemPartition = RSMI_MEMORY_PARTITION_NPS1; + newMemPartition <= RSMI_MEMORY_PARTITION_NPS8; + newMemPartition++) { + rsmi_memory_partition_type_t newMemoryPartition + = static_cast(newMemPartition); + std::cout << "Attempting to set memory partition to " + << memory_partition_string(newMemoryPartition) << "..." + << "\n"; + ret = rsmi_dev_memory_partition_set(dv_ind, newMemoryPartition); CHK_RSMI_NOT_SUPPORTED_RET(ret) if (ret == RSMI_STATUS_NOT_SUPPORTED) { // do not continue attempting to set, device does not support setting return RSMI_STATUS_SUCCESS; } - std::cout << "Done setting NPS mode to " - << nps_mode_string(newMemoryPartition) - << "." << std::endl; - std::cout << std::endl << std::endl; + std::cout << "Done setting memory partition to " + << memory_partition_string(newMemoryPartition) + << "." << "\n\n\n"; } - std::cout << "About to initate nps mode reset..." << std::endl; - ret = rsmi_dev_nps_mode_reset(dv_ind); + std::cout << "About to initate memory partition reset...\n"; + ret = rsmi_dev_memory_partition_reset(dv_ind); CHK_RSMI_NOT_SUPPORTED_RET(ret) - std::cout << "Done resetting nps mode." << std::endl; + std::cout << "Done resetting memory partition.\n"; - std::string myNpsMode = originalNpsMode; - if (myNpsMode.empty() == false) { - std::cout << "Resetting compute partition to " << originalNpsMode - << "... " << std::endl; - rsmi_nps_mode_type_t origNpsModeType - = mapStringToRSMINpsModeTypes[originalNpsMode]; - ret = rsmi_dev_nps_mode_set(dv_ind, origNpsModeType); + std::string myMemPart = originalMemoryPartition; + if (myMemPart.empty() == false) { + std::cout << "Resetting memory partition to " << originalMemoryPartition + << "...\n"; + rsmi_memory_partition_type_t origMemoryPartitionType + = mapStringToRSMIMemoryPartitionTypes[originalMemoryPartition]; + ret = rsmi_dev_memory_partition_set(dv_ind, origMemoryPartitionType); CHK_RSMI_NOT_SUPPORTED_RET(ret) - std::cout << "Done" << std::endl; + std::cout << "Done\n"; } return RSMI_STATUS_SUCCESS; } +template constexpr float convert_mw_to_w(T mw) { + return static_cast(mw / 1000.0); +} + int main() { rsmi_status_t ret; @@ -712,15 +714,17 @@ int main() { rsmi_frequencies_t f; uint32_t num_monitor_devs = 0; rsmi_gpu_metrics_t p; + RSMI_POWER_TYPE power_type = RSMI_INVALID_POWER; rsmi_num_monitor_devices(&num_monitor_devs); for (uint32_t i = 0; i < num_monitor_devs; ++i) { + std::cout << "\t**Device #: " << std::dec << i << std::endl; ret = rsmi_dev_id_get(i, &val_ui16); CHK_RSMI_RET_I(ret) - std::cout << "\t**Device ID: 0x" << std::hex << val_ui16 << std::endl; + std::cout << "\t**Device ID: 0x" << std::hex << val_ui16 << "\n"; ret = rsmi_dev_revision_get(i, &val_ui16); CHK_RSMI_RET_I(ret) - std::cout << "\t**Dev.Rev.ID: 0x" << std::hex << val_ui16 << std::endl; + std::cout << "\t**Dev.Rev.ID: 0x" << std::hex << val_ui16 << "\n"; char pcie_vendor_name[256]; ret = rsmi_dev_pcie_vendor_name_get(i, pcie_vendor_name, 256); @@ -737,69 +741,92 @@ int main() { ? "UNKNOWN" : current_compute_partition); if (ret != RSMI_STATUS_SUCCESS) { std::cout << ", RSMI_STATUS = "; - } else { - std::cout << std::endl; +} else { + std::cout << "\n"; } CHK_RSMI_NOT_SUPPORTED_OR_UNEXPECTED_DATA_RET(ret) - uint32_t len = 5; - char nps_mode[len]; - nps_mode[0] = '\0'; - ret = rsmi_dev_nps_mode_get(i, nps_mode, len); - std::cout << "\t**NPS Mode: " - << (((nps_mode == nullptr) - || ((nps_mode != nullptr) - && (nps_mode[0] == '\0'))) - ? "UNKNOWN" : nps_mode); + const uint32_t kLength = 5; + char memory_partition[kLength]; + memory_partition[0] = '\0'; + ret = rsmi_dev_memory_partition_get(i, memory_partition, kLength); + std::cout << "\t**Current Memory Partition: " + << (((memory_partition == nullptr) + || ((memory_partition != nullptr) + && (memory_partition[0] == '\0'))) + ? "UNKNOWN" : memory_partition); if (ret != RSMI_STATUS_SUCCESS) { std::cout << ", RSMI_STATUS = "; } else { - std::cout << std::endl; + std::cout << "\n"; } CHK_NOT_SUPPORTED_OR_UNEXPECTED_DATA_OR_INSUFFICIENT_SIZE_RET(ret) + std::cout << "\t**rsmi_minmax_bandwidth_get(0, " << i << ", ...): "; + ret = rsmi_dev_pci_id_get(0, &val_ui64); + ret = rsmi_dev_pci_id_get(i, &val2_ui64); + if (i > 0 && val_ui64 != val2_ui64) { + uint64_t min_bandwidth = 0; + uint64_t max_bandwidth = 0; + ret = rsmi_minmax_bandwidth_get(0, i, &min_bandwidth, &max_bandwidth); + CHK_RSMI_NOT_SUPPORTED_OR_UNEXPECTED_DATA_RET(ret) + std::cout << "\nMinimum Bandwidth: " << min_bandwidth + << "\nMaximum Bandwidth: " << max_bandwidth; + } else { + std::cout << "Not Supported\n"; + } + ret = rsmi_dev_gpu_metrics_info_get(i, &p); CHK_AND_PRINT_RSMI_ERR_RET(ret) - std::cout << "\t**GPU METRICS" << std::endl; + std::cout << "\t**GPU METRICS" << "\n"; ret = rsmi_dev_perf_level_get(i, &pfl); CHK_AND_PRINT_RSMI_ERR_RET(ret) std::cout << "\t**Performance Level:" << - perf_level_string(pfl) << std::endl; + perf_level_string(pfl) << "\n"; ret = rsmi_dev_overdrive_level_get(i, &val_ui32); CHK_AND_PRINT_RSMI_ERR_RET(ret) - std::cout << "\t**OverDrive Level:" << val_ui32 << std::endl; + std::cout << "\t**OverDrive Level:" << val_ui32 << "\n"; ret = rsmi_dev_gpu_clk_freq_get(i, RSMI_CLK_TYPE_MEM, &f); CHK_AND_PRINT_RSMI_ERR_RET(ret) std::cout << "\t**Supported GPU Memory clock frequencies: "; - std::cout << f.num_supported << std::endl; + std::cout << f.num_supported << "\n"; print_frequencies(&f); ret = rsmi_dev_gpu_clk_freq_get(i, RSMI_CLK_TYPE_SYS, &f); CHK_AND_PRINT_RSMI_ERR_RET(ret) std::cout << "\t**Supported GPU clock frequencies: "; - std::cout << f.num_supported << std::endl; + std::cout << f.num_supported << "\n"; print_frequencies(&f); ret = rsmi_dev_gpu_clk_freq_get(i, RSMI_CLK_TYPE_SOC, &f); CHK_RSMI_NOT_SUPPORTED_OR_UNEXPECTED_DATA_RET(ret) std::cout << "\t**Supported GPU clock frequencies (SOC clk): "; - std::cout << f.num_supported << std::endl; + std::cout << f.num_supported << "\n"; std::cout << "\t**Current value (SOC clk): "; - std::cout << f.current << std::endl; + std::cout << f.current << "\n"; print_frequencies(&f); std::cout << "\t**Monitor name: "; char name[128]; ret = rsmi_dev_name_get(i, name, 128); CHK_AND_PRINT_RSMI_ERR_RET(ret) - std::cout << name << std::endl; + std::cout << name << "\n"; - std::cout << "\t**Temperature: "; - ret = rsmi_dev_temp_metric_get(i, 0, RSMI_TEMP_CURRENT, &val_i64); + std::cout << "\t**Temperature (edge): "; + ret = rsmi_dev_temp_metric_get(i, RSMI_TEMP_TYPE_EDGE, + rsmi_temperature_metric_t::RSMI_TEMP_CURRENT, &val_i64); if (ret == RSMI_STATUS_SUCCESS) { - std::cout << val_i64/1000 << "C" << std::endl; + std::cout << val_i64/1000 << "C" << "\n"; + } + CHK_RSMI_NOT_SUPPORTED_RET(ret) + + std::cout << "\t**Temperature (junction): "; + ret = rsmi_dev_temp_metric_get(i, RSMI_TEMP_TYPE_JUNCTION, + rsmi_temperature_metric_t::RSMI_TEMP_CURRENT, &val_i64); + if (ret == RSMI_STATUS_SUCCESS) { + std::cout << (val_i64 / 1000) << "C" << std::endl; } CHK_RSMI_NOT_SUPPORTED_RET(ret) @@ -807,7 +834,7 @@ int main() { ret = rsmi_dev_volt_metric_get(i, RSMI_VOLT_TYPE_VDDGFX, RSMI_VOLT_CURRENT, &val_i64); if (ret == RSMI_STATUS_SUCCESS) { - std::cout << val_i64 << "mV" << std::endl; + std::cout << val_i64 << "mV" << "\n"; } CHK_RSMI_NOT_SUPPORTED_RET(ret) @@ -818,21 +845,21 @@ int main() { CHK_AND_PRINT_RSMI_ERR_RET(ret) std::cout << (static_cast(val_i64)/val_ui64) * 100; std::cout << "% (" << std::dec << val_i64 << "/" - << std::dec << val_ui64 << ")" << std::endl; + << std::dec << val_ui64 << ")" << "\n"; } CHK_RSMI_NOT_SUPPORTED_RET(ret) std::cout << "\t**Current fan RPMs: "; ret = rsmi_dev_fan_rpms_get(i, 0, &val_i64); if (ret == RSMI_STATUS_SUCCESS) { - std::cout << std::dec << val_i64 << std::endl; + std::cout << std::dec << val_i64 << "\n"; } CHK_RSMI_NOT_SUPPORTED_RET(ret) std::cout << "\t**Current Power Cap: "; ret = rsmi_dev_power_cap_get(i, 0, &val_ui64); if (ret == RSMI_STATUS_SUCCESS) { - std::cout << std::dec << val_ui64 << "uW" <(val_ui64)/1000 << " W" << std::endl; + std::cout << convert_mw_to_w(val_ui64) << " W" << std::endl; } CHK_RSMI_NOT_SUPPORTED_RET(ret) - std::cout << "\t=======" << std::endl; + + std::cout << "\t**Current Socket Power Usage: "; + ret = rsmi_dev_current_socket_power_get(i, &val_ui64); + if (ret == RSMI_STATUS_SUCCESS) { + std::cout << convert_mw_to_w(val_ui64) << " W" << std::endl; + } + CHK_RSMI_NOT_SUPPORTED_RET(ret) + + std::cout << "\t**Generic Power Usage: "; + ret = rsmi_dev_power_get(i, &val_ui64, &power_type); + if (ret == RSMI_STATUS_SUCCESS) { + std::cout << "[" << amd::smi::power_type_string(power_type) << "] " + << convert_mw_to_w(val_ui64) << " W" << std::endl; + } + CHK_RSMI_NOT_SUPPORTED_RET(ret) + std::cout << "\t=======" << "\n"; } - std::cout << "***** Testing write api's" << std::endl; + std::cout << "***** Testing write api's" << "\n"; if (isUserRunningAsSudo() == false) { std::cout << "Write APIs require users to execute with sudo. " - << "Cannot proceed." << std::endl; + << "Cannot proceed." << "\n"; return 0; } @@ -882,7 +924,7 @@ int main() { ret = test_set_freq(i); CHK_AND_PRINT_RSMI_ERR_RET(ret) - ret = test_set_nps_mode(i); + ret = test_set_memory_partition(i); CHK_AND_PRINT_RSMI_ERR_RET(ret) } diff --git a/rocm_smi/include/rocm_smi/rocm_smi.h b/rocm_smi/include/rocm_smi/rocm_smi.h index 44179e07f0..3e2735f870 100755 --- a/rocm_smi/include/rocm_smi/rocm_smi.h +++ b/rocm_smi/include/rocm_smi/rocm_smi.h @@ -40,8 +40,8 @@ * DEALINGS WITH THE SOFTWARE. * */ -#ifndef INCLUDE_ROCM_SMI_ROCM_SMI_H_ -#define INCLUDE_ROCM_SMI_ROCM_SMI_H_ +#ifndef ROCM_SMI_ROCM_SMI_H_ +#define ROCM_SMI_ROCM_SMI_H_ #ifdef __cplusplus extern "C" { @@ -393,27 +393,27 @@ typedef rsmi_compute_partition_type_t rsmi_compute_partition_type; /// \endcond /** - * @brief NPS Modes. This enum is used to identify various - * NPS mode types. + * @brief Memory Partitions. This enum is used to identify various + * memory partition types. */ typedef enum { RSMI_MEMORY_PARTITION_UNKNOWN = 0, - RSMI_MEMORY_PARTITION_NPS1, //!< NPS1 - All CCD & XCD data is interleaved - //!< accross all 8 HBM stacks (all stacks/1). - RSMI_MEMORY_PARTITION_NPS2, //!< NPS2 - 2 sets of CCDs or 4 XCD interleaved - //!< accross the 4 HBM stacks per AID pair - //!< (8 stacks/2). - RSMI_MEMORY_PARTITION_NPS4, //!< NPS4 - Each XCD data is interleaved accross - //!< accross 2 (or single) HBM stacks - //!< (8 stacks/8 or 8 stacks/4). - RSMI_MEMORY_PARTITION_NPS8, //!< NPS8 - Each XCD uses a single HBM stack - //!< (8 stacks/8). Or each XCD uses a single - //!< HBM stack & CCDs share 2 non-interleaved - //!< HBM stacks on its AID - //!< (AID[1,2,3] = 6 stacks/6). -} rsmi_nps_mode_type_t; + RSMI_MEMORY_PARTITION_NPS1, //!< NPS1 - All CCD & XCD data is interleaved + //!< accross all 8 HBM stacks (all stacks/1). + RSMI_MEMORY_PARTITION_NPS2, //!< NPS2 - 2 sets of CCDs or 4 XCD interleaved + //!< accross the 4 HBM stacks per AID pair + //!< (8 stacks/2). + RSMI_MEMORY_PARTITION_NPS4, //!< NPS4 - Each XCD data is interleaved accross + //!< accross 2 (or single) HBM stacks + //!< (8 stacks/8 or 8 stacks/4). + RSMI_MEMORY_PARTITION_NPS8, //!< NPS8 - Each XCD uses a single HBM stack + //!< (8 stacks/8). Or each XCD uses a single + //!< HBM stack & CCDs share 2 non-interleaved + //!< HBM stacks on its AID + //!< (AID[1,2,3] = 6 stacks/6). +} rsmi_memory_partition_type_t; /// \cond Ignore in docs. -typedef rsmi_nps_mode_type_t rsmi_nps_mode_type; +typedef rsmi_memory_partition_type_t rsmi_memory_partition_type; /// \endcond /** @@ -724,6 +724,15 @@ typedef enum { RSMI_UTILIZATION_COUNTER_LAST = RSMI_COARSE_GRAIN_MEM_ACTIVITY } RSMI_UTILIZATION_COUNTER_TYPE; +/** + * @brief Power types + */ +typedef enum { + RSMI_AVERAGE_POWER = 0, //!< Average Power + RSMI_CURRENT_POWER, //!< Current / Instant Power + RSMI_INVALID_POWER = 0xFFFFFFFF //!< Invalid / Undetected Power +} RSMI_POWER_TYPE; + /** * @brief The utilization counter data */ @@ -972,12 +981,10 @@ struct metrics_table_header_t { * @brief The GPU metrics version 3 */ #define RSMI_GPU_METRICS_API_CONTENT_VER_3 3 - /** * @brief This should match NUM_HBM_INSTANCES */ #define RSMI_NUM_HBM_INSTANCES 4 - /** * @brief Unit conversion factor for HBM temperatures */ @@ -1855,6 +1862,40 @@ rsmi_dev_power_ave_get(uint32_t dv_ind, uint32_t sensor_ind, uint64_t *power); rsmi_status_t rsmi_dev_current_socket_power_get(uint32_t dv_ind, uint64_t *socket_power); +/** + * @brief A generic get which attempts to retieve current socket power + * (also known as instant power) of the device index provided, if not + * supported tries to get average power consumed by device. Current + * socket power is typically supported by newer devices, whereas average + * power is generally reported on older devices. This function + * aims to provide backwards compatability depending on device support. + * + * @details Given a device index @p dv_ind, a pointer to a uint64_t + * @p power, and @p type this function will write the current socket or + * average power (in microwatts) to the uint64_t pointed to by @p power and + * a pointer to its @p type RSMI_POWER_TYPE read. + * + * @param[in] dv_ind a device index + * + * @param[inout] power a pointer to uint64_t to which the current or average + * power will be written to. If this parameter is nullptr, + * this function will return ::RSMI_STATUS_INVALID_ARGS if the function is + * supported with the provided, arguments and ::RSMI_STATUS_NOT_SUPPORTED + * if it is not supported with the provided arguments. + * + * @param[inout] type a pointer to RSMI_POWER_TYPE object. Returns the type + * of power retrieved from the device. Current power is ::RSMI_CURRENT_POWER + * and average power is ::RSMI_AVERAGE_POWER. If an error occurs, + * returns an invalid power type ::RSMI_INVALID_POWER. + * + * @retval ::RSMI_STATUS_SUCCESS call was successful + * @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not + * support this function with the given arguments + * @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid + */ +rsmi_status_t rsmi_dev_power_get(uint32_t dv_ind, uint64_t *power, + RSMI_POWER_TYPE *type); + /** * @brief Get the energy accumulator counter of the device with provided * device index. @@ -2553,7 +2594,8 @@ rsmi_status_t rsmi_dev_perf_level_get(uint32_t dv_ind, * @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid * */ -rsmi_status_t rsmi_perf_determinism_mode_set(uint32_t dv_ind, uint64_t clkvalue); +rsmi_status_t rsmi_perf_determinism_mode_set(uint32_t dv_ind, + uint64_t clkvalue); /** * @brief Get the overdrive percent associated with the device with provided @@ -3907,27 +3949,28 @@ rsmi_status_t rsmi_dev_compute_partition_reset(uint32_t dv_ind); /** @} */ // end of ComputePartition /*****************************************************************************/ -/** @defgroup NPSMode NPS Mode Functions - * These functions are used to query the device's NPS mode (memory partition). +/** @defgroup memory_partition The Memory Partition Functions + * These functions are used to query and set the device's current memory + * partition. * @{ */ /** - * @brief Retrieves the NPS mode (memory partition) for a desired device + * @brief Retrieves the current memory partition for a desired device * * @details - * Given a device index @p dv_ind and a string @p nps_mode , + * Given a device index @p dv_ind and a string @p memory_partition , * and uint32 @p len , this function will attempt to obtain the device's - * nps mode string. Upon successful retreival, the obtained device's - * nps mode string shall be stored in the passed @p nps_mode char string - * variable. + * memory partition string. Upon successful retreival, the obtained device's + * memory partition string shall be stored in the passed @p memory_partition + * char string variable. * * @param[in] dv_ind a device index * - * @param[inout] nps_mode a pointer to a char string variable, - * which the device's nps mode will be written to. + * @param[inout] memory_partition a pointer to a char string variable, + * which the device's memory partition will be written to. * - * @param[in] len the length of the caller provided buffer @p nps_mode , + * @param[in] len the length of the caller provided buffer @p memory_partition , * suggested length is 5 or greater. * * @retval ::RSMI_STATUS_SUCCESS call was successful @@ -3936,24 +3979,25 @@ rsmi_status_t rsmi_dev_compute_partition_reset(uint32_t dv_ind); * @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not * support this function * @retval ::RSMI_STATUS_INSUFFICIENT_SIZE is returned if @p len bytes is not - * large enough to hold the entire nps mode value. In this case, + * large enough to hold the entire memory partition value. In this case, * only @p len bytes will be written. * */ rsmi_status_t -rsmi_dev_nps_mode_get(uint32_t dv_ind, char *nps_mode, uint32_t len); +rsmi_dev_memory_partition_get(uint32_t dv_ind, char *memory_partition, + uint32_t len); /** - * @brief Modifies a selected device's NPS mode (memory partition) setting. + * @brief Modifies a selected device's current memory partition setting. * - * @details Given a device index @p dv_ind and a type of nps mode - * @p nps_mode, this function will attempt to update the selected - * device's nps mode setting. + * @details Given a device index @p dv_ind and a type of memory partition + * @p memory_partition, this function will attempt to update the selected + * device's memory partition setting. * * @param[in] dv_ind a device index * - * @param[in] nps_mode using enum ::rsmi_nps_mode_type_t, - * define what the selected device's NPS mode setting should be updated to. + * @param[in] memory_partition using enum ::rsmi_memory_partition_type_t, + * define what the selected device's current mode setting should be updated to. * * @retval ::RSMI_STATUS_SUCCESS call was successful * @retval ::RSMI_STATUS_PERMISSION function requires root access @@ -3965,14 +4009,15 @@ rsmi_dev_nps_mode_get(uint32_t dv_ind, char *nps_mode, uint32_t len); * */ rsmi_status_t -rsmi_dev_nps_mode_set(uint32_t dv_ind, rsmi_nps_mode_type_t nps_mode); +rsmi_dev_memory_partition_set(uint32_t dv_ind, + rsmi_memory_partition_type_t memory_partition); /** - * @brief Reverts a selected device's NPS mode setting back to its + * @brief Reverts a selected device's memory partition setting back to its * boot state. * * @details Given a device index @p dv_ind , this function will attempt to - * revert its NPS mode setting back to its boot state. + * revert its current memory partition setting back to its boot state. * * @param[in] dv_ind a device index * @@ -3984,9 +4029,9 @@ rsmi_dev_nps_mode_set(uint32_t dv_ind, rsmi_nps_mode_type_t nps_mode); * the amdgpu driver * */ -rsmi_status_t rsmi_dev_nps_mode_reset(uint32_t dv_ind); +rsmi_status_t rsmi_dev_memory_partition_reset(uint32_t dv_ind); -/** @} */ // end of NPSMode +/** @} */ // end of memory_partition /*****************************************************************************/ /** @defgroup APISupport Supported Functions @@ -4333,4 +4378,4 @@ rsmi_status_t rsmi_event_notification_stop(uint32_t dv_ind); #ifdef __cplusplus } #endif // __cplusplus -#endif // INCLUDE_ROCM_SMI_ROCM_SMI_H_ +#endif // ROCM_SMI_ROCM_SMI_H_ diff --git a/rocm_smi/include/rocm_smi/rocm_smi_device.h b/rocm_smi/include/rocm_smi/rocm_smi_device.h index d0743029f9..6aedfb0c1a 100755 --- a/rocm_smi/include/rocm_smi/rocm_smi_device.h +++ b/rocm_smi/include/rocm_smi/rocm_smi_device.h @@ -60,6 +60,7 @@ #include "rocm_smi/rocm_smi.h" #include "rocm_smi/rocm_smi_counters.h" #include "rocm_smi/rocm_smi_properties.h" +#include "rocm_smi/rocm_smi_gpu_metrics.h" #include "shared_mutex.h" //NOLINT namespace amd { @@ -238,6 +239,18 @@ class Device { template std::string readBootPartitionState(uint32_t dv_ind); rsmi_status_t check_amdgpu_property_reinforcement_query(uint32_t dev_idx, AMDGpuVerbTypes_t verb_type); + void dev_set_gpu_metric(GpuMetricsBasePtr gpu_metrics_ptr) { m_gpu_metrics_ptr = gpu_metrics_ptr; }; + GpuMetricsBasePtr& dev_get_gpu_metric() { return m_gpu_metrics_ptr; }; + const AMDGpuMetricsHeader_v1_t& dev_get_metrics_header() {return m_gpu_metrics_header; } + rsmi_status_t setup_gpu_metrics_reading(); + rsmi_status_t dev_read_gpu_metrics_header_data(); + rsmi_status_t dev_read_gpu_metrics_all_data(); + rsmi_status_t dev_log_gpu_metrics(); + rsmi_status_t run_internal_gpu_metrics_query(AMDGpuMetricsUnitType_t metric_counter, AMDGpuDynamicMetricTblValues_t& values); + + template + rsmi_status_t dev_run_gpu_metrics_query(AMDGpuMetricsUnitType_t metric_counter, T& metric_value); + private: std::shared_ptr monitor_; @@ -259,6 +272,8 @@ class Device { void *p_binary_data); int writeDevInfoStr(DevInfoTypes type, std::string valStr); rsmi_status_t run_amdgpu_property_reinforcement_query(const AMDGpuPropertyQuery_t& amdgpu_property_query); + + uint64_t bdfid_; uint64_t kfd_gpu_id_; std::unordered_set, + * nor the names of its contributors may be used to endorse or promote + * products derived from this Software without specific prior written + * permission. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS WITH THE SOFTWARE. + * + */ + +#ifndef ROCM_SMI_ROCM_SMI_GPU_METRICS_H_ +#define ROCM_SMI_ROCM_SMI_GPU_METRICS_H_ + +#include "rocm_smi/rocm_smi_common.h" +#include "rocm_smi/rocm_smi.h" + +#include +#include +#include +#include +#include + + +/** + * All 1.4 and newer GPU metrics are now defined in this header. + * + */ +namespace amd::smi +{ + +constexpr uint32_t kRSMI_GPU_METRICS_API_CONTENT_MAJOR_VER_1 = 1; +constexpr uint32_t kRSMI_GPU_METRICS_API_CONTENT_MINOR_VER_1 = 1; +constexpr uint32_t kRSMI_GPU_METRICS_API_CONTENT_MINOR_VER_2 = 2; +constexpr uint32_t kRSMI_GPU_METRICS_API_CONTENT_MINOR_VER_3 = 3; +constexpr uint32_t kRSMI_GPU_METRICS_API_CONTENT_MINOR_VER_4 = 4; +constexpr uint32_t kRSMI_LATEST_GPU_METRICS_API_CONTENT_MAJOR_VER = kRSMI_GPU_METRICS_API_CONTENT_MAJOR_VER_1; +constexpr uint32_t kRSMI_LATEST_GPU_METRICS_API_CONTENT_MINON_VER = kRSMI_GPU_METRICS_API_CONTENT_MINOR_VER_4; + + +// Note: As gpu metrics are updating +constexpr uint32_t kRSMI_GPU_METRICS_EXPIRATION_SECS = 5; + +// Note: This *must* match NUM_HBM_INSTANCES +constexpr uint32_t kRSMI_MAX_NUM_HBM_INSTANCES = 4; + +// Note: This *must* match NUM_XGMI_LINKS +constexpr uint32_t kRSMI_MAX_NUM_XGMI_LINKS = 8; + +// Note: This *must* match MAX_GFX_CLKS +constexpr uint32_t kRSMI_MAX_NUM_GFX_CLKS = 8; + +// Note: This *must* match MAX_CLKS +constexpr uint32_t kRSMI_MAX_NUM_CLKS = 4; + +// Note: This *must* match NUM_VCN +constexpr uint32_t kRSMI_MAX_NUM_VCN = 4; + + +struct AMDGpuMetricsHeader_v1_t +{ + uint16_t m_structure_size; + uint8_t m_format_revision; + uint8_t m_content_revision; +}; + + +struct AMDGpuMetricsBase_t; +using AMDGpuMetricsBaseRef = AMDGpuMetricsBase_t&; +struct AMDGpuMetricsBase_t +{ + virtual ~AMDGpuMetricsBase_t() = default; +}; + +struct AMDGpuMetrics_v11_t : AMDGpuMetricsBase_t +{ + ~AMDGpuMetrics_v11_t() = default; + + struct AMDGpuMetricsHeader_v1_t m_common_header; + + // Temperature + uint16_t m_temperature_edge; + uint16_t m_temperature_hotspot; + uint16_t m_temperature_mem; + uint16_t m_temperature_vrgfx; + uint16_t m_temperature_vrsoc; + uint16_t m_temperature_vrmem; + + // Utilization + uint16_t m_average_gfx_activity; + uint16_t m_average_umc_activity; // memory controller + uint16_t m_average_mm_activity; // UVD or VCN + + // Power/Energy + uint16_t m_average_socket_power; + uint64_t m_energy_accumulator; + + // Driver attached timestamp (in ns) + uint64_t m_system_clock_counter; + + // Average clocks + uint16_t m_average_gfxclk_frequency; + uint16_t m_average_socclk_frequency; + uint16_t m_average_uclk_frequency; + uint16_t m_average_vclk0_frequency; + uint16_t m_average_dclk0_frequency; + uint16_t m_average_vclk1_frequency; + uint16_t m_average_dclk1_frequency; + + // Current clocks + uint16_t m_current_gfxclk; + uint16_t m_current_socclk; + uint16_t m_current_uclk; + uint16_t m_current_vclk0; + uint16_t m_current_dclk0; + uint16_t m_current_vclk1; + uint16_t m_current_dclk1; + + // Throttle status + uint32_t m_throttle_status; + + // Fans + uint16_t m_current_fan_speed; + + // Link width/speed + uint16_t m_pcie_link_width; + uint16_t m_pcie_link_speed; // in 0.1 GT/s + + uint16_t m_padding; + + uint32_t m_gfx_activity_acc; + uint32_t m_mem_activity_acc; + + uint16_t m_temperature_hbm[kRSMI_MAX_NUM_HBM_INSTANCES]; +}; + +struct AMDGpuMetrics_v12_t : AMDGpuMetricsBase_t +{ + ~AMDGpuMetrics_v12_t() = default; + + struct AMDGpuMetricsHeader_v1_t m_common_header; + + // Temperature + uint16_t m_temperature_edge; + uint16_t m_temperature_hotspot; + uint16_t m_temperature_mem; + uint16_t m_temperature_vrgfx; + uint16_t m_temperature_vrsoc; + uint16_t m_temperature_vrmem; + + // Utilization + uint16_t m_average_gfx_activity; + uint16_t m_average_umc_activity; // memory controller + uint16_t m_average_mm_activity; // UVD or VCN + + // Power/Energy + uint16_t m_average_socket_power; + uint64_t m_energy_accumulator; // v1 mod. (32->64) + + // Driver attached timestamp (in ns) + uint64_t m_system_clock_counter; // v1 mod. (moved from top of struct) + + // Average clocks + uint16_t m_average_gfxclk_frequency; + uint16_t m_average_socclk_frequency; + uint16_t m_average_uclk_frequency; + uint16_t m_average_vclk0_frequency; + uint16_t m_average_dclk0_frequency; + uint16_t m_average_vclk1_frequency; + uint16_t m_average_dclk1_frequency; + + // Current clocks + uint16_t m_current_gfxclk; + uint16_t m_current_socclk; + uint16_t m_current_uclk; + uint16_t m_current_vclk0; + uint16_t m_current_dclk0; + uint16_t m_current_vclk1; + uint16_t m_current_dclk1; + + // Throttle status + uint32_t m_throttle_status; + + // Fans + uint16_t m_current_fan_speed; + + // Link width/speed + uint16_t m_pcie_link_width; // v1 mod.(8->16) + uint16_t m_pcie_link_speed; // in 0.1 GT/s; v1 mod. (8->16) + + uint16_t m_padding; // new in v1 + + uint32_t m_gfx_activity_acc; // new in v1 + uint32_t m_mem_activity_acc; // new in v1 + uint16_t m_temperature_hbm[kRSMI_MAX_NUM_HBM_INSTANCES]; // new in v1 + + // PMFW attached timestamp (10ns resolution) + uint64_t m_firmware_timestamp; +}; + +struct AMDGpuMetrics_v13_t : AMDGpuMetricsBase_t +{ + ~AMDGpuMetrics_v13_t() = default; + + struct AMDGpuMetricsHeader_v1_t m_common_header; + + // Temperature + uint16_t m_temperature_edge; + uint16_t m_temperature_hotspot; + uint16_t m_temperature_mem; + uint16_t m_temperature_vrgfx; + uint16_t m_temperature_vrsoc; + uint16_t m_temperature_vrmem; + + // Utilization + uint16_t m_average_gfx_activity; + uint16_t m_average_umc_activity; // memory controller + uint16_t m_average_mm_activity; // UVD or VCN + + // Power/Energy + uint16_t m_average_socket_power; + uint64_t m_energy_accumulator; // v1 mod. (32->64) + + // Driver attached timestamp (in ns) + uint64_t m_system_clock_counter; // v1 mod. (moved from top of struct) + + // Average clocks + uint16_t m_average_gfxclk_frequency; + uint16_t m_average_socclk_frequency; + uint16_t m_average_uclk_frequency; + uint16_t m_average_vclk0_frequency; + uint16_t m_average_dclk0_frequency; + uint16_t m_average_vclk1_frequency; + uint16_t m_average_dclk1_frequency; + + // Current clocks + uint16_t m_current_gfxclk; + uint16_t m_current_socclk; + uint16_t m_current_uclk; + uint16_t m_current_vclk0; + uint16_t m_current_dclk0; + uint16_t m_current_vclk1; + uint16_t m_current_dclk1; + + // Throttle status + uint32_t m_throttle_status; + + // Fans + uint16_t m_current_fan_speed; + + // Link width/speed + uint16_t m_pcie_link_width; // v1 mod.(8->16) + uint16_t m_pcie_link_speed; // in 0.1 GT/s; v1 mod. (8->16) + + uint16_t m_padding; // new in v1 + + uint32_t m_gfx_activity_acc; // new in v1 + uint32_t m_mem_activity_acc; // new in v1 + uint16_t m_temperature_hbm[kRSMI_MAX_NUM_HBM_INSTANCES]; // new in v1 + + // PMFW attached timestamp (10ns resolution) + uint64_t m_firmware_timestamp; + + // Voltage (mV) + uint16_t m_voltage_soc; + uint16_t m_voltage_gfx; + uint16_t m_voltage_mem; + + uint16_t m_padding1; + + // Throttle status + uint64_t m_indep_throttle_status; +}; + +struct AMDGpuMetrics_v14_t : AMDGpuMetricsBase_t +{ + ~AMDGpuMetrics_v14_t() = default; + + struct AMDGpuMetricsHeader_v1_t m_common_header; + + // Temperature (Celsius). It will be zero (0) if unsupported. + uint16_t m_temperature_hotspot; + uint16_t m_temperature_mem; + uint16_t m_temperature_vrsoc; + + // Power (Watts) + uint16_t m_curr_socket_power; + + // Utilization (%) + uint16_t m_average_gfx_activity; + uint16_t m_average_umc_activity; // memory controller + uint16_t m_vcn_activity[kRSMI_MAX_NUM_VCN]; // VCN instances activity percent (encode/decode) + + // Energy (15.259uJ (2^-16) units) + uint64_t m_energy_accumulator; + + // Driver attached timestamp (in ns) + uint64_t m_system_clock_counter; + + // Throttle status + uint32_t m_throttle_status; + + // Clock Lock Status. Each bit corresponds to clock instance + uint32_t m_gfxclk_lock_status; + + // Link width (number of lanes) and speed (in 0.1 GT/s) + uint16_t m_pcie_link_width; + uint16_t m_pcie_link_speed; // in 0.1 GT/s + + // XGMI bus width and bitrate (in Gbps) + uint16_t m_xgmi_link_width; + uint16_t m_xgmi_link_speed; + + // Utilization Accumulated (%) + uint32_t m_gfx_activity_acc; + uint32_t m_mem_activity_acc; + + // PCIE accumulated bandwidth (GB/sec) + uint64_t m_pcie_bandwidth_acc; + + // PCIE instantaneous bandwidth (GB/sec) + uint64_t m_pcie_bandwidth_inst; + + // XGMI accumulated data transfer size(KiloBytes) + uint64_t m_xgmi_read_data_acc[kRSMI_MAX_NUM_XGMI_LINKS]; + uint64_t m_xgmi_write_data_acc[kRSMI_MAX_NUM_XGMI_LINKS]; + + // PMFW attached timestamp (10ns resolution) + uint64_t m_firmware_timestamp; + + // Current clocks (Mhz) + uint16_t m_current_gfxclk[kRSMI_MAX_NUM_GFX_CLKS]; + uint16_t m_current_socclk[kRSMI_MAX_NUM_CLKS]; + uint16_t m_current_vclk0[kRSMI_MAX_NUM_CLKS]; + uint16_t m_current_dclk0[kRSMI_MAX_NUM_CLKS]; + uint16_t m_current_uclk; + + uint16_t m_padding; +}; +using AMGpuMetricsLatest_t = AMDGpuMetrics_v14_t; + + +using GPUMetricTempHbm_t = decltype(AMDGpuMetrics_v13_t::m_temperature_hbm); +using GPUMetricTempHbmTbl_t = std::array; + +using GPUMetricVcnActivity_t = decltype(AMDGpuMetrics_v14_t::m_vcn_activity); +using GPUMetricVcnActivityTbl_t = std::array; + +using GPUMetricXgmiReadDataAcc_t = decltype(AMDGpuMetrics_v14_t::m_xgmi_read_data_acc); +using GPUMetricXgmiWriteDataAcc_t = decltype(AMDGpuMetrics_v14_t::m_xgmi_write_data_acc); +using GPUMetricXgmiAccTbl_t = std::array; + +using GPUMetricCurrGfxClk_t = decltype(AMDGpuMetrics_v14_t::m_current_gfxclk); +using GPUMetricCurrGfxClkTbl_t = std::array; + +using GPUMetricCurrSocClk_t = decltype(AMDGpuMetrics_v14_t::m_current_socclk); +using GPUMetricCurrSocClkTbl_t = std::array; + +using GPUMetricCurrVClk0_t = decltype(AMDGpuMetrics_v14_t::m_current_vclk0); +using GPUMetricCurrVClkTbl_t = std::array; + +using GPUMetricCurrDClk0_t = decltype(AMDGpuMetrics_v14_t::m_current_dclk0); +using GPUMetricCurrDClkTbl_t = std::array; + + +/* + * When a new metric table is released, we have to update: * + 1. Constants related to the new metrics added; + (ie: kRSMI_MAX_NUM_XGMI_LINKS) + 2. Constants related to new version: + (ie: kRSMI_GPU_METRICS_API_CONTENT_MAJOR_VER_1) + (ie: kRSMI_GPU_METRICS_API_CONTENT_MINOR_VER_x) + (ie: kRSMI_LATEST_GPU_METRICS_API_CONTENT_MAJOR_VER) + (ie: kRSMI_LATEST_GPU_METRICS_API_CONTENT_MINOR_VER) + 3. Check if still use the same existing header or if a new one is needed: + (ie: AMDGpuMetricsHeader_v1_t) + 4. Create a new struct representing the new table format + (ie: AMDGpuMetrics_v13_t -> AMDGpuMetrics_v14_t) + 5. AMGpuMetricsLatest_t -> Newest AMDGpuMetrics_v1x_t + 6. AMDGpuMetricVersionFlags_t + (ie: AMDGpuMetricVersionFlags_t::kGpuMetricV14) +*/ + +using AMDGpuMetricTypeId_t = uint32_t; +using AMDGpuMetricTypeIdSeq_t = uint32_t; +using AMDGpuMetricVersionFlagId_t = uint32_t; + +enum class AMDGpuMetricsClassId_t : AMDGpuMetricTypeId_t +{ + kGpuMetricHeader = 0, + kGpuMetricTemperature, + kGpuMetricUtilization, + kGpuMetricPowerEnergy, + kGpuMetricSystemClockCounter, + kGpuMetricAverageClock, + kGpuMetricCurrentClock, + kGpuMetricThrottleStatus, + kGpuMetricGfxClkLockStatus, + kGpuMetricCurrentFanSpeed, + kGpuMetricLinkWidthSpeed, + kGpuMetricVoltage, + kGpuMetricTimestamp, +}; +using AMDGpuMetricsClassIdTranslationTbl_t = std::map; + +enum class AMDGpuMetricsUnitType_t : AMDGpuMetricTypeId_t +{ + // kGpuMetricTemperature counters + kMetricTempEdge, + kMetricTempHotspot, + kMetricTempMem, + kMetricTempVrGfx, + kMetricTempVrSoc, + kMetricTempVrMem, + kMetricTempHbm, + + // kGpuMetricUtilization counters + kMetricAvgGfxActivity, + kMetricAvgUmcActivity, + kMetricAvgMmActivity, + kMetricGfxActivityAccumulator, + kMetricMemActivityAccumulator, + kMetricVcnActivity, + + // kGpuMetricAverageClock counters + kMetricAvgGfxClockFrequency, + kMetricAvgSocClockFrequency, + kMetricAvgUClockFrequency, + kMetricAvgVClock0Frequency, + kMetricAvgDClock0Frequency, + kMetricAvgVClock1Frequency, + kMetricAvgDClock1Frequency, + + // kGpuMetricCurrentClock counters + kMetricCurrGfxClock, + kMetricCurrSocClock, + kMetricCurrUClock, + kMetricCurrVClock0, + kMetricCurrDClock0, + kMetricCurrVClock1, + kMetricCurrDClock1, + + // kGpuMetricThrottleStatus counters + kMetricThrottleStatus, + kMetricIndepThrottleStatus, + + // kGpuMetricGfxClkLockStatus counters + kMetricGfxClkLockStatus, + + // kGpuMetricCurrentFanSpeed counters + kMetricCurrFanSpeed, + + // kGpuMetricLinkWidthSpeed counters + kMetricPcieLinkWidth, + kMetricPcieLinkSpeed, + kMetricPcieBandwidthAccumulator, + kMetricPcieBandwidthInst, + kMetricXgmiLinkWidth, + kMetricXgmiLinkSpeed, + kMetricXgmiReadDataAccumulator, + kMetricXgmiWriteDataAccumulator, + + // kGpuMetricPowerEnergy counters + kMetricAvgSocketPower, + kMetricCurrSocketPower, + kMetricEnergyAccumulator, + + // kGpuMetricVoltage counters + kMetricVoltageSoc, + kMetricVoltageGfx, + kMetricVoltageMem, + + // kGpuMetricTimestamp counters + kMetricTSClockCounter, + kMetricTSFirmware, +}; +using AMDGpuMetricsUnitTypeTranslationTbl_t = std::map; + +using AMDGpuMetricsDataTypeId_t = uint8_t; +enum class AMDGpuMetricsDataType_t : AMDGpuMetricsDataTypeId_t +{ + kUInt8, + kUInt16, + kUInt32, + kUInt64, +}; + +struct AMDGpuDynamicMetricsValue_t +{ + uint64_t m_value; + std::string m_info; + AMDGpuMetricsDataType_t m_original_type; +}; +using AMDGpuDynamicMetricTblValues_t = std::vector; +using AMDGpuDynamicMetricsTbl_t = std::map>; + +// Note: All supported metric versions are listed her +// If not here, they are not supported +enum class AMDGpuMetricVersionFlags_t : AMDGpuMetricVersionFlagId_t +{ + kGpuMetricNone = 0x0, + kGpuMetricV10 = (0x1 << 0), + kGpuMetricV11 = (0x1 << 1), + kGpuMetricV12 = (0x1 << 2), + kGpuMetricV13 = (0x1 << 3), + kGpuMetricV14 = (0x1 << 4), +}; +using AMDGpuMetricVersionTranslationTbl_t = std::map; + + +class GpuMetricsBase_t; +using GpuMetricsBasePtr = std::shared_ptr; + +class GpuMetricsBase_t +{ + public: + virtual ~GpuMetricsBase_t() = default; + virtual size_t sizeof_metric_table() = 0; + virtual AMDGpuMetricsBaseRef get_metrics_table() = 0; + virtual AMDGpuMetricVersionFlags_t get_gpu_metrics_version_used() = 0; + virtual rsmi_status_t populate_metrics_dynamic_tbl() = 0; + + virtual AMDGpuDynamicMetricsTbl_t get_metrics_dynamic_tbl() { + return m_metrics_dynamic_tbl; + } + + protected: + AMDGpuDynamicMetricsTbl_t m_metrics_dynamic_tbl; + uint64_t m_metrics_timestamp; + +}; +using AMDGpuMetricFactories_t = std::map; + + +class GpuMetricsBase_v11_t final : public GpuMetricsBase_t +{ + public: + ~GpuMetricsBase_v11_t() = default; + + size_t sizeof_metric_table() override { + return sizeof(AMDGpuMetrics_v11_t); + } + + AMDGpuMetricsBaseRef get_metrics_table() override + { + return m_gpu_metrics_tbl; + } + + AMDGpuMetricVersionFlags_t get_gpu_metrics_version_used() override + { + return AMDGpuMetricVersionFlags_t::kGpuMetricV11; + } + + rsmi_status_t populate_metrics_dynamic_tbl() override; + + + private: + AMDGpuMetrics_v11_t m_gpu_metrics_tbl; + +}; + +class GpuMetricsBase_v12_t final : public GpuMetricsBase_t +{ + public: + ~GpuMetricsBase_v12_t() = default; + + size_t sizeof_metric_table() override { + return sizeof(AMDGpuMetrics_v12_t); + } + + AMDGpuMetricsBaseRef get_metrics_table() override + { + return m_gpu_metrics_tbl; + } + + AMDGpuMetricVersionFlags_t get_gpu_metrics_version_used() override + { + return AMDGpuMetricVersionFlags_t::kGpuMetricV12; + } + + rsmi_status_t populate_metrics_dynamic_tbl() override; + + + private: + AMDGpuMetrics_v12_t m_gpu_metrics_tbl; + +}; + +class GpuMetricsBase_v13_t final : public GpuMetricsBase_t +{ + public: + ~GpuMetricsBase_v13_t() = default; + + size_t sizeof_metric_table() override { + return sizeof(AMDGpuMetrics_v13_t); + } + + AMDGpuMetricsBaseRef get_metrics_table() override + { + return m_gpu_metrics_tbl; + } + + AMDGpuMetricVersionFlags_t get_gpu_metrics_version_used() override + { + return AMDGpuMetricVersionFlags_t::kGpuMetricV13; + } + + rsmi_status_t populate_metrics_dynamic_tbl() override; + + + private: + AMDGpuMetrics_v13_t m_gpu_metrics_tbl; + +}; + +class GpuMetricsBase_v14_t final : public GpuMetricsBase_t +{ + public: + ~GpuMetricsBase_v14_t() = default; + + size_t sizeof_metric_table() override { + return sizeof(AMDGpuMetrics_v14_t); + } + + AMDGpuMetricsBaseRef get_metrics_table() override + { + return m_gpu_metrics_tbl; + } + + AMDGpuMetricVersionFlags_t get_gpu_metrics_version_used() override + { + return AMDGpuMetricVersionFlags_t::kGpuMetricV14; + } + + rsmi_status_t populate_metrics_dynamic_tbl() override; + + + private: + AMDGpuMetrics_v14_t m_gpu_metrics_tbl; + +}; + +template +rsmi_status_t rsmi_dev_gpu_metrics_info_query(uint32_t dv_ind, AMDGpuMetricsUnitType_t metric_counter, T& metric_value); + +} // namespace amd::smi + +#endif // ROCM_SMI_ROCM_SMI_GPU_METRICS_H_ + diff --git a/rocm_smi/include/rocm_smi/rocm_smi_utils.h b/rocm_smi/include/rocm_smi/rocm_smi_utils.h index 174ae3e988..febbf5c049 100755 --- a/rocm_smi/include/rocm_smi/rocm_smi_utils.h +++ b/rocm_smi/include/rocm_smi/rocm_smi_utils.h @@ -111,6 +111,8 @@ bool isSystemBigEndian(); std::string getBuildType(); std::string getMyLibPath(); int subDirectoryCountInPath(const std::string path); +std::string monitor_type_string(amd::smi::MonitorTypes type); +std::string power_type_string(RSMI_POWER_TYPE type); template std::string print_int_as_hex(T i, bool showHexNotation=true) { std::stringstream ss; diff --git a/rocm_smi/python_smi_tools/rocm_smi.py b/rocm_smi/python_smi_tools/rocm_smi.py index 8db2d7eeea..6af7ac098b 100755 --- a/rocm_smi/python_smi_tools/rocm_smi.py +++ b/rocm_smi/python_smi_tools/rocm_smi.py @@ -43,6 +43,9 @@ JSON_DATA = {} # Version of the JSON output used to save clocks CLOCK_JSON_VERSION = 1 +# Apply max buffer to all data allocation +MAX_BUFF_SIZE = 256 + headerString = ' ROCm System Management Interface ' footerString = ' End of ROCm SMI Log ' # Output formatting @@ -529,8 +532,8 @@ def getComputePartition(device, silent=True): @param silent=Turn on to silence error output (you plan to handle manually). Default is on. """ - currentComputePartition = create_string_buffer(256) - ret = rocmsmi.rsmi_dev_compute_partition_get(device, currentComputePartition, 256) + currentComputePartition = create_string_buffer(MAX_BUFF_SIZE) + ret = rocmsmi.rsmi_dev_compute_partition_get(device, currentComputePartition, MAX_BUFF_SIZE) if rsmi_ret_ok(ret, device, 'get_compute_partition', silent) and currentComputePartition.value.decode(): return str(currentComputePartition.value.decode()) return "N/A" @@ -543,10 +546,10 @@ def getMemoryPartition(device, silent=True): @param silent=Turn on to silence error output (you plan to handle manually). Default is on. """ - currentNPSMode = create_string_buffer(256) - ret = rocmsmi.rsmi_dev_nps_mode_get(device, currentNPSMode, 256) - if rsmi_ret_ok(ret, device, 'get_NPS_mode', silent) and currentNPSMode.value.decode(): - return str(currentNPSMode.value.decode()) + currentMemoryPartition = create_string_buffer(MAX_BUFF_SIZE) + ret = rocmsmi.rsmi_dev_memory_partition_get(device, currentMemoryPartition, MAX_BUFF_SIZE) + if rsmi_ret_ok(ret, device, 'get_memory_partition', silent) and currentMemoryPartition.value.decode(): + return str(currentMemoryPartition.value.decode()) return "N/A" @@ -969,20 +972,20 @@ def resetComputePartition(deviceList): printLogSpacer() -def resetNpsMode(deviceList): - """ Reset NPS mode to its boot state +def resetMemoryPartition(deviceList): + """ Reset current memory partition to its boot state @param deviceList: List of DRM devices (can be a single-item list) """ - printLogSpacer(" Reset nps mode to its boot state ") + printLogSpacer(" Reset memory partition to its boot state ") for device in deviceList: originalPartition = getMemoryPartition(device) t1 = multiprocessing.Process(target=showProgressbar, - args=("Resetting NPS mode",13,)) + args=("Resetting memory partition",13,)) t1.start() addExtraLine=True start=time.time() - ret = rocmsmi.rsmi_dev_nps_mode_reset(device) + ret = rocmsmi.rsmi_dev_memory_partition_reset(device) stop=time.time() duration=stop-start if t1.is_alive(): @@ -990,9 +993,9 @@ def resetNpsMode(deviceList): t1.join() if duration < float(0.1): # For longer runs, add extra line before output addExtraLine=False # This is to prevent overriding progress bar - if rsmi_ret_ok(ret, device, 'reset_NPS_mode', silent=True): + if rsmi_ret_ok(ret, device, 'reset_memory_partition', silent=True): resetBootState = getMemoryPartition(device) - printLog(device, "Successfully reset nps mode (" + + printLog(device, "Successfully reset memory partition (" + originalPartition + ") to boot state (" + resetBootState + ")", None, addExtraLine) elif ret == rsmi_status_t.RSMI_STATUS_PERMISSION: @@ -1000,8 +1003,8 @@ def resetNpsMode(deviceList): elif ret == rsmi_status_t.RSMI_STATUS_NOT_SUPPORTED: printLog(device, 'Not supported on the given system', None, addExtraLine) else: - rsmi_ret_ok(ret, device, 'reset_NPS_mode') - printErrLog(device, 'Failed to reset nps mode to boot state') + rsmi_ret_ok(ret, device, 'reset_memory_partition') + printErrLog(device, 'Failed to reset memory partition to boot state') printLogSpacer() @@ -1631,29 +1634,29 @@ def showProgressbar(title="", timeInSeconds=13): time.sleep(1) -def setNPSMode(deviceList, npsMode): - """ Sets nps mode (memory partition) for a list of devices +def setMemoryPartition(deviceList, memoryPartition): + """ Sets memory partition (memory partition) for a list of devices @param deviceList: List of DRM devices (can be a single-item list) - @param npsMode: NPS Mode type to set as + @param memoryPartition: Memory Partition type to set as """ - printLogSpacer(' Set nps mode to %s ' % (str(npsMode).upper())) + printLogSpacer(' Set memory partition to %s ' % (str(memoryPartition).upper())) for device in deviceList: - npsMode = npsMode.upper() - if npsMode not in nps_mode_type_l: - printErrLog(device, 'Invalid nps mode type %s' - '\nValid nps mode types are %s' - % ( npsMode.upper(), - (', '.join(map(str, nps_mode_type_l))) )) + memoryPartition = memoryPartition.upper() + if memoryPartition not in memory_partition_type_l: + printErrLog(device, 'Invalid memory partition type %s' + '\nValid memory partition types are %s' + % ( memoryPartition.upper(), + (', '.join(map(str, memory_partition_type_l))) )) return (None, None) t1 = multiprocessing.Process(target=showProgressbar, - args=("Updating NPS mode",13,)) + args=("Updating memory partition",13,)) t1.start() addExtraLine=True start=time.time() - ret = rocmsmi.rsmi_dev_nps_mode_set(device, - rsmi_nps_mode_type_dict[npsMode]) + ret = rocmsmi.rsmi_dev_memory_partition_set(device, + rsmi_memory_partition_type_dict[memoryPartition]) stop=time.time() duration=stop-start if t1.is_alive(): @@ -1662,17 +1665,17 @@ def setNPSMode(deviceList, npsMode): if duration < float(0.1): # For longer runs, add extra line before output addExtraLine=False # This is to prevent overriding progress bar - if rsmi_ret_ok(ret, device, 'set_NPS_mode', silent=True): + if rsmi_ret_ok(ret, device, 'set_memory_partition', silent=True): printLog(device, - 'Successfully set nps mode to %s' % (npsMode), + 'Successfully set memory partition to %s' % (memoryPartition), None, addExtraLine) elif ret == rsmi_status_t.RSMI_STATUS_PERMISSION: printLog(device, 'Permission denied', None, addExtraLine) elif ret == rsmi_status_t.RSMI_STATUS_NOT_SUPPORTED: printLog(device, 'Not supported on the given system', None, addExtraLine) else: - rsmi_ret_ok(ret, device, 'set_NPS_mode') - printErrLog(device, 'Failed to retrieve NPS mode, even though device supports it.') + rsmi_ret_ok(ret, device, 'set_memory_partition') + printErrLog(device, 'Failed to retrieve memory partition, even though device supports it.') printLogSpacer() def showVersion(isCSV=False): @@ -2580,7 +2583,6 @@ def getDevProductInfo(device, silent=False): """ # Retrieve card vendor - MAX_BUFF_SIZE = 256 MAX_DESC_SIZE = 20 device_series = "N/A" device_model = "N/A" @@ -3344,22 +3346,22 @@ def showComputePartition(deviceList): printErrLog(device, 'Failed to retrieve compute partition, even though device supports it.') printLogSpacer() -def showNPSMode(deviceList): - """ Returns the current NPS mode for a list of devices +def showMemoryPartition(deviceList): + """ Returns the current memory partition for a list of devices @param deviceList: List of DRM devices (can be a single-item list) """ - npsMode = create_string_buffer(256) - printLogSpacer(' Current NPS Mode ') + memoryPartition = create_string_buffer(256) + printLogSpacer(' Current Memory Partition ') for device in deviceList: - ret = rocmsmi.rsmi_dev_nps_mode_get(device, npsMode, 256) - if rsmi_ret_ok(ret, device, 'get_NPS_mode',silent=True) and npsMode.value.decode(): - printLog(device, 'NPS Mode', npsMode.value.decode()) + ret = rocmsmi.rsmi_dev_memory_partition_get(device, memoryPartition, 256) + if rsmi_ret_ok(ret, device, 'get_memory_partition',silent=True) and memoryPartition.value.decode(): + printLog(device, 'Memory Partition', memoryPartition.value.decode()) elif ret == rsmi_status_t.RSMI_STATUS_NOT_SUPPORTED: printLog(device, 'Not supported on the given system', None) else: - rsmi_ret_ok(ret, device, 'get_NPS_mode') - printErrLog(device, 'Failed to retrieve NPS mode, even though device supports it.') + rsmi_ret_ok(ret, device, 'get_memory_partition') + printErrLog(device, 'Failed to retrieve current memory partition, even though device supports it.') printLogSpacer() @@ -3556,6 +3558,9 @@ def rsmi_ret_ok(my_ret, device=None, metric=None, silent=False): if my_ret != rsmi_status_t.RSMI_STATUS_SUCCESS: err_str = c_char_p() rocmsmi.rsmi_status_string(my_ret, byref(err_str)) + # leaving the commented out prints/logs to help identify errors in the future + # print("error string = " + str(err_str)) + # print("error string (w/ decode)= " + str(err_str.value.decode())) returnString = '' if device is not None: returnString += '%s GPU[%s]:' % (my_ret, device) @@ -3566,6 +3571,7 @@ def rsmi_ret_ok(my_ret, device=None, metric=None, silent=False): if err_str.value is not None: returnString += '%s\t' % (err_str.value.decode()) if not PRINT_JSON: + # logging.debug('%s', returnString) if not silent: logging.debug('%s', returnString) if my_ret in rsmi_status_verbose_err_out: @@ -3722,7 +3728,7 @@ if __name__ == '__main__': action='store_true') groupDisplay.add_argument('--shownodesbw', help='Shows the numa nodes ', action='store_true') groupDisplay.add_argument('--showcomputepartition', help='Shows current compute partitioning ', action='store_true') - groupDisplay.add_argument('--shownpsmode', help='Shows current NPS mode ', action='store_true') + groupDisplay.add_argument('--showmemorypartition', help='Shows current memory partition ', action='store_true') groupActionReset.add_argument('-r', '--resetclocks', help='Reset clocks and OverDrive to default', action='store_true') @@ -3734,7 +3740,7 @@ if __name__ == '__main__': groupActionReset.add_argument('--resetxgmierr', help='Reset XGMI error count', action='store_true') groupActionReset.add_argument('--resetperfdeterminism', help='Disable performance determinism', action='store_true') groupActionReset.add_argument('--resetcomputepartition', help='Resets to boot compute partition state', action='store_true') - groupActionReset.add_argument('--resetnpsmode', help='Resets to boot NPS mode state', action='store_true') + groupActionReset.add_argument('--resetmemorypartition', help='Resets to boot memory partition state', action='store_true') groupAction.add_argument('--setclock', help='Set Clock Frequency Level(s) for specified clock (requires manual Perf level)', metavar=('TYPE','LEVEL'), nargs=2) @@ -3772,8 +3778,8 @@ if __name__ == '__main__': groupAction.add_argument('--setcomputepartition', help='Set compute partition', choices=compute_partition_type_l + [x.lower() for x in compute_partition_type_l], type=str, nargs=1) - groupAction.add_argument('--setnpsmode', help='Set nps mode', - choices=nps_mode_type_l + [x.lower() for x in nps_mode_type_l], + groupAction.add_argument('--setmemorypartition', help='Set memory partition', + choices=memory_partition_type_l + [x.lower() for x in memory_partition_type_l], type=str, nargs=1) groupAction.add_argument('--rasenable', help='Enable RAS for specified block and error type', type=str, nargs=2, metavar=('BLOCK', 'ERRTYPE')) @@ -3823,7 +3829,7 @@ if __name__ == '__main__': or args.setpoweroverdrive or args.resetpoweroverdrive or args.rasenable or args.rasdisable or \ args.rasinject or args.gpureset or args.setperfdeterminism or args.setslevel or args.setmlevel or \ args.setvc or args.setsrange or args.setmrange or args.setclock or \ - args.setcomputepartition or args.setnpsmode or args.resetcomputepartition or args.resetnpsmode: + args.setcomputepartition or args.setmemorypartition or args.resetcomputepartition or args.resetmemorypartition: relaunchAsSudo() # If there is one or more device specified, use that for all commands, otherwise use a @@ -3886,7 +3892,7 @@ if __name__ == '__main__': args.showreplaycount = True args.showvc = True args.showcomputepartition = True - args.shownpsmode = True + args.showmemorypartition = True if not PRINT_JSON: args.showprofile = True @@ -4015,8 +4021,8 @@ if __name__ == '__main__': showEnergy(deviceList) if args.showcomputepartition: showComputePartition(deviceList) - if args.shownpsmode: - showNPSMode(deviceList) + if args.showmemorypartition: + showMemoryPartition(deviceList) if args.setclock: setClocks(deviceList, args.setclock[0], [int(args.setclock[1])]) if args.setsclk: @@ -4057,8 +4063,8 @@ if __name__ == '__main__': setPerfDeterminism(deviceList, args.setperfdeterminism[0]) if args.setcomputepartition: setComputePartition(deviceList, args.setcomputepartition[0]) - if args.setnpsmode: - setNPSMode(deviceList, args.setnpsmode[0]) + if args.setmemorypartition: + setMemoryPartition(deviceList, args.setmemorypartition[0]) if args.resetprofile: resetProfile(deviceList) if args.resetxgmierr: @@ -4067,8 +4073,8 @@ if __name__ == '__main__': resetPerfDeterminism(deviceList) if args.resetcomputepartition: resetComputePartition(deviceList) - if args.resetnpsmode: - resetNpsMode(deviceList) + if args.resetmemorypartition: + resetMemoryPartition(deviceList) if args.rasenable: setRas(deviceList, 'enable', args.rasenable[0], args.rasenable[1]) if args.rasdisable: diff --git a/rocm_smi/python_smi_tools/rsmiBindings.py b/rocm_smi/python_smi_tools/rsmiBindings.py index f913d99936..ee0ec76124 100644 --- a/rocm_smi/python_smi_tools/rsmiBindings.py +++ b/rocm_smi/python_smi_tools/rsmiBindings.py @@ -634,27 +634,27 @@ rsmi_compute_partition_type = rsmi_compute_partition_type_t # will return string 'CPX' compute_partition_type_l = ['CPX', 'SPX', 'DPX', 'TPX', 'QPX'] -class rsmi_nps_mode_type_t(c_int): +class rsmi_memory_partition_type_t(c_int): RSMI_MEMORY_PARTITION_UNKNOWN = 0 RSMI_MEMORY_PARTITION_NPS1 = 1 RSMI_MEMORY_PARTITION_NPS2 = 2 RSMI_MEMORY_PARTITION_NPS4 = 3 RSMI_MEMORY_PARTITION_NPS8 = 4 -rsmi_nps_mode_type_dict = { +rsmi_memory_partition_type_dict = { 'NPS1': 1, 'NPS2': 2, 'NPS4': 3, 'NPS8': 4 } -rsmi_nps_mode_type = rsmi_nps_mode_type_t +rsmi_memory_partition_type = rsmi_memory_partition_type_t -# nps_mode_type_l includes string names for the rsmi_compute_partition_type_t +# memory_partition_type_l includes string names for the rsmi_compute_partition_type_t # Usage example to get corresponding names: -# nps_mode_type_l[rsmi_nps_mode_type_t.RSMI_MEMORY_PARTITION_NPS2] +# memory_partition_type_l[rsmi_memory_partition_type_t.RSMI_MEMORY_PARTITION_NPS2] # will return string 'NPS2' -nps_mode_type_l = ['NPS1', 'NPS2', 'NPS4', 'NPS8'] +memory_partition_type_l = ['NPS1', 'NPS2', 'NPS4', 'NPS8'] class rsmi_power_label(str, Enum): AVG_POWER = '(Avg)' diff --git a/rocm_smi/src/rocm_smi.cc b/rocm_smi/src/rocm_smi.cc index cbaf9af45d..521c615016 100755 --- a/rocm_smi/src/rocm_smi.cc +++ b/rocm_smi/src/rocm_smi.cc @@ -61,12 +61,12 @@ #include #include #include -#include #include #include #include "rocm_smi/rocm_smi_common.h" // Should go before rocm_smi.h #include "rocm_smi/rocm_smi.h" +#include "rocm_smi/rocm_smi_gpu_metrics.h" #include "rocm_smi/rocm_smi_main.h" #include "rocm_smi/rocm_smi_device.h" #include "rocm_smi/rocm_smi_utils.h" @@ -77,7 +77,11 @@ #include "rocm_smi/rocm_smi64Config.h" #include "rocm_smi/rocm_smi_logger.h" -using namespace amd::smi; +using amd::smi::monitorTypesToString; +using amd::smi::getRSMIStatusString; +using amd::smi::AMDGpuMetricsUnitType_t; +using amd::smi::AMDGpuMetricTypeId_t; +auto &devInfoTypesStrings = amd::smi::RocmSMI::devInfoTypesStrings; static const uint32_t kMaxOverdriveLevel = 20; static const float kEnergyCounterResolution = 15.3F; @@ -417,7 +421,6 @@ static rsmi_status_t set_dev_mon_value(amd::smi::MonitorTypes type, if (ret == ENOENT) { return rsmi_status_t::RSMI_STATUS_NOT_SUPPORTED; } - return amd::smi::ErrnoToRsmiStatus(ret); } @@ -582,7 +585,7 @@ rsmi_status_t rsmi_dev_ecc_enabled_get(uint32_t dv_ind, if (ret != RSMI_STATUS_SUCCESS) { ss << __PRETTY_FUNCTION__ << " | ======= end =======" << ", returning get_dev_value_line() response = " - << amd::smi::getRSMIStatusString(ret); + << getRSMIStatusString(ret); LOG_ERROR(ss); return ret; } @@ -601,7 +604,7 @@ rsmi_status_t rsmi_dev_ecc_enabled_get(uint32_t dv_ind, ss << __PRETTY_FUNCTION__ << " | ======= end =======" << ", returning strtoul() response = " - << amd::smi::getRSMIStatusString(amd::smi::ErrnoToRsmiStatus(errno)); + << getRSMIStatusString(amd::smi::ErrnoToRsmiStatus(errno)); LOG_TRACE(ss); return amd::smi::ErrnoToRsmiStatus(errno); @@ -655,7 +658,7 @@ rsmi_status_t rsmi_dev_ecc_status_get(uint32_t dv_ind, rsmi_gpu_block_t block, if (ret != RSMI_STATUS_SUCCESS) { ss << __PRETTY_FUNCTION__ << " | ======= end =======" << ", returning rsmi_dev_ecc_enabled_get() response = " - << amd::smi::getRSMIStatusString(ret); + << getRSMIStatusString(ret); LOG_ERROR(ss); return ret; } @@ -716,7 +719,7 @@ rsmi_dev_ecc_count_get(uint32_t dv_ind, rsmi_gpu_block_t block, default: ss << __PRETTY_FUNCTION__ << " | ======= end =======" << ", default case -> reporting " - << amd::smi::getRSMIStatusString(RSMI_STATUS_NOT_SUPPORTED); + << getRSMIStatusString(RSMI_STATUS_NOT_SUPPORTED); LOG_ERROR(ss); return RSMI_STATUS_NOT_SUPPORTED; } @@ -736,7 +739,7 @@ rsmi_dev_ecc_count_get(uint32_t dv_ind, rsmi_gpu_block_t block, if (ret != RSMI_STATUS_SUCCESS) { ss << __PRETTY_FUNCTION__ << " | ======= end =======" << ", GetDevValueVec() ret was not RSMI_STATUS_SUCCESS" - << " -> reporting " << amd::smi::getRSMIStatusString(ret); + << " -> reporting " << getRSMIStatusString(ret); LOG_ERROR(ss); return ret; } @@ -755,7 +758,7 @@ rsmi_dev_ecc_count_get(uint32_t dv_ind, rsmi_gpu_block_t block, fs2 >> ec->correctable_err; ss << __PRETTY_FUNCTION__ << " | ======= end =======" - << ", reporting " << amd::smi::getRSMIStatusString(ret);; + << ", reporting " << getRSMIStatusString(ret);; LOG_TRACE(ss); return ret; CATCH @@ -856,7 +859,7 @@ rsmi_dev_id_get(uint32_t dv_ind, uint16_t *id) { ret = get_id(dv_ind, amd::smi::kDevDevID, id); ss << __PRETTY_FUNCTION__ << " | ======= end =======" - << ", reporting " << amd::smi::getRSMIStatusString(ret); + << ", reporting " << getRSMIStatusString(ret); LOG_TRACE(ss); return ret; } @@ -871,7 +874,7 @@ rsmi_dev_xgmi_physical_id_get(uint32_t dv_ind, uint16_t *id) { ret = get_id(dv_ind, amd::smi::kDevXGMIPhysicalID, id); ss << __PRETTY_FUNCTION__ << " | ======= end =======" - << ", reporting " << amd::smi::getRSMIStatusString(ret); + << ", reporting " << getRSMIStatusString(ret); LOG_TRACE(ss); return ret; } @@ -886,7 +889,7 @@ rsmi_dev_revision_get(uint32_t dv_ind, uint16_t *revision) { ret = get_id(dv_ind, amd::smi::kDevDevRevID, revision); outss << __PRETTY_FUNCTION__ << " | ======= end =======" - << ", reporting " << amd::smi::getRSMIStatusString(ret); + << ", reporting " << getRSMIStatusString(ret); LOG_TRACE(outss); return ret; } @@ -901,7 +904,7 @@ rsmi_dev_sku_get(uint32_t dv_ind, uint16_t *id) { CHK_SUPPORT_NAME_ONLY(id) ret = get_id(dv_ind, amd::smi::kDevDevProdNum, id); ss << __PRETTY_FUNCTION__ << " | ======= end =======" - << ", reporting " << amd::smi::getRSMIStatusString(ret); + << ", reporting " << getRSMIStatusString(ret); LOG_TRACE(ss); return ret; CATCH @@ -1926,8 +1929,8 @@ mapRSMIToStringComputePartitionTypes { {RSMI_COMPUTE_PARTITION_QPX, "QPX"} }; -std::map -mapRSMIToStringNPSModeTypes { +std::map +mapRSMIToStringMemoryPartitionTypes { {RSMI_MEMORY_PARTITION_UNKNOWN, "UNKNOWN"}, {RSMI_MEMORY_PARTITION_NPS1, "NPS1"}, {RSMI_MEMORY_PARTITION_NPS2, "NPS2"}, @@ -1935,8 +1938,8 @@ mapRSMIToStringNPSModeTypes { {RSMI_MEMORY_PARTITION_NPS8, "NPS8"} }; -std::map -mapStringToNPSModeTypes { +std::map +mapStringToMemoryPartitionTypes { {"NPS1", RSMI_MEMORY_PARTITION_NPS1}, {"NPS2", RSMI_MEMORY_PARTITION_NPS2}, {"NPS4", RSMI_MEMORY_PARTITION_NPS4}, @@ -3002,7 +3005,7 @@ rsmi_dev_current_socket_power_get(uint32_t dv_ind, uint64_t *socket_power) { rsmi_status_t rsmiReturn = RSMI_STATUS_NOT_SUPPORTED; std::string val_str; uint32_t sensor_ind = 1; // socket_power sysfs files have 1-based indices - MonitorTypes mon_type = amd::smi::kMonPowerInput; + amd::smi::MonitorTypes mon_type = amd::smi::kMonPowerInput; ss << __PRETTY_FUNCTION__ << " | ======= start =======, dv_ind=" << std::to_string(dv_ind); LOG_TRACE(ss); @@ -3069,6 +3072,58 @@ rsmi_dev_current_socket_power_get(uint32_t dv_ind, uint64_t *socket_power) { CATCH } +rsmi_status_t rsmi_dev_power_get(uint32_t dv_ind, uint64_t *power, + RSMI_POWER_TYPE *type) { + TRY + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << " | ======= start =======, dv_ind=" + << std::to_string(dv_ind); + LOG_TRACE(ss); + rsmi_status_t ret = RSMI_STATUS_NOT_SUPPORTED; + RSMI_POWER_TYPE temp_power_type = RSMI_INVALID_POWER; + uint64_t temp_power = 0; + + if (type == nullptr || power == nullptr) { + ret = RSMI_STATUS_INVALID_ARGS; + ss << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | Fail " + << " | Device #: " << dv_ind + << " | Type: " << amd::smi::power_type_string(temp_power_type) + << " | Cause: power or monitor type was a null ptr reference" + << " | Returning = " + << getRSMIStatusString(ret) << " |"; + LOG_ERROR(ss); + return ret; + } + + // only change return value on success, invalid otherwise + rsmi_status_t temp_ret = rsmi_dev_current_socket_power_get(dv_ind, &temp_power); + if (temp_ret == RSMI_STATUS_SUCCESS) { + temp_power_type = RSMI_CURRENT_POWER; + ret = temp_ret; + } else { + temp_ret = rsmi_dev_power_ave_get(dv_ind, 0, &temp_power); + if (temp_ret == RSMI_STATUS_SUCCESS) { + temp_power_type = RSMI_AVERAGE_POWER; + ret = temp_ret; + } + } + *power = temp_power; + *type = temp_power_type; + ss << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | Success " + << " | Device #: " << dv_ind + << " | Type: " << amd::smi::power_type_string(temp_power_type) + << " | Data: " << *power + << " | Returning = " + << getRSMIStatusString(ret) << " |"; + LOG_TRACE(ss); + return ret; + CATCH +} + rsmi_status_t rsmi_dev_energy_count_get(uint32_t dv_ind, uint64_t *power, float *counter_resolution, uint64_t *timestamp) { @@ -3279,7 +3334,7 @@ rsmi_dev_memory_total_get(uint32_t dv_ind, rsmi_memory_type_t mem_type, ss << __PRETTY_FUNCTION__ << " | inside success fallback... " << " | Device #: " << std::to_string(dv_ind) - << " | Type = " << RocmSMI::devInfoTypesStrings.at(mem_type_file) + << " | Type = " << devInfoTypesStrings.at(mem_type_file) << " | Data: total = " << std::to_string(*total) << " | ret = " << getRSMIStatusString(RSMI_STATUS_SUCCESS); LOG_DEBUG(ss); @@ -3290,7 +3345,7 @@ rsmi_dev_memory_total_get(uint32_t dv_ind, rsmi_memory_type_t mem_type, ss << __PRETTY_FUNCTION__ << " | after fallback... " << " | Device #: " << std::to_string(dv_ind) - << " | Type = " << RocmSMI::devInfoTypesStrings.at(mem_type_file) + << " | Type = " << devInfoTypesStrings.at(mem_type_file) << " | Data: total = " << std::to_string(*total) << " | ret = " << getRSMIStatusString(ret); LOG_DEBUG(ss); @@ -3359,7 +3414,7 @@ rsmi_dev_memory_usage_get(uint32_t dv_ind, rsmi_memory_type_t mem_type, ss << __PRETTY_FUNCTION__ << " no fallback needed! - " << " | Device #: " << std::to_string(dv_ind) - << " | Type = " << RocmSMI::devInfoTypesStrings.at(mem_type_file) + << " | Type = " << devInfoTypesStrings.at(mem_type_file) << " | Data: Used = " << std::to_string(*used) << " | Data: total = " << std::to_string(total) << " | ret = " << getRSMIStatusString(ret); @@ -3370,7 +3425,7 @@ rsmi_dev_memory_usage_get(uint32_t dv_ind, rsmi_memory_type_t mem_type, ss << __PRETTY_FUNCTION__ << " | in fallback == success ..." << " | Device #: " << std::to_string(dv_ind) - << " | Type = " << RocmSMI::devInfoTypesStrings.at(mem_type_file) + << " | Type = " << devInfoTypesStrings.at(mem_type_file) << " | Data: Used = " << std::to_string(*used) << " | Data: total = " << std::to_string(total) << " | ret = " << getRSMIStatusString(RSMI_STATUS_SUCCESS); @@ -3381,7 +3436,7 @@ rsmi_dev_memory_usage_get(uint32_t dv_ind, rsmi_memory_type_t mem_type, ss << __PRETTY_FUNCTION__ << " | at end!!!! after fallback ..." << " | Device #: " << std::to_string(dv_ind) - << " | Type = " << RocmSMI::devInfoTypesStrings.at(mem_type_file) + << " | Type = " << devInfoTypesStrings.at(mem_type_file) << " | Data: Used = " << std::to_string(*used) << " | ret = " << getRSMIStatusString(ret); LOG_DEBUG(ss); @@ -3710,7 +3765,6 @@ rsmi_dev_activity_avg_mm_get(uint32_t dv_ind, uint16_t* avg_activity) { } auto status_code(rsmi_status_t::RSMI_STATUS_SUCCESS); - auto avg_mm_activity(uint16_t(0)); rsmi_activity_metric_counter_t activity_metric_counter; status_code = rsmi_dev_activity_metric_get(dv_ind, rsmi_activity_metric_t::RSMI_ACTIVITY_MM, &activity_metric_counter); avg_activity = &activity_metric_counter.average_mm_activity; @@ -3728,7 +3782,6 @@ rsmi_dev_activity_avg_mm_get(uint32_t dv_ind, uint16_t* avg_activity) { CATCH } - rsmi_status_t rsmi_dev_vbios_version_get(uint32_t dv_ind, char *vbios, uint32_t len) { TRY @@ -4435,7 +4488,7 @@ rsmi_topo_get_link_weight(uint32_t dv_ind_src, uint32_t dv_ind_dst, rsmi_status_t rsmi_minmax_bandwidth_get(uint32_t dv_ind_src, uint32_t dv_ind_dst, - uint64_t *min_bandwidth, uint64_t *max_bandwidth){ + uint64_t *min_bandwidth, uint64_t *max_bandwidth) { TRY uint32_t dv_ind = dv_ind_src; @@ -4633,9 +4686,20 @@ rsmi_dev_compute_partition_get(uint32_t dv_ind, char *compute_partition, uint32_t len) { TRY std::ostringstream ss; - ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + ss << __PRETTY_FUNCTION__ << "| ======= start =======, dv_ind = " + << dv_ind; LOG_TRACE(ss); if ((len == 0) || (compute_partition == nullptr)) { + ss << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | Fail " + << " | Device #: " << dv_ind + << " | Type: " + << devInfoTypesStrings.at(amd::smi::kDevComputePartition) + << " | Cause: len was 0 or compute_partition variable was null" + << " | Returning = " + << getRSMIStatusString(RSMI_STATUS_INVALID_ARGS) << " |"; + LOG_ERROR(ss); return RSMI_STATUS_INVALID_ARGS; } CHK_SUPPORT_NAME_ONLY(compute_partition) @@ -4644,14 +4708,46 @@ rsmi_dev_compute_partition_get(uint32_t dv_ind, char *compute_partition, rsmi_status_t ret = get_compute_partition(dv_ind, returning_compute_partition); - if (ret != RSMI_STATUS_SUCCESS) { return ret; } + if (ret != RSMI_STATUS_SUCCESS) { + ss << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | Fail " + << " | Device #: " << dv_ind + << " | Type: " + << devInfoTypesStrings.at(amd::smi::kDevComputePartition) + << " | Cause: could not retrieve current compute partition" + << " | Returning = " + << getRSMIStatusString(ret) << " |"; + LOG_ERROR(ss); + return ret; + } std::size_t length = returning_compute_partition.copy(compute_partition, len); compute_partition[length]='\0'; if (len < (returning_compute_partition.size() + 1)) { + ss << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | Fail " + << " | Device #: " << dv_ind + << " | Type: " + << devInfoTypesStrings.at(amd::smi::kDevComputePartition) + << " | Cause: requested size was insufficient" + << " | Returning = " + << getRSMIStatusString(RSMI_STATUS_INSUFFICIENT_SIZE) << " |"; + LOG_ERROR(ss); return RSMI_STATUS_INSUFFICIENT_SIZE; } + ss << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | Success " + << " | Device #: " << dv_ind + << " | Type: " + << devInfoTypesStrings.at(amd::smi::kDevComputePartition) + << " | Data: " << compute_partition + << " | Returning = " + << getRSMIStatusString(ret) << " |"; + LOG_TRACE(ss); return ret; CATCH } @@ -4699,6 +4795,16 @@ rsmi_dev_compute_partition_set(uint32_t dv_ind, break; case RSMI_COMPUTE_PARTITION_INVALID: default: + ss << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | Fail " + << " | Device #: " << dv_ind + << " | Type: " + << devInfoTypesStrings.at(amd::smi::kDevComputePartition) + << " | Cause: requested setting was invalid" + << " | Returning = " + << getRSMIStatusString(RSMI_STATUS_INVALID_ARGS) << " |"; + LOG_ERROR(ss); return RSMI_STATUS_INVALID_ARGS; } @@ -4707,32 +4813,78 @@ rsmi_dev_compute_partition_set(uint32_t dv_ind, rsmi_status_t available_ret = is_available_compute_partition(dv_ind, newComputePartitionStr); if (available_ret != RSMI_STATUS_SUCCESS) { + ss << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | Fail " + << " | Device #: " << dv_ind + << " | Type: " + << devInfoTypesStrings.at(amd::smi::kDevComputePartition) + << " | Cause: not an available compute partition setting" + << " | Returning = " + << getRSMIStatusString(available_ret) << " |"; + LOG_ERROR(ss); return available_ret; } // do nothing if compute_partition is the current compute partition - rsmi_status_t ret_get = get_compute_partition(dv_ind, currentComputePartition); + rsmi_status_t ret_get = + get_compute_partition(dv_ind, currentComputePartition); // we can try to set, even if we get unexpected data if (ret_get != RSMI_STATUS_SUCCESS && ret_get != RSMI_STATUS_UNEXPECTED_DATA) { + ss << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | Fail " + << " | Device #: " << dv_ind + << " | Type: " + << devInfoTypesStrings.at(amd::smi::kDevComputePartition) + << " | Cause: could retrieve current compute partition or retrieved" + << " unexpected data" + << " | Returning = " + << getRSMIStatusString(ret_get) << " |"; + LOG_ERROR(ss); return ret_get; } rsmi_compute_partition_type_t currRSMIComputePartition = mapStringToRSMIComputePartitionTypes[currentComputePartition]; if (currRSMIComputePartition == compute_partition) { + ss << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | Success - compute partition was already set at requested value" + << " | Device #: " << dv_ind + << " | Type: " + << devInfoTypesStrings.at(amd::smi::kDevComputePartition) + << " | Data: " << newComputePartitionStr + << " | Returning = " + << getRSMIStatusString(RSMI_STATUS_SUCCESS) << " |"; + LOG_TRACE(ss); return RSMI_STATUS_SUCCESS; } GET_DEV_FROM_INDX int ret = dev->writeDevInfo(amd::smi::kDevComputePartition, newComputePartitionStr); - return amd::smi::ErrnoToRsmiStatus(ret); + rsmi_status_t returnResponse = amd::smi::ErrnoToRsmiStatus(ret); + ss << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | Success " + << " | Device #: " << dv_ind + << " | Type: " + << devInfoTypesStrings.at(amd::smi::kDevComputePartition) + << " | Data: " << newComputePartitionStr + << " | Returning = " + << getRSMIStatusString(returnResponse) << " |"; + LOG_TRACE(ss); + + // TODO(charpoag): investigate providing GPU busy state occurred with + return returnResponse; CATCH } -static rsmi_status_t get_nps_mode(uint32_t dv_ind, std::string &nps_mode) { +static rsmi_status_t get_memory_partition(uint32_t dv_ind, + std::string &memory_partition) { TRY - CHK_SUPPORT_NAME_ONLY(nps_mode.c_str()) + CHK_SUPPORT_NAME_ONLY(memory_partition.c_str()) std::string val_str; DEVICE_MUTEX @@ -4743,7 +4895,7 @@ static rsmi_status_t get_nps_mode(uint32_t dv_ind, std::string &nps_mode) { return ret; } - switch (mapStringToNPSModeTypes[val_str]) { + switch (mapStringToMemoryPartitionTypes[val_str]) { case RSMI_MEMORY_PARTITION_NPS1: case RSMI_MEMORY_PARTITION_NPS2: case RSMI_MEMORY_PARTITION_NPS4: @@ -4751,16 +4903,17 @@ static rsmi_status_t get_nps_mode(uint32_t dv_ind, std::string &nps_mode) { break; case RSMI_MEMORY_PARTITION_UNKNOWN: default: - // Retrieved an unknown NPS mode + // Retrieved an unknown memory partition return RSMI_STATUS_UNEXPECTED_DATA; } - nps_mode = val_str; + memory_partition = val_str; return RSMI_STATUS_SUCCESS; CATCH } rsmi_status_t -rsmi_dev_nps_mode_set(uint32_t dv_ind, rsmi_nps_mode_type_t nps_mode) { +rsmi_dev_memory_partition_set(uint32_t dv_ind, + rsmi_memory_partition_type_t memory_partition) { TRY std::ostringstream ss; ss << __PRETTY_FUNCTION__ << "| ======= start ======="; @@ -4770,7 +4923,7 @@ rsmi_dev_nps_mode_set(uint32_t dv_ind, rsmi_nps_mode_type_t nps_mode) { bool isCorrectDevice = false; char boardName[128]; boardName[0] = '\0'; - // rsmi_dev_nps_mode_set is only available for for discrete variant, + // rsmi_dev_memory_partition_set is only available for for discrete variant, // others are required to update through bios settings rsmi_dev_name_get(dv_ind, boardName, 128); std::string myBoardName = boardName; @@ -4784,14 +4937,24 @@ rsmi_dev_nps_mode_set(uint32_t dv_ind, rsmi_nps_mode_type_t nps_mode) { } if (!isCorrectDevice) { + ss << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | Fail " + << " | Device #: " << dv_ind + << " | Type: " + << devInfoTypesStrings.at(amd::smi::kDevMemoryPartition) + << " | Cause: device board name does not support this action" + << " | Returning = " + << getRSMIStatusString(RSMI_STATUS_INVALID_ARGS) << " |"; + LOG_ERROR(ss); return RSMI_STATUS_NOT_SUPPORTED; } - std::string newNPSMode - = mapRSMIToStringNPSModeTypes[nps_mode]; - std::string currentNPSMode; + std::string newMemoryPartition + = mapRSMIToStringMemoryPartitionTypes[memory_partition]; + std::string currentMemoryPartition; - switch (nps_mode) { + switch (memory_partition) { case RSMI_MEMORY_PARTITION_NPS1: case RSMI_MEMORY_PARTITION_NPS2: case RSMI_MEMORY_PARTITION_NPS4: @@ -4799,57 +4962,156 @@ rsmi_dev_nps_mode_set(uint32_t dv_ind, rsmi_nps_mode_type_t nps_mode) { break; case RSMI_MEMORY_PARTITION_UNKNOWN: default: + ss << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | Fail " + << " | Device #: " << dv_ind + << " | Type: " + << devInfoTypesStrings.at(amd::smi::kDevMemoryPartition) + << " | Cause: requested setting was invalid" + << " | Returning = " + << getRSMIStatusString(RSMI_STATUS_INVALID_ARGS) << " |"; + LOG_ERROR(ss); return RSMI_STATUS_INVALID_ARGS; } - // do nothing if nps_mode is the current NPS mode - rsmi_status_t ret_get = get_nps_mode(dv_ind, currentNPSMode); + // do nothing if memory_partition is the current mode + rsmi_status_t ret_get = get_memory_partition(dv_ind, currentMemoryPartition); // we can try to set, even if we get unexpected data if (ret_get != RSMI_STATUS_SUCCESS && ret_get != RSMI_STATUS_UNEXPECTED_DATA) { + ss << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | Fail " + << " | Device #: " << dv_ind + << " | Type: " + << devInfoTypesStrings.at(amd::smi::kDevMemoryPartition) + << " | Cause: could retrieve current memory partition or retrieved" + << " unexpected data" + << " | Returning = " + << getRSMIStatusString(ret_get) << " |"; + LOG_ERROR(ss); return ret_get; } - rsmi_nps_mode_type_t currRSMINpsMode - = mapStringToNPSModeTypes[currentNPSMode]; - if (currRSMINpsMode == nps_mode) { + rsmi_memory_partition_type_t currRSMIMemoryPartition + = mapStringToMemoryPartitionTypes[currentMemoryPartition]; + if (currRSMIMemoryPartition == memory_partition) { + ss << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | Success - no change, current memory partition was already requested" + << " setting" + << " | Device #: " << dv_ind + << " | Type: " + << devInfoTypesStrings.at(amd::smi::kDevMemoryPartition) + << " | Data: " << newMemoryPartition + << " | Returning = " + << getRSMIStatusString(RSMI_STATUS_SUCCESS) << " |"; + LOG_TRACE(ss); return RSMI_STATUS_SUCCESS; } GET_DEV_FROM_INDX - int ret = dev->writeDevInfo(amd::smi::kDevMemoryPartition, newNPSMode); + int ret = dev->writeDevInfo(amd::smi::kDevMemoryPartition, + newMemoryPartition); if (amd::smi::ErrnoToRsmiStatus(ret) != RSMI_STATUS_SUCCESS) { - return amd::smi::ErrnoToRsmiStatus(ret); + rsmi_status_t err = amd::smi::ErrnoToRsmiStatus(ret); + ss << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | Fail " + << " | Device #: " << dv_ind + << " | Type: " + << devInfoTypesStrings.at(amd::smi::kDevMemoryPartition) + << " | Cause: issue writing requested setting of " + newMemoryPartition + << " | Returning = " + << getRSMIStatusString(err) << " |"; + LOG_ERROR(ss); + return err; } - return dev->restartAMDGpuDriver(); + rsmi_status_t restartRet = dev->restartAMDGpuDriver(); + ss << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | Success - if restart completed successfully" + << " | Device #: " << dv_ind + << " | Type: " + << devInfoTypesStrings.at(amd::smi::kDevMemoryPartition) + << " | Data: " << newMemoryPartition + << " | Returning = " + << getRSMIStatusString(restartRet) << " |"; + LOG_TRACE(ss); + return restartRet; CATCH } rsmi_status_t -rsmi_dev_nps_mode_get(uint32_t dv_ind, char *nps_mode, +rsmi_dev_memory_partition_get(uint32_t dv_ind, char *memory_partition, uint32_t len) { TRY std::ostringstream ss; ss << __PRETTY_FUNCTION__ << "| ======= start ======="; LOG_TRACE(ss); - if ((len == 0) || (nps_mode == nullptr)) { + if ((len == 0) || (memory_partition == nullptr)) { + ss << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | Fail " + << " | Device #: " << dv_ind + << " | Type: " + << devInfoTypesStrings.at(amd::smi::kDevMemoryPartition) + << " | Cause: user sent invalid arguments, len = 0 or memory partition" + << " was a null ptr" + << " | Returning = " + << getRSMIStatusString(RSMI_STATUS_INVALID_ARGS) << " |"; + LOG_ERROR(ss); return RSMI_STATUS_INVALID_ARGS; } - CHK_SUPPORT_NAME_ONLY(nps_mode) + CHK_SUPPORT_NAME_ONLY(memory_partition) - std::string returning_nps_mode; - rsmi_status_t ret = get_nps_mode(dv_ind, - returning_nps_mode); + std::string returning_memory_partition; + rsmi_status_t ret = get_memory_partition(dv_ind, + returning_memory_partition); - if (ret != RSMI_STATUS_SUCCESS) { return ret; } + if (ret != RSMI_STATUS_SUCCESS) { + ss << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | Fail " + << " | Device #: " << dv_ind + << " | Type: " + << devInfoTypesStrings.at(amd::smi::kDevMemoryPartition) + << " | Cause: could not successfully retrieve current memory partition " + << " | Returning = " + << getRSMIStatusString(ret) << " |"; + LOG_ERROR(ss); + return ret; + } - std::size_t length = returning_nps_mode.copy(nps_mode, len); - nps_mode[length]='\0'; + std::size_t buff_size = + returning_memory_partition.copy(memory_partition, len); + memory_partition[buff_size] = '\0'; - if (len < (returning_nps_mode.size() + 1)) { + if (len < (returning_memory_partition.size() + 1)) { + ss << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | Fail " + << " | Device #: " << dv_ind + << " | Type: " + << devInfoTypesStrings.at(amd::smi::kDevMemoryPartition) + << " | Cause: could not successfully retrieve current memory partition " + << " | Returning = " + << getRSMIStatusString(ret) << " |"; + LOG_ERROR(ss); return RSMI_STATUS_INSUFFICIENT_SIZE; } + ss << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | Success " + << " | Device #: " << dv_ind + << " | Type: " + << devInfoTypesStrings.at(amd::smi::kDevMemoryPartition) + << " | Data: " << memory_partition + << " | Returning = " + << getRSMIStatusString(ret) << " |"; + LOG_TRACE(ss); return ret; CATCH } @@ -4863,22 +5125,37 @@ rsmi_status_t rsmi_dev_compute_partition_reset(uint32_t dv_ind) { DEVICE_MUTEX GET_DEV_FROM_INDX rsmi_status_t ret = RSMI_STATUS_NOT_SUPPORTED; - // read temp file + + // Only use 1st index, rest are there in-case of future issues + // NOTE: Partitions sets cause rocm-smi indexes to fluctuate + // since the nodes are grouped in respect to primary node - why we only use + // 1st node/device id to reset std::string bootState = - dev->readBootPartitionState(dv_ind); + dev->readBootPartitionState(0); + // Initiate reset // If bootState is UNKNOWN, we cannot reset - return RSMI_STATUS_NOT_SUPPORTED // Likely due to device not supporting it if (bootState != "UNKNOWN") { rsmi_compute_partition_type_t compute_partition = - mapStringToRSMIComputePartitionTypes[bootState]; + mapStringToRSMIComputePartitionTypes[bootState]; ret = rsmi_dev_compute_partition_set(dv_ind, compute_partition); } + ss << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | Success - if original boot state was not unknown or valid setting" + << " | Device #: " << dv_ind + << " | Type: " + << devInfoTypesStrings.at(amd::smi::kDevComputePartition) + << " | Data: " << bootState + << " | Returning = " + << getRSMIStatusString(ret) << " |"; + LOG_TRACE(ss); return ret; CATCH } -rsmi_status_t rsmi_dev_nps_mode_reset(uint32_t dv_ind) { +rsmi_status_t rsmi_dev_memory_partition_reset(uint32_t dv_ind) { TRY std::ostringstream ss; ss << __PRETTY_FUNCTION__ << "| ======= start ======="; @@ -4887,16 +5164,32 @@ rsmi_status_t rsmi_dev_nps_mode_reset(uint32_t dv_ind) { DEVICE_MUTEX GET_DEV_FROM_INDX rsmi_status_t ret = RSMI_STATUS_NOT_SUPPORTED; - // read temp file + + // Only use 1st index, rest are there in-case of future issues + // NOTE: Partitions sets cause rocm-smi indexes to fluctuate. + // Since the nodes are grouped in respect to primary node - why we only use + // 1st node/device id to reset std::string bootState = - dev->readBootPartitionState(dv_ind); + dev->readBootPartitionState(0); + // Initiate reset // If bootState is UNKNOWN, we cannot reset - return RSMI_STATUS_NOT_SUPPORTED // Likely due to device not supporting it if (bootState != "UNKNOWN") { - rsmi_nps_mode_type_t nps_mode = mapStringToNPSModeTypes[bootState]; - ret = rsmi_dev_nps_mode_set(dv_ind, nps_mode); + rsmi_memory_partition_type_t memory_partition = + mapStringToMemoryPartitionTypes[bootState]; + ret = rsmi_dev_memory_partition_set(dv_ind, memory_partition); } + ss << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | Success - if original boot state was not unknown or valid setting" + << " | Device #: " << dv_ind + << " | Type: " + << devInfoTypesStrings.at(amd::smi::kDevMemoryPartition) + << " | Data: " << bootState + << " | Returning = " + << getRSMIStatusString(ret) << " |"; + LOG_TRACE(ss); return ret; CATCH } @@ -5361,6 +5654,616 @@ rsmi_status_t rsmi_event_notification_stop(uint32_t dv_ind) { CATCH } +// +// NOTE: APIs related to new 'GPU Metrics' related work are added here +// so they can be used/tested. +// +rsmi_status_t +rsmi_dev_temp_hotspot_get(uint32_t dv_ind, uint16_t* hotspot_value) +{ + TRY + std::ostringstream ostrstream; + ostrstream << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ostrstream); + + const auto gpu_metric_unit(AMDGpuMetricsUnitType_t::kMetricTempHotspot); + auto status_code = rsmi_dev_gpu_metrics_info_query(dv_ind, gpu_metric_unit, *hotspot_value); + ostrstream << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | End Result " + << " | Device #: " << dv_ind + << " | Metric Type: " << static_cast(gpu_metric_unit) + << " | Returning = " << status_code << " " << getRSMIStatusString(status_code) << " |"; + LOG_INFO(ostrstream); + + return status_code; + CATCH +} + +rsmi_status_t +rsmi_dev_temp_mem_get(uint32_t dv_ind, uint16_t* mem_value) +{ + TRY + std::ostringstream ostrstream; + ostrstream << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ostrstream); + + const auto gpu_metric_unit(AMDGpuMetricsUnitType_t::kMetricTempMem); + auto status_code = rsmi_dev_gpu_metrics_info_query(dv_ind, gpu_metric_unit, *mem_value); + ostrstream << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | End Result " + << " | Device #: " << dv_ind + << " | Metric Type: " << static_cast(gpu_metric_unit) + << " | Returning = " << status_code << " " << getRSMIStatusString(status_code) << " |"; + LOG_INFO(ostrstream); + + return status_code; + CATCH +} + +rsmi_status_t +rsmi_dev_temp_vrsoc_get(uint32_t dv_ind, uint16_t* vrsoc_value) +{ + TRY + std::ostringstream ostrstream; + ostrstream << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ostrstream); + + const auto gpu_metric_unit(AMDGpuMetricsUnitType_t::kMetricTempVrSoc); + auto status_code = rsmi_dev_gpu_metrics_info_query(dv_ind, gpu_metric_unit, *vrsoc_value); + ostrstream << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | End Result " + << " | Device #: " << dv_ind + << " | Metric Type: " << static_cast(gpu_metric_unit) + << " | Returning = " << status_code << " " << getRSMIStatusString(status_code) << " |"; + LOG_INFO(ostrstream); + + return status_code; + CATCH +} + +rsmi_status_t +rsmi_dev_curr_socket_power_get(uint32_t dv_ind, uint16_t* socket_power_value) +{ + TRY + std::ostringstream ostrstream; + ostrstream << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ostrstream); + + const auto gpu_metric_unit(AMDGpuMetricsUnitType_t::kMetricCurrSocketPower); + auto status_code = rsmi_dev_gpu_metrics_info_query(dv_ind, gpu_metric_unit, *socket_power_value); + ostrstream << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | End Result " + << " | Device #: " << dv_ind + << " | Metric Type: " << static_cast(gpu_metric_unit) + << " | Returning = " << status_code << " " << getRSMIStatusString(status_code) << " |"; + LOG_INFO(ostrstream); + + return status_code; + CATCH +} + +rsmi_status_t +rsmi_dev_avg_gfx_activity_get(uint32_t dv_ind, uint16_t* gfx_activity_value) +{ + TRY + std::ostringstream ostrstream; + ostrstream << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ostrstream); + + const auto gpu_metric_unit(AMDGpuMetricsUnitType_t::kMetricAvgGfxActivity); + auto status_code = rsmi_dev_gpu_metrics_info_query(dv_ind, gpu_metric_unit, *gfx_activity_value); + ostrstream << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | End Result " + << " | Device #: " << dv_ind + << " | Metric Type: " << static_cast(gpu_metric_unit) + << " | Returning = " << status_code << " " << getRSMIStatusString(status_code) << " |"; + LOG_INFO(ostrstream); + + return status_code; + CATCH +} + +rsmi_status_t +rsmi_dev_avg_umc_activity_get(uint32_t dv_ind, uint16_t* umc_activity_value) +{ + TRY + std::ostringstream ostrstream; + ostrstream << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ostrstream); + + const auto gpu_metric_unit(AMDGpuMetricsUnitType_t::kMetricAvgUmcActivity); + auto status_code = rsmi_dev_gpu_metrics_info_query(dv_ind, gpu_metric_unit, *umc_activity_value); + ostrstream << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | End Result " + << " | Device #: " << dv_ind + << " | Metric Type: " << static_cast(gpu_metric_unit) + << " | Returning = " << status_code << " " << getRSMIStatusString(status_code) << " |"; + LOG_INFO(ostrstream); + + return status_code; + CATCH +} + +rsmi_status_t +rsmi_dev_energy_acc_get(uint32_t dv_ind, uint64_t* energy_acc_value) +{ + TRY + std::ostringstream ostrstream; + ostrstream << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ostrstream); + + const auto gpu_metric_unit(AMDGpuMetricsUnitType_t::kMetricEnergyAccumulator); + auto status_code = rsmi_dev_gpu_metrics_info_query(dv_ind, gpu_metric_unit, *energy_acc_value); + ostrstream << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | End Result " + << " | Device #: " << dv_ind + << " | Metric Type: " << static_cast(gpu_metric_unit) + << " | Returning = " << status_code << " " << getRSMIStatusString(status_code) << " |"; + LOG_INFO(ostrstream); + + return status_code; + CATCH +} + +rsmi_status_t +rsmi_dev_system_clock_counter_get(uint32_t dv_ind, uint64_t* system_clock_counter_value) +{ + TRY + std::ostringstream ostrstream; + ostrstream << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ostrstream); + + const auto gpu_metric_unit(AMDGpuMetricsUnitType_t::kMetricTSClockCounter); + auto status_code = rsmi_dev_gpu_metrics_info_query(dv_ind, gpu_metric_unit, *system_clock_counter_value); + ostrstream << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | End Result " + << " | Device #: " << dv_ind + << " | Metric Type: " << static_cast(gpu_metric_unit) + << " | Returning = " << status_code << " " << getRSMIStatusString(status_code) << " |"; + LOG_INFO(ostrstream); + + return status_code; + CATCH +} + +rsmi_status_t +rsmi_dev_firmware_timestamp_get(uint32_t dv_ind, uint64_t* firmware_timestamp_value) +{ + TRY + std::ostringstream ostrstream; + ostrstream << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ostrstream); + + const auto gpu_metric_unit(AMDGpuMetricsUnitType_t::kMetricTSFirmware); + auto status_code = rsmi_dev_gpu_metrics_info_query(dv_ind, gpu_metric_unit, *firmware_timestamp_value); + ostrstream << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | End Result " + << " | Device #: " << dv_ind + << " | Metric Type: " << static_cast(gpu_metric_unit) + << " | Returning = " << status_code << " " << getRSMIStatusString(status_code) << " |"; + LOG_INFO(ostrstream); + + return status_code; + CATCH +} + +rsmi_status_t +rsmi_dev_throttle_status_get(uint32_t dv_ind, uint32_t* throttle_status_value) +{ + TRY + std::ostringstream ostrstream; + ostrstream << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ostrstream); + + const auto gpu_metric_unit(AMDGpuMetricsUnitType_t::kMetricThrottleStatus); + auto status_code = rsmi_dev_gpu_metrics_info_query(dv_ind, gpu_metric_unit, *throttle_status_value); + ostrstream << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | End Result " + << " | Device #: " << dv_ind + << " | Metric Type: " << static_cast(gpu_metric_unit) + << " | Returning = " << status_code << " " << getRSMIStatusString(status_code) << " |"; + LOG_INFO(ostrstream); + + return status_code; + CATCH +} + +rsmi_status_t +rsmi_dev_pcie_link_width_get(uint32_t dv_ind, uint16_t* pcie_link_width_value) +{ + TRY + std::ostringstream ostrstream; + ostrstream << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ostrstream); + + const auto gpu_metric_unit(AMDGpuMetricsUnitType_t::kMetricPcieLinkWidth); + auto status_code = rsmi_dev_gpu_metrics_info_query(dv_ind, gpu_metric_unit, *pcie_link_width_value); + ostrstream << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | End Result " + << " | Device #: " << dv_ind + << " | Metric Type: " << static_cast(gpu_metric_unit) + << " | Returning = " << status_code << " " << getRSMIStatusString(status_code) << " |"; + LOG_INFO(ostrstream); + + return status_code; + CATCH +} + +rsmi_status_t +rsmi_dev_pcie_link_speed_get(uint32_t dv_ind, uint16_t* pcie_link_speed_value) +{ + TRY + std::ostringstream ostrstream; + ostrstream << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ostrstream); + + const auto gpu_metric_unit(AMDGpuMetricsUnitType_t::kMetricPcieLinkSpeed); + auto status_code = rsmi_dev_gpu_metrics_info_query(dv_ind, gpu_metric_unit, *pcie_link_speed_value); + ostrstream << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | End Result " + << " | Device #: " << dv_ind + << " | Metric Type: " << static_cast(gpu_metric_unit) + << " | Returning = " << status_code << " " << getRSMIStatusString(status_code) << " |"; + LOG_INFO(ostrstream); + + return status_code; + CATCH +} + +rsmi_status_t +rsmi_dev_xgmi_link_width_get(uint32_t dv_ind, uint16_t* xgmi_link_width_value) +{ + TRY + std::ostringstream ostrstream; + ostrstream << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ostrstream); + + const auto gpu_metric_unit(AMDGpuMetricsUnitType_t::kMetricXgmiLinkWidth); + auto status_code = rsmi_dev_gpu_metrics_info_query(dv_ind, gpu_metric_unit, *xgmi_link_width_value); + ostrstream << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | End Result " + << " | Device #: " << dv_ind + << " | Metric Type: " << static_cast(gpu_metric_unit) + << " | Returning = " << status_code << " " << getRSMIStatusString(status_code) << " |"; + LOG_INFO(ostrstream); + + return status_code; + CATCH +} + +rsmi_status_t +rsmi_dev_xgmi_link_speed_get(uint32_t dv_ind, uint16_t* xgmi_link_speed_value) +{ + TRY + std::ostringstream ostrstream; + ostrstream << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ostrstream); + + const auto gpu_metric_unit(AMDGpuMetricsUnitType_t::kMetricXgmiLinkSpeed); + auto status_code = rsmi_dev_gpu_metrics_info_query(dv_ind, gpu_metric_unit, *xgmi_link_speed_value); + ostrstream << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | End Result " + << " | Device #: " << dv_ind + << " | Metric Type: " << static_cast(gpu_metric_unit) + << " | Returning = " << status_code << " " << getRSMIStatusString(status_code) << " |"; + LOG_INFO(ostrstream); + + return status_code; + CATCH +} + +rsmi_status_t +rsmi_dev_gfxclk_lock_status_get(uint32_t dv_ind, uint32_t* gfxclk_lock_status_value) +{ + TRY + std::ostringstream ostrstream; + ostrstream << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ostrstream); + + const auto gpu_metric_unit(AMDGpuMetricsUnitType_t::kMetricGfxClkLockStatus); + auto status_code = rsmi_dev_gpu_metrics_info_query(dv_ind, gpu_metric_unit, *gfxclk_lock_status_value); + ostrstream << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | End Result " + << " | Device #: " << dv_ind + << " | Metric Type: " << static_cast(gpu_metric_unit) + << " | Returning = " << status_code << " " << getRSMIStatusString(status_code) << " |"; + LOG_INFO(ostrstream); + + return status_code; + CATCH +} + +rsmi_status_t +rsmi_dev_gfx_activity_acc_get(uint32_t dv_ind, uint32_t* gfx_activity_acc_value) +{ + TRY + std::ostringstream ostrstream; + ostrstream << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ostrstream); + + const auto gpu_metric_unit(AMDGpuMetricsUnitType_t::kMetricGfxActivityAccumulator); + auto status_code = rsmi_dev_gpu_metrics_info_query(dv_ind, gpu_metric_unit, *gfx_activity_acc_value); + ostrstream << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | End Result " + << " | Device #: " << dv_ind + << " | Metric Type: " << static_cast(gpu_metric_unit) + << " | Returning = " << status_code << " " << getRSMIStatusString(status_code) << " |"; + LOG_INFO(ostrstream); + + return status_code; + CATCH +} + +rsmi_status_t +rsmi_dev_mem_activity_acc_get(uint32_t dv_ind, uint32_t* mem_activity_acc_value) +{ + TRY + std::ostringstream ostrstream; + ostrstream << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ostrstream); + + const auto gpu_metric_unit(AMDGpuMetricsUnitType_t::kMetricMemActivityAccumulator); + auto status_code = rsmi_dev_gpu_metrics_info_query(dv_ind, gpu_metric_unit, *mem_activity_acc_value); + ostrstream << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | End Result " + << " | Device #: " << dv_ind + << " | Metric Type: " << static_cast(gpu_metric_unit) + << " | Returning = " << status_code << " " << getRSMIStatusString(status_code) << " |"; + LOG_INFO(ostrstream); + + return status_code; + CATCH +} + +rsmi_status_t +rsmi_dev_pcie_bandwidth_acc_get(uint32_t dv_ind, uint64_t* pcie_bandwidth_acc_value) +{ + TRY + std::ostringstream ostrstream; + ostrstream << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ostrstream); + + const auto gpu_metric_unit(AMDGpuMetricsUnitType_t::kMetricPcieBandwidthAccumulator); + auto status_code = rsmi_dev_gpu_metrics_info_query(dv_ind, gpu_metric_unit, *pcie_bandwidth_acc_value); + ostrstream << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | End Result " + << " | Device #: " << dv_ind + << " | Metric Type: " << static_cast(gpu_metric_unit) + << " | Returning = " << status_code << " " << getRSMIStatusString(status_code) << " |"; + LOG_INFO(ostrstream); + + return status_code; + CATCH +} + +rsmi_status_t +rsmi_dev_pcie_bandwidth_inst_get(uint32_t dv_ind, uint64_t* pcie_bandwidth_inst_value) +{ + TRY + std::ostringstream ostrstream; + ostrstream << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ostrstream); + + const auto gpu_metric_unit(AMDGpuMetricsUnitType_t::kMetricPcieBandwidthInst); + auto status_code = rsmi_dev_gpu_metrics_info_query(dv_ind, gpu_metric_unit, *pcie_bandwidth_inst_value); + ostrstream << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | End Result " + << " | Device #: " << dv_ind + << " | Metric Type: " << static_cast(gpu_metric_unit) + << " | Returning = " << status_code << " " << getRSMIStatusString(status_code) << " |"; + LOG_INFO(ostrstream); + + return status_code; + CATCH +} + +rsmi_status_t +rsmi_dev_curr_uclk_get(uint32_t dv_ind, uint16_t* uclk_value) +{ + TRY + std::ostringstream ostrstream; + ostrstream << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ostrstream); + + const auto gpu_metric_unit(AMDGpuMetricsUnitType_t::kMetricCurrUClock); + auto status_code = rsmi_dev_gpu_metrics_info_query(dv_ind, gpu_metric_unit, *uclk_value); + ostrstream << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | End Result " + << " | Device #: " << dv_ind + << " | Metric Type: " << static_cast(gpu_metric_unit) + << " | Returning = " << status_code << " " << getRSMIStatusString(status_code) << " |"; + LOG_INFO(ostrstream); + + return status_code; + CATCH +} + +rsmi_status_t +rsmi_dev_vcn_activity_get(uint32_t dv_ind, amd::smi::GPUMetricVcnActivityTbl_t* vcn_activity_value) +{ + TRY + std::ostringstream ostrstream; + ostrstream << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ostrstream); + + const auto gpu_metric_unit(AMDGpuMetricsUnitType_t::kMetricVcnActivity); + amd::smi::GPUMetricVcnActivityTbl_t tmp_vcn_activity_value; + *vcn_activity_value = tmp_vcn_activity_value; + auto status_code(rsmi_status_t::RSMI_STATUS_SUCCESS); + ostrstream << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | End Result " + << " | Device #: " << dv_ind + << " | Metric Type: " << static_cast(gpu_metric_unit) + << " | Returning = " << status_code << " " << getRSMIStatusString(status_code) << " |"; + LOG_INFO(ostrstream); + return status_code; + CATCH +} + +rsmi_status_t +rsmi_dev_xgmi_read_data_get(uint32_t dv_ind, amd::smi::GPUMetricXgmiAccTbl_t* xgmi_read_data_acc_value) +{ + TRY + std::ostringstream ostrstream; + ostrstream << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ostrstream); + + const auto gpu_metric_unit(AMDGpuMetricsUnitType_t::kMetricVcnActivity); + amd::smi::GPUMetricXgmiAccTbl_t tmp_xgmi_read_data_acc_value; + *xgmi_read_data_acc_value = tmp_xgmi_read_data_acc_value; + auto status_code(rsmi_status_t::RSMI_STATUS_SUCCESS); + ostrstream << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | End Result " + << " | Device #: " << dv_ind + << " | Metric Type: " << static_cast(gpu_metric_unit) + << " | Returning = " << status_code << " " << getRSMIStatusString(status_code) << " |"; + LOG_INFO(ostrstream); + return status_code; + CATCH +} + +rsmi_status_t +rsmi_dev_xgmi_write_data_get(uint32_t dv_ind, amd::smi::GPUMetricXgmiAccTbl_t* xgmi_write_data_acc_value) +{ + TRY + std::ostringstream ostrstream; + ostrstream << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ostrstream); + + const auto gpu_metric_unit(AMDGpuMetricsUnitType_t::kMetricVcnActivity); + amd::smi::GPUMetricXgmiAccTbl_t tmp_xgmi_write_data_acc_value; + *xgmi_write_data_acc_value = tmp_xgmi_write_data_acc_value; + auto status_code(rsmi_status_t::RSMI_STATUS_SUCCESS); + ostrstream << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | End Result " + << " | Device #: " << dv_ind + << " | Metric Type: " << static_cast(gpu_metric_unit) + << " | Returning = " << status_code << " " << getRSMIStatusString(status_code) << " |"; + LOG_INFO(ostrstream); + return status_code; + CATCH +} + +rsmi_status_t +rsmi_dev_curr_gfxclk_get(uint32_t dv_ind, amd::smi::GPUMetricCurrGfxClkTbl_t* current_gfxclk_value) +{ + TRY + std::ostringstream ostrstream; + ostrstream << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ostrstream); + + const auto gpu_metric_unit(AMDGpuMetricsUnitType_t::kMetricVcnActivity); + amd::smi::GPUMetricCurrGfxClkTbl_t tmp_current_gfxclk_value; + *current_gfxclk_value = tmp_current_gfxclk_value; + auto status_code(rsmi_status_t::RSMI_STATUS_SUCCESS); + ostrstream << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | End Result " + << " | Device #: " << dv_ind + << " | Metric Type: " << static_cast(gpu_metric_unit) + << " | Returning = " << status_code << " " << getRSMIStatusString(status_code) << " |"; + LOG_INFO(ostrstream); + return status_code; + CATCH +} + +rsmi_status_t +rsmi_dev_curr_socclk_get(uint32_t dv_ind, amd::smi::GPUMetricCurrSocClkTbl_t* current_socclk_value) +{ + TRY + std::ostringstream ostrstream; + ostrstream << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ostrstream); + + const auto gpu_metric_unit(AMDGpuMetricsUnitType_t::kMetricVcnActivity); + amd::smi::GPUMetricCurrSocClkTbl_t tmp_current_socclk_value; + *current_socclk_value = tmp_current_socclk_value; + auto status_code(rsmi_status_t::RSMI_STATUS_SUCCESS); + ostrstream << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | End Result " + << " | Device #: " << dv_ind + << " | Metric Type: " << static_cast(gpu_metric_unit) + << " | Returning = " << status_code << " " << getRSMIStatusString(status_code) << " |"; + LOG_INFO(ostrstream); + return status_code; + CATCH +} + +rsmi_status_t +rsmi_dev_curr_vclk0_get(uint32_t dv_ind, amd::smi::GPUMetricCurrVClkTbl_t* current_vclk_value) +{ + TRY + std::ostringstream ostrstream; + ostrstream << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ostrstream); + + const auto gpu_metric_unit(AMDGpuMetricsUnitType_t::kMetricVcnActivity); + amd::smi::GPUMetricCurrVClkTbl_t tmp_current_vclk_value; + *current_vclk_value = tmp_current_vclk_value; + auto status_code(rsmi_status_t::RSMI_STATUS_SUCCESS); + ostrstream << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | End Result " + << " | Device #: " << dv_ind + << " | Metric Type: " << static_cast(gpu_metric_unit) + << " | Returning = " << status_code << " " << getRSMIStatusString(status_code) << " |"; + LOG_INFO(ostrstream); + return status_code; + CATCH +} + +rsmi_status_t +rsmi_dev_curr_vdlk0_get(uint32_t dv_ind, amd::smi::GPUMetricCurrDClkTbl_t* current_dclk_value) +{ + TRY + std::ostringstream ostrstream; + ostrstream << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ostrstream); + + const auto gpu_metric_unit(AMDGpuMetricsUnitType_t::kMetricVcnActivity); + amd::smi::GPUMetricCurrDClkTbl_t tmp_current_dclk_value; + *current_dclk_value = tmp_current_dclk_value; + auto status_code(rsmi_status_t::RSMI_STATUS_SUCCESS); + ostrstream << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | End Result " + << " | Device #: " << dv_ind + << " | Metric Type: " << static_cast(gpu_metric_unit) + << " | Returning = " << status_code << " " << getRSMIStatusString(status_code) << " |"; + LOG_INFO(ostrstream); + return status_code; + CATCH +} + +// +// End of: new GPU Metrics related work. +// + + // UNDOCUMENTED FUNCTIONS // This functions are not declared in rocm_smi.h. They are either not fully // supported, or to be used for test purposes. @@ -5395,3 +6298,4 @@ rsmi_test_refcount(uint64_t refcnt_type) { return static_cast(smi.ref_count()); } + diff --git a/rocm_smi/src/rocm_smi_device.cc b/rocm_smi/src/rocm_smi_device.cc index 572ade8f35..85aebef6f4 100755 --- a/rocm_smi/src/rocm_smi_device.cc +++ b/rocm_smi/src/rocm_smi_device.cc @@ -1328,7 +1328,7 @@ template rsmi_status_t storeParameter(uint32_t dv_ind); // Uses template specialization, to restrict types to identify // calls needed to complete the function. // typename - restricted to -// rsmi_compute_partition_type_t or rsmi_compute_partition_type_t +// rsmi_compute_partition_type_t or rsmi_memory_partition_type_t // dv_ind - device index // tempFileName - base file name template <> @@ -1342,9 +1342,9 @@ rsmi_status_t storeParameter(uint32_t dv_ind) { if (doesFileExist) { return returnStatus; } - uint32_t length = 128; - char data[length]; - rsmi_status_t ret = rsmi_dev_compute_partition_get(dv_ind, data, length); + const uint32_t kLen = 128; + char data[kLen]; + rsmi_status_t ret = rsmi_dev_compute_partition_get(dv_ind, data, kLen); rsmi_status_t storeRet; if (ret == RSMI_STATUS_SUCCESS) { @@ -1368,31 +1368,32 @@ rsmi_status_t storeParameter(uint32_t dv_ind) { // Uses template specialization, to restrict types to identify // calls needed to complete the function. // typename - restricted to -// rsmi_compute_partition_type_t or rsmi_compute_partition_type_t +// rsmi_compute_partition_type_t or rsmi_memory_partition_type_t // dv_ind - device index // tempFileName - base file name -template <> rsmi_status_t storeParameter(uint32_t dv_ind) { +template <> +rsmi_status_t storeParameter(uint32_t dv_ind) { rsmi_status_t returnStatus = RSMI_STATUS_SUCCESS; - uint32_t length = 128; - char data[length]; + uint32_t kDatalength = 128; + char data[kDatalength]; bool doesFileExist; std::tie(doesFileExist, std::ignore) = readTmpFile(dv_ind, "boot", - "nps_mode"); + "memory_partition"); // if temporary file exists -> we do not need to store anything new // if not, read & store the state value if (doesFileExist) { return returnStatus; } - rsmi_status_t ret = rsmi_dev_nps_mode_get(dv_ind, data, length); + rsmi_status_t ret = rsmi_dev_memory_partition_get(dv_ind, data, kDatalength); rsmi_status_t storeRet; if (ret == RSMI_STATUS_SUCCESS) { - storeRet = storeTmpFile(dv_ind, "nps_mode", "boot", data); + storeRet = storeTmpFile(dv_ind, "memory_partition", "boot", data); } else if (ret == RSMI_STATUS_NOT_SUPPORTED) { // not supported is ok - storeRet = storeTmpFile(dv_ind, "nps_mode", "boot", "UNKNOWN"); + storeRet = storeTmpFile(dv_ind, "memory_partition", "boot", "UNKNOWN"); } else { - storeRet = storeTmpFile(dv_ind, "nps_mode", "boot", "UNKNOWN"); + storeRet = storeTmpFile(dv_ind, "memory_partition", "boot", "UNKNOWN"); returnStatus = ret; } @@ -1406,9 +1407,9 @@ template <> rsmi_status_t storeParameter(uint32_t dv_ind) rsmi_status_t Device::storeDevicePartitions(uint32_t dv_ind) { rsmi_status_t returnStatus = RSMI_STATUS_SUCCESS; returnStatus = storeParameter(dv_ind); - rsmi_status_t npsRet = storeParameter(dv_ind); - if (returnStatus == RSMI_STATUS_SUCCESS) { // only record earliest error - returnStatus = npsRet; + rsmi_status_t ret = storeParameter(dv_ind); + if (returnStatus == RSMI_STATUS_SUCCESS) { // only record earliest error + returnStatus = ret; } return returnStatus; } @@ -1437,10 +1438,11 @@ std::string Device::readBootPartitionState( // or rsmi_compute_partition_type_t // dv_ind - device index template <> -std::string Device::readBootPartitionState( +std::string Device::readBootPartitionState( uint32_t dv_ind) { std::string boot_state; - std::tie(std::ignore, boot_state) = readTmpFile(dv_ind, "boot", "nps_mode"); + std::tie(std::ignore, boot_state) = readTmpFile(dv_ind, "boot", + "memory_partition"); return boot_state; } diff --git a/rocm_smi/src/rocm_smi_gpu_metrics.cc b/rocm_smi/src/rocm_smi_gpu_metrics.cc index 13fc58fc1a..e8aa54eef9 100755 --- a/rocm_smi/src/rocm_smi_gpu_metrics.cc +++ b/rocm_smi/src/rocm_smi_gpu_metrics.cc @@ -41,26 +41,34 @@ * */ +#include "rocm_smi/rocm_smi_gpu_metrics.h" +#include "rocm_smi/rocm_smi_common.h" // Should go before rocm_smi.h +#include "rocm_smi/rocm_smi.h" +#include "rocm_smi/rocm_smi_main.h" +#include "rocm_smi/rocm_smi_utils.h" +#include "rocm_smi/rocm_smi_exception.h" +#include "rocm_smi/rocm_smi_device.h" +#include "rocm_smi/rocm_smi_logger.h" + #include #include #include #include +#include #include #include #include #include #include +#include #include // NOLINT #include +#include +#include +#include #include -#include "rocm_smi/rocm_smi_common.h" // Should go before rocm_smi.h -#include "rocm_smi/rocm_smi_main.h" -#include "rocm_smi/rocm_smi_utils.h" -#include "rocm_smi/rocm_smi_exception.h" -#include "rocm_smi/rocm_smi_logger.h" - using namespace amd::smi; #define TRY try { @@ -526,3 +534,1097 @@ rsmi_dev_gpu_metrics_info_get(uint32_t dv_ind, rsmi_gpu_metrics_t *smu) { return ret; CATCH } + + +namespace amd::smi +{ + +constexpr uint16_t join_metrics_version(uint8_t format_rev, uint8_t content_rev) +{ + return (format_rev << 8 | content_rev); +} + +constexpr uint16_t join_metrics_version(const AMDGpuMetricsHeader_v1_t& metrics_header) +{ + return join_metrics_version(metrics_header.m_format_revision, metrics_header.m_content_revision); +} + +AMDGpuMetricsHeader_v1_t disjoin_metrics_version(uint16_t version) +{ + AMDGpuMetricsHeader_v1_t metrics_header; + + metrics_header.m_format_revision = static_cast((version & 0xFF00) >> 8); + metrics_header.m_content_revision = static_cast(version & 0x00FF); + + return metrics_header; +} + +uint64_t actual_timestamp_in_secs() +{ + using namespace std::chrono; + return duration_cast(system_clock::now().time_since_epoch()).count(); +} + +std::string stringfy_metrics_header(const AMDGpuMetricsHeader_v1_t& metrics_header) +{ + std::stringstream metrics_header_info; + metrics_header_info + << "Format: " << print_unsigned_hex_and_int(metrics_header.m_format_revision) + << "." << print_unsigned_hex_and_int(metrics_header.m_content_revision) + << " Size: " << print_unsigned_hex_and_int(metrics_header.m_structure_size); + + return metrics_header_info.str(); +} + +// +// version 1,0: 256 +// version 1,1: 257 +// version 1,2: 258 +// version 1,3: 259 +// version 1,4: 260 +// version 1,5: 261 +// +const AMDGpuMetricVersionTranslationTbl_t amdgpu_metric_version_translation_table +{ + {join_metrics_version(1, 1), AMDGpuMetricVersionFlags_t::kGpuMetricV11}, + {join_metrics_version(1, 2), AMDGpuMetricVersionFlags_t::kGpuMetricV12}, + {join_metrics_version(1, 3), AMDGpuMetricVersionFlags_t::kGpuMetricV13}, + {join_metrics_version(1, 4), AMDGpuMetricVersionFlags_t::kGpuMetricV14}, +}; + +/** + * +*/ +const AMDGpuMetricsClassIdTranslationTbl_t amdgpu_metrics_class_id_translation_table +{ + {AMDGpuMetricsClassId_t::kGpuMetricHeader, "Header"}, + {AMDGpuMetricsClassId_t::kGpuMetricTemperature, "Temperature"}, + {AMDGpuMetricsClassId_t::kGpuMetricUtilization, "Utilization"}, + {AMDGpuMetricsClassId_t::kGpuMetricPowerEnergy, "Power/Energy"}, + {AMDGpuMetricsClassId_t::kGpuMetricSystemClockCounter, "System Clock"}, + {AMDGpuMetricsClassId_t::kGpuMetricAverageClock, "Average Clock"}, + {AMDGpuMetricsClassId_t::kGpuMetricCurrentClock, "Current Clock"}, + {AMDGpuMetricsClassId_t::kGpuMetricThrottleStatus, "Throttle"}, + {AMDGpuMetricsClassId_t::kGpuMetricGfxClkLockStatus, "Gfx Clock Lock"}, + {AMDGpuMetricsClassId_t::kGpuMetricCurrentFanSpeed, "Current Fan Speed"}, + {AMDGpuMetricsClassId_t::kGpuMetricLinkWidthSpeed, "Link/Bandwidth/Speed"}, + {AMDGpuMetricsClassId_t::kGpuMetricVoltage, "Voltage"}, + {AMDGpuMetricsClassId_t::kGpuMetricTimestamp, "Timestamp"}, +}; + +const AMDGpuMetricsUnitTypeTranslationTbl_t amdgpu_metrics_unit_type_translation_table +{ + // kGpuMetricTemperature counters + {AMDGpuMetricsUnitType_t::kMetricTempEdge, "TempEdge"}, + {AMDGpuMetricsUnitType_t::kMetricTempHotspot, "TempHotspot"}, + {AMDGpuMetricsUnitType_t::kMetricTempMem, "TempMem"}, + {AMDGpuMetricsUnitType_t::kMetricTempVrGfx, "TempVrGfx"}, + {AMDGpuMetricsUnitType_t::kMetricTempVrSoc, "TempVrSoc"}, + {AMDGpuMetricsUnitType_t::kMetricTempVrMem, "TempVrMem"}, + {AMDGpuMetricsUnitType_t::kMetricTempHbm, "TempHbm"}, + + // kGpuMetricUtilization counters + {AMDGpuMetricsUnitType_t::kMetricAvgGfxActivity, "AvgGfxActivity"}, + {AMDGpuMetricsUnitType_t::kMetricAvgUmcActivity, "AvgUmcActivity"}, + {AMDGpuMetricsUnitType_t::kMetricAvgMmActivity, "AvgMmActivity"}, + {AMDGpuMetricsUnitType_t::kMetricGfxActivityAccumulator, "GfxActivityAcc"}, + {AMDGpuMetricsUnitType_t::kMetricMemActivityAccumulator, "MemActivityAcc"}, + {AMDGpuMetricsUnitType_t::kMetricVcnActivity, "VcnActivity"}, + + // kGpuMetricAverageClock counters + {AMDGpuMetricsUnitType_t::kMetricAvgGfxClockFrequency, "AvgGfxClockFrequency"}, + {AMDGpuMetricsUnitType_t::kMetricAvgSocClockFrequency, "AvgSocClockFrequency"}, + {AMDGpuMetricsUnitType_t::kMetricAvgUClockFrequency, "AvgUClockFrequency"}, + {AMDGpuMetricsUnitType_t::kMetricAvgVClock0Frequency, "AvgVClock0Frequency"}, + {AMDGpuMetricsUnitType_t::kMetricAvgDClock0Frequency, "AvgDClock0Frequency"}, + {AMDGpuMetricsUnitType_t::kMetricAvgVClock1Frequency, "AvgVClock1Frequency"}, + {AMDGpuMetricsUnitType_t::kMetricAvgDClock1Frequency, "AvgDClock1Frequency"}, + + // kGpuMetricCurrentClock counters + {AMDGpuMetricsUnitType_t::kMetricCurrGfxClock, "CurrGfxClock"}, + {AMDGpuMetricsUnitType_t::kMetricCurrSocClock, "CurrSocClock"}, + {AMDGpuMetricsUnitType_t::kMetricCurrUClock, "CurrUClock"}, + {AMDGpuMetricsUnitType_t::kMetricCurrVClock0, "CurrVClock0"}, + {AMDGpuMetricsUnitType_t::kMetricCurrDClock0, "CurrDClock0"}, + {AMDGpuMetricsUnitType_t::kMetricCurrVClock1, "CurrVClock1"}, + {AMDGpuMetricsUnitType_t::kMetricCurrDClock1, "CurrDClock1"}, + + // kGpuMetricThrottleStatus counters + {AMDGpuMetricsUnitType_t::kMetricThrottleStatus, "ThrottleStatus"}, + {AMDGpuMetricsUnitType_t::kMetricIndepThrottleStatus, "IndepThrottleStatus"}, + + // kGpuMetricGfxClkLockStatus counters + {AMDGpuMetricsUnitType_t::kMetricGfxClkLockStatus, "GfxClkLockStatus"}, + + // kGpuMetricCurrentFanSpeed counters + {AMDGpuMetricsUnitType_t::kMetricCurrFanSpeed, "CurrFanSpeed"}, + + // kGpuMetricLinkWidthSpeed counters + {AMDGpuMetricsUnitType_t::kMetricPcieLinkWidth, "PcieLinkWidth"}, + {AMDGpuMetricsUnitType_t::kMetricPcieLinkSpeed, "PcieLinkSpeed"}, + {AMDGpuMetricsUnitType_t::kMetricPcieBandwidthAccumulator, "PcieBandwidthAcc"}, + {AMDGpuMetricsUnitType_t::kMetricPcieBandwidthInst, "PcieBandwidthInst"}, + {AMDGpuMetricsUnitType_t::kMetricXgmiLinkWidth, "XgmiLinkWidth"}, + {AMDGpuMetricsUnitType_t::kMetricXgmiLinkSpeed, "XgmiLinkSpeed"}, + {AMDGpuMetricsUnitType_t::kMetricXgmiReadDataAccumulator, "XgmiReadDataAcc"}, + {AMDGpuMetricsUnitType_t::kMetricXgmiWriteDataAccumulator, "XgmiWriteDataAcc"}, + + // kGpuMetricPowerEnergy counters + {AMDGpuMetricsUnitType_t::kMetricAvgSocketPower, "AvgSocketPower"}, + {AMDGpuMetricsUnitType_t::kMetricCurrSocketPower, "CurrSocketPower"}, + {AMDGpuMetricsUnitType_t::kMetricEnergyAccumulator, "EnergyAcc"}, + + // kGpuMetricVoltage counters + {AMDGpuMetricsUnitType_t::kMetricVoltageSoc, "VoltageSoc"}, + {AMDGpuMetricsUnitType_t::kMetricVoltageGfx, "VoltageGfx"}, + {AMDGpuMetricsUnitType_t::kMetricVoltageMem, "VoltageMem"}, + + // kGpuMetricTimestamp counters + {AMDGpuMetricsUnitType_t::kMetricTSClockCounter, "TSClockCounter"}, + {AMDGpuMetricsUnitType_t::kMetricTSFirmware, "TSFirmware"}, +}; + + +AMDGpuMetricVersionFlags_t translate_header_to_flag_version(const AMDGpuMetricsHeader_v1_t& metrics_header) +{ + const auto flag_version = join_metrics_version(metrics_header); + if (amdgpu_metric_version_translation_table.find(flag_version) != amdgpu_metric_version_translation_table.end()) { + return amdgpu_metric_version_translation_table.at(flag_version); + } + + return AMDGpuMetricVersionFlags_t::kGpuMetricNone; +} + +rsmi_status_t is_gpu_metrics_version_supported(const AMDGpuMetricsHeader_v1_t& metrics_header) +{ + const auto flag_version = join_metrics_version(metrics_header); + return (amdgpu_metric_version_translation_table.find(flag_version) != + amdgpu_metric_version_translation_table.end()) + ? rsmi_status_t::RSMI_STATUS_SUCCESS : rsmi_status_t::RSMI_STATUS_NOT_SUPPORTED; +} + +struct AMDGpuMetricsLogInfo_t +{ + rsmi_status_t m_status_code; + std::string m_title; + std::string m_pretty_function; +}; + +class AMDGpuMetricsLogger_t +{ + public: + enum class LogInfoType_t + { + kLogError, + kLogAlarm, + kLogInfo, + kLogBuffer, + kLogTrace, + kLogDebug, + }; + + void operator()(const AMDGpuMetricsLogInfo_t& log_info) + { + m_ostrstream << log_info.m_pretty_function << log_info.m_title; + LOG_TRACE(m_ostrstream); + + m_ostrstream << log_info.m_pretty_function + << " | ======= end ======= " + << " | Fail " + << " | Device #: " + << " | Metric Version: " + << " | Cause: Couldn't get a valid metric object" + << " | Returning = " + << getRSMIStatusString(log_info.m_status_code) + << " |"; + + LOG_ERROR(m_ostrstream); + } + + private: + std::ostringstream m_ostrstream; + +}; + + +AMDGpuMetricFactories_t amd_gpu_metrics_factory_table +{ + {AMDGpuMetricVersionFlags_t::kGpuMetricV11, std::make_unique(GpuMetricsBase_v11_t{})}, + {AMDGpuMetricVersionFlags_t::kGpuMetricV12, std::make_unique(GpuMetricsBase_v12_t{})}, + {AMDGpuMetricVersionFlags_t::kGpuMetricV13, std::make_unique(GpuMetricsBase_v13_t{})}, + {AMDGpuMetricVersionFlags_t::kGpuMetricV14, std::make_unique(GpuMetricsBase_v14_t{})}, +}; + +GpuMetricsBasePtr amdgpu_metrics_factory(AMDGpuMetricVersionFlags_t gpu_metric_version) +{ + auto contains = [](const AMDGpuMetricVersionFlags_t metric_version) { + return (amd_gpu_metrics_factory_table.find(metric_version) != amd_gpu_metrics_factory_table.end()); + }; + + if (contains(gpu_metric_version)) { + return std::move(amd_gpu_metrics_factory_table[gpu_metric_version]); + } + + return nullptr; +} + +template +AMDGpuDynamicMetricTblValues_t format_metric_row(const T& metric, const std::string& value_title) +{ + auto multi_values = AMDGpuDynamicMetricTblValues_t{}; + + auto get_data_type_info = [&]() { + auto data_type(AMDGpuMetricsDataType_t::kUInt64); + if constexpr (std::is_array_v) { + const uint8_t check_uint8[]={1}; + const uint16_t check_uint16[]={2}; + const uint32_t check_uint32[]={3}; + const uint64_t check_uint64[]={4}; + if constexpr (std::is_same_v) { + data_type = AMDGpuMetricsDataType_t::kUInt8; + } + if constexpr (std::is_same_v) { + data_type = AMDGpuMetricsDataType_t::kUInt16; + } + if constexpr (std::is_same_v) { + data_type = AMDGpuMetricsDataType_t::kUInt32; + } + if constexpr (std::is_same_v) { + data_type = AMDGpuMetricsDataType_t::kUInt64; + } + return std::make_tuple(data_type, static_cast(std::end(metric) - std::begin(metric))); + } + + const uint16_t kSingleValue(1); + if constexpr (std::is_same_v) { + data_type = AMDGpuMetricsDataType_t::kUInt8; + } + if constexpr (std::is_same_v) { + data_type = AMDGpuMetricsDataType_t::kUInt16; + } + if constexpr (std::is_same_v) { + data_type = AMDGpuMetricsDataType_t::kUInt32; + } + if constexpr (std::is_same_v) { + data_type = AMDGpuMetricsDataType_t::kUInt64; + } + return std::make_tuple(data_type, kSingleValue); + }; + + const auto [data_type, num_values] = get_data_type_info(); + for (auto idx = uint16_t(0); idx < num_values; ++idx) { + auto value = uint64_t(0); + if constexpr (std::is_array_v) { + value = (metric[idx]); + } + else { + value = (metric); + } + + auto amdgpu_dynamic_metric_value = [&]() { + AMDGpuDynamicMetricsValue_t amdgpu_dynamic_metric_value_init{}; + amdgpu_dynamic_metric_value_init.m_value = value; + amdgpu_dynamic_metric_value_init.m_info = (value_title + " : " + std::to_string(idx)); + amdgpu_dynamic_metric_value_init.m_original_type = data_type; + return amdgpu_dynamic_metric_value_init; + }(); + + multi_values.emplace_back(amdgpu_dynamic_metric_value); + } + + return multi_values; +} + +rsmi_status_t GpuMetricsBase_v14_t::populate_metrics_dynamic_tbl() +{ + // Temperature Info + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricTemperature] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricTempHotspot, + format_metric_row(m_gpu_metrics_tbl.m_temperature_hotspot, + "temperature_hotspot")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricTemperature] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricTempHotspot, + format_metric_row(m_gpu_metrics_tbl.m_temperature_hotspot, + "temperature_hotspot")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricTemperature] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricTempMem, + format_metric_row(m_gpu_metrics_tbl.m_temperature_mem, + "temperature_mem")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricTemperature] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricTempVrSoc, + format_metric_row(m_gpu_metrics_tbl.m_temperature_vrsoc, + "temperature_vrsoc")) + ); + + // Power/Energy Info + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricPowerEnergy] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricCurrSocketPower, + format_metric_row(m_gpu_metrics_tbl.m_curr_socket_power, + "curr_socket_power")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricPowerEnergy] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricEnergyAccumulator, + format_metric_row(m_gpu_metrics_tbl.m_energy_accumulator, + "energy_acc")) + ); + + // Utilization Info + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricUtilization] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricAvgGfxActivity, + format_metric_row(m_gpu_metrics_tbl.m_average_gfx_activity, + "average_gfx_activity")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricUtilization] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricAvgUmcActivity, + format_metric_row(m_gpu_metrics_tbl.m_average_umc_activity, + "average_umc_activity")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricUtilization] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricVcnActivity, + format_metric_row(m_gpu_metrics_tbl.m_vcn_activity, + "[average_vcn_activity]")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricUtilization] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricGfxActivityAccumulator, + format_metric_row(m_gpu_metrics_tbl.m_gfx_activity_acc, + "gfx_activity_acc")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricUtilization] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricMemActivityAccumulator, + format_metric_row(m_gpu_metrics_tbl.m_mem_activity_acc, + "mem_activity_acc")) + ); + + // Timestamp Info + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricTimestamp] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricTSFirmware, + format_metric_row(m_gpu_metrics_tbl.m_firmware_timestamp, + "firmware_timestamp")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricTimestamp] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricTSClockCounter, + format_metric_row(m_gpu_metrics_tbl.m_system_clock_counter, + "system_clock_counter")) + ); + + // Throttle Info + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricThrottleStatus] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricThrottleStatus, + format_metric_row(m_gpu_metrics_tbl.m_throttle_status, + "throttle_status")) + ); + + // GfxLock Info + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricGfxClkLockStatus] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricGfxClkLockStatus, + format_metric_row(m_gpu_metrics_tbl.m_gfxclk_lock_status, + "gfxclk_lock_status")) + ); + + // Link/Width/Speed Info + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricLinkWidthSpeed] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricPcieLinkWidth, + format_metric_row(m_gpu_metrics_tbl.m_pcie_link_width, + "pcie_link_width")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricLinkWidthSpeed] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricPcieLinkSpeed, + format_metric_row(m_gpu_metrics_tbl.m_pcie_link_speed, + "pcie_link_speed")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricLinkWidthSpeed] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricXgmiLinkWidth, + format_metric_row(m_gpu_metrics_tbl.m_xgmi_link_width, + "xgmi_link_width")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricLinkWidthSpeed] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricXgmiLinkSpeed, + format_metric_row(m_gpu_metrics_tbl.m_xgmi_link_speed, + "xgmi_link_speed")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricLinkWidthSpeed] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricPcieBandwidthAccumulator,\ + format_metric_row(m_gpu_metrics_tbl.m_pcie_bandwidth_acc, + "pcie_bandwidth_acc")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricLinkWidthSpeed] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricPcieBandwidthInst, + format_metric_row(m_gpu_metrics_tbl.m_pcie_bandwidth_acc, + "pcie_bandwidth_inst")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricLinkWidthSpeed] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricXgmiReadDataAccumulator, + format_metric_row(m_gpu_metrics_tbl.m_xgmi_read_data_acc, + "[xgmi_read_data_acc]")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricLinkWidthSpeed] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricXgmiWriteDataAccumulator, + format_metric_row(m_gpu_metrics_tbl.m_xgmi_write_data_acc, + "[xgmi_write_data_acc]")) + ); + + // CurrentClock Info + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricCurrentClock] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricCurrGfxClock, + format_metric_row(m_gpu_metrics_tbl.m_current_gfxclk, + "[current_gfxclk]")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricCurrentClock] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricCurrSocClock, + format_metric_row(m_gpu_metrics_tbl.m_current_socclk, + "[current_socclk]")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricCurrentClock] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricCurrVClock0, + format_metric_row(m_gpu_metrics_tbl.m_current_vclk0, + "[current_vclk0]")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricCurrentClock] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricCurrDClock0, + format_metric_row(m_gpu_metrics_tbl.m_current_dclk0, + "[current_dclk0]")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricCurrentClock] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricCurrUClock, + format_metric_row(m_gpu_metrics_tbl.m_current_uclk, + "current_uclk")) + ); + + return rsmi_status_t::RSMI_STATUS_SUCCESS; +} + +rsmi_status_t GpuMetricsBase_v13_t::populate_metrics_dynamic_tbl() +{ + // Temperature Info + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricTemperature] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricTempEdge, + format_metric_row(m_gpu_metrics_tbl.m_temperature_edge, + "temperature_edge")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricTemperature] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricTempHotspot, + format_metric_row(m_gpu_metrics_tbl.m_temperature_hotspot, + "temperature_hotspot")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricTemperature] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricTempMem, + format_metric_row(m_gpu_metrics_tbl.m_temperature_mem, + "temperature_mem")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricTemperature] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricTempVrGfx, + format_metric_row(m_gpu_metrics_tbl.m_temperature_vrgfx, + "temperature_vrgfx")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricTemperature] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricTempVrSoc, + format_metric_row(m_gpu_metrics_tbl.m_temperature_vrsoc, + "temperature_vrsoc")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricTemperature] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricTempVrMem, + format_metric_row(m_gpu_metrics_tbl.m_temperature_vrmem, + "temperature_vrmem")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricTemperature] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricTempHbm, + format_metric_row(m_gpu_metrics_tbl.m_temperature_hbm, + "[temperature_hbm]")) + ); + + // Power/Energy Info + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricPowerEnergy] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricAvgSocketPower, + format_metric_row(m_gpu_metrics_tbl.m_average_socket_power, + "average_socket_power")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricPowerEnergy] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricEnergyAccumulator, + format_metric_row(m_gpu_metrics_tbl.m_energy_accumulator, + "energy_acc")) + ); + + // Utilization Info + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricUtilization] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricAvgGfxActivity, + format_metric_row(m_gpu_metrics_tbl.m_average_gfx_activity, + "average_gfx_activity")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricUtilization] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricAvgUmcActivity, + format_metric_row(m_gpu_metrics_tbl.m_average_umc_activity, + "average_umc_activity")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricUtilization] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricAvgMmActivity, + format_metric_row(m_gpu_metrics_tbl.m_average_mm_activity, + "average_mm_activity")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricUtilization] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricGfxActivityAccumulator, + format_metric_row(m_gpu_metrics_tbl.m_gfx_activity_acc, + "gfx_activity_acc")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricUtilization] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricMemActivityAccumulator, + format_metric_row(m_gpu_metrics_tbl.m_mem_activity_acc, + "mem_activity_acc")) + ); + + // Timestamp Info + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricTimestamp] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricTSFirmware, + format_metric_row(m_gpu_metrics_tbl.m_firmware_timestamp, + "firmware_timestamp")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricTimestamp] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricTSClockCounter, + format_metric_row(m_gpu_metrics_tbl.m_system_clock_counter, + "system_clock_counter")) + ); + + // Fan Info + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricCurrentFanSpeed] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricCurrFanSpeed, + format_metric_row(m_gpu_metrics_tbl.m_current_fan_speed, + "current_fan_speed")) + ); + + // Throttle Info + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricThrottleStatus] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricThrottleStatus, + format_metric_row(m_gpu_metrics_tbl.m_throttle_status, + "throttle_status")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricThrottleStatus] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricIndepThrottleStatus, + format_metric_row(m_gpu_metrics_tbl.m_indep_throttle_status, + "indep_throttle_status")) + ); + + // Average Info + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricAverageClock] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricAvgGfxClockFrequency, + format_metric_row(m_gpu_metrics_tbl.m_average_gfxclk_frequency, + "average_gfxclk_frequency")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricAverageClock] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricAvgSocClockFrequency, + format_metric_row(m_gpu_metrics_tbl.m_average_socclk_frequency, + "average_socclk_frequency")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricAverageClock] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricAvgUClockFrequency, + format_metric_row(m_gpu_metrics_tbl.m_average_uclk_frequency, + "average_uclk_frequency")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricAverageClock] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricAvgVClock0Frequency, + format_metric_row(m_gpu_metrics_tbl.m_average_vclk0_frequency, + "average_vclk0_frequency")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricAverageClock] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricAvgDClock0Frequency, + format_metric_row(m_gpu_metrics_tbl.m_average_dclk0_frequency, + "average_dclk0_frequency")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricAverageClock] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricAvgVClock1Frequency, + format_metric_row(m_gpu_metrics_tbl.m_average_vclk1_frequency, + "average_vclk1_frequency")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricAverageClock] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricAvgDClock1Frequency, + format_metric_row(m_gpu_metrics_tbl.m_average_dclk1_frequency, + "average_dclk1_frequency")) + ); + + // CurrentClock Info + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricCurrentClock] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricCurrGfxClock, + format_metric_row(m_gpu_metrics_tbl.m_current_gfxclk, + "current_gfxclk")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricCurrentClock] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricCurrSocClock, + format_metric_row(m_gpu_metrics_tbl.m_current_socclk, + "current_socclk")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricCurrentClock] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricCurrUClock, + format_metric_row(m_gpu_metrics_tbl.m_current_uclk, + "current_uclk")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricCurrentClock] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricCurrVClock0, + format_metric_row(m_gpu_metrics_tbl.m_current_vclk0, + "current_vclk0")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricCurrentClock] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricCurrDClock0, + format_metric_row(m_gpu_metrics_tbl.m_current_dclk0, + "current_dclk0")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricCurrentClock] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricCurrVClock1, + format_metric_row(m_gpu_metrics_tbl.m_current_vclk1, + "current_vclk1")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricCurrentClock] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricCurrDClock1, + format_metric_row(m_gpu_metrics_tbl.m_current_dclk1, + "current_dclk1")) + ); + + // Link/Width/Speed Info + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricLinkWidthSpeed] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricPcieLinkWidth, + format_metric_row(m_gpu_metrics_tbl.m_pcie_link_width, + "pcie_link_width")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricLinkWidthSpeed] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricPcieLinkSpeed, + format_metric_row(m_gpu_metrics_tbl.m_pcie_link_speed, + "pcie_link_speed")) + ); + + // Voltage Info + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricVoltage] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricVoltageSoc, + format_metric_row(m_gpu_metrics_tbl.m_voltage_soc, + "voltage_soc")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricVoltage] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricVoltageGfx, + format_metric_row(m_gpu_metrics_tbl.m_voltage_gfx, + "voltage_gfx")) + ); + m_metrics_dynamic_tbl[AMDGpuMetricsClassId_t::kGpuMetricVoltage] + .insert(std::make_pair(AMDGpuMetricsUnitType_t::kMetricVoltageMem, + format_metric_row(m_gpu_metrics_tbl.m_voltage_mem, + "voltage_mem")) + ); + + return rsmi_status_t::RSMI_STATUS_SUCCESS; +} + +rsmi_status_t GpuMetricsBase_v12_t::populate_metrics_dynamic_tbl() +{ + // TODO: Implement these; + return rsmi_status_t::RSMI_STATUS_NOT_YET_IMPLEMENTED; +} + +rsmi_status_t GpuMetricsBase_v11_t::populate_metrics_dynamic_tbl() +{ + // TODO: Implement these; + return rsmi_status_t::RSMI_STATUS_NOT_YET_IMPLEMENTED; +} + + +rsmi_status_t Device::dev_read_gpu_metrics_header_data() +{ + std::ostringstream ostrstream; + auto status_code(rsmi_status_t::RSMI_STATUS_SUCCESS); + ostrstream << __PRETTY_FUNCTION__ << " | ======= start ======="; + LOG_TRACE(ostrstream); + + // Check if/when metrics table needs to be refreshed. + auto now_ts = actual_timestamp_in_secs(); + if (((!m_gpu_metrics_header.m_structure_size) || + (!m_gpu_metrics_header.m_format_revision) || + (!m_gpu_metrics_header.m_content_revision)) || + ((now_ts - m_gpu_metrics_updated_timestamp) >= + kRSMI_GPU_METRICS_EXPIRATION_SECS)) { + auto op_result = readDevInfo(DevInfoTypes::kDevGpuMetrics, + sizeof(AMDGpuMetricsHeader_v1_t), + &m_gpu_metrics_header); + if ((status_code = ErrnoToRsmiStatus(op_result)) != + rsmi_status_t::RSMI_STATUS_SUCCESS) { + ostrstream << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | Fail " + << " | Device #: " << index() + << " | Metric Version: " << stringfy_metrics_header(m_gpu_metrics_header) + << " | Cause: readDevInfo(kDevGpuMetrics)" + << " | Returning = " + << getRSMIStatusString(status_code) + << " Could not read Metrics Header: " + << print_unsigned_int(m_gpu_metrics_header.m_structure_size) + << " |"; + LOG_ERROR(ostrstream); + return status_code; + } + if ((status_code = is_gpu_metrics_version_supported(m_gpu_metrics_header)) == + rsmi_status_t::RSMI_STATUS_NOT_SUPPORTED) { + ostrstream << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | Fail " + << " | Device #: " << index() + << " | Metric Version: " << stringfy_metrics_header(m_gpu_metrics_header) + << " | Cause: gpu metric file version is not supported: " + << " | Returning = " + << getRSMIStatusString(status_code) + << " Could not read Metrics Header: " + << print_unsigned_int(m_gpu_metrics_header.m_structure_size) + << " |"; + LOG_ERROR(ostrstream); + return status_code; + } + + m_gpu_metrics_updated_timestamp = actual_timestamp_in_secs(); + } + + ostrstream << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | Success " + << " | Device #: " << index() + << " | Metric Version: " << stringfy_metrics_header(m_gpu_metrics_header) + << " | Update Timestamp: " << m_gpu_metrics_updated_timestamp + << " | Returning = " + << getRSMIStatusString(status_code) + << " |"; + LOG_TRACE(ostrstream); + return status_code; +} + +rsmi_status_t Device::dev_read_gpu_metrics_all_data() +{ + std::ostringstream ostrstream; + auto status_code(rsmi_status_t::RSMI_STATUS_SUCCESS); + ostrstream << __PRETTY_FUNCTION__ << " | ======= start ======="; + LOG_TRACE(ostrstream); + + // At this point we should have a valid gpu_metrics pointer. + if (!m_gpu_metrics_ptr) { + status_code = rsmi_status_t::RSMI_STATUS_UNEXPECTED_DATA; + ostrstream << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | Fail " + << " | Device #: " << index() + << " | Metric Version: " << stringfy_metrics_header(dev_get_metrics_header()) + << " | Cause: Couldn't get a valid metric object" + << " | Returning = " + << getRSMIStatusString(status_code) + << " |"; + LOG_ERROR(ostrstream); + return status_code; + } + + auto op_result = readDevInfo(DevInfoTypes::kDevGpuMetrics, + m_gpu_metrics_ptr->sizeof_metric_table(), + &m_gpu_metrics_ptr->get_metrics_table()); + if ((status_code = ErrnoToRsmiStatus(op_result)) != + rsmi_status_t::RSMI_STATUS_SUCCESS) { + ostrstream << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | Fail " + << " | Device #: " << index() + << " | Metric Version: " << stringfy_metrics_header(m_gpu_metrics_header) + << " | Cause: readDevInfo(kDevGpuMetrics)" + << " | Returning = " + << getRSMIStatusString(status_code) + << " Could not read Metrics Header: " + << print_unsigned_int(m_gpu_metrics_header.m_structure_size) + << " |"; + LOG_ERROR(ostrstream); + return status_code; + } + + m_gpu_metrics_updated_timestamp = actual_timestamp_in_secs(); + ostrstream << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | Success " + << " | Device #: " << index() + << " | Metric Version: " << stringfy_metrics_header(m_gpu_metrics_header) + << " | Update Timestamp: " << m_gpu_metrics_updated_timestamp + << " | Returning = " + << getRSMIStatusString(status_code) + << " |"; + LOG_TRACE(ostrstream); + return status_code; +} + +rsmi_status_t Device::setup_gpu_metrics_reading() +{ + std::ostringstream ostrstream; + auto status_code(rsmi_status_t::RSMI_STATUS_SUCCESS); + ostrstream << __PRETTY_FUNCTION__ << " | ======= start ======="; + LOG_TRACE(ostrstream); + + status_code = dev_read_gpu_metrics_header_data(); + if (status_code != rsmi_status_t::RSMI_STATUS_SUCCESS) { + return status_code; + } + + const auto gpu_metrics_flag_version = translate_header_to_flag_version(dev_get_metrics_header()); + if (gpu_metrics_flag_version == AMDGpuMetricVersionFlags_t::kGpuMetricNone) { + status_code = rsmi_status_t::RSMI_STATUS_NOT_SUPPORTED; + ostrstream << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | Fail " + << " | Device #: " << index() + << " | Metric Version: " << stringfy_metrics_header(dev_get_metrics_header()) + << " | [Translates to: " << join_metrics_version(dev_get_metrics_header()) + << " ] " + << " | Cause: Metric version found is not supported!" + << " | Returning = " + << getRSMIStatusString(status_code) + << " |"; + LOG_ERROR(ostrstream); + return status_code; + } + + auto gpu_metrics_ptr = amdgpu_metrics_factory(gpu_metrics_flag_version); + if (!gpu_metrics_ptr) { + status_code = rsmi_status_t::RSMI_STATUS_UNEXPECTED_DATA; + ostrstream << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | Fail " + << " | Device #: " << index() + << " | Metric Version: " << stringfy_metrics_header(dev_get_metrics_header()) + << " | Cause: amdgpu_metrics_factory() couldn't get a valid metric object" + << " | Returning = " + << getRSMIStatusString(status_code) + << " |"; + LOG_ERROR(ostrstream); + return status_code; + } + + /// gpu_metrics_ptr has the pointer to the proper object type/version. + dev_set_gpu_metric(gpu_metrics_ptr); + status_code = dev_read_gpu_metrics_all_data(); + if (status_code != rsmi_status_t::RSMI_STATUS_SUCCESS) { + ostrstream << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | Fail " + << " | Device #: " << index() + << " | Metric Version: " << stringfy_metrics_header(dev_get_metrics_header()) + << " | Cause: dev_read_gpu_metrics_all_data() couldn't read gpu metric data!" + << " | Returning = " + << getRSMIStatusString(status_code) + << " |"; + LOG_ERROR(ostrstream); + return status_code; + } + + return status_code; +} + +rsmi_status_t Device::dev_log_gpu_metrics() +{ + std::ostringstream ostrstream; + auto status_code(rsmi_status_t::RSMI_STATUS_SUCCESS); + ostrstream << __PRETTY_FUNCTION__ << " | ======= start ======="; + LOG_TRACE(ostrstream); + + // At this point we should have a valid gpu_metrics pointer. + if (!m_gpu_metrics_ptr) { + status_code = rsmi_status_t::RSMI_STATUS_UNEXPECTED_DATA; + ostrstream << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | Fail " + << " | Device #: " << index() + << " | Metric Version: " << stringfy_metrics_header(dev_get_metrics_header()) + << " | Cause: Couldn't get a valid metric object" + << " | Returning = " + << getRSMIStatusString(status_code) + << " |"; + LOG_ERROR(ostrstream); + return status_code; + } + + // Header info + auto header_output = [&]() { + const auto gpu_metrics_header = dev_get_metrics_header(); + ostrstream << "GPU Metrics Header: \n"; + ostrstream << "Timestamp: " << m_gpu_metrics_updated_timestamp << "\n"; + ostrstream << "Based on: " << static_cast(m_gpu_metrics_ptr->get_gpu_metrics_version_used()) << "\n"; + ostrstream << print_unsigned_hex_and_int(gpu_metrics_header.m_structure_size, " ->structure_size "); + ostrstream << print_unsigned_hex_and_int(gpu_metrics_header.m_format_revision, " ->format_revision "); + ostrstream << print_unsigned_hex_and_int(gpu_metrics_header.m_content_revision, " ->content_revision "); + LOG_DEBUG(ostrstream); + return; + }; + + auto table_content_output = [&]() { + const auto gpu_metrics_tbl = m_gpu_metrics_ptr->get_metrics_dynamic_tbl(); + + ostrstream << "GPU Metrics Data: \n"; + for (const auto& [metric_class, metric_data] : gpu_metrics_tbl) { + ostrstream << amdgpu_metrics_class_id_translation_table.at(metric_class) << "\n"; + + for (const auto& [metric_unit, metric_values] : metric_data) { + for (const auto& metric_value : metric_values) { + ostrstream << print_unsigned_hex_and_int(metric_value.m_value, metric_value.m_info); + } + } + } + return; + }; + + // + header_output(); + table_content_output(); + + return status_code; +} + +rsmi_status_t Device::run_internal_gpu_metrics_query(AMDGpuMetricsUnitType_t metric_counter, AMDGpuDynamicMetricTblValues_t& values) +{ + std::ostringstream ostrstream; + auto status_code(rsmi_status_t::RSMI_STATUS_NOT_FOUND); + ostrstream << __PRETTY_FUNCTION__ << " | ======= start ======="; + LOG_TRACE(ostrstream); + + status_code = setup_gpu_metrics_reading(); + if (status_code != rsmi_status_t::RSMI_STATUS_SUCCESS) { + return status_code; + } + + if (!m_gpu_metrics_ptr) { + status_code = rsmi_status_t::RSMI_STATUS_UNEXPECTED_DATA; + ostrstream << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | Fail " + << " | Device #: " << index() + << " | Metric Version: " << stringfy_metrics_header(dev_get_metrics_header()) + << " | Cause: Couldn't get a valid metric object" + << " | Returning = " + << getRSMIStatusString(status_code) + << " |"; + LOG_ERROR(ostrstream); + return status_code; + } + + // Lookup the dynamic table + const auto gpu_metrics_tbl = m_gpu_metrics_ptr->get_metrics_dynamic_tbl(); + for (const auto& [metric_class, metric_data] : gpu_metrics_tbl) { + for (const auto& [metric_unit, metric_values] : metric_data) { + if (metric_unit == metric_counter) { + values = metric_values; + return rsmi_status_t::RSMI_STATUS_SUCCESS; + } + } + } + + return status_code; +} + + +template struct is_vector : std::false_type {}; +template struct is_vector> : std::true_type {}; +template inline constexpr bool is_vector_v = is_vector::value; + +template struct is_array : std::false_type {}; +template struct is_array> : std::true_type {}; + +template struct is_bounded_uint8_array : std::false_type {}; +template struct is_bounded_uint16_array : std::false_type {}; +template struct is_bounded_uint32_array : std::false_type {}; +template struct is_bounded_uint64_array : std::false_type {}; + +template +struct is_bounded_uint8_array : std::true_type {}; + +template +struct is_bounded_uint16_array : std::true_type {}; + +template +struct is_bounded_uint32_array : std::true_type {}; + +template +struct is_bounded_uint64_array : std::true_type {}; + +template struct is_bounded_array : std::false_type {}; + +template +struct is_bounded_array : std::true_type {}; + + +template +rsmi_status_t rsmi_dev_gpu_metrics_info_query(uint32_t dv_ind, AMDGpuMetricsUnitType_t metric_counter, T& metric_value) +{ + std::ostringstream ostrstream; + auto status_code(rsmi_status_t::RSMI_STATUS_SUCCESS); + ostrstream << __PRETTY_FUNCTION__ << " | ======= start ======="; + LOG_TRACE(ostrstream); + + AMDGpuDynamicMetricTblValues_t tmp_values{}; + GET_DEV_FROM_INDX + status_code = dev->run_internal_gpu_metrics_query(metric_counter, tmp_values); + if ((status_code != rsmi_status_t::RSMI_STATUS_SUCCESS) || tmp_values.empty()) { + ostrstream << __PRETTY_FUNCTION__ + << " | ======= end ======= " + << " | Fail " + << " | Device #: " << dv_ind + << " | Metric Version: " << stringfy_metrics_header(dev->dev_get_metrics_header()) + << " | Cause: Couldn't find metric/counter requested" + << " | Metric Type: " << static_cast(metric_counter) + << " " << amdgpu_metrics_unit_type_translation_table.at(metric_counter) + << " | Values: " << tmp_values.size() + << " | Returning = " + << getRSMIStatusString(status_code) + << " |"; + LOG_ERROR(ostrstream); + return status_code; + } + + const auto num_stored_elems = (std::end(tmp_values) - std::begin(tmp_values)); + if constexpr (std::is_array_v) { + std::variant tmp_value; + auto idx = uint16_t(0); + for (const auto& value : tmp_values) { + tmp_value = value.m_value; + idx++; + switch (value.m_original_type) { + case AMDGpuMetricsDataType_t::kUInt8: + metric_value[idx] = std::get(tmp_value); + break; + + case AMDGpuMetricsDataType_t::kUInt16: + metric_value[idx] = std::get(tmp_value); + break; + + case AMDGpuMetricsDataType_t::kUInt32: + metric_value[idx] = std::get(tmp_value); + break; + + case AMDGpuMetricsDataType_t::kUInt64: + metric_value[idx] = std::get(tmp_value); + break; + + default: + break; + } + + metric_value[idx++] = tmp_value; + } + } + if constexpr ((std::is_same_v) || (std::is_same_v) || + (std::is_same_v) || (std::is_same_v)) { + T tmp_value(0); + tmp_value = static_cast(tmp_values[0].m_value); + metric_value = tmp_value; + } + + return status_code; +} + + +template +rsmi_status_t rsmi_dev_gpu_metrics_info_query(uint32_t dv_ind, AMDGpuMetricsUnitType_t metric_counter, uint8_t& metric_value); + +template +rsmi_status_t rsmi_dev_gpu_metrics_info_query(uint32_t dv_ind, AMDGpuMetricsUnitType_t metric_counter, uint16_t& metric_value); + +template +rsmi_status_t rsmi_dev_gpu_metrics_info_query(uint32_t dv_ind, AMDGpuMetricsUnitType_t metric_counter, uint32_t& metric_value); + +template +rsmi_status_t rsmi_dev_gpu_metrics_info_query(uint32_t dv_ind, AMDGpuMetricsUnitType_t metric_counter, uint64_t& metric_value); + + +} //namespace amd::smi diff --git a/rocm_smi/src/rocm_smi_kfd.cc b/rocm_smi/src/rocm_smi_kfd.cc index 00c7404711..39e5e4791b 100755 --- a/rocm_smi/src/rocm_smi_kfd.cc +++ b/rocm_smi/src/rocm_smi_kfd.cc @@ -56,6 +56,7 @@ #include #include #include +#include #include "rocm_smi/rocm_smi_io_link.h" #include "rocm_smi/rocm_smi_kfd.h" @@ -202,6 +203,7 @@ int ReadKFDDeviceProperties(uint32_t kfd_node_id, int ret; std::ifstream fs; std::string properties_path; + std::ostringstream ss; assert(retVec != nullptr); @@ -211,9 +213,14 @@ int ReadKFDDeviceProperties(uint32_t kfd_node_id, return ret; } + ss << __PRETTY_FUNCTION__ << " | properties file contains = {"; while (std::getline(fs, line)) { retVec->push_back(line); + ss << line << ",\n"; } + ss << "}"; + // Leaving below to debug any future properties file changes + // LOG_DEBUG(ss); if (retVec->empty()) { fs.close(); @@ -635,15 +642,20 @@ int KFDNode::ReadProperties(void) { } std::string key_str; - // std::string val_str; + std::string val_str; uint64_t val_int; // Assume all properties are unsigned integers for now std::istringstream fs; + std::ostringstream ss; for (const auto & i : propVec) { fs.str(i); fs >> key_str; - fs >> val_int; - + fs >> val_str; + // Leaving below to debug any new properties file changes + // ss << __PRETTY_FUNCTION__ << " | key = " << key_str + // << "; val = " << val_str; + // LOG_TRACE(ss); + val_int = std::stoull(val_str); properties_[key_str] = val_int; fs.str(""); diff --git a/rocm_smi/src/rocm_smi_main.cc b/rocm_smi/src/rocm_smi_main.cc index bed19c3f36..3b7293cd49 100755 --- a/rocm_smi/src/rocm_smi_main.cc +++ b/rocm_smi/src/rocm_smi_main.cc @@ -59,6 +59,7 @@ #include #include #include +#include #include "rocm_smi/rocm_smi.h" #include "rocm_smi/rocm_smi_device.h" @@ -783,7 +784,7 @@ uint32_t RocmSMI::DiscoverAmdgpuDevices(void) { myNode.s_node_id = node_id; myNode.s_gpu_id = gpu_id; myNode.s_unique_id = unique_id; - if(gpu_id != 0) { // only add gpu nodes, 0 = CPU + if (gpu_id != 0) { // only add gpu nodes, 0 = CPU allSystemNodes.emplace(unique_id, myNode); } } else { @@ -793,93 +794,119 @@ uint32_t RocmSMI::DiscoverAmdgpuDevices(void) { } ss << __PRETTY_FUNCTION__ << " | Ordered system nodes found = {"; - for(auto i: allSystemNodes) { + for (auto i : allSystemNodes) { ss << "\n[node_id = " << std::to_string(i.second.s_node_id) << "; gpu_id = " << std::to_string(i.second.s_gpu_id) << "; unique_id = " << std::to_string(i.second.s_unique_id) - << "], " - ; + << "], "; } ss << "}"; LOG_DEBUG(ss); + uint32_t cardAdded = 0; // Discover all root cards & gpu partitions associated with each - for (uint32_t node_id = 0; node_id < count; node_id++) { + for (uint32_t cardId = 0; cardId < count; cardId++) { std::string path = kPathDRMRoot; path += "/card"; - path += std::to_string(node_id); + path += std::to_string(cardId); uint64_t primary_unique_id = 0; // each identified gpu card node is a primary node for // potential matching unique ids if (isAMDGPU(path) || - (init_options_ & RSMI_INIT_FLAG_ALL_GPUS)) { - std::string d_name = "card"; - d_name += std::to_string(node_id); - AddToDeviceList(d_name); + (init_options_ & RSMI_INIT_FLAG_ALL_GPUS)) { + std::string d_name = "card"; + d_name += std::to_string(cardId); + AddToDeviceList(d_name); - ss << __PRETTY_FUNCTION__ - << " | Ordered system nodes seen in lookup = {"; - for (auto i : allSystemNodes) { - ss << "\n[node_id = " << std::to_string(i.second.s_node_id) - << "; gpu_id = " << std::to_string(i.second.s_gpu_id) - << "; unique_id = " << std::to_string(i.second.s_unique_id) - << "], "; - } - ss << "}"; - LOG_DEBUG(ss); + ss << __PRETTY_FUNCTION__ + << " | Ordered system nodes seen in lookup = {"; + for (auto i : allSystemNodes) { + ss << "\n[node_id = " << std::to_string(i.second.s_node_id) + << "; gpu_id = " << std::to_string(i.second.s_gpu_id) + << "; unique_id = " << std::to_string(i.second.s_unique_id) + << "], "; + } + ss << "}"; + LOG_DEBUG(ss); - uint64_t temp_primary_unique_id = 0; - if (allSystemNodes.empty()) { - continue; - } + uint64_t temp_primary_unique_id = 0; + if (allSystemNodes.empty()) { + cardAdded++; + ss << __PRETTY_FUNCTION__ + << " | allSystemNodes.empty() = true, continue..."; + LOG_DEBUG(ss); + continue; + } - // get lowest key 1st to keep order of nodes matching card - uint32_t lowest_NodeId = 0; - uint32_t curr_NodeId = 0; + // get current partition + const int kSize = 256; + char computePartition[kSize]; + std::string strCompPartition = "UNKNOWN"; + uint32_t numMonDevices = 0; + rsmi_num_monitor_devices(&numMonDevices); + if (rsmi_dev_compute_partition_get(cardAdded, computePartition, kSize) + == RSMI_STATUS_SUCCESS) { + strCompPartition = computePartition; + } + uint64_t device_uuid = 0; + if (rsmi_dev_unique_id_get(cardAdded, &device_uuid) + != RSMI_STATUS_SUCCESS) { + cardAdded++; + allSystemNodes.erase(device_uuid); + ss << __PRETTY_FUNCTION__ + << " | rsmi_dev_unique_id_get(cardId, &device_uuid)" + << " was not successful, continue.. "; + LOG_DEBUG(ss); + continue; + } - for (auto it = allSystemNodes.begin(), end = allSystemNodes.end(); - it != end; it = allSystemNodes.upper_bound(it->first)) { - curr_NodeId = it->second.s_node_id; - if (it == allSystemNodes.begin()) { - lowest_NodeId = it->second.s_node_id; - } - if (curr_NodeId <= lowest_NodeId) { - lowest_NodeId = curr_NodeId; - temp_primary_unique_id = it->second.s_unique_id; - } - } - ss << __PRETTY_FUNCTION__ - << " | lowest_NodeId = " << std::to_string(lowest_NodeId) - << " | curr_NodeId = " << std::to_string(curr_NodeId) - << " | temp_primary_unique_id = " - << std::to_string(temp_primary_unique_id); - LOG_DEBUG(ss); + temp_primary_unique_id = + allSystemNodes.find(device_uuid)->second.s_unique_id; + auto temp_numb_nodes = allSystemNodes.count(temp_primary_unique_id); - if (temp_primary_unique_id != 0) { - primary_unique_id = temp_primary_unique_id; - } else { - allSystemNodes.erase(primary_unique_id); - continue; - } + ss << __PRETTY_FUNCTION__ + << " | device/node id (cardId) = " << std::to_string(cardId) + << " | card id (cardAdded) = " << std::to_string(cardAdded) + << " | numMonDevices = " << std::to_string(numMonDevices) + << " | compute partition = " << strCompPartition + << " | temp_primary_unique_id = " + << std::to_string(temp_primary_unique_id) + << " | Num of nodes matching temp_primary_unique_id = " + << temp_numb_nodes + << " | device_uuid (hex/uint) = " + << print_unsigned_hex_and_int(device_uuid) + << " | device_uuid (uint64_t) = " << device_uuid; + LOG_DEBUG(ss); - auto numb_nodes = allSystemNodes.count(primary_unique_id); - ss << __PRETTY_FUNCTION__ << " | REFRESH - primary_unique_id = " - << std::to_string(primary_unique_id) << " has " - << std::to_string(numb_nodes) << " known gpu nodes"; - LOG_DEBUG(ss); - while (numb_nodes > 1) { - std::string secNode = "card"; - secNode += std::to_string(node_id); // add the primary node id - AddToDeviceList(secNode); - numb_nodes--; - } - // remove already added nodes associated with current card - auto erasedNodes = allSystemNodes.erase(primary_unique_id); - ss << __PRETTY_FUNCTION__ << " | After finding primary_unique_id = " - << std::to_string(primary_unique_id) << " erased " - << std::to_string(erasedNodes) << " nodes"; - LOG_DEBUG(ss); + if (temp_primary_unique_id != 0) { + primary_unique_id = temp_primary_unique_id; + } else { + cardAdded++; + // remove already added nodes associated with current card + auto erasedNodes = allSystemNodes.erase(0); + continue; + } + + auto numb_nodes = allSystemNodes.count(primary_unique_id); + ss << __PRETTY_FUNCTION__ << " | REFRESH - primary_unique_id = " + << std::to_string(primary_unique_id) << " has " + << std::to_string(numb_nodes) << " known gpu nodes"; + LOG_DEBUG(ss); + while (numb_nodes > 1) { + std::string secNode = "card"; + secNode += std::to_string(cardId); // add the primary node id + AddToDeviceList(secNode); + numb_nodes--; + cardAdded++; + } + // remove already added nodes associated with current card + auto erasedNodes = allSystemNodes.erase(primary_unique_id); + ss << __PRETTY_FUNCTION__ << " | After finding primary_unique_id = " + << std::to_string(primary_unique_id) << " erased " + << std::to_string(erasedNodes) << " nodes"; + LOG_DEBUG(ss); + cardAdded++; } } diff --git a/rocm_smi/src/rocm_smi_utils.cc b/rocm_smi/src/rocm_smi_utils.cc index 3bb69c4572..3f9a8b874a 100755 --- a/rocm_smi/src/rocm_smi_utils.cc +++ b/rocm_smi/src/rocm_smi_utils.cc @@ -45,7 +45,6 @@ #include #include #include -#include #include #include @@ -60,7 +59,6 @@ #include #include #include -#include #include #include "rocm_smi/rocm_smi.h" @@ -926,5 +924,97 @@ int subDirectoryCountInPath(const std::string path) { return dir_count; } +std::string monitor_type_string(MonitorTypes type) { + const std::map monitorTypesToString{ + {kMonName, + "MonitorTypes::kMonName"}, + {kMonTemp, + "MonitorTypes::kMonTemp"}, + {kMonFanSpeed, + "MonitorTypes::kMonFanSpeed"}, + {kMonMaxFanSpeed, + "MonitorTypes::kMonMaxFanSpeed"}, + {kMonFanRPMs, + "MonitorTypes::kMonFanRPMs"}, + {kMonFanCntrlEnable, + "MonitorTypes::kMonFanCntrlEnable"}, + {kMonPowerCap, + "MonitorTypes::kMonPowerCap"}, + {kMonPowerCapDefault, + "MonitorTypes::kMonPowerCapDefault"}, + {kMonPowerCapMax, + "MonitorTypes::kMonPowerCapMax"}, + {kMonPowerCapMin, + "MonitorTypes::kMonPowerCapMin"}, + {kMonPowerAve, + "MonitorTypes::kMonPowerAve"}, + {kMonPowerInput, + "MonitorTypes::kMonPowerInput"}, + {kMonPowerLabel, + "MonitorTypes::kMonPowerLabel"}, + {kMonTempMax, + "MonitorTypes::kMonTempMax"}, + {kMonTempMin, + "MonitorTypes::kMonTempMin"}, + {kMonTempMaxHyst, + "MonitorTypes::kMonTempMaxHyst"}, + {kMonTempMinHyst, + "MonitorTypes::kMonTempMinHyst"}, + {kMonTempCritical, + "MonitorTypes::kMonTempCritical"}, + {kMonTempCriticalHyst, + "MonitorTypes::kMonTempCriticalHyst"}, + {kMonTempEmergency, + "MonitorTypes::kMonTempEmergency"}, + {kMonTempEmergencyHyst, + "MonitorTypes::kMonTempEmergencyHyst"}, + {kMonTempCritMin, + "MonitorTypes::kMonTempCritMin"}, + {kMonTempCritMinHyst, + "MonitorTypes::kMonTempCritMinHyst"}, + {kMonTempOffset, + "MonitorTypes::kMonTempOffset"}, + {kMonTempLowest, + "MonitorTypes::kMonTempLowest"}, + {kMonTempHighest, + "MonitorTypes::kMonTempHighest"}, + {kMonTempLabel, + "MonitorTypes::kMonTempLabel"}, + {kMonVolt, + "MonitorTypes::kMonVolt"}, + {kMonVoltMax, + "MonitorTypes::kMonVoltMax"}, + {kMonVoltMinCrit, + "MonitorTypes::kMonVoltMinCrit"}, + {kMonVoltMin, + "MonitorTypes::kMonVoltMin"}, + {kMonVoltMaxCrit, + "MonitorTypes::kMonVoltMaxCrit"}, + {kMonVoltAverage, + "MonitorTypes::kMonVoltAverage"}, + {kMonVoltLowest, + "MonitorTypes::kMonVoltLowest"}, + {kMonVoltHighest, + "MonitorTypes::kMonVoltHighest"}, + {kMonVoltLabel, + "MonitorTypes::kMonVoltLabel"}, + {kMonInvalid, + "MonitorTypes::kMonInvalid"}, + }; + return monitorTypesToString.at(type); +} + +std::string power_type_string(RSMI_POWER_TYPE type) { + const std::map powerTypesToString{ + {RSMI_AVERAGE_POWER, + "RSMI_POWER_TYPE::RSMI_AVERAGE_POWER"}, + {RSMI_CURRENT_POWER, + "RSMI_POWER_TYPE::RSMI_CURRENT_POWER"}, + {RSMI_INVALID_POWER, + "RSMI_POWER_TYPE::RSMI_INVALID_POWER"}, + }; + return powerTypesToString.at(type); +} + } // namespace smi } // namespace amd diff --git a/src/amd_smi/amd_smi.cc b/src/amd_smi/amd_smi.cc index 201881b462..ff5988c126 100644 --- a/src/amd_smi/amd_smi.cc +++ b/src/amd_smi/amd_smi.cc @@ -951,7 +951,7 @@ amdsmi_status_t amdsmi_status_t amdsmi_topo_get_link_type(amdsmi_processor_handle processor_handle_src, amdsmi_processor_handle processor_handle_dst, - uint64_t *hops, AMDSMI_IO_LINK_TYPE *type) { + uint64_t *hops, amdsmi_io_link_type_t *type) { AMDSMI_CHECK_INIT(); amd::smi::AMDSmiGPUDevice* src_device = nullptr; @@ -1609,19 +1609,32 @@ amdsmi_get_gpu_total_ecc_count(amdsmi_processor_handle processor_handle, amdsmi_ } amd::smi::AMDSmiGPUDevice* gpu_device = nullptr; - amdsmi_status_t r = get_gpu_device_from_handle(processor_handle, &gpu_device); - if (r != AMDSMI_STATUS_SUCCESS) - return r; + amdsmi_status_t status = get_gpu_device_from_handle(processor_handle, &gpu_device); + if (status != AMDSMI_STATUS_SUCCESS) + return status; - amdsmi_status_t status; if (gpu_device->check_if_drm_is_supported()){ - status = smi_amdgpu_get_ecc_error_count(gpu_device, ec); - if (status != AMDSMI_STATUS_SUCCESS) { - return status; + amdsmi_ras_err_state_t state = {}; + // Iterate through the ecc blocks + for (auto block = AMDSMI_GPU_BLOCK_FIRST; block <= AMDSMI_GPU_BLOCK_LAST; + block = (amdsmi_gpu_block_t)(block * 2)) { + // Clear the previous ecc block counts + amdsmi_error_count_t block_ec = {}; + // Check if the current ecc block is enabled + status = amdsmi_get_gpu_ras_block_features_enabled(processor_handle, block, &state); + if (status == AMDSMI_STATUS_SUCCESS && state == AMDSMI_RAS_ERR_STATE_ENABLED) { + // Increment the total ecc counts by the ecc block counts + status = amdsmi_get_gpu_ecc_count(processor_handle, block, &block_ec); + if (status == AMDSMI_STATUS_SUCCESS) { + // Increase the total ecc counts + ec->correctable_count += block_ec.correctable_count; + ec->uncorrectable_count += block_ec.uncorrectable_count; + } + } } } else { - // rocm + return AMDSMI_STATUS_NOT_SUPPORTED; } return AMDSMI_STATUS_SUCCESS; diff --git a/tests/amd_smi_test/functional/hw_topology_read.cc b/tests/amd_smi_test/functional/hw_topology_read.cc index 68204afb7f..c4ad7810ad 100755 --- a/tests/amd_smi_test/functional/hw_topology_read.cc +++ b/tests/amd_smi_test/functional/hw_topology_read.cc @@ -137,7 +137,7 @@ void TestHWTopologyRead::Run(void) { gpu_links[dv_ind_src][dv_ind_dst].weight = 0; gpu_links[dv_ind_src][dv_ind_dst].accessible = true; } else { - AMDSMI_IO_LINK_TYPE type; + amdsmi_io_link_type_t type; err = amdsmi_topo_get_link_type(processor_handles_[dv_ind_src], processor_handles_[dv_ind_dst], &gpu_links[dv_ind_src][dv_ind_dst].hops, &type); diff --git a/tests/amd_smi_test/functional/power_read.cc b/tests/amd_smi_test/functional/power_read.cc index b4e26ce7b3..98f2b1ffd0 100755 --- a/tests/amd_smi_test/functional/power_read.cc +++ b/tests/amd_smi_test/functional/power_read.cc @@ -5,7 +5,7 @@ * The University of Illinois/NCSA * Open Source License (NCSA) * - * Copyright (c) 2022, Advanced Micro Devices, Inc. + * Copyright (c) 2019-2023, Advanced Micro Devices, Inc. * All rights reserved. * * Developed by: @@ -88,6 +88,7 @@ void TestPowerRead::Close() { void TestPowerRead::Run(void) { amdsmi_status_t err; uint64_t val_ui64, val2_ui64; + amdsmi_power_type_t type = AMDSMI_INVALID_POWER; TestBase::Run(); if (setup_failed_) { diff --git a/tests/amd_smi_test/functional/power_read.h b/tests/amd_smi_test/functional/power_read.h index 7a7047b591..49d3a4cb43 100755 --- a/tests/amd_smi_test/functional/power_read.h +++ b/tests/amd_smi_test/functional/power_read.h @@ -5,7 +5,7 @@ * The University of Illinois/NCSA * Open Source License (NCSA) * - * Copyright (c) 2022, Advanced Micro Devices, Inc. + * Copyright (c) 2019-2023, Advanced Micro Devices, Inc. * All rights reserved. * * Developed by: diff --git a/tests/amd_smi_test/main.cc b/tests/amd_smi_test/main.cc index c4e1ced1d1..9765ab325f 100644 --- a/tests/amd_smi_test/main.cc +++ b/tests/amd_smi_test/main.cc @@ -264,6 +264,8 @@ TEST(amdsmitstReadOnly, TestMutualExclusion) { RunCustomTestEpilog(&tst); } */ +// TODO: add TestComputePartitionReadWrite +// TODO: add TestMemoryPartitionReadWrite TEST(amdsmitstReadWrite, TestEvtNotifReadWrite) { TestEvtNotifReadWrite tst; RunGenericTest(&tst); diff --git a/tests/rocm_smi_test/functional/id_info_read.cc b/tests/rocm_smi_test/functional/id_info_read.cc deleted file mode 100755 index 1988d951a1..0000000000 --- a/tests/rocm_smi_test/functional/id_info_read.cc +++ /dev/null @@ -1,325 +0,0 @@ -/* - * ============================================================================= - * The University of Illinois/NCSA - * Open Source License (NCSA) - * - * Copyright (c) 2019, Advanced Micro Devices, Inc. - * All rights reserved. - * - * Developed by: - * - * AMD Research and AMD ROC Software Development - * - * Advanced Micro Devices, Inc. - * - * www.amd.com - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal with the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimers. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimers in - * the documentation and/or other materials provided with the distribution. - * - Neither the names of , - * nor the names of its contributors may be used to endorse or promote - * products derived from this Software without specific prior written - * permission. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS WITH THE SOFTWARE. - * - */ - -#include -#include - -#include -#include - -#include "gtest/gtest.h" -#include "rocm_smi/rocm_smi.h" -#include "rocm_smi_test/functional/id_info_read.h" -#include "rocm_smi_test/test_common.h" - -TestIdInfoRead::TestIdInfoRead() : TestBase() { - set_title("RSMI ID Info Read Test"); - set_description("This test verifies that ID information such as the " - "device, subsystem and vendor IDs can be read properly."); -} - -TestIdInfoRead::~TestIdInfoRead(void) { -} - -void TestIdInfoRead::SetUp(void) { - TestBase::SetUp(); - - return; -} - -void TestIdInfoRead::DisplayTestInfo(void) { - TestBase::DisplayTestInfo(); -} - -void TestIdInfoRead::DisplayResults(void) const { - TestBase::DisplayResults(); - return; -} - -void TestIdInfoRead::Close() { - // This will close handles opened within rsmitst utility calls and call - // rsmi_shut_down(), so it should be done after other hsa cleanup - TestBase::Close(); -} - -static const uint32_t kBufferLen = 80; - -void TestIdInfoRead::Run(void) { - rsmi_status_t err; - uint16_t id; - uint64_t val_ui64; - uint32_t drm_render_minor; - - char buffer[kBufferLen]; - - TestBase::Run(); - if (setup_failed_) { - std::cout << "** SetUp Failed for this test. Skipping.**" << std::endl; - return; - } - - for (uint32_t i = 0; i < num_monitor_devs(); ++i) { - IF_VERB(STANDARD) { - std::cout << "\t*************************" << std::endl; - std::cout << "\t**Device index: " << i << std::endl; - } - - // Get the device ID, name, vendor ID and vendor name for the device - err = rsmi_dev_id_get(i, &id); - if (err == RSMI_STATUS_NOT_SUPPORTED) { - rsmi_status_t ret; - // Verify api support checking functionality is working - ret = rsmi_dev_id_get(i, nullptr); - ASSERT_EQ(ret, RSMI_STATUS_NOT_SUPPORTED); - } else { - CHK_ERR_ASRT(err) - - IF_VERB(STANDARD) { - std::cout << "\t**Device ID: 0x" << std::hex << id << std::endl; - } - // Verify api support checking functionality is working - err = rsmi_dev_id_get(i, nullptr); - ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS); - } - // Get device Revision - err = rsmi_dev_revision_get(i, &id); - if (err == RSMI_STATUS_NOT_SUPPORTED) { - rsmi_status_t ret; - // Verify api support checking functionality is working - ret = rsmi_dev_revision_get(i, nullptr); - ASSERT_EQ(ret, RSMI_STATUS_NOT_SUPPORTED); - } else { - CHK_ERR_ASRT(err) - - IF_VERB(STANDARD) { - std::cout << "\t**Dev.Rev.ID: 0x" << std::hex << id << std::endl; - } - // Verify api support checking functionality is working - err = rsmi_dev_revision_get(i, nullptr); - ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS); - } - - err = rsmi_dev_name_get(i, buffer, kBufferLen); - if (err == RSMI_STATUS_NOT_SUPPORTED) { - std::cout << "\t**Device Marketing name not found on this system." << - std::endl; - // Verify api support checking functionality is working - err = rsmi_dev_name_get(i, nullptr, kBufferLen); - ASSERT_EQ(err, RSMI_STATUS_NOT_SUPPORTED); - } else { - CHK_ERR_ASRT(err) - IF_VERB(STANDARD) { - std::cout << "\t**Device Marketing name: " << buffer << std::endl; - } - // Verify api support checking functionality is working - err = rsmi_dev_name_get(i, nullptr, kBufferLen); - ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS); - } - err = rsmi_dev_brand_get(i, buffer, kBufferLen); - if (err == RSMI_STATUS_NOT_SUPPORTED) { - // Verify api support checking functionality is working - err = rsmi_dev_brand_get(i, nullptr, kBufferLen); - ASSERT_EQ(err, RSMI_STATUS_NOT_SUPPORTED); - } else { - CHK_ERR_ASRT(err) - IF_VERB(STANDARD) { - std::cout << "\t**Device Brand name: " << buffer << std::endl; - } - // Verify api support checking functionality is working - err = rsmi_dev_brand_get(i, nullptr, kBufferLen); - ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS); - } - err = rsmi_dev_vram_vendor_get(i, buffer, kBufferLen); - if (err == RSMI_STATUS_NOT_SUPPORTED) { - std::cout << - "\t**Vram Vendor string not supported on this system." << std::endl; - err = rsmi_dev_vram_vendor_get(i, nullptr, kBufferLen); - ASSERT_EQ(err, RSMI_STATUS_NOT_SUPPORTED); - } else { - CHK_ERR_ASRT(err) - IF_VERB(STANDARD) { - std::cout << "\t**Device Vram Vendor name: " << buffer << std::endl; - } - err = rsmi_dev_vram_vendor_get(i, nullptr, kBufferLen); - ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS); - } - err = rsmi_dev_vendor_id_get(i, &id); - if (err == RSMI_STATUS_NOT_SUPPORTED) { - // Verify api support checking functionality is working - err = rsmi_dev_vendor_id_get(i, nullptr); - ASSERT_EQ(err, RSMI_STATUS_NOT_SUPPORTED); - } else { - CHK_ERR_ASRT(err) - IF_VERB(STANDARD) { - std::cout << "\t**Vendor ID: 0x" << std::hex << id << std::endl; - } - // Verify api support checking functionality is working - err = rsmi_dev_vendor_id_get(i, nullptr); - ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS); - } - err = rsmi_dev_drm_render_minor_get(i, &drm_render_minor); - if (err == RSMI_STATUS_NOT_SUPPORTED) { - // Verify api support checking functionality is working - err = rsmi_dev_drm_render_minor_get(i, nullptr); - ASSERT_EQ(err, RSMI_STATUS_NOT_SUPPORTED); - } else { - CHK_ERR_ASRT(err) - IF_VERB(STANDARD) { - std::cout << "\t**DRM Render Minor: " << drm_render_minor << std::endl; - } - // Verify api support checking functionality is working - err = rsmi_dev_drm_render_minor_get(i, nullptr); - ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS); - } - err = rsmi_dev_vendor_name_get(i, buffer, kBufferLen); - if (err == RSMI_STATUS_NOT_SUPPORTED) { - std::cout << "\t**Device Vendor name string not found on this system." << - std::endl; - // Verify api support checking functionality is working - err = rsmi_dev_vendor_name_get(i, nullptr, kBufferLen); - ASSERT_EQ(err, RSMI_STATUS_NOT_SUPPORTED); - } else { - CHK_ERR_ASRT(err) - IF_VERB(STANDARD) { - std::cout << "\t**Device Vendor name: " << buffer << std::endl; - } - // Verify api support checking functionality is working - err = rsmi_dev_vendor_name_get(i, nullptr, kBufferLen); - ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS); - } - - // Get the device ID, name, vendor ID and vendor name for the sub-device - err = rsmi_dev_subsystem_id_get(i, &id); - if (err == RSMI_STATUS_NOT_SUPPORTED) { - // Verify api support checking functionality is working - err = rsmi_dev_subsystem_id_get(i, nullptr); - ASSERT_EQ(err, RSMI_STATUS_NOT_SUPPORTED); - } else { - CHK_ERR_ASRT(err) - IF_VERB(STANDARD) { - std::cout << "\t**Subsystem ID: 0x" << std::hex << id << std::endl; - } - // Verify api support checking functionality is working - err = rsmi_dev_subsystem_id_get(i, nullptr); - ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS); - } - err = rsmi_dev_subsystem_name_get(i, buffer, kBufferLen); - if (err == RSMI_STATUS_NOT_SUPPORTED) { - std::cout << "\t**Subsystem name string not found on this system." << - std::endl; - // Verify api support checking functionality is working - err = rsmi_dev_subsystem_name_get(i, nullptr, kBufferLen); - ASSERT_EQ(err, RSMI_STATUS_NOT_SUPPORTED); - } else { - CHK_ERR_ASRT(err) - IF_VERB(STANDARD) { - std::cout << "\t**Subsystem name: " << buffer << std::endl; - } - // Verify api support checking functionality is working - err = rsmi_dev_subsystem_name_get(i, nullptr, kBufferLen); - ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS); - } - err = rsmi_dev_subsystem_vendor_id_get(i, &id); - if (err == RSMI_STATUS_NOT_SUPPORTED) { - // Verify api support checking functionality is working - err = rsmi_dev_subsystem_vendor_id_get(i, nullptr); - ASSERT_EQ(err, RSMI_STATUS_NOT_SUPPORTED); - } else { - CHK_ERR_ASRT(err) - IF_VERB(STANDARD) { - std::cout << "\t**Sub-system Vendor ID: 0x" << std::hex << - id << std::endl; - } - // Verify api support checking functionality is working - err = rsmi_dev_subsystem_vendor_id_get(i, nullptr); - ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS); - } - err = rsmi_dev_vendor_name_get(i, buffer, kBufferLen); - if (err == RSMI_STATUS_NOT_SUPPORTED) { - std::cout << - "\t**Subsystem Vendor name string not found on this system." << - std::endl; - // Verify api support checking functionality is working - err = rsmi_dev_vendor_name_get(i, nullptr, kBufferLen); - ASSERT_EQ(err, RSMI_STATUS_NOT_SUPPORTED); - } else { - CHK_ERR_ASRT(err) - IF_VERB(STANDARD) { - std::cout << "\t**Subsystem Vendor name: " << buffer << std::endl; - } - // Verify api support checking functionality is working - err = rsmi_dev_vendor_name_get(i, nullptr, kBufferLen); - ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS); - } - - err = rsmi_dev_pci_id_get(i, &val_ui64); - // Don't check for RSMI_STATUS_NOT_SUPPORTED since this should always be - // supported. It is not based on a sysfs file. - CHK_ERR_ASRT(err) - IF_VERB(STANDARD) { - std::cout << "\t**PCI ID (BDFID): 0x" << std::hex << val_ui64; - std::cout << " (" << std::dec << val_ui64 << ")" << std::endl; - } - // Verify api support checking functionality is working - err = rsmi_dev_pci_id_get(i, nullptr); - ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS); - - err = rsmi_dev_serial_number_get(i, buffer, kBufferLen); - if (err == RSMI_STATUS_NOT_SUPPORTED) { - // Verify api support checking functionality is working - err = rsmi_dev_serial_number_get(i, nullptr, kBufferLen); - ASSERT_EQ(err, RSMI_STATUS_NOT_SUPPORTED); - - std::cout << - "\t**Serial Number string not supported on this system." << std::endl; - } else { - CHK_ERR_ASRT(err) - IF_VERB(STANDARD) { - std::cout << "\t**Device Serial Number:" << buffer << std::endl; - } - // Verify api support checking functionality is working - err = rsmi_dev_serial_number_get(i, nullptr, kBufferLen); - ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS); - } - } -}