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
304 lines
10 KiB
C++
304 lines
10 KiB
C++
/*******************************************************************************
|
|
*
|
|
* MIT License
|
|
*
|
|
* Copyright (c) 2019 Advanced Micro Devices, Inc.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in all
|
|
* copies or substantial portions of the Software.
|
|
*
|
|
* 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
|
|
* AUTHORS 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 IN THE
|
|
* SOFTWARE.
|
|
*
|
|
*******************************************************************************/
|
|
|
|
#include <miopen/find_db.hpp>
|
|
|
|
#include <miopen/handle.hpp>
|
|
#include <miopen/logger.hpp>
|
|
#include <miopen/perf_field.hpp>
|
|
#if MIOPEN_EMBED_DB
|
|
#include <miopen_data.hpp>
|
|
#endif
|
|
#include <miopen/filesystem.hpp>
|
|
|
|
#include <optional>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
namespace miopen {
|
|
|
|
namespace debug {
|
|
|
|
// NOLINTNEXTLINE (cppcoreguidelines-avoid-non-const-global-variables)
|
|
MIOPEN_EXPORT bool testing_find_db_enabled = true;
|
|
|
|
/// \todo Remove when #1723 is resolved.
|
|
std::optional<fs::path>& testing_find_db_path_override()
|
|
{
|
|
// NOLINTNEXTLINE (cppcoreguidelines-avoid-non-const-global-variables)
|
|
static std::optional<fs::path> data{std::nullopt};
|
|
return data;
|
|
}
|
|
|
|
} // namespace debug
|
|
|
|
#if MIOPEN_EMBED_DB
|
|
template <class TDb>
|
|
fs::path FindDbRecord_t<TDb>::GetInstalledPathEmbed(const Handle& handle,
|
|
const std::string& path_suffix)
|
|
{
|
|
static const auto embed_path = [&] {
|
|
const std::string ext = ".fdb.txt";
|
|
const auto root_path = GetSystemDbPath();
|
|
const auto base_name = handle.GetDbBasename();
|
|
const auto suffix = GetSystemFindDbSuffix() + path_suffix;
|
|
const auto filename = base_name + "." + suffix + ext;
|
|
const auto file_path = root_path / filename;
|
|
if(miopen_data().find(make_object_file_name(filename)) != miopen_data().end())
|
|
{
|
|
MIOPEN_LOG_I2("Found exact embedded find database file:" << filename);
|
|
return file_path;
|
|
}
|
|
else
|
|
{
|
|
MIOPEN_LOG_I2("inexact find database search");
|
|
std::vector<fs::path> all_files;
|
|
for(const auto& kinder : miopen_data())
|
|
{
|
|
const auto& fname = kinder.first.stem();
|
|
const auto& filepath = root_path / fname;
|
|
if(EndsWith(fname.string(), path_suffix + ".fdb.txt"))
|
|
all_files.push_back(filepath);
|
|
}
|
|
|
|
const auto db_id = handle.GetTargetProperties().DbId();
|
|
const int real_cu_count = handle.GetMaxComputeUnits();
|
|
int closest_cu = std::numeric_limits<int>::max();
|
|
fs::path best_path;
|
|
for(const auto& entry : all_files)
|
|
{
|
|
const auto fname = entry.stem().string();
|
|
MIOPEN_LOG_I2("Checking embedded find db file: " << fname);
|
|
// Check for alternate back end same ASIC
|
|
if(fname.rfind(base_name, 0) == 0)
|
|
{
|
|
return entry;
|
|
}
|
|
if(db_id.empty() || !miopen::StartsWith(db_id, "gfx") || real_cu_count == 0)
|
|
return fs::path{};
|
|
// Check for alternate ASIC any back end
|
|
if(fname.rfind(db_id, 0) == 0)
|
|
{
|
|
const auto pos = fname.find('_');
|
|
int cur_count = -1;
|
|
if(pos != std::string::npos)
|
|
cur_count = std::stoi(fname.substr(pos + 1));
|
|
else
|
|
cur_count = std::stoi(fname.substr(db_id.length()), nullptr, 16);
|
|
if(abs(cur_count - real_cu_count) < (closest_cu))
|
|
{
|
|
best_path = entry;
|
|
closest_cu = abs(cur_count - real_cu_count);
|
|
}
|
|
}
|
|
}
|
|
return best_path;
|
|
}
|
|
}();
|
|
return embed_path;
|
|
}
|
|
|
|
#else
|
|
|
|
template <class TDb>
|
|
fs::path FindDbRecord_t<TDb>::GetInstalledPathFile(const Handle& handle,
|
|
const std::string& path_suffix)
|
|
{
|
|
static const fs::path installed_path = [&] {
|
|
const std::string ext = ".fdb.txt";
|
|
const auto root_path = GetSystemDbPath();
|
|
const auto base_name = handle.GetDbBasename();
|
|
const auto suffix =
|
|
GetSystemFindDbSuffix() + (path_suffix.empty() ? "" : ('.' + path_suffix));
|
|
auto file_path = root_path / (base_name + "." + suffix + ext);
|
|
if(fs::exists(file_path))
|
|
{
|
|
MIOPEN_LOG_I2("Found exact find database file: " << file_path);
|
|
return std::move(file_path);
|
|
}
|
|
|
|
MIOPEN_LOG_I2("inexact find database search");
|
|
if(!fs::is_directory(root_path))
|
|
{
|
|
MIOPEN_LOG_I("Database directory does not exist");
|
|
file_path = fs::path{};
|
|
return std::move(file_path);
|
|
}
|
|
|
|
MIOPEN_LOG_I2("Iterating over find db directory " << root_path);
|
|
std::vector<fs::path> all_files;
|
|
std::vector<fs::path> contents;
|
|
std::copy(fs::directory_iterator(root_path),
|
|
fs::directory_iterator(),
|
|
std::back_inserter(contents));
|
|
for(auto const& filepath : contents)
|
|
{
|
|
if(fs::is_regular_file(filepath) && filepath.extension() == path_suffix + ".fdb.txt")
|
|
all_files.push_back(filepath);
|
|
}
|
|
|
|
const auto db_id = handle.GetTargetProperties().DbId();
|
|
const int real_cu_count = handle.GetMaxComputeUnits();
|
|
int closest_cu = std::numeric_limits<int>::max();
|
|
|
|
for(const auto& entry : all_files)
|
|
{
|
|
const auto fname = entry.stem().string();
|
|
MIOPEN_LOG_I("Checking find db file: " << fname);
|
|
// Check for alternate back end same ASIC
|
|
if(fname.starts_with(base_name))
|
|
{
|
|
file_path = entry;
|
|
return std::move(file_path);
|
|
}
|
|
if(db_id.empty() || !miopen::StartsWith(db_id, "gfx") || real_cu_count == 0)
|
|
{
|
|
file_path = fs::path{};
|
|
return std::move(file_path); // empty
|
|
}
|
|
// Check for alternate ASIC any back end
|
|
if(fname.starts_with(db_id))
|
|
{
|
|
const auto pos = fname.find('_');
|
|
int cur_count = -1;
|
|
if(pos != std::string::npos)
|
|
cur_count = std::stoi(fname.substr(pos + 1));
|
|
else
|
|
cur_count = std::stoi(fname.substr(db_id.length()), nullptr, 16);
|
|
if(abs(cur_count - real_cu_count) < (closest_cu))
|
|
{
|
|
file_path = entry;
|
|
closest_cu = abs(cur_count - real_cu_count);
|
|
}
|
|
}
|
|
}
|
|
return std::move(file_path);
|
|
}();
|
|
|
|
return installed_path;
|
|
}
|
|
#endif
|
|
template <class TDb>
|
|
fs::path FindDbRecord_t<TDb>::GetInstalledPath(const Handle& handle, const std::string& path_suffix)
|
|
{
|
|
#if !MIOPEN_DISABLE_SYSDB
|
|
#if MIOPEN_EMBED_DB
|
|
return GetInstalledPathEmbed(handle, path_suffix);
|
|
#else
|
|
return GetInstalledPathFile(handle, path_suffix);
|
|
#endif
|
|
#else
|
|
std::ignore = handle;
|
|
std::ignore = path_suffix;
|
|
return "";
|
|
#endif
|
|
}
|
|
|
|
template <class TDb>
|
|
fs::path FindDbRecord_t<TDb>::GetUserPath(const Handle& handle, const std::string& path_suffix)
|
|
{
|
|
#if !MIOPEN_DISABLE_USERDB
|
|
return GetUserDbPath() / (handle.GetDbBasename() + '.' + GetUserDbSuffix() +
|
|
(path_suffix.empty() ? "" : '.' + path_suffix) + ".ufdb.txt");
|
|
#else
|
|
std::ignore = handle;
|
|
std::ignore = path_suffix;
|
|
return "";
|
|
#endif
|
|
}
|
|
|
|
template <class TDb>
|
|
bool FindDbRecord_t<TDb>::Validate(const Handle& handle, const NetworkConfig& config) const
|
|
{
|
|
auto unbuilt = false;
|
|
auto any = false;
|
|
|
|
if(content.has_value())
|
|
{
|
|
for(const auto& pair : content->As<FindDbData>())
|
|
{
|
|
if(in_sync)
|
|
{
|
|
if(!handle.GetInvoker(config, {{pair.first}}))
|
|
{
|
|
unbuilt = true;
|
|
// This is not an logged as error because no error was detected.
|
|
// Find wasn't executed yet and invokers were not prepared.
|
|
LogFindDbItem(pair);
|
|
break;
|
|
}
|
|
|
|
any = true;
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
MIOPEN_LOG_E("Error: no content.");
|
|
}
|
|
|
|
return !any || unbuilt;
|
|
}
|
|
|
|
template <class TDb>
|
|
void FindDbRecord_t<TDb>::CopyTo(std::vector<Solution>& to) const
|
|
{
|
|
if(content.has_value())
|
|
{
|
|
const auto range = content->As<FindDbData>();
|
|
std::transform(range.begin(), range.end(), std::back_inserter(to), [](const auto& pair) {
|
|
return Solution{solver::Id{pair.first}, pair.second.time, pair.second.workspace};
|
|
});
|
|
}
|
|
else
|
|
{
|
|
MIOPEN_LOG_E("Error: no content.");
|
|
}
|
|
}
|
|
|
|
template <class TDb>
|
|
void FindDbRecord_t<TDb>::LogFindDbItem(const std::pair<std::string, FindDbData>& item) const
|
|
{
|
|
if(content.has_value())
|
|
{
|
|
MIOPEN_LOG_I2("Kernel cache entry not found for solver: "
|
|
<< item.first << " at network config: " << content->GetKey());
|
|
|
|
for(const auto& pair2 : content->As<FindDbData>())
|
|
MIOPEN_LOG_I2("Find-db record content: " << pair2.first << ':' << pair2.second);
|
|
}
|
|
else
|
|
{
|
|
MIOPEN_LOG_E("Error: no content.");
|
|
}
|
|
}
|
|
|
|
template class FindDbRecord_t<FindDb>;
|
|
template class FindDbRecord_t<UserFindDb>;
|
|
|
|
} // namespace miopen
|