fix: [SWDEV-458862] [rocm/rocm_smi_lib]
Fixes reading pp_od_clk_voltage new variable format and size. Code changes related to the following: * get_od_clk_volt_info() * get_od_clk_volt_curve_regions() * Unit tests * CLI options removed: --showclkvolt, --showvc, --showvoltagerange, --setvc Change-Id: Ieedb845eeadcea2f2e447ec576c253ad2a814176 Signed-off-by: Oliveira, Daniel <daniel.oliveira@amd.com>
Этот коммит содержится в:
коммит произвёл
Maisam Arif
родитель
3282aaa8de
Коммит
48ddd9abd7
@@ -2869,6 +2869,8 @@ rsmi_status_t rsmi_dev_od_clk_info_set(uint32_t dv_ind, rsmi_freq_ind_t level,
|
||||
/**
|
||||
* @brief This function sets 1 of the 3 voltage curve points.
|
||||
*
|
||||
* @deprecated This function is deprecated due to driver changes.
|
||||
*
|
||||
* @details Given a device index @p dv_ind, a voltage point @p vpoint
|
||||
* and a voltage value @p voltvalue this function will set voltage curve point
|
||||
*
|
||||
@@ -2894,6 +2896,8 @@ rsmi_status_t rsmi_dev_od_volt_info_set(uint32_t dv_ind, uint32_t vpoint,
|
||||
* @brief This function will retrieve the current valid regions in the
|
||||
* frequency/voltage space.
|
||||
*
|
||||
* @deprecated This function is deprecated due to driver changes.
|
||||
*
|
||||
* @details Given a device index @p dv_ind, a pointer to an unsigned integer
|
||||
* @p num_regions and a buffer of ::rsmi_freq_volt_region_t structures, @p
|
||||
* buffer, this function will populate @p buffer with the current
|
||||
|
||||
@@ -45,14 +45,17 @@
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <type_traits>
|
||||
#include <tuple>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
#include <queue>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "rocm_smi/rocm_smi_device.h"
|
||||
|
||||
@@ -123,6 +126,12 @@ std::string print_rsmi_od_volt_freq_regions(uint32_t num_regions,
|
||||
bool is_sudo_user();
|
||||
rsmi_status_t rsmi_get_gfx_target_version(uint32_t dv_ind,
|
||||
std::string *gfx_version);
|
||||
|
||||
std::string leftTrim(const std::string &s);
|
||||
std::string rightTrim(const std::string &s);
|
||||
std::string trim(const std::string &s);
|
||||
std::string removeNewLines(const std::string &s);
|
||||
|
||||
std::string removeString(const std::string origStr,
|
||||
const std::string &removeMe);
|
||||
template <typename T>
|
||||
@@ -296,6 +305,291 @@ class ScopedAcquire {
|
||||
// In VM environment, the /proc/cpuinfo set hypervisor flag by default
|
||||
bool is_vm_guest();
|
||||
|
||||
|
||||
//
|
||||
enum class TagSplitterPositional_t
|
||||
{
|
||||
kFIRST,
|
||||
kBETWEEN,
|
||||
kLAST,
|
||||
kNONE,
|
||||
};
|
||||
|
||||
template <typename PrimaryKeyType = std::string, typename PrimaryDataType = std::string,
|
||||
typename SecondaryKeyType = PrimaryKeyType, typename SecondaryDataType = PrimaryDataType>
|
||||
class TagTextContents_t
|
||||
{
|
||||
public:
|
||||
using TextLines_t = std::vector<std::string>;
|
||||
using PrimaryList_t = std::vector<PrimaryDataType>;
|
||||
using SecondaryList_t = std::vector<SecondaryDataType>;
|
||||
using PrimaryKeyTbl_t = std::map<PrimaryKeyType, PrimaryList_t>;
|
||||
using SecondaryKeyTbl_t = std::map<SecondaryKeyType, SecondaryList_t>;
|
||||
using StructuredKeysTbl_t = std::map<PrimaryDataType, std::map<SecondaryKeyType, SecondaryDataType>>;
|
||||
|
||||
//
|
||||
TagTextContents_t() = default;
|
||||
TagTextContents_t(const TagTextContents_t&) = delete;
|
||||
TagTextContents_t(TagTextContents_t&&) = delete;
|
||||
TagTextContents_t& operator=(const TagTextContents_t&) = delete;
|
||||
TagTextContents_t& operator=(TagTextContents_t&&) = delete;
|
||||
|
||||
explicit TagTextContents_t(const TextLines_t& text_content)
|
||||
: m_text_content(text_content) {}
|
||||
|
||||
TagTextContents_t& set_text_content(const TextLines_t& text_content)
|
||||
{
|
||||
m_text_content = text_content;
|
||||
}
|
||||
|
||||
TagTextContents_t& set_title_terminator(const std::string& title_mark,
|
||||
TagSplitterPositional_t title_mark_position) {
|
||||
m_title_mark = title_mark;
|
||||
m_title_mark_position = title_mark_position;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
TagTextContents_t& set_key_data_splitter(const std::string& line_splitter_mark,
|
||||
TagSplitterPositional_t line_mark_position) {
|
||||
m_line_splitter_mark = line_splitter_mark;
|
||||
m_line_mark_position = line_mark_position;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
TagTextContents_t& structure_content() {
|
||||
// Sanitizes the content.
|
||||
if (!m_text_content.empty()) {
|
||||
std::for_each(m_text_content.begin(), m_text_content.end(), trim);
|
||||
section_title_lookup();
|
||||
section_data_lookup();
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
decltype(auto) get_title_size() {
|
||||
return m_primary.size();
|
||||
}
|
||||
|
||||
decltype(auto) get_structured_subkeys_size(const PrimaryKeyType& prim_key) {
|
||||
return m_structured[prim_key].size();
|
||||
}
|
||||
|
||||
decltype(auto) contains_title_key(const PrimaryKeyType& key) {
|
||||
return (m_primary.find(key) != m_primary.end());
|
||||
}
|
||||
|
||||
decltype(auto) contains_structured_key(const PrimaryKeyType& prim_key,
|
||||
const SecondaryKeyType& sec_key) {
|
||||
if (auto first_key_itr = m_structured.find(prim_key);
|
||||
first_key_itr != m_structured.end()) {
|
||||
if (auto sec_key_itr = first_key_itr->second.find(sec_key);
|
||||
sec_key_itr != first_key_itr->second.end()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
decltype(auto) get_structured_value_by_keys(const PrimaryKeyType& prim_key,
|
||||
const SecondaryKeyType& sec_key,
|
||||
bool is_value_id = true) {
|
||||
if (auto first_key_itr = m_structured.find(prim_key);
|
||||
first_key_itr != m_structured.end()) {
|
||||
if (auto sec_key_itr = first_key_itr->second.find(sec_key);
|
||||
sec_key_itr != first_key_itr->second.end()) {
|
||||
SecondaryDataType key_value{};
|
||||
if (is_value_id) {
|
||||
key_value = SecondaryDataType(sec_key_itr->first) + " ";
|
||||
}
|
||||
key_value += sec_key_itr->second;
|
||||
return key_value;
|
||||
}
|
||||
}
|
||||
|
||||
return SecondaryDataType{};
|
||||
}
|
||||
|
||||
decltype(auto) get_structured_data_subkey_by_position(const PrimaryKeyType& prim_key,
|
||||
uint32_t key_position) {
|
||||
auto key_counter = uint32_t(0);
|
||||
SecondaryKeyType data_key{};
|
||||
if (key_position < (get_structured_subkeys_size(prim_key))) {
|
||||
for (const auto& [sec_key, sec_value] : m_structured[prim_key]) {
|
||||
if (key_counter == key_position) {
|
||||
data_key = static_cast<SecondaryKeyType>(sec_key);
|
||||
return data_key;
|
||||
}
|
||||
++key_counter;
|
||||
}
|
||||
}
|
||||
|
||||
return data_key;
|
||||
}
|
||||
|
||||
decltype(auto) get_structured_data_subkey_first(const PrimaryKeyType& prim_key) {
|
||||
return (get_structured_value_by_keys(prim_key,
|
||||
get_structured_data_subkey_by_position(prim_key, 0)));
|
||||
}
|
||||
|
||||
decltype(auto) get_structured_data_subkey_last(const PrimaryKeyType& prim_key) {
|
||||
return (get_structured_value_by_keys(prim_key, get_structured_data_subkey_by_position(prim_key,
|
||||
(get_structured_subkeys_size(prim_key) - 1))));
|
||||
}
|
||||
|
||||
void reset() {
|
||||
m_text_content.clear();
|
||||
m_primary.clear();
|
||||
m_structured.clear();
|
||||
m_title_mark.clear();
|
||||
m_line_splitter_mark.clear();
|
||||
m_title_mark_position = TagSplitterPositional_t::kNONE;
|
||||
m_line_mark_position = TagSplitterPositional_t::kNONE;
|
||||
}
|
||||
|
||||
decltype(auto) dump_structured_content() {
|
||||
std::ostringstream ostrstream;
|
||||
ostrstream << __PRETTY_FUNCTION__ << "| ======= start =======" << "\n";
|
||||
ostrstream << "** Primary Table **" << "\n";
|
||||
for (const auto& [key, values] : m_primary) {
|
||||
ostrstream << "key: " << key << " values: " << values.size() << "\n";
|
||||
for (const auto& value : values) {
|
||||
ostrstream << "\t value: " << value << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
ostrstream << "\n ** Structured Table **" << "\n";
|
||||
for (const auto& [prim_key, prim_values] : m_structured) {
|
||||
ostrstream << "key: " << prim_key << "\n";
|
||||
for (const auto& [sec_key, sec_value] : prim_values) {
|
||||
ostrstream << "\t key: " << sec_key << " -> " << sec_value << "\n";
|
||||
}
|
||||
}
|
||||
ostrstream << "\n\n";
|
||||
|
||||
return ostrstream.str();
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
TextLines_t m_text_content;
|
||||
PrimaryKeyTbl_t m_primary;
|
||||
StructuredKeysTbl_t m_structured;
|
||||
std::string m_title_mark;
|
||||
std::string m_line_splitter_mark;
|
||||
TagSplitterPositional_t m_title_mark_position;
|
||||
TagSplitterPositional_t m_line_mark_position;
|
||||
|
||||
//
|
||||
// Note: Organizes table with Title as a Key, and a list of values.
|
||||
//
|
||||
decltype(auto) section_title_lookup() {
|
||||
if (m_title_mark.empty() ||
|
||||
m_title_mark_position == TagSplitterPositional_t::kNONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Note:
|
||||
// - top_title_line: Left pointer for the sliding window
|
||||
// - bottom_title_line: Right pointer for the sliding window
|
||||
//
|
||||
auto top_title_line = uint32_t(std::numeric_limits<uint32_t>::max());
|
||||
auto bottom_title_line = uint32_t(std::numeric_limits<uint32_t>::max());
|
||||
auto line_counter = uint32_t(0);
|
||||
|
||||
//
|
||||
// Note: This whole interval/window where the section/title starts, and where it ends.
|
||||
//
|
||||
auto update_primary_tbl = [&](const uint32_t& from_line, const uint32_t& to_line) {
|
||||
auto key = static_cast<PrimaryKeyType>(m_text_content[from_line]);
|
||||
for (auto line_num(from_line + 1); line_num < to_line; ++line_num) {
|
||||
if ((line_num < m_text_content.size()) && !m_text_content[line_num].empty()) {
|
||||
m_primary[key].push_back(m_text_content[line_num]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
auto adjust_sliding_window = [&](const uint32_t& title_line) {
|
||||
// First time top_title_line gets adjusted.
|
||||
if (top_title_line == uint32_t(std::numeric_limits<uint32_t>::max())) {
|
||||
top_title_line = title_line;
|
||||
bottom_title_line = top_title_line;
|
||||
return;
|
||||
}
|
||||
if (title_line > bottom_title_line) {
|
||||
bottom_title_line = title_line;
|
||||
update_primary_tbl(top_title_line, bottom_title_line);
|
||||
top_title_line = bottom_title_line;
|
||||
}
|
||||
};
|
||||
|
||||
for (const auto& line : m_text_content) {
|
||||
auto was_title_found{false};
|
||||
switch (m_title_mark_position) {
|
||||
case TagSplitterPositional_t::kFIRST:
|
||||
// Section/Title Mark was found at the first position
|
||||
if (line.find_first_of(m_title_mark.c_str()) == 0) {
|
||||
was_title_found = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case TagSplitterPositional_t::kLAST:
|
||||
// Section/Title Mark was found at the last position
|
||||
if ((line.find_last_of(m_title_mark.c_str()) + 1) == line.size()) {
|
||||
was_title_found = true;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (was_title_found) {
|
||||
adjust_sliding_window(line_counter);
|
||||
}
|
||||
++line_counter;
|
||||
}
|
||||
|
||||
// Any remaining elements?
|
||||
if (line_counter > bottom_title_line) {
|
||||
update_primary_tbl(bottom_title_line, (line_counter - 1));
|
||||
}
|
||||
}
|
||||
|
||||
decltype(auto) section_data_lookup() {
|
||||
if (m_line_splitter_mark.empty() ||
|
||||
m_line_mark_position == TagSplitterPositional_t::kNONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Note: Organizes table with Title as a Key, a Key/ID for values and values.
|
||||
// It takes into consideration the initial constraints were all good and
|
||||
// that the primary table has been populated.
|
||||
for (const auto& [prim_key, prim_values] : m_primary) {
|
||||
for (const auto& value : prim_values) {
|
||||
if (auto mark_pos = value.find_first_of(m_line_splitter_mark.c_str());
|
||||
mark_pos != std::string::npos) {
|
||||
auto sec_key = trim(value.substr(0, mark_pos + 1));
|
||||
auto sec_data = trim(value.substr((mark_pos + 1), value.size()));
|
||||
if (!sec_key.empty()) {
|
||||
m_structured[prim_key].insert(std::make_pair(sec_key, sec_data));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
using TextFileTagContents_t = TagTextContents_t<std::string, std::string,
|
||||
std::string, std::string>;
|
||||
|
||||
|
||||
} // namespace smi
|
||||
} // namespace amd
|
||||
|
||||
|
||||
Ссылка в новой задаче
Block a user