diff --git a/projects/amdsmi/CHANGELOG.md b/projects/amdsmi/CHANGELOG.md index 3caaedcd35..1379b3ccd5 100644 --- a/projects/amdsmi/CHANGELOG.md +++ b/projects/amdsmi/CHANGELOG.md @@ -571,6 +571,12 @@ GPU: 0 - **Removed usage of _validate_positive in Parser and replaced with _positive_int and _not_negative_int as appropriate**. - This will allow 0 to be a valid input for several options in setting CPUs where appropriate (for example, as a mode or NBIOID) +- **Removed `--ras` option from `amd-smi static` command in Guest environments**. + - VMs don't have permission from Hosts to obtain RAS information, so this option was made invalid on Guest environments. + +- **Removed `--ecc` option from `amd-smi monitor` command in Guest environments**. + - Guest VMs do not support getting current ECC counts from the Host cards. + ### Optimizations - **Adjusted ordering of gpu_metrics calls to ensure that pcie_bw values remain stable in `amd-smi metric` & `amd-smi monitor`**. diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_commands.py b/projects/amdsmi/amdsmi_cli/amdsmi_commands.py index 02bcc45f35..348503548e 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_commands.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_commands.py @@ -311,8 +311,6 @@ class AMDSMICommands(): args.board = board if driver: args.driver = driver - if ras: - args.ras = ras if vram: args.vram = vram if cache: @@ -321,12 +319,14 @@ class AMDSMICommands(): args.process_isolation = process_isolation # Store args that are applicable to the current platform - current_platform_args = ["asic", "bus", "vbios", "driver", "ras", + current_platform_args = ["asic", "bus", "vbios", "driver", "vram", "cache", "board", "process_isolation"] - current_platform_values = [args.asic, args.bus, args.vbios, args.driver, args.ras, + current_platform_values = [args.asic, args.bus, args.vbios, args.driver, args.vram, args.cache, args.board, args.process_isolation] if self.helpers.is_linux() and self.helpers.is_baremetal(): + if ras: + args.ras = ras if partition: args.partition = partition if limit: @@ -336,7 +336,8 @@ class AMDSMICommands(): if xgmi_plpd: args.xgmi_plpd = xgmi_plpd current_platform_args += ["ras", "limit", "partition", "soc_pstate", "xgmi_plpd"] - current_platform_values += [args.ras, args.limit, args.partition, args.soc_pstate, args.xgmi_plpd] + current_platform_values += [args.ras, args.limit, args.partition, + args.soc_pstate, args.xgmi_plpd] if self.helpers.is_linux() and not self.helpers.is_virtual_os(): if numa: @@ -1249,10 +1250,9 @@ class AMDSMICommands(): args.temperature = temperature if pcie: args.pcie = pcie - if throttle: - args.throttle = throttle - current_platform_args += ["usage", "power", "clock", "temperature", "pcie", "throttle"] - current_platform_values += [args.usage, args.power, args.clock, args.temperature, args.pcie, args.throttle] + current_platform_args += ["usage", "power", "clock", "temperature", "pcie"] + current_platform_values += [args.usage, args.power, args.clock, + args.temperature, args.pcie] # Only args that are applicable to Hypervisors and BM Linux if self.helpers.is_hypervisor() or (self.helpers.is_baremetal() and self.helpers.is_linux()): @@ -1276,8 +1276,12 @@ class AMDSMICommands(): args.xgmi_err = xgmi_err if energy: args.energy = energy - current_platform_args += ["fan", "voltage_curve", "overdrive", "perf_level", "xgmi_err", "energy"] - current_platform_values += [args.fan, args.voltage_curve, args.overdrive, args.perf_level, args.xgmi_err, args.energy] + if throttle: + args.throttle = throttle + current_platform_args += ["fan", "voltage_curve", "overdrive", "perf_level", + "xgmi_err", "energy", "throttle"] + current_platform_values += [args.fan, args.voltage_curve, args.overdrive, + args.perf_level, args.xgmi_err, args.energy, args.throttle] if self.helpers.is_hypervisor(): if schedule: @@ -1291,7 +1295,8 @@ class AMDSMICommands(): if xgmi: args.xgmi = xgmi current_platform_args += ["schedule", "guard", "guest_data", "fb_usage", "xgmi"] - current_platform_values += [args.schedule, args.guard, args.guest_data, args.fb_usage, args.xgmi] + current_platform_values += [args.schedule, args.guard, args.guest_data, + args.fb_usage, args.xgmi] # Handle No GPU passed if args.gpu == None: @@ -4513,6 +4518,22 @@ class AMDSMICommands(): if args.gpu == None: args.gpu = self.device_handles + # handle platform for ecc + if self.helpers.is_virtual_os(): + args.ecc = False + if not any([args.power_usage, args.temperature, args.gfx, args.mem, + args.encoder, args.decoder, args.vram_usage, args.pcie, args.violation]): + args.power_usage = args.temperature = args.gfx = args.mem = \ + args.encoder = args.decoder = \ + args.vram_usage = args.pcie = args.violation = True + else: + if not any([args.power_usage, args.temperature, args.gfx, args.mem, + args.encoder, args.decoder, args.ecc, + args.vram_usage, args.pcie, args.violation]): + args.power_usage = args.temperature = args.gfx = args.mem = \ + args.encoder = args.decoder = args.ecc = \ + args.vram_usage = args.pcie = args.violation = True + # If all arguments are False, the print all values # Don't include process in this logic as it's an optional edge case if not any([args.power_usage, args.temperature, args.gfx, args.mem, diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_parser.py b/projects/amdsmi/amdsmi_cli/amdsmi_parser.py index 3f4059a86f..830cf7239f 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_parser.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_parser.py @@ -635,10 +635,10 @@ class AMDSMIParser(argparse.ArgumentParser): static_parser.add_argument('-c', '--cache', action='store_true', required=False, help=cache_help) static_parser.add_argument('-B', '--board', action='store_true', required=False, help=board_help) static_parser.add_argument('-R', '--process-isolation', action='store_true', required=False, help=process_isolation_help) - static_parser.add_argument('-r', '--ras', action='store_true', required=False, help=ras_help) # Options to display on Hypervisors and Baremetal if self.helpers.is_hypervisor() or self.helpers.is_baremetal(): + static_parser.add_argument('-r', '--ras', action='store_true', required=False, help=ras_help) static_parser.add_argument('-p', '--partition', action='store_true', required=False, help=partition_help) static_parser.add_argument('-l', '--limit', action='store_true', required=False, help=limit_help) static_parser.add_argument('-P', '--soc-pstate', action='store_true', required=False, help=soc_pstate_help) @@ -1039,8 +1039,8 @@ class AMDSMIParser(argparse.ArgumentParser): set_power_cap_help = "Set power capacity limit" set_soc_pstate_help = "Set the GPU soc pstate policy using policy id\n" set_xgmi_plpd_help = "Set the GPU XGMI per-link power down policy using policy id\n" - set_process_isolation_help = "Enable or disable the GPU process isolation: 0 for disable and 1 for enable.\n" set_clk_limit_help = "Sets the sclk (aka gfxclk) or mclk minimum and maximum frequencies. \nOf form: amd-smi set -L (sclk | mclk) (min | max) value" + set_process_isolation_help = "Enable or disable the GPU process isolation on a per partition basis: 0 for disable and 1 for enable.\n" # Help text for CPU set options set_cpu_pwr_limit_help = "Set power limit for the given socket. Input parameter is power limit value." @@ -1131,7 +1131,7 @@ class AMDSMIParser(argparse.ArgumentParser): reset_compute_help = "Reset compute partitions on the specified GPU" reset_memory_help = "Reset memory partitions on the specified GPU" reset_power_cap_help = "Reset power capacity limit to max capable" - reset_gpu_clean_local_data_help = "Clean up local data in LDS/GPRs" + reset_gpu_clean_local_data_help = "Clean up local data in LDS/GPRs on a per partition basis" # Create reset subparser reset_parser = subparsers.add_parser('reset', help=reset_help, description=reset_subcommand_help) @@ -1207,7 +1207,10 @@ class AMDSMIParser(argparse.ArgumentParser): monitor_parser.add_argument('-m', '--mem', action='store_true', required=False, help=mem_util_help) monitor_parser.add_argument('-n', '--encoder', action='store_true', required=False, help=encoder_util_help) monitor_parser.add_argument('-d', '--decoder', action='store_true', required=False, help=decoder_util_help) - monitor_parser.add_argument('-e', '--ecc', action='store_true', required=False, help=ecc_help) + + if not self.helpers.is_virtual_os(): + monitor_parser.add_argument('-e', '--ecc', action='store_true', required=False, help=ecc_help) + monitor_parser.add_argument('-v', '--vram-usage', action='store_true', required=False, help=mem_usage_help) monitor_parser.add_argument('-r', '--pcie', action='store_true', required=False, help=pcie_bandwidth_help) monitor_parser.add_argument('-q', '--process', action='store_true', required=False, help=process_help) diff --git a/projects/amdsmi/goamdsmi_shim/CMakeLists.txt b/projects/amdsmi/goamdsmi_shim/CMakeLists.txt index dceee4e29e..5f8c7f11e0 100644 --- a/projects/amdsmi/goamdsmi_shim/CMakeLists.txt +++ b/projects/amdsmi/goamdsmi_shim/CMakeLists.txt @@ -120,7 +120,7 @@ set(go_amd_smi_install_headers ## Add the install directives for the runtime library. install(TARGETS ${GOAMDSMI_SHIM_TARGET} - LIBRARY DESTINATION lib COMPONENT ${GOAMDSMI_SHIM_COMPONENT}) + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${GOAMDSMI_SHIM_COMPONENT}) install(FILES ${go_amd_smi_install_headers} DESTINATION include) diff --git a/projects/amdsmi/include/amd_smi/amdsmi.h b/projects/amdsmi/include/amd_smi/amdsmi.h index 0b11641daf..bf629275fd 100644 --- a/projects/amdsmi/include/amd_smi/amdsmi.h +++ b/projects/amdsmi/include/amd_smi/amdsmi.h @@ -1973,33 +1973,32 @@ amdsmi_status_t amdsmi_get_socket_handles(uint32_t *socket_count, #ifdef ENABLE_ESMI_LIB /** - * @brief Get the list of cpu socket handles in the system. + * @brief Get the list of cpu handles in the system. * * @platform{cpu_bm} * * @details Depends on AMDSMI_INIT_AMD_CPUS flag passed to ::amdsmi_init. - * The socket handles can be used to query the processor handles in that socket, which - * will be used in other APIs to get processor detail information. + * The processor handles can be used in other APIs to get processor detail information. * - * @param[in,out] socket_count As input, the value passed - * through this parameter is the number of ::amdsmi_cpusocket_handle that - * may be safely written to the memory pointed to by @p socket_handles. This is the - * limit on how many socket handles will be written to @p socket_handles. On return, @p - * socket_count will contain the number of socket handles written to @p socket_handles, - * or the number of socket handles that could have been written if enough memory had been + * @param[in,out] cpu_count As input, the value passed + * through this parameter is the number of ::amdsmi_processor_handle that + * may be safely written to the memory pointed to by @p processor_handles. This is the + * limit on how many processor handles will be written to @p processor_handles. On return, @p + * socket_count will contain the number of processor handles written to @p processor_handles, + * or the number of processor handles that could have been written if enough memory had been * provided. - * If @p socket_handles is NULL, as output, @p socket_count will contain - * how many sockets are available to read in the system. + * If @p processor_handles is NULL, as output, @p cpu_count will contain + * how many processors are available to read in the system. * * @param[in,out] socket_handles A pointer to a block of memory to which the - * ::amdsmi_cpusocket_handle values will be written. This value may be NULL. - * In this case, this function can be used to query how many sockets are + * ::amdsmi_processor_handle values will be written. This value may be NULL. + * In this case, this function can be used to query how many processors are * available to read in the system. * * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ -amdsmi_status_t amdsmi_get_cpusocket_handles(uint32_t *socket_count, - amdsmi_cpusocket_handle* socket_handles); +amdsmi_status_t amdsmi_get_cpu_handles(uint32_t *cpu_count, + amdsmi_processor_handle *processor_handles); #endif /** @@ -2134,21 +2133,20 @@ amdsmi_status_t amdsmi_get_processor_handles(amdsmi_socket_handle socket_handle, #ifdef ENABLE_ESMI_LIB /** - * @brief Get the list of the cpu core handles associated to a cpu socket. + * @brief Get the list of the cpu core handles in a system. * * @platform{cpu_bm} * - * @details This function retrieves the cpu core handles of a cpu socket. - * @param[in] socket_handle The cpu socket to query - * @param[in,out] processor_count As input, the value passed + * @details This function retrieves the cpu core handles of a system. + * @param[in,out] cores_count As input, the value passed * through this parameter is the number of ::amdsmi_processor_handle's that * may be safely written to the memory pointed to by @p processor_handles. This is the - * limit on how many processor handles will be written to @p processor_handles. On return, @p - * processor_count will contain the number of processor handles written to @p processor_handles, - * or the number of processor handles that could have been written if enough memory had been + * limit on how many core handles will be written to @p processor_handles. On return, @p + * cores_count will contain the number of core processor handles written to @p processor_handles, + * or the number of core processor handles that could have been written if enough memory had been * provided. * If @p processor_handles is NULL, as output, @p processor_count will contain - * how many cpu cores are available to read for the cpu socket. + * how many cpu cores are available to read in the system. * * @param[in,out] processor_handles A pointer to a block of memory to which the * ::amdsmi_processor_handle values will be written. This value may be NULL. @@ -2157,9 +2155,8 @@ amdsmi_status_t amdsmi_get_processor_handles(amdsmi_socket_handle socket_handle, * * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ -amdsmi_status_t amdsmi_get_cpucore_handles(amdsmi_cpusocket_handle socket_handle, - uint32_t *processor_count, - amdsmi_processor_handle* processor_handles); +amdsmi_status_t amdsmi_get_cpucore_handles(uint32_t *cores_count, + amdsmi_processor_handle* processor_handles); #endif /** diff --git a/projects/amdsmi/py-interface/amdsmi_interface.py b/projects/amdsmi/py-interface/amdsmi_interface.py index 7cc37897b3..fa96a01819 100644 --- a/projects/amdsmi/py-interface/amdsmi_interface.py +++ b/projects/amdsmi/py-interface/amdsmi_interface.py @@ -668,36 +668,22 @@ def amdsmi_get_cpusocket_handles() -> List[amdsmi_wrapper.amdsmi_socket_handle]: Returns: `List`: List containing all of the found cpu socket handles. """ - socket_handles = amdsmi_get_socket_handles() - cpu_handles = [] - type = amdsmi_wrapper.AMDSMI_PROCESSOR_TYPE_AMD_CPU - for socket in socket_handles: - cpu_count = ctypes.c_uint32() - null_ptr = ctypes.POINTER(amdsmi_wrapper.amdsmi_processor_handle)() - _check_res( - amdsmi_wrapper.amdsmi_get_processor_handles_by_type( - socket, - type, - null_ptr, - ctypes.byref(cpu_count), - ) - ) - processor_handles = ( - amdsmi_wrapper.amdsmi_processor_handle * cpu_count.value)() - _check_res( - amdsmi_wrapper.amdsmi_get_processor_handles_by_type( - socket, - type, - processor_handles, - ctypes.byref(cpu_count) - ) - ) - cpu_handles.extend( - [ - amdsmi_wrapper.amdsmi_processor_handle(processor_handles[dev_idx]) - for dev_idx in range(cpu_count.value) - ] - ) + cpu_count = ctypes.c_uint32(0) + null_ptr = ctypes.POINTER(amdsmi_wrapper.amdsmi_processor_handle)() + _check_res( + amdsmi_wrapper.amdsmi_get_cpu_handles( + ctypes.byref(cpu_count), null_ptr) + ) + proc_handles = (amdsmi_wrapper.amdsmi_processor_handle * + cpu_count.value)() + _check_res( + amdsmi_wrapper.amdsmi_get_cpu_handles( + ctypes.byref(cpu_count), proc_handles) + ) + cpu_handles = [ + amdsmi_wrapper.amdsmi_processor_handle(proc_handles[sock_idx]) + for sock_idx in range(cpu_count.value) + ] return cpu_handles @@ -761,37 +747,23 @@ def amdsmi_get_processor_handles() -> List[amdsmi_wrapper.amdsmi_processor_handl return devices def amdsmi_get_cpucore_handles() -> List[amdsmi_wrapper.amdsmi_processor_handle]: - socket_handles = amdsmi_get_socket_handles() - core_handles = [] - type = amdsmi_wrapper.AMDSMI_PROCESSOR_TYPE_AMD_CPU_CORE + cores_count = ctypes.c_uint32(0) + null_ptr = ctypes.POINTER(amdsmi_wrapper.amdsmi_processor_handle)() + _check_res( + amdsmi_wrapper.amdsmi_get_cpucore_handles( + ctypes.byref(cores_count), null_ptr) + ) + proc_handles = (amdsmi_wrapper.amdsmi_processor_handle * + cores_count.value)() + _check_res( + amdsmi_wrapper.amdsmi_get_cpucore_handles( + ctypes.byref(cores_count), proc_handles) + ) + core_handles = [ + amdsmi_wrapper.amdsmi_processor_handle(proc_handles[sock_idx]) + for sock_idx in range(cores_count.value) + ] - for socket in socket_handles: - core_count = ctypes.c_uint32() - null_ptr = ctypes.POINTER(amdsmi_wrapper.amdsmi_processor_handle)() - _check_res( - amdsmi_wrapper.amdsmi_get_processor_handles_by_type( - socket, - type, - null_ptr, - ctypes.byref(core_count), - ) - ) - c_handles = ( - amdsmi_wrapper.amdsmi_processor_handle * core_count.value)() - _check_res( - amdsmi_wrapper.amdsmi_get_processor_handles_by_type( - socket, - type, - c_handles, - ctypes.byref(core_count) - ) - ) - core_handles.extend( - [ - amdsmi_wrapper.amdsmi_processor_handle(c_handles[dev_idx]) - for dev_idx in range(core_count.value) - ] - ) return core_handles diff --git a/projects/amdsmi/py-interface/amdsmi_wrapper.py b/projects/amdsmi/py-interface/amdsmi_wrapper.py index b16593187d..e52e147fc1 100644 --- a/projects/amdsmi/py-interface/amdsmi_wrapper.py +++ b/projects/amdsmi/py-interface/amdsmi_wrapper.py @@ -181,16 +181,6 @@ try: except OSError as error: print(error) print("Unable to find amdsmi library try installing amd-smi-lib from your package manager") -class FunctionFactoryStub: - def __getattr__(self, _): - return ctypes.CFUNCTYPE(lambda y:y) - -# libraries['FIXME_STUB'] explanation -# As you did not list (-l libraryname.so) a library that exports this function -# This is a non-working stub instead. -# You can either re-run clan2py with -l /path/to/library.so -# Or manually fix this by comment the ctypes.CDLL loading -_libraries['FIXME_STUB'] = FunctionFactoryStub() # ctypes.CDLL('FIXME_STUB') @@ -2081,9 +2071,9 @@ amdsmi_shut_down.argtypes = [] amdsmi_get_socket_handles = _libraries['libamd_smi.so'].amdsmi_get_socket_handles amdsmi_get_socket_handles.restype = amdsmi_status_t amdsmi_get_socket_handles.argtypes = [ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.POINTER(None))] -amdsmi_get_cpusocket_handles = _libraries['FIXME_STUB'].amdsmi_get_cpusocket_handles -amdsmi_get_cpusocket_handles.restype = amdsmi_status_t -amdsmi_get_cpusocket_handles.argtypes = [ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.POINTER(None))] +amdsmi_get_cpu_handles = _libraries['libamd_smi.so'].amdsmi_get_cpu_handles +amdsmi_get_cpu_handles.restype = amdsmi_status_t +amdsmi_get_cpu_handles.argtypes = [ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.POINTER(None))] size_t = ctypes.c_uint64 amdsmi_get_socket_info = _libraries['libamd_smi.so'].amdsmi_get_socket_info amdsmi_get_socket_info.restype = amdsmi_status_t @@ -2100,9 +2090,9 @@ amdsmi_get_processor_handles_by_type.argtypes = [amdsmi_socket_handle, processor amdsmi_get_processor_handles = _libraries['libamd_smi.so'].amdsmi_get_processor_handles amdsmi_get_processor_handles.restype = amdsmi_status_t amdsmi_get_processor_handles.argtypes = [amdsmi_socket_handle, ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.POINTER(None))] -amdsmi_get_cpucore_handles = _libraries['FIXME_STUB'].amdsmi_get_cpucore_handles +amdsmi_get_cpucore_handles = _libraries['libamd_smi.so'].amdsmi_get_cpucore_handles amdsmi_get_cpucore_handles.restype = amdsmi_status_t -amdsmi_get_cpucore_handles.argtypes = [amdsmi_cpusocket_handle, ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.POINTER(None))] +amdsmi_get_cpucore_handles.argtypes = [ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.POINTER(None))] amdsmi_get_processor_type = _libraries['libamd_smi.so'].amdsmi_get_processor_type amdsmi_get_processor_type.restype = amdsmi_status_t amdsmi_get_processor_type.argtypes = [amdsmi_processor_handle, ctypes.POINTER(processor_type_t)] @@ -2818,8 +2808,9 @@ __all__ = \ 'amdsmi_get_cpu_dimm_power_consumption', 'amdsmi_get_cpu_dimm_temp_range_and_refresh_rate', 'amdsmi_get_cpu_dimm_thermal_sensor', 'amdsmi_get_cpu_family', - 'amdsmi_get_cpu_fclk_mclk', 'amdsmi_get_cpu_hsmp_proto_ver', - 'amdsmi_get_cpu_model', 'amdsmi_get_cpu_prochot_status', + 'amdsmi_get_cpu_fclk_mclk', 'amdsmi_get_cpu_handles', + 'amdsmi_get_cpu_hsmp_proto_ver', 'amdsmi_get_cpu_model', + 'amdsmi_get_cpu_prochot_status', 'amdsmi_get_cpu_pwr_svi_telemetry_all_rails', 'amdsmi_get_cpu_smu_fw_version', 'amdsmi_get_cpu_socket_c0_residency', @@ -2830,8 +2821,8 @@ __all__ = \ 'amdsmi_get_cpu_socket_power', 'amdsmi_get_cpu_socket_power_cap', 'amdsmi_get_cpu_socket_power_cap_max', 'amdsmi_get_cpu_socket_temperature', 'amdsmi_get_cpucore_handles', - 'amdsmi_get_cpusocket_handles', 'amdsmi_get_energy_count', - 'amdsmi_get_esmi_err_msg', 'amdsmi_get_fw_info', + 'amdsmi_get_energy_count', 'amdsmi_get_esmi_err_msg', + 'amdsmi_get_fw_info', 'amdsmi_get_gpu_accelerator_partition_profile', 'amdsmi_get_gpu_activity', 'amdsmi_get_gpu_asic_info', 'amdsmi_get_gpu_available_counters', diff --git a/projects/amdsmi/rocm_smi/include/rocm_smi/rocm_smi.h b/projects/amdsmi/rocm_smi/include/rocm_smi/rocm_smi.h index 2fefdd0ed8..baa6988816 100644 --- a/projects/amdsmi/rocm_smi/include/rocm_smi/rocm_smi.h +++ b/projects/amdsmi/rocm_smi/include/rocm_smi/rocm_smi.h @@ -3647,12 +3647,9 @@ rsmi_status_t rsmi_dev_process_isolation_set(uint32_t dv_ind, * * @param[in] dv_ind a device index * - * @param[in] sclean the clean flag. Only 1 will take effect and other number - * are reserved for future usage. - * * @return ::RSMI_STATUS_SUCCESS is returned upon successful call, non-zero on fail */ -rsmi_status_t rsmi_dev_gpu_run_cleaner_shader(uint32_t dv_ind, uint32_t sclean); +rsmi_status_t rsmi_dev_gpu_run_cleaner_shader(uint32_t dv_ind); /** @} */ // end of PerfCont diff --git a/projects/amdsmi/rocm_smi/include/rocm_smi/rocm_smi_io_link.h b/projects/amdsmi/rocm_smi/include/rocm_smi/rocm_smi_io_link.h index e7bc35ebc2..f57987e8fd 100644 --- a/projects/amdsmi/rocm_smi/include/rocm_smi/rocm_smi_io_link.h +++ b/projects/amdsmi/rocm_smi/include/rocm_smi/rocm_smi_io_link.h @@ -82,6 +82,14 @@ typedef enum _LINK_DIRECTORY_TYPE { P2P_LINK_DIRECTORY = 1 } LINK_DIRECTORY_TYPE; +enum class IOLinkDirectionType_t +{ + kNonDirectional = 0, + kUniDirectional = 1, + kBiDirectional = 2, +}; + + class IOLink { public: explicit IOLink(uint32_t node_indx, uint32_t link_indx, LINK_DIRECTORY_TYPE link_dir_type) : @@ -121,6 +129,9 @@ class IOLink { rsmi_p2p_capability_t link_cap_; }; +using IOLinksPerNodeList_t = std::map>; +using IOLinksPerNodeListPtr_t = IOLinksPerNodeList_t*; + int DiscoverIOLinksPerNode(uint32_t node_indx, std::map> *links); @@ -137,6 +148,10 @@ int DiscoverP2PLinks(std::map, std::shared_ptr> *links); +IOLinkDirectionType_t DiscoverIOLinkPerNodeDirection(uint32_t src_node_idx, + uint32_t dst_node_idx); + + } // namespace smi } // namespace amd diff --git a/projects/amdsmi/rocm_smi/src/rocm_smi.cc b/projects/amdsmi/rocm_smi/src/rocm_smi.cc index baeb6a85c9..90593b0523 100644 --- a/projects/amdsmi/rocm_smi/src/rocm_smi.cc +++ b/projects/amdsmi/rocm_smi/src/rocm_smi.cc @@ -810,7 +810,7 @@ rsmi_dev_pci_id_get(uint32_t dv_ind, uint64_t *bdfid) { * Add domain to full pci_id: * BDFID = ((DOMAIN & 0xFFFFFFFF) << 32) | ((PARTITION_ID & 0xF) << 28) | * ((BUS & 0xFF) << 8) | ((DEVICE & 0x1F) <<3 ) | (FUNCTION & 0x7) - * + * * bits [63:32] = domain * bits [31:28] or bits [2:0] = partition id * bits [27:16] = reserved @@ -2192,8 +2192,7 @@ rsmi_status_t rsmi_dev_process_isolation_set(uint32_t dv_ind, CATCH } -rsmi_status_t rsmi_dev_gpu_run_cleaner_shader(uint32_t dv_ind, - uint32_t sclean) { +rsmi_status_t rsmi_dev_gpu_run_cleaner_shader(uint32_t dv_ind) { rsmi_status_t ret; TRY @@ -2204,7 +2203,11 @@ rsmi_status_t rsmi_dev_gpu_run_cleaner_shader(uint32_t dv_ind, DEVICE_MUTEX GET_DEV_FROM_INDX - std::string value = std::to_string(sclean); + // To reset you need to provide the partition id + // echo "0" | sudo tee  /sys/class/drm/cardX/device/run_cleaner_shader + uint32_t partition_id = 0; + rsmi_dev_partition_id_get(dv_ind, &partition_id); + std::string value = std::to_string(partition_id); int ret = dev->writeDevInfo(amd::smi::kDevShaderClean , value); return amd::smi::ErrnoToRsmiStatus(ret); @@ -5367,7 +5370,25 @@ rsmi_topo_get_p2p_status(uint32_t dv_ind_src, uint32_t dv_ind_dst, // Unexpected IO Link type read return RSMI_STATUS_NOT_SUPPORTED; } - *cap = it->second->get_link_capability(); + + /* + * Note: Adjust tmp_capability for the returned capabilities. + * Todo: We need to fix it directy as part of the KFD Nodes 'KFDNode::Initialize(void)' + * However, it involves a more complex change, so we will discuss it and fix in in the future. + * Ideally, due to the fact we would need to check every IO link (for each KFD node), and + * considering the topology could change (ie; new GPUs added, partioning changed, etc), we + * are looking into O(N^2) time complexity, no to mention the fact that the IO links then + * need to be changed/updated too. I have some ideas about how to do this, but it will take + * some time to implement and test it, should we consider it is *really necessary*. + * + */ + auto tmp_capability = it->second->get_link_capability(); + if (auto link_direction_result = amd::smi::DiscoverIOLinkPerNodeDirection(node_ind_src, node_ind_dst); + link_direction_result == amd::smi::IOLinkDirectionType_t::kBiDirectional) { + // 1 = true, 0 = false + tmp_capability.is_iolink_bi_directional = 1; + } + *cap = tmp_capability; return RSMI_STATUS_SUCCESS; } diff --git a/projects/amdsmi/rocm_smi/src/rocm_smi_io_link.cc b/projects/amdsmi/rocm_smi/src/rocm_smi_io_link.cc index 93b4ae238a..6ff48fe9b7 100644 --- a/projects/amdsmi/rocm_smi/src/rocm_smi_io_link.cc +++ b/projects/amdsmi/rocm_smi/src/rocm_smi_io_link.cc @@ -442,5 +442,38 @@ int IOLink::UpdateP2pCapability(void) { return 0; } +IOLinkDirectionType_t DiscoverIOLinkPerNodeDirection(uint32_t src_node_idx, uint32_t dst_node_idx) +{ + /* Note: Lets look at the IOLinks of the source node and see if there is a link to the target node + * Then we do the same inverting the actors (source and target) and see if there is a link + */ + auto direction_type(IOLinkDirectionType_t::kNonDirectional); + auto src_links_list = IOLinksPerNodeList_t(); + auto dst_links_list = IOLinksPerNodeList_t(); + if (auto src_discover_result = DiscoverLinksPerNode(src_node_idx, &src_links_list, IO_LINK_DIRECTORY); + src_discover_result == 0) { + for (const auto& [key, value] : src_links_list) { + if (key == dst_node_idx) { + direction_type = IOLinkDirectionType_t::kUniDirectional; + break; + } + } + } + + if (auto dst_discover_result = DiscoverLinksPerNode(dst_node_idx, &dst_links_list, IO_LINK_DIRECTORY); + dst_discover_result == 0) { + for (const auto& [key, value] : dst_links_list) { + if (key == src_node_idx) { + direction_type = (direction_type == IOLinkDirectionType_t::kUniDirectional ? + IOLinkDirectionType_t::kBiDirectional : IOLinkDirectionType_t::kUniDirectional); + break; + } + } + } + + return direction_type; +} + + } // namespace smi } // namespace amd diff --git a/projects/amdsmi/src/amd_smi/amd_smi.cc b/projects/amdsmi/src/amd_smi/amd_smi.cc index cb478122e5..be2b34361f 100644 --- a/projects/amdsmi/src/amd_smi/amd_smi.cc +++ b/projects/amdsmi/src/amd_smi/amd_smi.cc @@ -1858,8 +1858,7 @@ amdsmi_status_t amdsmi_set_gpu_process_isolation(amdsmi_processor_handle process amdsmi_status_t amdsmi_clean_gpu_local_data(amdsmi_processor_handle processor_handle) { AMDSMI_CHECK_INIT(); - return rsmi_wrapper(rsmi_dev_gpu_run_cleaner_shader, processor_handle, - 1); + return rsmi_wrapper(rsmi_dev_gpu_run_cleaner_shader, processor_handle); } amdsmi_status_t @@ -3843,6 +3842,115 @@ amdsmi_status_t amdsmi_get_cpu_model(uint32_t *cpu_model) return AMDSMI_STATUS_SUCCESS; } +amdsmi_status_t amdsmi_get_cpu_handles(uint32_t *cpu_count, + amdsmi_processor_handle *processor_handles) +{ + uint32_t soc_count = 0, index = 0, cpu_per_soc = 0; + processor_type_t processor_type = AMDSMI_PROCESSOR_TYPE_AMD_CPU; + std::vector cpu_handles; + amdsmi_status_t status; + + AMDSMI_CHECK_INIT(); + if (cpu_count == nullptr) + return AMDSMI_STATUS_INVAL; + + status = amdsmi_get_socket_handles(&soc_count, nullptr); + if (status != AMDSMI_STATUS_SUCCESS) + return status; + + // Allocate the memory for the sockets + std::vector sockets(soc_count); + // Get the sockets of the system + status = amdsmi_get_socket_handles(&soc_count, &sockets[0]); + if (status != AMDSMI_STATUS_SUCCESS) + return status; + + for (index = 0 ; index < soc_count; index++) + { + cpu_per_soc = 0; + status = amdsmi_get_processor_handles_by_type(sockets[index], processor_type, + nullptr, &cpu_per_soc); + if (status != AMDSMI_STATUS_SUCCESS) + return status; + + // Allocate the memory for the cpus + std::vector plist(cpu_per_soc); + // Get the cpus for each socket + status = amdsmi_get_processor_handles_by_type(sockets[index], processor_type, + &plist[0], &cpu_per_soc); + if (status != AMDSMI_STATUS_SUCCESS) + return status; + cpu_handles.insert(cpu_handles.end(), plist.begin(), plist.end()); + } + + // Get the cpu count + *cpu_count = cpu_handles.size(); + if (processor_handles == nullptr) + return AMDSMI_STATUS_SUCCESS; + + // Copy the cpu socket handles + for (uint32_t i = 0; i < *cpu_count; i++) + processor_handles[i] = reinterpret_cast(cpu_handles[i]); + + return status; +} + +amdsmi_status_t amdsmi_get_cpucore_handles(uint32_t *cores_count, + amdsmi_processor_handle* processor_handles) +{ + uint32_t soc_count = 0, index = 0, cores_per_soc = 0; + processor_type_t processor_type = AMDSMI_PROCESSOR_TYPE_AMD_CPU_CORE; + std::vector core_handles; + amdsmi_status_t status; + + AMDSMI_CHECK_INIT(); + if (cores_count == nullptr) { + return AMDSMI_STATUS_INVAL; + } + + // Get sockets count + status = amdsmi_get_socket_handles(&soc_count, nullptr); + if (status != AMDSMI_STATUS_SUCCESS) + return status; + + // Allocate the memory for the sockets + std::vector sockets(soc_count); + // Get the sockets of the system + status = amdsmi_get_socket_handles(&soc_count, &sockets[0]); + if (status != AMDSMI_STATUS_SUCCESS) + return status; + + for (index = 0 ; index < soc_count; index++) + { + cores_per_soc = 0; + status = amdsmi_get_processor_handles_by_type(sockets[index], processor_type, + nullptr, &cores_per_soc); + if (status != AMDSMI_STATUS_SUCCESS) + return status; + + // Allocate the memory for the cores + std::vector plist(cores_per_soc); + // Get the coress for each socket + status = amdsmi_get_processor_handles_by_type(sockets[index], processor_type, + &plist[0], &cores_per_soc); + if (status != AMDSMI_STATUS_SUCCESS) + return status; + + core_handles.insert(core_handles.end(), plist.begin(), plist.end()); + } + + // Get the cores count + *cores_count = core_handles.size(); + if (processor_handles == nullptr) + return AMDSMI_STATUS_SUCCESS; + + // Copy the core handles + for (uint32_t i = 0; i < *cores_count; i++) + processor_handles[i] = reinterpret_cast(core_handles[i]); + + return status; +} + amdsmi_status_t amdsmi_get_esmi_err_msg(amdsmi_status_t status, const char **status_string) { for (auto& iter : amd::smi::esmi_status_map) { diff --git a/projects/amdsmi/tools/generator.py b/projects/amdsmi/tools/generator.py index dd32cc03dc..022e7886bf 100644 --- a/projects/amdsmi/tools/generator.py +++ b/projects/amdsmi/tools/generator.py @@ -106,6 +106,48 @@ def write_header(full_path_file_name): shutil.move(abs_path, full_path_file_name) +def write_file(full_path_file_name, contents): + fh, abs_path = tempfile.mkstemp() + with os.fdopen(fh, 'w') as new_file: + for line in contents: + new_file.write(f'{line}\n') + + shutil.copymode(full_path_file_name, abs_path) + os.remove(full_path_file_name) + shutil.move(abs_path, full_path_file_name) + + +def find_replacement(search_str1, search_str2, line): + pos1 = line.find(search_str1) + if pos1 < 0: + return '' + + if len(search_str2): + pos2 = line.find(search_str2, pos1) + if pos2 < 0: + return '' + else: + pos2 = len(line) - 1 + + return line[pos1:pos2+1] + + +def find_line_num(search_str, line): + pos1 = line.find(search_str) + if pos1 < 0: + return 0 + items = line[pos1:].split(':') + if len(items) < 2: + return 0 + + line_num = items[1].strip() + if not line_num.isdigit(): + return 0 + + line_num = int(line_num) + return (line_num) + + def main(): output_file, input_file, library, clang_extra_args = parseArgument() @@ -157,54 +199,150 @@ except OSError as error: arguments.append("--clang-args=-I" + clang_include_dir + clang_extra_args) clangToPy(arguments) - write_header(output_file) replace_line(output_file, line_to_replace, new_line) + write_header(output_file) - # Custom handling for anonymous struct within amdsmi_bdf_t in Linux + # Custom handling for struct in Linux if os_platform == "Linux": - # Get line number for anonymous error in struct_amdsmi_bdf_t - reference_line = "uint64_t function_number :" - line_number = -1 - with open(input_file, 'r') as file: - for input_file_line_number, line in enumerate(file, 1): - if reference_line in line: - line_number = input_file_line_number - 1 # Anonymous line will error on the line before this - break + with open(input_file, 'r') as fin: + input_file_contents = fin.read() + input_file_array = input_file_contents.split('\n') - if line_number == -1: - print("Could not find reference line in amdsmi.h for amdsmi_bdf_t struct. Skipping anonymous struct replacement.") - else: - print(f"Found reference line in amdsmi.h for amdsmi_bdf_t struct at line {line_number}") - union_anon_line = "union_amdsmi_bdf_t._anonymous_ = ('_0',)" - replace_line(output_file, union_anon_line, "") + with open(output_file, 'r') as fin: + output_file_contents = fin.read() + output_file_array = output_file_contents.split('\n') - internal_union_anon_line = f"('_0', struct_struct (anonymous at amdsmi.h:{line_number}:3))" - internal_union_struct_line = "('struct_amdsmi_bdf_t', struct_amdsmi_bdf_t)" - replace_line(output_file, internal_union_anon_line, internal_union_struct_line) + # Find all unamed occurences in the output_file + struct_name_dict = {} + for index, line in enumerate(output_file_array): + if 'amdsmi.h:' in line: + # Handling "struct_struct ( at amdsmi.h::)" + if 'anonymous' in line or 'unnamed' in line: + search_name = 'unnamed' + if 'anonymous' in line: + search_name = 'anonymous' - struct_anon_line = f"struct_struct (anonymous at amdsmi.h:{line_number}:3)" - struct_amdsmi_bdf_t_line = "struct_amdsmi_bdf_t" - replace_line(output_file, struct_anon_line, struct_amdsmi_bdf_t_line) + # Find the amdsmi.h line number for this instance + # Example 1: + # class struct_struct (anonymous at amdsmi.h:370:9)(Structure): + # line_num = 370 + # Example 2: + # class struct_struct (unnamed at amdsmi.h:782:9)(Structure): + # line_num = 782 + line_num = find_line_num(search_name, line) + if line_num == 0: + print(f'Error: {index+1}: Could determine amdsmi.h line number in {line}, skipping replacement') + continue - struct_anon_all_line = "'struct_struct (anonymous at" - struct_amdsmi_bdf_t_line = "'struct_amdsmi_bdf_t'," - replace_line(output_file, struct_anon_all_line, struct_amdsmi_bdf_t_line) + # Using in amdsmi.h starting at the line_num to find the structure name + # Search the following lines for "open curly bracket" that has a name + # Example 1: + # 369: typedef union { + # 370: struct { + # 371: uint64_t function_number : 3; + # 375: }; + # 377: } amdsmi_bdf_t; + # struct_name = amdsmi_bdf_t + # Example 2: + # 782: struct { + # 783: uint64_t gfx; + # 786: } engine_usage; + # struct_name = engine_usage + struct_name = '' + for i in range(1, 50): + input_line = input_file_array[line_num + i] + # { matches close curly brackets on next line + if '}' in input_line: + struct_name = input_line.strip()[1:-1].strip() + if len(struct_name): + struct_name = struct_name.split('[')[0] # ] + break + if not len(struct_name): + print(f'Error: {index+1}: Could not find struct name using line number {line_num}, skipping replacement') + continue - struct_anon_all_line = ", 'struct_struct" - replace_line(output_file, struct_anon_all_line, ",") + # Generate the replacement for this line + # Example: + # class struct_struct (unnamed at amdsmi.h:782:9)(Structure): + # becomes + # class struct_engine_usage(Structure): + str_replace = find_replacement('struct_struct', ')', line) + if len(str_replace) > 0: + str_with = f'struct_{struct_name}' + else: + # Example + # (unnamed at amdsmi.h:787:9)', 'uint32_t', 'uint64_t', 'uint8_t', + # becomes + # 'struct_memory_usage', 'uint32_t', 'uint64_t', 'uint8_t', + str_replace = find_replacement(f'({search_name}', ')', line) + if len(str_replace) == 0: + print(f'Error: {index+1}: Could not find structure name in {line}, skipping replacement') + continue + str_with = f"'struct_{struct_name}" - struct_anon_all_line = "(anonymous at " - struct_amdsmi_bdf_t_line = "'struct_amdsmi_bdf_t'," - replace_line(output_file, struct_anon_all_line, struct_amdsmi_bdf_t_line) + # Save the line number and struct_name association for possible additional replacements + if line_num not in struct_name_dict: + struct_name_dict[line_num] = struct_name - struct_anon_all_line_to_remove = f"amdsmi.h:{line_number}:3)', " - replace_line(output_file, struct_anon_all_line_to_remove, "") + # Do the replace + new_line = line.replace(str_replace, str_with) - # Custom handling to ensure amdsmi_get_utilization_count doesn't multiply the struct by 0 - print(f"Replacing amdsmi_get_utilization_count line in {output_file}") - utilization_count_line_bad = "amdsmi_get_utilization_count.argtypes = [amdsmi_processor_handle, struct_amdsmi_utilization_counter_t * 0, uint32_t, ctypes.POINTER(ctypes.c_uint64)]" - utilization_count_line_good = "amdsmi_get_utilization_count.argtypes = [amdsmi_processor_handle, ctypes.POINTER(struct_amdsmi_utilization_counter_t), uint32_t, ctypes.POINTER(ctypes.c_uint64)]" - replace_line(output_file, utilization_count_line_bad, utilization_count_line_good) + # Look for special replacements that has the struct_name + # Example + # ('_0', struct_struct (anonymous at amdsmi.h:370:9)), + # becomes + # ('struct_amdsmi_bdf_t', struct_amdsmi_bdf_t), + if '_0' in new_line: + new_line = new_line.replace('_0', f'struct_{struct_name}') + + # Look for special replacements that has an amdsmi.h: + # Example + # amdsmi.h:370:9)', 'uint8_t', + # becomes + # 'uint8_t, + if 'amdsmi.h:' in new_line: + str_replace = find_replacement('amdsmi.h:', ',', line) + if len(str_replace) > 0: + new_line = new_line.replace(str_replace, '') + + # Save the replaced line into the array + output_file_array[index] = new_line + + # Look for special replacements + new_line = output_file_array[index] + + # Example + # union_amdsmi_bdf_t._anonymous_ = ('_0',) + # becomes + # + if '_anonymous_' in new_line: + new_line = '' + output_file_array[index] = new_line + + # Example + # 'struct_pcie_static_', 'struct_struct (anonymous at + # becomes + # 'struct_pcie_static_', + name = ", 'struct_struct" + if name in new_line: + str_replace = find_replacement(name, '', new_line) + if len(str_replace) > 0: + new_line = new_line.replace(str_replace, ',') + output_file_array[index] = new_line + + # Example + # amdsmi_get_utilization_count.argtypes = [amdsmi_processor_handle, struct_amdsmi_utilization_counter_t * 0, uint32_t, ctypes.POINTER(ctypes.c_uint64)] + # becomes + # amdsmi_get_utilization_count.argtypes = [amdsmi_processor_handle, ctypes.POINTER(struct_amdsmi_utilization_counter_t), uint32_t, ctypes.POINTER(ctypes.c_uint64)] + name = "amdsmi_get_utilization_count.argtypes" + if name in new_line: + str_replace = find_replacement(name, '', new_line) + if len(str_replace) > 0: + str_with = 'amdsmi_get_utilization_count.argtypes = [amdsmi_processor_handle, ctypes.POINTER(struct_amdsmi_utilization_counter_t), uint32_t, ctypes.POINTER(ctypes.c_uint64)]' + new_line = new_line.replace(str_replace, str_with) + output_file_array[index] = new_line + + write_file(output_file, output_file_array) if __name__ == "__main__": main()