diff --git a/include/rocm_smi/rocm_smi.h b/include/rocm_smi/rocm_smi.h index 6b755ef154..4a15c6178c 100755 --- a/include/rocm_smi/rocm_smi.h +++ b/include/rocm_smi/rocm_smi.h @@ -70,7 +70,8 @@ extern "C" { */ //! Guaranteed maximum possible number of supported frequencies -#define RSMI_MAX_NUM_FREQUENCIES 32 +//! (32 normal + 1 sleep frequency) +#define RSMI_MAX_NUM_FREQUENCIES 33 //! Maximum possible value for fan speed. Should be used as the denominator //! when determining fan speed percentage. @@ -747,6 +748,11 @@ typedef rsmi_power_profile_status_t rsmi_power_profile_status; * @brief This structure holds information about clock frequencies. */ typedef struct { + /** + * Deep Sleep frequency is only supported by some GPUs + */ + bool has_deep_sleep; + /** * The number of supported frequencies */ diff --git a/python_smi_tools/rocm_smi.py b/python_smi_tools/rocm_smi.py index cc9bc1f695..f705ad22a9 100755 --- a/python_smi_tools/rocm_smi.py +++ b/python_smi_tools/rocm_smi.py @@ -1808,12 +1808,21 @@ def showClocks(deviceList): if not rsmi_ret_ok(ret, device, 'get_clk_freq_' + clk_type, True): continue printLog(device, 'Supported %s frequencies on GPU%s' % (clk_type, str(device)), None) - for x in range(freq.num_supported): - fr = '{:>.0f}Mhz'.format(freq.frequency[x] / 1000000) - if x == freq.current: - printLog(device, str(x), str(fr) + ' *') - else: - printLog(device, str(x), str(fr)) + for i in range(freq.num_supported): + freq_string = '{:>.0f}Mhz'.format(freq.frequency[i] / 1000000) + if i == freq.current: + freq_string += ' *' + freq_index = i + # Deep Sleep frequency is only supported by some GPUs + # It is indicated by letter 'S' instead of the index number + if freq.has_deep_sleep: + # sleep state + if i == 0: + freq_index = 'S' + # all indices are offset by 1 because Deep Sleep occupies index 0 + else: + freq_index = i - 1 + printLog(device, str(freq_index), freq_string) printLog(device, '', None) else: logging.debug('{} frequency is unsupported on device[{}]'.format(clk_type, device)) @@ -1822,12 +1831,11 @@ def showClocks(deviceList): ret = rocmsmi.rsmi_dev_pci_bandwidth_get(device, byref(bw)) if rsmi_ret_ok(ret, device, 'get_PCIe_bandwidth', True): printLog(device, 'Supported %s frequencies on GPU%s' % ('PCIe', str(device)), None) - for x in range(bw.transfer_rate.num_supported): - fr = '{:>.1f}GT/s x{}'.format(bw.transfer_rate.frequency[x] / 1000000000, bw.lanes[x]) - if x == bw.transfer_rate.current: - printLog(device, str(x), str(fr) + ' *') - else: - printLog(device, str(x), str(fr)) + for i in range(bw.transfer_rate.num_supported): + freq_string = '{:>.1f}GT/s x{}'.format(bw.transfer_rate.frequency[i] / 1000000000, bw.lanes[i]) + if i == bw.transfer_rate.current: + freq_string += ' *' + printLog(device, str(i), str(freq_string)) printLog(device, '', None) else: logging.debug('PCIe frequency is unsupported on device [{}]'.format(device)) @@ -1857,9 +1865,17 @@ def showCurrentClocks(deviceList, clk_defined=None, concise=False): printLog(device, '%s current clock frequency not found' % (clk_defined), None) continue fr = freq.frequency[levl] / 1000000 + freq_index = levl + if freq.has_deep_sleep: + # sleep state + if levl == 0: + freq_index = 'S' + # all indices are offset by 1 because Deep Sleep occupies index 0 + else: + freq_index = levl - 1 if concise: # in case function is used for concise output, no need to print. return '{:.0f}Mhz'.format(fr) - printLog(device, '{} clock level'.format(clk_defined), '{} ({:.0f}Mhz)'.format(levl, fr)) + printLog(device, '{} clock level'.format(clk_defined), '{} ({:.0f}Mhz)'.format(freq_index, fr)) elif not concise: logging.debug('{} clock is unsupported on device[{}]'.format(clk_defined, device)) @@ -1872,12 +1888,20 @@ def showCurrentClocks(deviceList, clk_defined=None, concise=False): if levl >= freq.num_supported: printLog(device, '%s current clock frequency not found' % (clk_type), None) continue + freq_index = levl + if freq.has_deep_sleep: + # sleep state + if levl == 0: + freq_index = 'S' + # all indices are offset by 1 because Deep Sleep occupies index 0 + else: + freq_index = levl - 1 fr = freq.frequency[levl] / 1000000 if PRINT_JSON: printLog(device, '%s clock speed:' % (clk_type), '(%sMhz)' % (str(fr)[:-2])) - printLog(device, '%s clock level:' % (clk_type), levl) + printLog(device, '%s clock level:' % (clk_type), freq_index) else: - printLog(device, '%s clock level: %s' % (clk_type, levl), '(%sMhz)' % (str(fr)[:-2])) + printLog(device, '%s clock level: %s' % (clk_type, freq_index), '(%sMhz)' % (str(fr)[:-2])) elif not concise: logging.debug('{} clock is unsupported on device[{}]'.format(clk_type, device)) # pcie clocks diff --git a/python_smi_tools/rsmiBindings.py.in b/python_smi_tools/rsmiBindings.py.in index e6b141889f..284319e10f 100644 --- a/python_smi_tools/rsmiBindings.py.in +++ b/python_smi_tools/rsmiBindings.py.in @@ -59,7 +59,7 @@ gpu_id = c_uint32(0) # Policy enums -RSMI_MAX_NUM_FREQUENCIES = 32 +RSMI_MAX_NUM_FREQUENCIES = 33 RSMI_MAX_FAN_SPEED = 255 RSMI_NUM_VOLTAGE_CURVE_POINTS = 3 @@ -492,7 +492,8 @@ rsmi_power_profile_status = rsmi_power_profile_status_t class rsmi_frequencies_t(Structure): - _fields_ = [('num_supported', c_int32), + _fields_ = [('has_deep_sleep', c_bool), + ('num_supported', c_int32), ('current', c_uint32), ('frequency', c_uint64 * RSMI_MAX_NUM_FREQUENCIES)] diff --git a/src/rocm_smi.cc b/src/rocm_smi.cc index b05f37dbb8..f35ab6a193 100755 --- a/src/rocm_smi.cc +++ b/src/rocm_smi.cc @@ -147,14 +147,21 @@ static uint64_t freq_string_to_int(const std::vector &freq_lines, std::istringstream fs(freq_lines[i]); - uint32_t ind; + char junk_ch; + int ind; float freq; - std::string junk; + std::string junk_str; std::string units_str; std::string star_str; - fs >> ind; - fs >> junk; // colon + if (fs.peek() == 'S') { + // Deep Sleep frequency is only supported by some GPUs + fs >> junk_ch; + } else { + // All other frequency indices are numbers + fs >> ind; + } + fs >> junk_str; // colon fs >> freq; fs >> units_str; fs >> star_str; @@ -1084,9 +1091,14 @@ static rsmi_status_t get_frequencies(amd::smi::DevInfoTypes type, rsmi_clk_type_ } f->num_supported = static_cast(val_vec.size()); - bool current = false; f->current = RSMI_MAX_NUM_FREQUENCIES + 1; // init to an invalid value + // Deep Sleep frequency is only supported by some GPUs + // It is indicated by letter 'S' instead of the index number + f->has_deep_sleep = (val_vec[0][0] == 'S'); + + bool current = false; + for (uint32_t i = 0; i < f->num_supported; ++i) { f->frequency[i] = freq_string_to_int(val_vec, ¤t, lanes, i); @@ -1113,9 +1125,9 @@ static rsmi_status_t get_frequencies(amd::smi::DevInfoTypes type, rsmi_clk_type_ sysvalue += " Previous Value"; sysvalue += ' ' + std::to_string(f->frequency[f->current]); DEBUG_LOG("More than one current clock. ", sysvalue); - } - else + } else { f->current = i; + } } }