CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
201 lines
5.8 KiB
C++
201 lines
5.8 KiB
C++
// Copyright (c) Advanced Micro Devices, Inc., or its affiliates.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
#include <algorithm>
|
|
#include <cctype> // std::isspace()
|
|
#include <iostream>
|
|
#include <numeric>
|
|
#include <ostream>
|
|
#include <ranges>
|
|
#include <string>
|
|
#include <unordered_map>
|
|
#include <utility>
|
|
|
|
#include <miopen/config.h>
|
|
#include <miopen/conv_algo_name.hpp>
|
|
#include <miopen/db_record.hpp>
|
|
#include <miopen/logger.hpp>
|
|
|
|
// Keep compatibility with old format for reading existing system find-db files.
|
|
// To be removed when the system find-db files regenerated in the 2.0 format.
|
|
#define WORKAROUND_ISSUE_1987 1
|
|
|
|
namespace miopen {
|
|
|
|
bool DbRecord::SetValues(const std::string& id, const std::string& values)
|
|
{
|
|
constexpr auto log_level = MIOPEN_ENABLE_SQLITE ? LoggingLevel::Info2 : LoggingLevel::Info;
|
|
|
|
// No need to update the file if values are the same:
|
|
const auto it = map.find(id);
|
|
if(it == map.end() || it->second != values)
|
|
{
|
|
MIOPEN_LOG(log_level,
|
|
key << ", content " << (it == map.end() ? "inserted" : "overwritten") << ": "
|
|
<< id << ':' << values);
|
|
map[id] = values;
|
|
return true;
|
|
}
|
|
MIOPEN_LOG(log_level, key << ", content is the same, not changed:" << id << ':' << values);
|
|
return false;
|
|
}
|
|
|
|
bool DbRecord::GetValues(const std::string& id, std::string& values) const
|
|
{
|
|
const auto it = map.find(id);
|
|
|
|
if(it == map.end())
|
|
{
|
|
MIOPEN_LOG_I(key << '=' << id << ':' << "<values not found>");
|
|
return false;
|
|
}
|
|
|
|
values = it->second;
|
|
MIOPEN_LOG_I(key << '=' << id << ':' << values);
|
|
return true;
|
|
}
|
|
|
|
bool DbRecord::EraseValues(const std::string& id)
|
|
{
|
|
const auto it = map.find(id);
|
|
if(it != map.end())
|
|
{
|
|
MIOPEN_LOG_I(key << ", removed: " << id << ':' << it->second);
|
|
map.erase(it);
|
|
return true;
|
|
}
|
|
MIOPEN_LOG_W(key << ", not found: " << id);
|
|
return false;
|
|
}
|
|
|
|
#if WORKAROUND_ISSUE_1987
|
|
/// Transform find-db (v.1.0) ID:VALUES to the current format.
|
|
/// Implementation is intentionally straightforward.
|
|
/// Do not include the 1st value from VALUES (solver name) into transformed VALUES.
|
|
/// Ignore FdbKCache_Key pair (last two values).
|
|
/// Append id (algorithm) to VALUES.
|
|
/// Use solver name as ID.
|
|
static bool TransformFindDbItem10to20(std::string& id, std::string& values)
|
|
{
|
|
MIOPEN_LOG_T("Legacy find-db item: " << id << ':' << values);
|
|
std::size_t pos = values.find(',');
|
|
if(pos == std::string::npos)
|
|
return false;
|
|
const auto solver = values.substr(0, pos);
|
|
|
|
const auto time_workspace_pos = pos + 1;
|
|
pos = values.find(',', time_workspace_pos);
|
|
if(pos == std::string::npos)
|
|
return false;
|
|
pos = values.find(',', pos + 1);
|
|
if(pos == std::string::npos)
|
|
return false;
|
|
const auto time_workspace = values.substr(time_workspace_pos, pos - time_workspace_pos);
|
|
|
|
values = time_workspace + ',' + id;
|
|
id = solver;
|
|
MIOPEN_LOG_T("Transformed find-db item: " << id << ':' << values);
|
|
return true;
|
|
}
|
|
#endif
|
|
|
|
bool DbRecord::ParseContents(std::istream& contents)
|
|
{
|
|
std::string id_and_values;
|
|
int found = 0;
|
|
|
|
map.clear();
|
|
|
|
while(std::getline(contents, id_and_values, ';'))
|
|
{
|
|
const auto id_size = id_and_values.find(':');
|
|
|
|
// Empty VALUES is ok, empty ID is not:
|
|
if(id_size == std::string::npos)
|
|
{
|
|
MIOPEN_LOG_E("Ill-formed file: ID not found; skipped; key: " << key);
|
|
continue;
|
|
}
|
|
|
|
auto id = id_and_values.substr(0, id_size);
|
|
auto values = id_and_values.substr(id_size + 1);
|
|
|
|
const auto ltrim = [](std::string& str) {
|
|
auto e = std::ranges::find_if_not(str, [](char c) { return std::isspace(c); });
|
|
str.erase(str.begin(), e);
|
|
return str;
|
|
};
|
|
const auto rtrim = [](std::string& str) {
|
|
auto e = std::ranges::find_if_not(str | std::views::reverse,
|
|
[](char c) { return std::isspace(c); });
|
|
str.erase(e.base(), str.end());
|
|
return str;
|
|
};
|
|
|
|
ltrim(values);
|
|
rtrim(values);
|
|
|
|
#if WORKAROUND_ISSUE_1987
|
|
// Detect legacy find-db item (v.1.0 ID:VALUES) and transform it to the current format.
|
|
// For now, *only* legacy find-db record use convolution algorithm as ID, so if ID is
|
|
// a valid algorithm, then we can safely assume that the item is in legacy format.
|
|
if(IsValidConvolutionDirAlgo(id))
|
|
{
|
|
if(!TransformFindDbItem10to20(id, values))
|
|
{
|
|
MIOPEN_LOG_E("Ill-formed legacy find-db item: " << values);
|
|
continue;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
if(map.find(id) != map.end())
|
|
{
|
|
MIOPEN_LOG_E("Duplicate ID (ignored): " << id << "; key: " << key);
|
|
continue;
|
|
}
|
|
|
|
map.emplace(id, values);
|
|
++found;
|
|
}
|
|
|
|
return (found > 0);
|
|
}
|
|
|
|
void DbRecord::WriteContents(std::ostream& stream) const
|
|
{
|
|
if(map.empty())
|
|
return;
|
|
|
|
stream << key << '=';
|
|
WriteIdsAndValues(stream);
|
|
}
|
|
|
|
void DbRecord::WriteIdsAndValues(std::ostream& stream) const
|
|
{
|
|
if(map.empty())
|
|
return;
|
|
|
|
const auto pairsJoiner = [](const std::string& sum,
|
|
const std::pair<std::string, std::string>& pair) {
|
|
const auto pair_str = pair.first + ':' + pair.second;
|
|
return sum.empty() ? pair_str : sum + ';' + pair_str;
|
|
};
|
|
|
|
stream << std::accumulate(map.begin(), map.end(), std::string(), pairsJoiner) << std::endl;
|
|
}
|
|
|
|
void DbRecord::Merge(const DbRecord& that)
|
|
{
|
|
if(key != that.key)
|
|
return;
|
|
|
|
for(const auto& that_pair : that.map)
|
|
{
|
|
if(map.find(that_pair.first) != map.end())
|
|
continue;
|
|
map[that_pair.first] = that_pair.second;
|
|
}
|
|
}
|
|
} // namespace miopen
|