From 8244a677db9f6956111d762cff8399dbc4ae2ab5 Mon Sep 17 00:00:00 2001 From: "Galantsev, Dmitrii" Date: Thu, 5 Oct 2023 12:49:11 -0500 Subject: [PATCH 01/11] Update package version Change-Id: Ie094f75d028a09f862729094815f8a2b6ea8ad78 Signed-off-by: Galantsev, Dmitrii --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a16e48ba7f..0fb959ad07 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,7 +35,7 @@ find_program (GIT NAMES git) ## Setup the package version based on git tags. set(PKG_VERSION_GIT_TAG_PREFIX "rsmi_pkg_ver") -get_package_version_number("5.0.0" ${PKG_VERSION_GIT_TAG_PREFIX} GIT) +get_package_version_number("6.0.0" ${PKG_VERSION_GIT_TAG_PREFIX} GIT) message("Package version: ${PKG_VERSION_STR}") set(${ROCM_SMI_LIBS_TARGET}_VERSION_MAJOR "${VERSION_MAJOR}") set(${ROCM_SMI_LIBS_TARGET}_VERSION_MINOR "${VERSION_MINOR}") @@ -46,8 +46,8 @@ set(${ROCM_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) From b251bb0c9f9174355fb69c1e2b6b593b7d12c38a Mon Sep 17 00:00:00 2001 From: Charis Poag Date: Thu, 21 Sep 2023 14:53:35 -0500 Subject: [PATCH 02/11] Rename NPS -> memory partition + compute partition node fix * Updates: - rocm_smi_lib + CLI: Rename all "NPS mode" -> "memory partition" related files/functions/API/CLI to align with correct technical naming - rocm_smi_main: fixed identifying primary card's unique id utilize rsmi_dev_unique_id_get to map which KFD nodes belong to it - rsmi_dev_*_partition*: now have better logging output - compute partition tests: Added 20 sec delay for workaround until GPU busy is confirmed as the issue - CPPLint fixes/formatting - [Example] Moved all endl to "\n" for efficiency - [Example] Added Edge & Junction temperature examples - [Example] Added rsmi_minmax_bandwidth_get() example - WIP Change-Id: Ida6db6fda7e0ac9d696a34cb15b4746e69d58d51 Signed-off-by: Charis Poag --- include/rocm_smi/rocm_smi.h | 92 ++--- python_smi_tools/rocm_smi.py | 114 +++--- python_smi_tools/rsmiBindings.py.in | 12 +- rocm_smi/example/rocm_smi_example.cc | 320 +++++++++-------- src/rocm_smi.cc | 333 +++++++++++++++--- src/rocm_smi_device.cc | 38 +- src/rocm_smi_kfd.cc | 18 +- src/rocm_smi_main.cc | 161 +++++---- .../functional/computepartition_read_write.cc | 75 ++-- ...write.cc => memorypartition_read_write.cc} | 167 ++++----- ...d_write.h => memorypartition_read_write.h} | 14 +- tests/rocm_smi_test/main.cc | 6 +- 12 files changed, 847 insertions(+), 503 deletions(-) rename tests/rocm_smi_test/functional/{npsmode_read_write.cc => memorypartition_read_write.cc} (59%) rename tests/rocm_smi_test/functional/{npsmode_read_write.h => memorypartition_read_write.h} (85%) diff --git a/include/rocm_smi/rocm_smi.h b/include/rocm_smi/rocm_smi.h index 764a459814..7817acd6ea 100755 --- a/include/rocm_smi/rocm_smi.h +++ b/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" { @@ -379,27 +379,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 /** @@ -2413,7 +2413,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 @@ -3767,27 +3768,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 @@ -3796,24 +3798,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 @@ -3825,14 +3828,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 * @@ -3844,9 +3848,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 @@ -4193,4 +4197,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/python_smi_tools/rocm_smi.py b/python_smi_tools/rocm_smi.py index 8db2d7eeea..6af7ac098b 100755 --- a/python_smi_tools/rocm_smi.py +++ b/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/python_smi_tools/rsmiBindings.py.in b/python_smi_tools/rsmiBindings.py.in index f913d99936..ee0ec76124 100644 --- a/python_smi_tools/rsmiBindings.py.in +++ b/python_smi_tools/rsmiBindings.py.in @@ -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/example/rocm_smi_example.cc b/rocm_smi/example/rocm_smi_example.cc index 815b00382e..45e79b07fd 100755 --- a/rocm_smi/example/rocm_smi_example.cc +++ b/rocm_smi/example/rocm_smi_example.cc @@ -58,9 +58,9 @@ if (RET != RSMI_STATUS_SUCCESS) { \ const char *err_str; \ std::cout << "[ERROR] RSMI call returned " << (RET) \ - << " at line " << __LINE__ << std::endl; \ + << " at line " << __LINE__ << "\n"; \ rsmi_status_string((RET), &err_str); \ - std::cout << err_str << std::endl; \ + std::cout << err_str << "\n"; \ } \ } @@ -100,10 +100,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 +112,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 +121,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 +133,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 +145,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 +189,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 +216,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 +231,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 +274,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 +292,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 +326,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 +376,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 +389,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 +407,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 +437,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 +461,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 +469,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 +479,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 +494,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 +541,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 +554,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 +562,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 +581,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,95 +604,94 @@ 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; } @@ -717,10 +716,10 @@ int main() { for (uint32_t i = 0; i < num_monitor_devs; ++i) { 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 current_compute_partition[256]; current_compute_partition[0] = '\0'; @@ -732,69 +731,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" << "\n"; } CHK_RSMI_NOT_SUPPORTED_RET(ret) @@ -802,7 +824,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) @@ -813,21 +835,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 << static_cast(val_ui64)/1000 << " W" << "\n"; } CHK_RSMI_NOT_SUPPORTED_RET(ret) - std::cout << "\t=======" << std::endl; + 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; } @@ -877,7 +899,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/src/rocm_smi.cc b/src/rocm_smi.cc index b6c9155347..2108a52289 100755 --- a/src/rocm_smi.cc +++ b/src/rocm_smi.cc @@ -417,7 +417,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); } @@ -1823,8 +1822,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"}, @@ -1832,8 +1831,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}, @@ -4240,7 +4239,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; @@ -4438,9 +4437,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: " + << RocmSMI::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) @@ -4449,14 +4459,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: " + << RocmSMI::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: " + << RocmSMI::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: " + << RocmSMI::devInfoTypesStrings.at(amd::smi::kDevComputePartition) + << " | Data: " << compute_partition + << " | Returning = " + << getRSMIStatusString(ret) << " |"; + LOG_TRACE(ss); return ret; CATCH } @@ -4504,6 +4546,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: " + << RocmSMI::devInfoTypesStrings.at(amd::smi::kDevComputePartition) + << " | Cause: requested setting was invalid" + << " | Returning = " + << getRSMIStatusString(RSMI_STATUS_INVALID_ARGS) << " |"; + LOG_ERROR(ss); return RSMI_STATUS_INVALID_ARGS; } @@ -4512,32 +4564,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: " + << RocmSMI::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: " + << RocmSMI::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: " + << RocmSMI::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: " + << RocmSMI::devInfoTypesStrings.at(amd::smi::kDevComputePartition) + << " | Data: " << newComputePartitionStr + << " | Returning = " + << getRSMIStatusString(returnResponse) << " |"; + LOG_TRACE(ss); + + // TODO(charpoag): investigate providing GPU busy state occured 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 @@ -4548,7 +4646,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: @@ -4556,16 +4654,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 ======="; @@ -4575,7 +4674,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; @@ -4589,14 +4688,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: " + << RocmSMI::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: @@ -4604,57 +4713,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: " + << RocmSMI::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: " + << RocmSMI::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: " + << RocmSMI::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: " + << RocmSMI::devInfoTypesStrings.at(amd::smi::kDevMemoryPartition) + << " | Cause: issue writing reqested 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: " + << RocmSMI::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: " + << RocmSMI::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: " + << RocmSMI::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: " + << RocmSMI::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: " + << RocmSMI::devInfoTypesStrings.at(amd::smi::kDevMemoryPartition) + << " | Data: " << memory_partition + << " | Returning = " + << getRSMIStatusString(ret) << " |"; + LOG_TRACE(ss); return ret; CATCH } @@ -4668,22 +4876,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: " + << RocmSMI::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 ======="; @@ -4692,16 +4915,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: " + << RocmSMI::devInfoTypesStrings.at(amd::smi::kDevMemoryPartition) + << " | Data: " << bootState + << " | Returning = " + << getRSMIStatusString(ret) << " |"; + LOG_TRACE(ss); return ret; CATCH } diff --git a/src/rocm_smi_device.cc b/src/rocm_smi_device.cc index 33d35bed0a..bd3ac5da9d 100755 --- a/src/rocm_smi_device.cc +++ b/src/rocm_smi_device.cc @@ -1272,7 +1272,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 <> @@ -1286,9 +1286,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) { @@ -1312,31 +1312,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; } @@ -1350,9 +1351,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; } @@ -1381,10 +1382,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/src/rocm_smi_kfd.cc b/src/rocm_smi_kfd.cc index 7fe9004cc3..9b7e0e5eaa 100755 --- a/src/rocm_smi_kfd.cc +++ b/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" @@ -183,6 +184,7 @@ int ReadKFDDeviceProperties(uint32_t kfd_node_id, int ret; std::ifstream fs; std::string properties_path; + std::ostringstream ss; assert(retVec != nullptr); @@ -192,9 +194,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(); @@ -616,15 +623,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/src/rocm_smi_main.cc b/src/rocm_smi_main.cc index d180253211..05851a88e6 100755 --- a/src/rocm_smi_main.cc +++ b/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" @@ -780,7 +781,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 { @@ -790,93 +791,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/tests/rocm_smi_test/functional/computepartition_read_write.cc b/tests/rocm_smi_test/functional/computepartition_read_write.cc index 691a18aae6..06297a9371 100755 --- a/tests/rocm_smi_test/functional/computepartition_read_write.cc +++ b/tests/rocm_smi_test/functional/computepartition_read_write.cc @@ -45,8 +45,12 @@ #include #include +#include #include +#include // NOLINT [build] +#include +#include #include "gtest/gtest.h" #include "rocm_smi/rocm_smi.h" @@ -134,6 +138,26 @@ void TestComputePartitionReadWrite::Run(void) { return; } + // Confirm system supports compute partition, before executing wait + ret = rsmi_dev_compute_partition_get(0, orig_char_computePartition, 255); + if (ret == RSMI_STATUS_SUCCESS) { + // Adding a delay - since changing partitions depends on gpus not + // being in an active state, we'll wait a few seconds before starting + // full testing + auto start = std::chrono::high_resolution_clock::now(); + int waitTime = 20; + std::cout << "** Waiting for " + << std::dec << waitTime + << " seconds, for any GPU" + << " activity to clear up. **" << std::endl; + sleep(waitTime); + auto stop = std::chrono::high_resolution_clock::now(); + auto duration = + std::chrono::duration_cast(stop - start); + std::cout << "** Waiting took " << duration.count() / 1000000 + << " seconds **" << std::endl; + } + for (uint32_t dv_ind = 0; dv_ind < num_monitor_devs(); ++dv_ind) { if (dv_ind != 0) { IF_VERB(STANDARD) { @@ -142,7 +166,7 @@ void TestComputePartitionReadWrite::Run(void) { } PrintDeviceHeader(dv_ind); - //Standard checks to see if API is supported, before running full tests + // Standard checks to see if API is supported, before running full tests ret = rsmi_dev_compute_partition_get(dv_ind, orig_char_computePartition, 255); if (ret == RSMI_STATUS_NOT_SUPPORTED) { @@ -169,12 +193,12 @@ void TestComputePartitionReadWrite::Run(void) { ASSERT_EQ(RSMI_STATUS_SUCCESS, ret); // Verify api support checking functionality is working - uint32_t length = 2; - char smallBuffer[length]; - err = rsmi_dev_compute_partition_get(dv_ind, smallBuffer, length); + uint32_t kLength = 2; + char smallBuffer[kLength]; + err = rsmi_dev_compute_partition_get(dv_ind, smallBuffer, kLength); size_t size = sizeof(smallBuffer)/sizeof(*smallBuffer); ASSERT_EQ(err, RSMI_STATUS_INSUFFICIENT_SIZE); - ASSERT_EQ((size_t)length, size); + ASSERT_EQ((size_t)kLength, size); IF_VERB(STANDARD) { if (err == RSMI_STATUS_INSUFFICIENT_SIZE) { std::cout << "\t**" @@ -207,9 +231,9 @@ void TestComputePartitionReadWrite::Run(void) { } // Verify api support checking functionality is working - rsmi_compute_partition_type new_computePartition - = rsmi_compute_partition_type::RSMI_COMPUTE_PARTITION_INVALID; - err = rsmi_dev_compute_partition_set(dv_ind, new_computePartition); + rsmi_compute_partition_type_t newPartition + = rsmi_compute_partition_type_t::RSMI_COMPUTE_PARTITION_INVALID; + err = rsmi_dev_compute_partition_set(dv_ind, newPartition); ASSERT_TRUE((err == RSMI_STATUS_INVALID_ARGS) || (err == RSMI_STATUS_NOT_SUPPORTED) || (err == RSMI_STATUS_PERMISSION)); @@ -246,24 +270,24 @@ void TestComputePartitionReadWrite::Run(void) { * //!< work together with shared memory */ - for (int partition = RSMI_COMPUTE_PARTITION_CPX; - partition <= RSMI_COMPUTE_PARTITION_QPX; + for (int partition = + rsmi_compute_partition_type_t::RSMI_COMPUTE_PARTITION_CPX; + partition <= rsmi_compute_partition_type_t::RSMI_COMPUTE_PARTITION_QPX; partition++) { - new_computePartition - = static_cast(partition); + newPartition = static_cast(partition); IF_VERB(STANDARD) { std::cout << std::endl; std::cout << "\t**" << "======== TEST RSMI_COMPUTE_PARTITION_" - << computePartitionString(new_computePartition) + << computePartitionString(newPartition) << " ===============" << std::endl; } IF_VERB(STANDARD) { std::cout << "\t**" << "Attempting to set compute partition to: " - << computePartitionString(new_computePartition) << std::endl; + << computePartitionString(newPartition) << std::endl; } - ret = rsmi_dev_compute_partition_set(dv_ind, new_computePartition); + ret = rsmi_dev_compute_partition_set(dv_ind, newPartition); bool isSettingUnavailable = false; ASSERT_TRUE((ret == RSMI_STATUS_SUCCESS) || (ret == RSMI_STATUS_SETTING_UNAVAILABLE)); @@ -282,7 +306,7 @@ void TestComputePartitionReadWrite::Run(void) { } if (isSettingUnavailable) { ASSERT_EQ(RSMI_STATUS_SETTING_UNAVAILABLE, ret); - ASSERT_STRNE(computePartitionString(new_computePartition).c_str(), + ASSERT_STRNE(computePartitionString(newPartition).c_str(), current_char_computePartition); IF_VERB(STANDARD) { std::cout << "\t**" @@ -290,19 +314,19 @@ void TestComputePartitionReadWrite::Run(void) { << "RSMI_STATUS_SETTING_UNAVAILABLE,\n\t current compute " << "partition (" << current_char_computePartition << ") did not update to (" - << computePartitionString(new_computePartition) << ")" + << computePartitionString(newPartition) << ")" << std::endl; } } else { ASSERT_EQ(RSMI_STATUS_SUCCESS, ret); - ASSERT_STREQ(computePartitionString(new_computePartition).c_str(), + ASSERT_STREQ(computePartitionString(newPartition).c_str(), current_char_computePartition); IF_VERB(STANDARD) { std::cout << "\t**" << "Confirmed current compute partition (" << current_char_computePartition << ") matches" << "\n\t requested compute partition (" - << computePartitionString(new_computePartition) << ")" + << computePartitionString(newPartition) << ")" << std::endl; } } @@ -355,26 +379,27 @@ void TestComputePartitionReadWrite::Run(void) { << "=========== TEST RETURN TO ORIGINAL COMPUTE PARTITION " << "SETTING ========" << std::endl; } - new_computePartition - = mapStringToRSMIComputePartitionTypes.at(orig_char_computePartition); - ret = rsmi_dev_compute_partition_set(dv_ind, new_computePartition); + newPartition + = mapStringToRSMIComputePartitionTypes.at( + std::string(orig_char_computePartition)); + ret = rsmi_dev_compute_partition_set(dv_ind, newPartition); CHK_ERR_ASRT(ret) IF_VERB(STANDARD) { std::cout << "\t**" << "Returning compute partition to: " - << computePartitionString(new_computePartition) << std::endl; + << computePartitionString(newPartition) << std::endl; } ret = rsmi_dev_compute_partition_get(dv_ind, current_char_computePartition, 255); CHK_ERR_ASRT(ret) IF_VERB(STANDARD) { std::cout << "\t**" << "Attempted to set compute partition: " - << computePartitionString(new_computePartition) << std::endl + << computePartitionString(newPartition) << std::endl << "\t**" << "Current compute partition: " << current_char_computePartition << std::endl; } ASSERT_EQ(RSMI_STATUS_SUCCESS, ret); - ASSERT_STREQ(computePartitionString(new_computePartition).c_str(), + ASSERT_STREQ(computePartitionString(newPartition).c_str(), current_char_computePartition); } } diff --git a/tests/rocm_smi_test/functional/npsmode_read_write.cc b/tests/rocm_smi_test/functional/memorypartition_read_write.cc similarity index 59% rename from tests/rocm_smi_test/functional/npsmode_read_write.cc rename to tests/rocm_smi_test/functional/memorypartition_read_write.cc index 67296ffbba..c24d3a915c 100755 --- a/tests/rocm_smi_test/functional/npsmode_read_write.cc +++ b/tests/rocm_smi_test/functional/memorypartition_read_write.cc @@ -47,45 +47,47 @@ #include #include +#include +#include #include "gtest/gtest.h" #include "rocm_smi/rocm_smi.h" -#include "rocm_smi_test/functional/npsmode_read_write.h" +#include "rocm_smi_test/functional/memorypartition_read_write.h" #include "rocm_smi_test/test_common.h" -TestNPSModeReadWrite::TestNPSModeReadWrite() : TestBase() { - set_title("RSMI NPS Mode Read Test"); - set_description("The NPS Mode tests verifies that the memory " - "parition setting can be read and updated properly."); +TestMemoryPartitionReadWrite::TestMemoryPartitionReadWrite() : TestBase() { + set_title("RSMI Memory Partition Read Test"); + set_description("The memory partition tests verifies that the memory " + "partition settings can be read and updated properly."); } -TestNPSModeReadWrite::~TestNPSModeReadWrite(void) { +TestMemoryPartitionReadWrite::~TestMemoryPartitionReadWrite(void) { } -void TestNPSModeReadWrite::SetUp(void) { +void TestMemoryPartitionReadWrite::SetUp(void) { TestBase::SetUp(); return; } -void TestNPSModeReadWrite::DisplayTestInfo(void) { +void TestMemoryPartitionReadWrite::DisplayTestInfo(void) { TestBase::DisplayTestInfo(); } -void TestNPSModeReadWrite::DisplayResults(void) const { +void TestMemoryPartitionReadWrite::DisplayResults(void) const { TestBase::DisplayResults(); return; } -void TestNPSModeReadWrite::Close() { +void TestMemoryPartitionReadWrite::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 std::string -npsModeString(rsmi_nps_mode_type npsModeType) { - switch (npsModeType) { +memoryPartitionString(rsmi_memory_partition_type memoryPartitionType) { + switch (memoryPartitionType) { case RSMI_MEMORY_PARTITION_NPS1: return "NPS1"; case RSMI_MEMORY_PARTITION_NPS2: @@ -99,20 +101,20 @@ npsModeString(rsmi_nps_mode_type npsModeType) { } } -static const std::map -mapStringToRSMINpsModeTypes { +static const std::map +mapStringToRSMIMemoryPartitionTypes { {"NPS1", RSMI_MEMORY_PARTITION_NPS1}, {"NPS2", RSMI_MEMORY_PARTITION_NPS2}, {"NPS4", RSMI_MEMORY_PARTITION_NPS4}, {"NPS8", RSMI_MEMORY_PARTITION_NPS8} }; -void TestNPSModeReadWrite::Run(void) { +void TestMemoryPartitionReadWrite::Run(void) { rsmi_status_t ret, err; - char orig_nps_mode[255]; - char current_nps_mode[255]; - orig_nps_mode[0] = '\0'; - current_nps_mode[0] = '\0'; + char orig_memory_partition[255]; + char current_memory_partition[255]; + orig_memory_partition[0] = '\0'; + current_memory_partition[0] = '\0'; TestBase::Run(); if (setup_failed_) { @@ -128,8 +130,8 @@ void TestNPSModeReadWrite::Run(void) { } PrintDeviceHeader(dv_ind); - //Standard checks to see if API is supported, before running full tests - ret = rsmi_dev_nps_mode_get(dv_ind, orig_nps_mode, 255); + // Standard checks to see if API is supported, before running full tests + ret = rsmi_dev_memory_partition_get(dv_ind, orig_memory_partition, 255); if (ret == RSMI_STATUS_NOT_SUPPORTED) { IF_VERB(STANDARD) { std::cout << "\t**" << ": " @@ -140,36 +142,35 @@ void TestNPSModeReadWrite::Run(void) { CHK_ERR_ASRT(ret) } IF_VERB(STANDARD) { - std::cout << std::endl << "\t**" - << "NPS Mode: " - << orig_nps_mode << std::endl; + std::cout << std::endl << "\t**Current Memory Partition: " + << orig_memory_partition << std::endl; } - if ((orig_nps_mode == nullptr) || - (orig_nps_mode[0] == '\0')) { - std::cout << "***System nps mode value is not defined or received unexpected data. " - "Skip nps mode test." << std::endl; + if ((orig_memory_partition == nullptr) || + (orig_memory_partition[0] == '\0')) { + std::cout << "***System memory partition value is not defined or received" + " unexpected data. Skip memory partition test." << std::endl; continue; } ASSERT_TRUE(ret == RSMI_STATUS_SUCCESS); // Verify api support checking functionality is working - uint32_t length = 2; - char smallBuffer[length]; - err = rsmi_dev_nps_mode_get(dv_ind, smallBuffer, length); + uint32_t kLen = 2; + char smallBuffer[kLen]; + err = rsmi_dev_memory_partition_get(dv_ind, smallBuffer, kLen); size_t size = sizeof(smallBuffer)/sizeof(*smallBuffer); ASSERT_EQ(err, RSMI_STATUS_INSUFFICIENT_SIZE); - ASSERT_EQ((size_t)length, size); + ASSERT_EQ((size_t)kLen, size); if (err == RSMI_STATUS_INSUFFICIENT_SIZE) { IF_VERB(STANDARD) { std::cout << "\t**" << "Confirmed RSMI_STATUS_INSUFFICIENT_SIZE was returned " - << "and size matches length requested." << std::endl; + << "and size matches kLen requested." << std::endl; } } // Verify api support checking functionality is working - err = rsmi_dev_nps_mode_get(dv_ind, nullptr, 255); + err = rsmi_dev_memory_partition_get(dv_ind, nullptr, 255); ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS); if (err == RSMI_STATUS_INVALID_ARGS) { @@ -181,7 +182,7 @@ void TestNPSModeReadWrite::Run(void) { } // Verify api support checking functionality is working - err = rsmi_dev_nps_mode_get(dv_ind, orig_nps_mode, 0); + err = rsmi_dev_memory_partition_get(dv_ind, orig_memory_partition, 0); ASSERT_TRUE((err == RSMI_STATUS_INVALID_ARGS) || (err == RSMI_STATUS_NOT_SUPPORTED)); if (err == RSMI_STATUS_INVALID_ARGS) { @@ -193,12 +194,12 @@ void TestNPSModeReadWrite::Run(void) { } /******************************/ - /* rsmi_dev_nps_mode_set(...) */ + /* rsmi_dev_memory_partition_set(...) */ /******************************/ // Verify api support checking functionality is working - rsmi_nps_mode_type new_nps_mode; - err = rsmi_dev_nps_mode_set(dv_ind, new_nps_mode); - // Note: new_nps_mode is not set + rsmi_memory_partition_type new_memory_partition; + err = rsmi_dev_memory_partition_set(dv_ind, new_memory_partition); + // Note: new_memory_partition is not set ASSERT_TRUE((err == RSMI_STATUS_INVALID_ARGS) || (err == RSMI_STATUS_NOT_SUPPORTED)); if (err == RSMI_STATUS_INVALID_ARGS) { @@ -210,9 +211,9 @@ void TestNPSModeReadWrite::Run(void) { } else if (err == RSMI_STATUS_NOT_SUPPORTED) { IF_VERB(STANDARD) { std::cout << "\t**" << ": " - << "rsmi_dev_nps_mode_set not supported on this device" - << "\n\t (if rsmi_dev_nps_mode_get works, then likely " - << "need to set in bios)" + << "rsmi_dev_memory_partition_set not supported on this " + << "device\n\t (if rsmi_dev_memory_partition_get works, " + << "then likely need to set in bios)" << std::endl; } continue; @@ -222,8 +223,9 @@ void TestNPSModeReadWrite::Run(void) { ASSERT_FALSE(err == RSMI_STATUS_PERMISSION); // Verify api support checking functionality is working - new_nps_mode = rsmi_nps_mode_type::RSMI_MEMORY_PARTITION_UNKNOWN; - err = rsmi_dev_nps_mode_set(dv_ind, new_nps_mode); + new_memory_partition = + rsmi_memory_partition_type::RSMI_MEMORY_PARTITION_UNKNOWN; + err = rsmi_dev_memory_partition_set(dv_ind, new_memory_partition); ASSERT_TRUE((err == RSMI_STATUS_INVALID_ARGS) || (err == RSMI_STATUS_NOT_SUPPORTED) || (err == RSMI_STATUS_PERMISSION)); @@ -242,101 +244,106 @@ void TestNPSModeReadWrite::Run(void) { } // Re-run original get, so we can reset to later - ret = rsmi_dev_nps_mode_get(dv_ind, orig_nps_mode, 255); + ret = rsmi_dev_memory_partition_get(dv_ind, orig_memory_partition, 255); ASSERT_EQ(RSMI_STATUS_SUCCESS, ret); for (int partition = RSMI_MEMORY_PARTITION_NPS1; partition <= RSMI_MEMORY_PARTITION_NPS8; partition++) { - new_nps_mode = static_cast(partition); + new_memory_partition = static_cast(partition); IF_VERB(STANDARD) { std::cout << std::endl; std::cout << "\t**" << "======== TEST RSMI_MEMORY_PARTITION_" - << npsModeString(new_nps_mode) + << memoryPartitionString(new_memory_partition) << " ===============" << std::endl; } IF_VERB(STANDARD) { std::cout << "\t**" - << "Attempting to set nps mode to: " - << npsModeString(new_nps_mode) << std::endl; + << "Attempting to set memory partition to: " + << memoryPartitionString(new_memory_partition) << std::endl; } - ret = rsmi_dev_nps_mode_set(dv_ind, new_nps_mode); + ret = rsmi_dev_memory_partition_set(dv_ind, new_memory_partition); CHK_ERR_ASRT(ret) - ret = rsmi_dev_nps_mode_get(dv_ind, current_nps_mode, 255); + ret = rsmi_dev_memory_partition_get(dv_ind, current_memory_partition, + 255); CHK_ERR_ASRT(ret) IF_VERB(STANDARD) { std::cout << "\t**" - << "Current nps mode: " << current_nps_mode << std::endl; + << "Current memory partition: " << current_memory_partition + << std::endl; } ASSERT_EQ(RSMI_STATUS_SUCCESS, ret); - ASSERT_STREQ(npsModeString(new_nps_mode).c_str(), current_nps_mode); + ASSERT_STREQ(memoryPartitionString(new_memory_partition).c_str(), + current_memory_partition); } - /* TEST RETURN TO BOOT NPS MODE SETTING */ + /* TEST RETURN TO BOOT MEMORY PARTITION SETTING */ IF_VERB(STANDARD) { std::cout << std::endl; std::cout << "\t**" - << "=========== TEST RETURN TO BOOT NPS MODE SETTING " - << "========" << std::endl; + << "=========== TEST RETURN TO BOOT MEMORY PARTITION " + << "SETTING ========" << std::endl; } - std::string oldMode = current_nps_mode; + std::string oldMode = current_memory_partition; bool wasResetSuccess = false; - ret = rsmi_dev_nps_mode_reset(dv_ind); + ret = rsmi_dev_memory_partition_reset(dv_ind); ASSERT_TRUE((ret == RSMI_STATUS_SUCCESS) || (ret == RSMI_STATUS_NOT_SUPPORTED)); if (ret == RSMI_STATUS_SUCCESS) { wasResetSuccess = true; } - ret = rsmi_dev_nps_mode_get(dv_ind, current_nps_mode, 255); + ret = rsmi_dev_memory_partition_get(dv_ind, current_memory_partition, 255); CHK_ERR_ASRT(ret) IF_VERB(STANDARD) { std::cout << "\t**" - << "Current nps mode: " << current_nps_mode << std::endl; + << "Current memory partition: " << current_memory_partition + << std::endl; } if (wasResetSuccess) { - ASSERT_STRNE(oldMode.c_str(), current_nps_mode); + ASSERT_STRNE(oldMode.c_str(), current_memory_partition); IF_VERB(STANDARD) { std::cout << "\t**" - << "Confirmed prior nps mode (" << oldMode << ") is not " - << "equal to current nps mode (" - << current_nps_mode << ")" << std::endl; + << "Confirmed prior memory partition (" << oldMode << ") is " + << "not equal to current memory partition (" + << current_memory_partition << ")" << std::endl; } } else { - ASSERT_STREQ(oldMode.c_str(), current_nps_mode); + ASSERT_STREQ(oldMode.c_str(), current_memory_partition); IF_VERB(STANDARD) { std::cout << "\t**" - << "Confirmed prior nps mode (" << oldMode << ") is equal" - << " to current nps mode (" - << current_nps_mode << ")" << std::endl; + << "Confirmed prior memory partition (" << oldMode << ") is " + << "equal to current memory partition (" + << current_memory_partition << ")" << std::endl; } } - /* TEST RETURN TO ORIGINAL NPS MODE SETTING */ + /* TEST RETURN TO ORIGINAL MEMORY PARTITION SETTING */ IF_VERB(STANDARD) { std::cout << std::endl; std::cout << "\t**" - << "=========== TEST RETURN TO ORIGINAL NPS MODE " + << "=========== TEST RETURN TO ORIGINAL MEMORY PARTITION " << "SETTING ========" << std::endl; } - new_nps_mode - = mapStringToRSMINpsModeTypes.at(orig_nps_mode); + new_memory_partition + = mapStringToRSMIMemoryPartitionTypes.at(orig_memory_partition); IF_VERB(STANDARD) { - std::cout << "\t**" << "Returning nps mode to: " - << npsModeString(new_nps_mode) << std::endl; + std::cout << "\t**" << "Returning memory partition to: " + << memoryPartitionString(new_memory_partition) << std::endl; } - ret = rsmi_dev_nps_mode_set(dv_ind, new_nps_mode); + ret = rsmi_dev_memory_partition_set(dv_ind, new_memory_partition); CHK_ERR_ASRT(ret) - ret = rsmi_dev_nps_mode_get(dv_ind, current_nps_mode, 255); + ret = rsmi_dev_memory_partition_get(dv_ind, current_memory_partition, 255); CHK_ERR_ASRT(ret) IF_VERB(STANDARD) { - std::cout << "\t**" << "Attempted to set nps mode: " - << npsModeString(new_nps_mode) << std::endl - << "\t**" << "Current nps mode: " << current_nps_mode + std::cout << "\t**" << "Attempted to set memory partition: " + << memoryPartitionString(new_memory_partition) << std::endl + << "\t**" << "Current memory partition: " + << current_memory_partition << std::endl; } ASSERT_EQ(RSMI_STATUS_SUCCESS, ret); - ASSERT_STREQ(npsModeString(new_nps_mode).c_str(), current_nps_mode); + ASSERT_STREQ(memoryPartitionString(new_memory_partition).c_str(), current_memory_partition); } } diff --git a/tests/rocm_smi_test/functional/npsmode_read_write.h b/tests/rocm_smi_test/functional/memorypartition_read_write.h similarity index 85% rename from tests/rocm_smi_test/functional/npsmode_read_write.h rename to tests/rocm_smi_test/functional/memorypartition_read_write.h index 54eed75e01..1576ae9029 100755 --- a/tests/rocm_smi_test/functional/npsmode_read_write.h +++ b/tests/rocm_smi_test/functional/memorypartition_read_write.h @@ -42,17 +42,17 @@ * DEALINGS WITH THE SOFTWARE. * */ -#ifndef TESTS_ROCM_SMI_TEST_FUNCTIONAL_NPSMODE_READ_WRITE_H_ -#define TESTS_ROCM_SMI_TEST_FUNCTIONAL_NPSMODE_READ_WRITE_H_ +#ifndef TESTS_ROCM_SMI_TEST_FUNCTIONAL_MEMORYPARTITION_READ_WRITE_H_ +#define TESTS_ROCM_SMI_TEST_FUNCTIONAL_MEMORYPARTITION_READ_WRITE_H_ #include "rocm_smi_test/test_base.h" -class TestNPSModeReadWrite : public TestBase { +class TestMemoryPartitionReadWrite : public TestBase { public: - TestNPSModeReadWrite(); + TestMemoryPartitionReadWrite(); - // @Brief: Destructor for test case of TestNPSModeReadWrite - virtual ~TestNPSModeReadWrite(); + // @Brief: Destructor for test case of TestMemoryPartitionReadWrite + virtual ~TestMemoryPartitionReadWrite(); // @Brief: Setup the environment for measurement virtual void SetUp(); @@ -70,4 +70,4 @@ class TestNPSModeReadWrite : public TestBase { virtual void DisplayTestInfo(void); }; -#endif // TESTS_ROCM_SMI_TEST_FUNCTIONAL_NPSMODE_READ_WRITE_H_ +#endif // TESTS_ROCM_SMI_TEST_FUNCTIONAL_MEMORYPARTITION_READ_WRITE_H_ diff --git a/tests/rocm_smi_test/main.cc b/tests/rocm_smi_test/main.cc index 774aaaa0ce..8e140f4634 100755 --- a/tests/rocm_smi_test/main.cc +++ b/tests/rocm_smi_test/main.cc @@ -87,7 +87,7 @@ #include "rocm_smi_test/functional/gpu_metrics_read.h" #include "rocm_smi_test/functional/metrics_counter_read.h" #include "rocm_smi_test/functional/perf_determinism.h" -#include "functional/npsmode_read_write.h" +#include "functional/memorypartition_read_write.h" static RSMITstGlobals *sRSMIGlvalues = nullptr; @@ -271,8 +271,8 @@ TEST(rsmitstReadWrite, TestComputePartitionReadWrite) { TestComputePartitionReadWrite tst; RunGenericTest(&tst); } -TEST(rsmitstReadWrite, TestNPSModeReadWrite) { - TestNPSModeReadWrite tst; +TEST(rsmitstReadWrite, TestMemoryPartitionReadWrite) { + TestMemoryPartitionReadWrite tst; RunGenericTest(&tst); } TEST(rsmitstReadWrite, TestEvtNotifReadWrite) { From 4e4ebde640a01e09cf853bdb30987b07bc87747c Mon Sep 17 00:00:00 2001 From: "Oliveira, Daniel" Date: Fri, 29 Sep 2023 12:49:48 -0500 Subject: [PATCH 03/11] rocm_smi_lib: Fix Modernize and refactor gpu_metrics Adds support for 'gpu_metrics_v1_4' and new counters Code changes related to the following: * rsmi gpu_metrics APIs * rsmi gpu_metrics Logs * The new gpu_metrics are now part of the Device Build changes related to the following: None Change-Id: Ie748e977cd0a01c6a2fb82260014c0699605dbb3 Signed-off-by: Oliveira, Daniel --- CMakeLists.txt | 2 + include/rocm_smi/rocm_smi.h | 2 - include/rocm_smi/rocm_smi_device.h | 20 + include/rocm_smi/rocm_smi_gpu_metrics.h | 681 ++++++++++++++ src/rocm_smi.cc | 613 ++++++++++++- src/rocm_smi_gpu_metrics.cc | 1114 ++++++++++++++++++++++- 6 files changed, 2422 insertions(+), 10 deletions(-) create mode 100644 include/rocm_smi/rocm_smi_gpu_metrics.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 0fb959ad07..c5bb82ce3a 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,6 +73,7 @@ endif() ## Compiler flags set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -fno-rtti -m64 -msse -msse2 ") + # Security options set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wconversion -Wcast-align ") @@ -148,6 +149,7 @@ set(CMN_INC_LIST ${CMN_INC_LIST} "${COMMON_INC_DIR}/rocm_smi_exception.h") set(CMN_INC_LIST ${CMN_INC_LIST} "${COMMON_INC_DIR}/rocm_smi_counters.h") set(CMN_INC_LIST ${CMN_INC_LIST} "${COMMON_INC_DIR}/rocm_smi_kfd.h") set(CMN_INC_LIST ${CMN_INC_LIST} "${COMMON_INC_DIR}/rocm_smi_io_link.h") +set(CMN_INC_LIST ${CMN_INC_LIST} "${COMMON_INC_DIR}/rocm_smi_gpu_metrics.h") set(CMN_INC_LIST ${CMN_INC_LIST} "${COMMON_INC_DIR}/rocm_smi.h") set(CMN_INC_LIST ${CMN_INC_LIST} "${COMMON_INC_DIR}/rocm_smi_logger.h") set(CMN_INC_LIST ${CMN_INC_LIST} "${COMMON_INC_DIR}/rocm_smi_properties.h") diff --git a/include/rocm_smi/rocm_smi.h b/include/rocm_smi/rocm_smi.h index 7817acd6ea..900dcee0f2 100755 --- a/include/rocm_smi/rocm_smi.h +++ b/include/rocm_smi/rocm_smi.h @@ -929,12 +929,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 */ diff --git a/include/rocm_smi/rocm_smi_device.h b/include/rocm_smi/rocm_smi_device.h index 7a28e1327c..0880350a3e 100755 --- a/include/rocm_smi/rocm_smi_device.h +++ b/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 { @@ -228,6 +229,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_; @@ -249,6 +262,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/src/rocm_smi.cc b/src/rocm_smi.cc index 2108a52289..3f09b83683 100755 --- a/src/rocm_smi.cc +++ b/src/rocm_smi.cc @@ -3517,7 +3517,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; @@ -3535,7 +3534,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 @@ -5405,6 +5403,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, GPUMetricVcnActivityTbl_t* vcn_activity_value) +{ + TRY + std::ostringstream ostrstream; + ostrstream << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ostrstream); + + const auto gpu_metric_unit(AMDGpuMetricsUnitType_t::kMetricVcnActivity); + 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, 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); + 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, 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); + 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, GPUMetricCurrGfxClkTbl_t* current_gfxclk_value) +{ + TRY + std::ostringstream ostrstream; + ostrstream << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ostrstream); + + const auto gpu_metric_unit(AMDGpuMetricsUnitType_t::kMetricVcnActivity); + 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, GPUMetricCurrSocClkTbl_t* current_socclk_value) +{ + TRY + std::ostringstream ostrstream; + ostrstream << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ostrstream); + + const auto gpu_metric_unit(AMDGpuMetricsUnitType_t::kMetricVcnActivity); + 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, GPUMetricCurrVClkTbl_t* current_vclk_value) +{ + TRY + std::ostringstream ostrstream; + ostrstream << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ostrstream); + + const auto gpu_metric_unit(AMDGpuMetricsUnitType_t::kMetricVcnActivity); + 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, GPUMetricCurrDClkTbl_t* current_dclk_value) +{ + TRY + std::ostringstream ostrstream; + ostrstream << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ostrstream); + + const auto gpu_metric_unit(AMDGpuMetricsUnitType_t::kMetricVcnActivity); + 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. @@ -5439,3 +6047,4 @@ rsmi_test_refcount(uint64_t refcnt_type) { return static_cast(smi.ref_count()); } + diff --git a/src/rocm_smi_gpu_metrics.cc b/src/rocm_smi_gpu_metrics.cc index 16d629895d..6123eae147 100755 --- a/src/rocm_smi_gpu_metrics.cc +++ b/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 From 31a1fcce7d3f6c6fae8f69671329f8e3fdb0d692 Mon Sep 17 00:00:00 2001 From: Charis Poag Date: Wed, 4 Oct 2023 16:18:32 -0500 Subject: [PATCH 04/11] Add rsmi_dev_power_get * Updates: - [API] Added rsmi_dev_power_get(uint32_t dv_ind, uint64_t *power, RSMI_POWER_TYPE *type) provides generic get to average or current power & provides backwards compatibility - Added a utility function to get MonitorTypes (monitor_type_string(type)) & RSMI_POWER_TYPE (power_type_string(type)) strings - [Tests] Added rsmi_dev_power_get tests and provided better verification of return values for all power APIs - [Tests] Updated power outputs to show correct units - [example] Now uses avg, current, and generic power functions with type output response Change-Id: I5ca06ca37fd5f61e100f2835b664d6cdd1ca42e6 Signed-off-by: Charis Poag --- include/rocm_smi/rocm_smi.h | 43 +++++++ include/rocm_smi/rocm_smi_utils.h | 2 + rocm_smi/example/rocm_smi_example.cc | 32 +++++- src/rocm_smi.cc | 111 ++++++++++++++----- src/rocm_smi_utils.cc | 94 +++++++++++++++- tests/rocm_smi_test/functional/power_read.cc | 54 ++++++--- tests/rocm_smi_test/functional/power_read.h | 2 +- tests/rocm_smi_test/test_common.cc | 5 + tests/rocm_smi_test/test_common.h | 2 + 9 files changed, 294 insertions(+), 51 deletions(-) diff --git a/include/rocm_smi/rocm_smi.h b/include/rocm_smi/rocm_smi.h index 900dcee0f2..a3396ae4a2 100755 --- a/include/rocm_smi/rocm_smi.h +++ b/include/rocm_smi/rocm_smi.h @@ -697,6 +697,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 */ @@ -1729,6 +1738,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. diff --git a/include/rocm_smi/rocm_smi_utils.h b/include/rocm_smi/rocm_smi_utils.h index 49a3521dc1..9c1ef0290d 100755 --- a/include/rocm_smi/rocm_smi_utils.h +++ b/include/rocm_smi/rocm_smi_utils.h @@ -110,6 +110,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/example/rocm_smi_example.cc b/rocm_smi/example/rocm_smi_example.cc index 45e79b07fd..a2df8e66ee 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__ << "\n"; \ - rsmi_status_string((RET), &err_str); \ - std::cout << err_str << "\n"; \ + << " at line " << __LINE__ << std::endl; \ + std::cout << amd::smi::getRSMIStatusString(RET) << std::endl; \ } \ } @@ -696,6 +695,10 @@ static rsmi_status_t test_set_memory_partition(uint32_t dv_ind) { 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; @@ -711,9 +714,11 @@ 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 << "\n"; @@ -816,7 +821,7 @@ int main() { 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" << "\n"; + std::cout << (val_i64 / 1000) << "C" << std::endl; } CHK_RSMI_NOT_SUPPORTED_RET(ret) @@ -864,7 +869,22 @@ int main() { std::cout << "\t**Average Power Usage: "; ret = rsmi_dev_power_ave_get(i, 0, &val_ui64); if (ret == RSMI_STATUS_SUCCESS) { - std::cout << static_cast(val_ui64)/1000 << " W" << "\n"; + std::cout << convert_mw_to_w(val_ui64) << " W" << std::endl; + } + CHK_RSMI_NOT_SUPPORTED_RET(ret) + + 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"; diff --git a/src/rocm_smi.cc b/src/rocm_smi.cc index 3f09b83683..2ee44473ad 100755 --- a/src/rocm_smi.cc +++ b/src/rocm_smi.cc @@ -61,7 +61,6 @@ #include #include #include -#include #include #include @@ -77,7 +76,9 @@ #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; +auto &devInfoTypesStrings = amd::smi::RocmSMI::devInfoTypesStrings; static const uint32_t kMaxOverdriveLevel = 20; static const float kEnergyCounterResolution = 15.3F; @@ -2838,7 +2839,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); @@ -2905,6 +2906,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) { @@ -3106,7 +3159,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); @@ -3117,7 +3170,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); @@ -3166,7 +3219,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); @@ -3177,7 +3230,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); @@ -3188,7 +3241,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); @@ -4444,7 +4497,7 @@ rsmi_dev_compute_partition_get(uint32_t dv_ind, char *compute_partition, << " | Fail " << " | Device #: " << dv_ind << " | Type: " - << RocmSMI::devInfoTypesStrings.at(amd::smi::kDevComputePartition) + << devInfoTypesStrings.at(amd::smi::kDevComputePartition) << " | Cause: len was 0 or compute_partition variable was null" << " | Returning = " << getRSMIStatusString(RSMI_STATUS_INVALID_ARGS) << " |"; @@ -4463,7 +4516,7 @@ rsmi_dev_compute_partition_get(uint32_t dv_ind, char *compute_partition, << " | Fail " << " | Device #: " << dv_ind << " | Type: " - << RocmSMI::devInfoTypesStrings.at(amd::smi::kDevComputePartition) + << devInfoTypesStrings.at(amd::smi::kDevComputePartition) << " | Cause: could not retrieve current compute partition" << " | Returning = " << getRSMIStatusString(ret) << " |"; @@ -4480,7 +4533,7 @@ rsmi_dev_compute_partition_get(uint32_t dv_ind, char *compute_partition, << " | Fail " << " | Device #: " << dv_ind << " | Type: " - << RocmSMI::devInfoTypesStrings.at(amd::smi::kDevComputePartition) + << devInfoTypesStrings.at(amd::smi::kDevComputePartition) << " | Cause: requested size was insufficient" << " | Returning = " << getRSMIStatusString(RSMI_STATUS_INSUFFICIENT_SIZE) << " |"; @@ -4492,7 +4545,7 @@ rsmi_dev_compute_partition_get(uint32_t dv_ind, char *compute_partition, << " | Success " << " | Device #: " << dv_ind << " | Type: " - << RocmSMI::devInfoTypesStrings.at(amd::smi::kDevComputePartition) + << devInfoTypesStrings.at(amd::smi::kDevComputePartition) << " | Data: " << compute_partition << " | Returning = " << getRSMIStatusString(ret) << " |"; @@ -4549,7 +4602,7 @@ rsmi_dev_compute_partition_set(uint32_t dv_ind, << " | Fail " << " | Device #: " << dv_ind << " | Type: " - << RocmSMI::devInfoTypesStrings.at(amd::smi::kDevComputePartition) + << devInfoTypesStrings.at(amd::smi::kDevComputePartition) << " | Cause: requested setting was invalid" << " | Returning = " << getRSMIStatusString(RSMI_STATUS_INVALID_ARGS) << " |"; @@ -4567,7 +4620,7 @@ rsmi_dev_compute_partition_set(uint32_t dv_ind, << " | Fail " << " | Device #: " << dv_ind << " | Type: " - << RocmSMI::devInfoTypesStrings.at(amd::smi::kDevComputePartition) + << devInfoTypesStrings.at(amd::smi::kDevComputePartition) << " | Cause: not an available compute partition setting" << " | Returning = " << getRSMIStatusString(available_ret) << " |"; @@ -4586,7 +4639,7 @@ rsmi_dev_compute_partition_set(uint32_t dv_ind, << " | Fail " << " | Device #: " << dv_ind << " | Type: " - << RocmSMI::devInfoTypesStrings.at(amd::smi::kDevComputePartition) + << devInfoTypesStrings.at(amd::smi::kDevComputePartition) << " | Cause: could retrieve current compute partition or retrieved" << " unexpected data" << " | Returning = " @@ -4602,7 +4655,7 @@ rsmi_dev_compute_partition_set(uint32_t dv_ind, << " | Success - compute partition was already set at requested value" << " | Device #: " << dv_ind << " | Type: " - << RocmSMI::devInfoTypesStrings.at(amd::smi::kDevComputePartition) + << devInfoTypesStrings.at(amd::smi::kDevComputePartition) << " | Data: " << newComputePartitionStr << " | Returning = " << getRSMIStatusString(RSMI_STATUS_SUCCESS) << " |"; @@ -4619,7 +4672,7 @@ rsmi_dev_compute_partition_set(uint32_t dv_ind, << " | Success " << " | Device #: " << dv_ind << " | Type: " - << RocmSMI::devInfoTypesStrings.at(amd::smi::kDevComputePartition) + << devInfoTypesStrings.at(amd::smi::kDevComputePartition) << " | Data: " << newComputePartitionStr << " | Returning = " << getRSMIStatusString(returnResponse) << " |"; @@ -4691,7 +4744,7 @@ rsmi_dev_memory_partition_set(uint32_t dv_ind, << " | Fail " << " | Device #: " << dv_ind << " | Type: " - << RocmSMI::devInfoTypesStrings.at(amd::smi::kDevMemoryPartition) + << devInfoTypesStrings.at(amd::smi::kDevMemoryPartition) << " | Cause: device board name does not support this action" << " | Returning = " << getRSMIStatusString(RSMI_STATUS_INVALID_ARGS) << " |"; @@ -4716,7 +4769,7 @@ rsmi_dev_memory_partition_set(uint32_t dv_ind, << " | Fail " << " | Device #: " << dv_ind << " | Type: " - << RocmSMI::devInfoTypesStrings.at(amd::smi::kDevMemoryPartition) + << devInfoTypesStrings.at(amd::smi::kDevMemoryPartition) << " | Cause: requested setting was invalid" << " | Returning = " << getRSMIStatusString(RSMI_STATUS_INVALID_ARGS) << " |"; @@ -4734,7 +4787,7 @@ rsmi_dev_memory_partition_set(uint32_t dv_ind, << " | Fail " << " | Device #: " << dv_ind << " | Type: " - << RocmSMI::devInfoTypesStrings.at(amd::smi::kDevMemoryPartition) + << devInfoTypesStrings.at(amd::smi::kDevMemoryPartition) << " | Cause: could retrieve current memory partition or retrieved" << " unexpected data" << " | Returning = " @@ -4751,7 +4804,7 @@ rsmi_dev_memory_partition_set(uint32_t dv_ind, << " setting" << " | Device #: " << dv_ind << " | Type: " - << RocmSMI::devInfoTypesStrings.at(amd::smi::kDevMemoryPartition) + << devInfoTypesStrings.at(amd::smi::kDevMemoryPartition) << " | Data: " << newMemoryPartition << " | Returning = " << getRSMIStatusString(RSMI_STATUS_SUCCESS) << " |"; @@ -4770,7 +4823,7 @@ rsmi_dev_memory_partition_set(uint32_t dv_ind, << " | Fail " << " | Device #: " << dv_ind << " | Type: " - << RocmSMI::devInfoTypesStrings.at(amd::smi::kDevMemoryPartition) + << devInfoTypesStrings.at(amd::smi::kDevMemoryPartition) << " | Cause: issue writing reqested setting of " + newMemoryPartition << " | Returning = " << getRSMIStatusString(err) << " |"; @@ -4784,7 +4837,7 @@ rsmi_dev_memory_partition_set(uint32_t dv_ind, << " | Success - if restart completed successfully" << " | Device #: " << dv_ind << " | Type: " - << RocmSMI::devInfoTypesStrings.at(amd::smi::kDevMemoryPartition) + << devInfoTypesStrings.at(amd::smi::kDevMemoryPartition) << " | Data: " << newMemoryPartition << " | Returning = " << getRSMIStatusString(restartRet) << " |"; @@ -4806,7 +4859,7 @@ rsmi_dev_memory_partition_get(uint32_t dv_ind, char *memory_partition, << " | Fail " << " | Device #: " << dv_ind << " | Type: " - << RocmSMI::devInfoTypesStrings.at(amd::smi::kDevMemoryPartition) + << devInfoTypesStrings.at(amd::smi::kDevMemoryPartition) << " | Cause: user sent invalid arguments, len = 0 or memory partition" << " was a null ptr" << " | Returning = " @@ -4826,7 +4879,7 @@ rsmi_dev_memory_partition_get(uint32_t dv_ind, char *memory_partition, << " | Fail " << " | Device #: " << dv_ind << " | Type: " - << RocmSMI::devInfoTypesStrings.at(amd::smi::kDevMemoryPartition) + << devInfoTypesStrings.at(amd::smi::kDevMemoryPartition) << " | Cause: could not successfully retrieve current memory partition " << " | Returning = " << getRSMIStatusString(ret) << " |"; @@ -4844,7 +4897,7 @@ rsmi_dev_memory_partition_get(uint32_t dv_ind, char *memory_partition, << " | Fail " << " | Device #: " << dv_ind << " | Type: " - << RocmSMI::devInfoTypesStrings.at(amd::smi::kDevMemoryPartition) + << devInfoTypesStrings.at(amd::smi::kDevMemoryPartition) << " | Cause: could not successfully retrieve current memory partition " << " | Returning = " << getRSMIStatusString(ret) << " |"; @@ -4856,7 +4909,7 @@ rsmi_dev_memory_partition_get(uint32_t dv_ind, char *memory_partition, << " | Success " << " | Device #: " << dv_ind << " | Type: " - << RocmSMI::devInfoTypesStrings.at(amd::smi::kDevMemoryPartition) + << devInfoTypesStrings.at(amd::smi::kDevMemoryPartition) << " | Data: " << memory_partition << " | Returning = " << getRSMIStatusString(ret) << " |"; @@ -4895,7 +4948,7 @@ rsmi_status_t rsmi_dev_compute_partition_reset(uint32_t dv_ind) { << " | Success - if original boot state was not unknown or valid setting" << " | Device #: " << dv_ind << " | Type: " - << RocmSMI::devInfoTypesStrings.at(amd::smi::kDevComputePartition) + << devInfoTypesStrings.at(amd::smi::kDevComputePartition) << " | Data: " << bootState << " | Returning = " << getRSMIStatusString(ret) << " |"; @@ -4934,7 +4987,7 @@ rsmi_status_t rsmi_dev_memory_partition_reset(uint32_t dv_ind) { << " | Success - if original boot state was not unknown or valid setting" << " | Device #: " << dv_ind << " | Type: " - << RocmSMI::devInfoTypesStrings.at(amd::smi::kDevMemoryPartition) + << devInfoTypesStrings.at(amd::smi::kDevMemoryPartition) << " | Data: " << bootState << " | Returning = " << getRSMIStatusString(ret) << " |"; diff --git a/src/rocm_smi_utils.cc b/src/rocm_smi_utils.cc index 66944ba524..db11f0645c 100755 --- a/src/rocm_smi_utils.cc +++ b/src/rocm_smi_utils.cc @@ -48,7 +48,6 @@ #include #include #include -#include #include #include @@ -63,7 +62,6 @@ #include #include #include -#include #include #include "rocm_smi/rocm_smi.h" @@ -884,5 +882,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/tests/rocm_smi_test/functional/power_read.cc b/tests/rocm_smi_test/functional/power_read.cc index 641ddde00e..f379fd48c8 100755 --- a/tests/rocm_smi_test/functional/power_read.cc +++ b/tests/rocm_smi_test/functional/power_read.cc @@ -5,7 +5,7 @@ * The University of Illinois/NCSA * Open Source License (NCSA) * - * Copyright (c) 2019, Advanced Micro Devices, Inc. + * Copyright (c) 2019-2023, Advanced Micro Devices, Inc. * All rights reserved. * * Developed by: @@ -89,6 +89,7 @@ void TestPowerRead::Close() { void TestPowerRead::Run(void) { rsmi_status_t err; uint64_t val_ui64, val2_ui64; + RSMI_POWER_TYPE type = RSMI_INVALID_POWER; TestBase::Run(); if (setup_failed_) { @@ -119,44 +120,71 @@ void TestPowerRead::Run(void) { /* Average Power */ err = rsmi_dev_power_ave_get(i, 0, &val_ui64); + + ASSERT_TRUE(err == RSMI_STATUS_SUCCESS + || err == RSMI_STATUS_NOT_SUPPORTED); if (err == RSMI_STATUS_NOT_SUPPORTED) { std::cout << "\t**Average Power Usage: not supported on this device" << std::endl; } else { + CHK_RSMI_PERM_ERR(err) IF_VERB(STANDARD) { std::cout << "\t**Average Power Usage: "; - CHK_RSMI_PERM_ERR(err) if (err == RSMI_STATUS_SUCCESS) { - std::cout << static_cast(val_ui64) / 1000 << " mW" + std::cout << static_cast(val_ui64) / 1000 << " W" << std::endl; } - // Verify api support checking functionality is working - err = rsmi_dev_power_ave_get(i, 0, nullptr); - ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS); } + // Verify api support checking functionality is working + err = rsmi_dev_power_ave_get(i, 0, nullptr); + ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS); } /* Current Socket Power */ err = rsmi_dev_current_socket_power_get(i, &val_ui64); - + ASSERT_TRUE(err == RSMI_STATUS_SUCCESS + || err == RSMI_STATUS_NOT_SUPPORTED); if (err == RSMI_STATUS_NOT_SUPPORTED) { std::cout << "\t**Current Socket Power: not supported" " on this device" << std::endl; } else { + CHK_RSMI_PERM_ERR(err) IF_VERB(STANDARD) { std::cout << "\t**Current Socket Power: "; - CHK_RSMI_PERM_ERR(err) if (err == RSMI_STATUS_SUCCESS) { - std::cout << static_cast(val_ui64) / 1000 << " mW" + std::cout << static_cast(val_ui64) / 1000 << " W" << std::endl; } - // Verify api support checking functionality is working - err = rsmi_dev_current_socket_power_get(i, nullptr); - // std::cout << "err = " << amd::smi::getRSMIStatusString(err); - ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS); } + // Verify api support checking functionality is working + err = rsmi_dev_current_socket_power_get(i, nullptr); + ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS); + } + + /* Generic Power */ + err = rsmi_dev_power_get(i, &val_ui64, &type); + ASSERT_TRUE(err == RSMI_STATUS_SUCCESS + || err == RSMI_STATUS_NOT_SUPPORTED); + + if (err == RSMI_STATUS_NOT_SUPPORTED) { + std::cout << + "\t**Generic Power: not supported" + " on this device" << std::endl; + } else { + CHK_RSMI_PERM_ERR(err) + IF_VERB(STANDARD) { + std::cout << "\t**Generic Power: "; + if (err == RSMI_STATUS_SUCCESS) { + std::cout << "[" << amd::smi::power_type_string(type) << "] " + << static_cast(val_ui64) / 1000 << " W" + << std::endl; + } + } + // Verify api support checking functionality is working + err = rsmi_dev_power_get(i, nullptr, nullptr); + ASSERT_EQ(err, RSMI_STATUS_INVALID_ARGS); } std::cout << "\n"; } diff --git a/tests/rocm_smi_test/functional/power_read.h b/tests/rocm_smi_test/functional/power_read.h index f9d5b83e33..2a5746c251 100755 --- a/tests/rocm_smi_test/functional/power_read.h +++ b/tests/rocm_smi_test/functional/power_read.h @@ -5,7 +5,7 @@ * The University of Illinois/NCSA * Open Source License (NCSA) * - * Copyright (c) 2019, Advanced Micro Devices, Inc. + * Copyright (c) 2019-2023, Advanced Micro Devices, Inc. * All rights reserved. * * Developed by: diff --git a/tests/rocm_smi_test/test_common.cc b/tests/rocm_smi_test/test_common.cc index db6fa24098..5e8e3f8e47 100755 --- a/tests/rocm_smi_test/test_common.cc +++ b/tests/rocm_smi_test/test_common.cc @@ -54,6 +54,7 @@ #include "rocm_smi_test/test_base.h" #include "rocm_smi_test/test_common.h" #include "rocm_smi/rocm_smi.h" +#include "rocm_smi/rocm_smi_utils.h" static const std::map kDevPerfLvlNameMap = { @@ -227,6 +228,10 @@ const char *FreqEnumToStr(rsmi_clk_type rsmi_clk) { } } +void printRSMIError(rsmi_status_t err) { + std::cout << "err = " << amd::smi::getRSMIStatusString(err); +} + #if ENABLE_SMI void DumpMonitorInfo(const TestBase *test) { int ret = 0; diff --git a/tests/rocm_smi_test/test_common.h b/tests/rocm_smi_test/test_common.h index ba425cc462..f976a7c0e7 100755 --- a/tests/rocm_smi_test/test_common.h +++ b/tests/rocm_smi_test/test_common.h @@ -98,4 +98,6 @@ void DumpMonitorInfo(const TestBase *test); } \ } +void printRSMIError(rsmi_status_t err); + #endif // TESTS_ROCM_SMI_TEST_TEST_COMMON_H_ From b47d028da2af7d83e79491fea483e171482b54d5 Mon Sep 17 00:00:00 2001 From: Maisam Arif Date: Tue, 10 Oct 2023 10:32:20 -0500 Subject: [PATCH 05/11] Removed uncountable blocks from metric --ecc-block Signed-off-by: Maisam Arif Change-Id: Iab8ed3f80c8ebd7ffd3bfcf197e1a0b03782b498 --- amdsmi_cli/amdsmi_commands.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/amdsmi_cli/amdsmi_commands.py b/amdsmi_cli/amdsmi_commands.py index 9c5aa09f3e..a243adfd74 100644 --- a/amdsmi_cli/amdsmi_commands.py +++ b/amdsmi_cli/amdsmi_commands.py @@ -1003,19 +1003,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: From b46ae13011c59fce282a052460b22b1a2eff30d7 Mon Sep 17 00:00:00 2001 From: Maisam Arif Date: Tue, 10 Oct 2023 13:22:36 -0500 Subject: [PATCH 06/11] Corrected total ecc counts Signed-off-by: Maisam Arif Change-Id: I48b85d6476b829604044daab420883f94551abe2 --- amdsmi_cli/amdsmi_parser.py | 2 +- src/amd_smi/amd_smi.cc | 29 +++++++++++++++++++++-------- 2 files changed, 22 insertions(+), 9 deletions(-) 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/src/amd_smi/amd_smi.cc b/src/amd_smi/amd_smi.cc index 201881b462..78f9c130bb 100644 --- a/src/amd_smi/amd_smi.cc +++ b/src/amd_smi/amd_smi.cc @@ -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; From 1b606acf73e906488933c45c31d5dce78a84a226 Mon Sep 17 00:00:00 2001 From: "Galantsev, Dmitrii" Date: Tue, 10 Oct 2023 17:58:23 -0500 Subject: [PATCH 07/11] Fix amdsmi.h and update wrapper Having an unnamed struct confuses our wrapper generator. Adding a name solved it. Change-Id: Iab3e73317fb21fb3667beef04878d4f3da96eadf Signed-off-by: Galantsev, Dmitrii --- include/amd_smi/amdsmi.h | 2 +- py-interface/amdsmi_wrapper.py | 39 ++++++++++++++++++++++++++++------ 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/include/amd_smi/amdsmi.h b/include/amd_smi/amdsmi.h index 5b85077f4c..6f0c3d17be 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]; diff --git a/py-interface/amdsmi_wrapper.py b/py-interface/amdsmi_wrapper.py index 2d2e8bde27..c0b40745ff 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 @@ -1563,6 +1584,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)] @@ -1926,7 +1950,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,7 +1985,7 @@ __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', @@ -2006,8 +2030,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 +2041,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'] From 3f0071599dd45229843cf35cb34f12e7330b998f Mon Sep 17 00:00:00 2001 From: "Galantsev, Dmitrii" Date: Wed, 11 Oct 2023 11:46:49 -0500 Subject: [PATCH 08/11] Fix rocm_smi.cc Change-Id: Ib074dd542d8d37a6a618e10bd3bd389ad0cef108 Signed-off-by: Galantsev, Dmitrii --- src/rocm_smi.cc | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/rocm_smi.cc b/src/rocm_smi.cc index 2ee44473ad..93536bedc9 100755 --- a/src/rocm_smi.cc +++ b/src/rocm_smi.cc @@ -78,6 +78,8 @@ 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; @@ -5901,7 +5903,7 @@ rsmi_dev_curr_uclk_get(uint32_t dv_ind, uint16_t* uclk_value) } rsmi_status_t -rsmi_dev_vcn_activity_get(uint32_t dv_ind, GPUMetricVcnActivityTbl_t* vcn_activity_value) +rsmi_dev_vcn_activity_get(uint32_t dv_ind, amd::smi::GPUMetricVcnActivityTbl_t* vcn_activity_value) { TRY std::ostringstream ostrstream; @@ -5909,7 +5911,7 @@ rsmi_dev_vcn_activity_get(uint32_t dv_ind, GPUMetricVcnActivityTbl_t* vcn_activi LOG_TRACE(ostrstream); const auto gpu_metric_unit(AMDGpuMetricsUnitType_t::kMetricVcnActivity); - GPUMetricVcnActivityTbl_t tmp_vcn_activity_value; + 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__ @@ -5924,7 +5926,7 @@ rsmi_dev_vcn_activity_get(uint32_t dv_ind, GPUMetricVcnActivityTbl_t* vcn_activi } rsmi_status_t -rsmi_dev_xgmi_read_data_get(uint32_t dv_ind, GPUMetricXgmiAccTbl_t* xgmi_read_data_acc_value) +rsmi_dev_xgmi_read_data_get(uint32_t dv_ind, amd::smi::GPUMetricXgmiAccTbl_t* xgmi_read_data_acc_value) { TRY std::ostringstream ostrstream; @@ -5932,7 +5934,7 @@ rsmi_dev_xgmi_read_data_get(uint32_t dv_ind, GPUMetricXgmiAccTbl_t* xgmi_read_da LOG_TRACE(ostrstream); const auto gpu_metric_unit(AMDGpuMetricsUnitType_t::kMetricVcnActivity); - GPUMetricXgmiAccTbl_t tmp_xgmi_read_data_acc_value; + 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__ @@ -5947,7 +5949,7 @@ rsmi_dev_xgmi_read_data_get(uint32_t dv_ind, GPUMetricXgmiAccTbl_t* xgmi_read_da } rsmi_status_t -rsmi_dev_xgmi_write_data_get(uint32_t dv_ind, GPUMetricXgmiAccTbl_t* xgmi_write_data_acc_value) +rsmi_dev_xgmi_write_data_get(uint32_t dv_ind, amd::smi::GPUMetricXgmiAccTbl_t* xgmi_write_data_acc_value) { TRY std::ostringstream ostrstream; @@ -5955,7 +5957,7 @@ rsmi_dev_xgmi_write_data_get(uint32_t dv_ind, GPUMetricXgmiAccTbl_t* xgmi_write_ LOG_TRACE(ostrstream); const auto gpu_metric_unit(AMDGpuMetricsUnitType_t::kMetricVcnActivity); - GPUMetricXgmiAccTbl_t tmp_xgmi_write_data_acc_value; + 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__ @@ -5970,7 +5972,7 @@ rsmi_dev_xgmi_write_data_get(uint32_t dv_ind, GPUMetricXgmiAccTbl_t* xgmi_write_ } rsmi_status_t -rsmi_dev_curr_gfxclk_get(uint32_t dv_ind, GPUMetricCurrGfxClkTbl_t* current_gfxclk_value) +rsmi_dev_curr_gfxclk_get(uint32_t dv_ind, amd::smi::GPUMetricCurrGfxClkTbl_t* current_gfxclk_value) { TRY std::ostringstream ostrstream; @@ -5978,7 +5980,7 @@ rsmi_dev_curr_gfxclk_get(uint32_t dv_ind, GPUMetricCurrGfxClkTbl_t* current_gfxc LOG_TRACE(ostrstream); const auto gpu_metric_unit(AMDGpuMetricsUnitType_t::kMetricVcnActivity); - GPUMetricCurrGfxClkTbl_t tmp_current_gfxclk_value; + 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__ @@ -5993,7 +5995,7 @@ rsmi_dev_curr_gfxclk_get(uint32_t dv_ind, GPUMetricCurrGfxClkTbl_t* current_gfxc } rsmi_status_t -rsmi_dev_curr_socclk_get(uint32_t dv_ind, GPUMetricCurrSocClkTbl_t* current_socclk_value) +rsmi_dev_curr_socclk_get(uint32_t dv_ind, amd::smi::GPUMetricCurrSocClkTbl_t* current_socclk_value) { TRY std::ostringstream ostrstream; @@ -6001,7 +6003,7 @@ rsmi_dev_curr_socclk_get(uint32_t dv_ind, GPUMetricCurrSocClkTbl_t* current_socc LOG_TRACE(ostrstream); const auto gpu_metric_unit(AMDGpuMetricsUnitType_t::kMetricVcnActivity); - GPUMetricCurrSocClkTbl_t tmp_current_socclk_value; + 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__ @@ -6016,7 +6018,7 @@ rsmi_dev_curr_socclk_get(uint32_t dv_ind, GPUMetricCurrSocClkTbl_t* current_socc } rsmi_status_t -rsmi_dev_curr_vclk0_get(uint32_t dv_ind, GPUMetricCurrVClkTbl_t* current_vclk_value) +rsmi_dev_curr_vclk0_get(uint32_t dv_ind, amd::smi::GPUMetricCurrVClkTbl_t* current_vclk_value) { TRY std::ostringstream ostrstream; @@ -6024,7 +6026,7 @@ rsmi_dev_curr_vclk0_get(uint32_t dv_ind, GPUMetricCurrVClkTbl_t* current_vclk_va LOG_TRACE(ostrstream); const auto gpu_metric_unit(AMDGpuMetricsUnitType_t::kMetricVcnActivity); - GPUMetricCurrVClkTbl_t tmp_current_vclk_value; + 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__ @@ -6039,7 +6041,7 @@ rsmi_dev_curr_vclk0_get(uint32_t dv_ind, GPUMetricCurrVClkTbl_t* current_vclk_va } rsmi_status_t -rsmi_dev_curr_vdlk0_get(uint32_t dv_ind, GPUMetricCurrDClkTbl_t* current_dclk_value) +rsmi_dev_curr_vdlk0_get(uint32_t dv_ind, amd::smi::GPUMetricCurrDClkTbl_t* current_dclk_value) { TRY std::ostringstream ostrstream; @@ -6047,7 +6049,7 @@ rsmi_dev_curr_vdlk0_get(uint32_t dv_ind, GPUMetricCurrDClkTbl_t* current_dclk_va LOG_TRACE(ostrstream); const auto gpu_metric_unit(AMDGpuMetricsUnitType_t::kMetricVcnActivity); - GPUMetricCurrDClkTbl_t tmp_current_dclk_value; + 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__ From 262b5b025482c18da3bfba2f2c81cc95d2e48342 Mon Sep 17 00:00:00 2001 From: Maisam Arif Date: Wed, 11 Oct 2023 13:28:27 -0500 Subject: [PATCH 09/11] Added xgmi physical id to static --asic Signed-off-by: Maisam Arif Change-Id: I9e9f5929da635d22495aa394f2a9e5e6ce441706 --- amdsmi_cli/amdsmi_commands.py | 3 ++- py-interface/README.md | 3 +++ py-interface/amdsmi_interface.py | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/amdsmi_cli/amdsmi_commands.py b/amdsmi_cli/amdsmi_commands.py index a243adfd74..76f1d20c9a 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" diff --git a/py-interface/README.md b/py-interface/README.md index 72f9f843fd..bf7d547809 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) ``` diff --git a/py-interface/amdsmi_interface.py b/py-interface/amdsmi_interface.py index 9c439e3104..a3b1b4127b 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 } From c6e54e09e7bf8434345f5f3745a694e4b0ca3a7e Mon Sep 17 00:00:00 2001 From: Maisam Arif Date: Tue, 10 Oct 2023 14:20:11 -0500 Subject: [PATCH 10/11] Placeholders for new ras values Signed-off-by: Maisam Arif Change-Id: I66cea253b19a5029172af0a3f4dd2f993c13b309 Signed-off-by: Maisam Arif --- amdsmi_cli/amdsmi_commands.py | 26 ++++++++++++++++----- py-interface/README.md | 40 ++++++++++++++++++++++++++++++++ py-interface/__init__.py | 1 + py-interface/amdsmi_interface.py | 19 ++++++++++++++- 4 files changed, 79 insertions(+), 7 deletions(-) diff --git a/amdsmi_cli/amdsmi_commands.py b/amdsmi_cli/amdsmi_commands.py index 76f1d20c9a..b598a15d5c 100644 --- a/amdsmi_cli/amdsmi_commands.py +++ b/amdsmi_cli/amdsmi_commands.py @@ -437,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: @@ -467,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() diff --git a/py-interface/README.md b/py-interface/README.md index bf7d547809..8147ba1b6d 100644 --- a/py-interface/README.md +++ b/py-interface/README.md @@ -942,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 a3b1b4127b..98907c2708 100644 --- a/py-interface/amdsmi_interface.py +++ b/py-interface/amdsmi_interface.py @@ -832,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 From c988ff1730f879840379f7d74ffc7aca46611558 Mon Sep 17 00:00:00 2001 From: "Galantsev, Dmitrii" Date: Tue, 10 Oct 2023 17:58:23 -0500 Subject: [PATCH 11/11] Fix amdsmi.h and update wrapper Having an unnamed struct confuses our wrapper generator. Adding a name solved it. Change-Id: Iab3e73317fb21fb3667beef04878d4f3da96eadf Signed-off-by: Galantsev, Dmitrii --- include/amd_smi/amdsmi.h | 2 +- py-interface/amdsmi_wrapper.py | 39 ++++++++++++++++++++++++++++------ 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/include/amd_smi/amdsmi.h b/include/amd_smi/amdsmi.h index 5b85077f4c..6f0c3d17be 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]; diff --git a/py-interface/amdsmi_wrapper.py b/py-interface/amdsmi_wrapper.py index 2d2e8bde27..c0b40745ff 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 @@ -1563,6 +1584,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)] @@ -1926,7 +1950,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,7 +1985,7 @@ __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', @@ -2006,8 +2030,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 +2041,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']