omnitrace-avail generate config (#69)
* Config updates
- See PR #69 for details
- change type of OMNITRACE_DL_VERBOSE
- add "deprecated" category to OMNITRACE_ROCM_SMI_DEVICES
- reduce size of perfetto shared memory size hint
- deprecate OMNITRACE_OUTPUT_FILE in favor of OMNITRACE_PERFETTO_FILE
- set papi event choices
- read config file after reading command line
- fix update of OMNITRACE_DL_VERBOSE
- mark several settings as hidden
- timemory update support hidden attribute for settings
- rework get_perfetto_output_filename()
- Hide settings from not available backends
* Rework omnitrace-avail to support dumping configurations
* Overwrite query, tests, output flag
- Support using -O flag when dumping config
- Support checking before overwriting existing config
- Support --force to overwrite existing config
- Fix get_component_info not including omnitrace components
- Testing for dumping config
* Update documentation on omnitrace-avail
* Fix issue with timemory format + "/__w/"
* Update output prefix keys docs
* Rename --dump-config to --generate-config
* Hide MPI related options
- OMNITRACE_PERFETTO_COMBINE_TRACES and OMNITRACE_COLLAPSE_PROCESSES are hidden w/o MPI support
[ROCm/rocprofiler-systems commit: 1877ebf47b]
This commit is contained in:
committed by
GitHub
parent
d622135c92
commit
cb0b57b8e6
@@ -4,10 +4,24 @@
|
||||
#
|
||||
# ------------------------------------------------------------------------------#
|
||||
|
||||
add_executable(
|
||||
add_executable(omnitrace-avail)
|
||||
|
||||
target_sources(
|
||||
omnitrace-avail
|
||||
${CMAKE_CURRENT_LIST_DIR}/avail.cpp ${CMAKE_CURRENT_LIST_DIR}/avail.hpp
|
||||
$<TARGET_OBJECTS:omnitrace::omnitrace-object-library>)
|
||||
PRIVATE ${CMAKE_CURRENT_LIST_DIR}/avail.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/avail.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/common.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/common.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/component_categories.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/defines.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/enumerated_list.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/generate_config.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/generate_config.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/get_availability.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/get_categories.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/info_type.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/info_type.hpp
|
||||
$<TARGET_OBJECTS:omnitrace::omnitrace-object-library>)
|
||||
|
||||
target_include_directories(omnitrace-avail PRIVATE ${CMAKE_CURRENT_LIST_DIR})
|
||||
target_compile_definitions(omnitrace-avail PRIVATE OMNITRACE_EXTERN_COMPONENTS=0)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -22,8 +22,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#define TIMEMORY_DISABLE_BANNER
|
||||
#define TIMEMORY_DISABLE_COMPONENT_STORAGE_INIT
|
||||
#include "defines.hpp"
|
||||
|
||||
#include <timemory/settings/macros.hpp>
|
||||
#include <timemory/tpls/cereal/archives.hpp>
|
||||
|
||||
@@ -0,0 +1,393 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2022 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
//
|
||||
// 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 "common.hpp"
|
||||
|
||||
#include <timemory/mpl/apply.hpp>
|
||||
#include <timemory/settings/settings.hpp>
|
||||
#include <timemory/variadic/macros.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <sys/stat.h>
|
||||
|
||||
using settings = ::tim::settings;
|
||||
|
||||
std::string global_delim = std::string{ "|" };
|
||||
bool csv = false;
|
||||
bool markdown = false;
|
||||
bool alphabetical = false;
|
||||
bool available_only = false;
|
||||
bool all_info = false;
|
||||
bool force_brief = false;
|
||||
bool debug_msg = false;
|
||||
bool case_insensitive = false;
|
||||
bool regex_hl = false;
|
||||
bool expand_keys = false;
|
||||
bool force_config = false;
|
||||
int32_t max_width = 0;
|
||||
int32_t num_cols = 0;
|
||||
int32_t min_width = 40;
|
||||
int32_t padding = 4;
|
||||
str_vec_t regex_keys = {};
|
||||
str_vec_t category_regex_keys = {};
|
||||
str_set_t category_view = {};
|
||||
std::stringstream lerr = {};
|
||||
|
||||
// explicit setting names to exclude
|
||||
std::set<std::string> settings_exclude = {
|
||||
"OMNITRACE_ENVIRONMENT",
|
||||
"OMNITRACE_COMMAND_LINE",
|
||||
"cereal_class_version",
|
||||
"settings",
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
namespace
|
||||
{
|
||||
const auto&
|
||||
get_regex_constants()
|
||||
{
|
||||
static auto _constants = []() {
|
||||
auto _v = regex_const::egrep | regex_const::optimize;
|
||||
if(case_insensitive) _v |= regex_const::icase;
|
||||
return _v;
|
||||
}();
|
||||
return _constants;
|
||||
}
|
||||
|
||||
const auto&
|
||||
get_regex_pattern()
|
||||
{
|
||||
static auto _pattern = []() {
|
||||
std::array<std::string, 2> _v{};
|
||||
for(const auto& itr : regex_keys)
|
||||
{
|
||||
if(itr.empty()) continue;
|
||||
std::string _pattern = {};
|
||||
if(itr.at(0) == '~')
|
||||
{
|
||||
_pattern = itr.substr(1);
|
||||
_v.at(1) += "|" + _pattern;
|
||||
}
|
||||
else
|
||||
{
|
||||
_pattern = itr;
|
||||
_v.at(0) += "|" + _pattern;
|
||||
}
|
||||
lerr << "Adding regex key: '" << _pattern << "'...\n";
|
||||
}
|
||||
for(auto& itr : _v)
|
||||
if(!itr.empty()) itr = itr.substr(1);
|
||||
|
||||
return _v;
|
||||
}();
|
||||
return _pattern;
|
||||
}
|
||||
|
||||
auto
|
||||
get_regex()
|
||||
{
|
||||
static auto _rc = std::array<std::regex, 2>{
|
||||
std::regex(get_regex_pattern().at(0), get_regex_constants()),
|
||||
std::regex(get_regex_pattern().at(1), get_regex_constants())
|
||||
};
|
||||
return _rc;
|
||||
}
|
||||
|
||||
bool
|
||||
regex_match(const std::string& _line)
|
||||
{
|
||||
if(get_regex_pattern().at(0).empty() && get_regex_pattern().at(1).empty())
|
||||
return true;
|
||||
|
||||
static size_t lerr_width = 0;
|
||||
lerr_width = std::max<size_t>(lerr_width, _line.length());
|
||||
std::stringstream _line_ss;
|
||||
_line_ss << "'" << _line << "'";
|
||||
|
||||
if(!get_regex_pattern().at(1).empty())
|
||||
{
|
||||
if(std::regex_match(_line, get_regex().at(1)))
|
||||
{
|
||||
lerr << std::left << std::setw(lerr_width) << _line_ss.str()
|
||||
<< " matched negating pattern '" << get_regex_pattern().at(1)
|
||||
<< "'...\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if(std::regex_search(_line, get_regex().at(1)))
|
||||
{
|
||||
lerr << std::left << std::setw(lerr_width) << _line_ss.str()
|
||||
<< " found negating pattern '" << get_regex_pattern().at(1) << "'...\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(!get_regex_pattern().at(0).empty())
|
||||
{
|
||||
if(std::regex_match(_line, get_regex().at(0)))
|
||||
{
|
||||
lerr << std::left << std::setw(lerr_width) << _line_ss.str()
|
||||
<< " matched pattern '" << get_regex_pattern().at(0) << "'...\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
if(std::regex_search(_line, get_regex().at(0)))
|
||||
{
|
||||
lerr << std::left << std::setw(lerr_width) << _line_ss.str()
|
||||
<< " found pattern '" << get_regex_pattern().at(0) << "'...\n";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
lerr << std::left << std::setw(lerr_width) << _line_ss.str() << " missing pattern '"
|
||||
<< get_regex_pattern().at(0) << "'...\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string
|
||||
regex_replace(const std::string& _line)
|
||||
{
|
||||
#if defined(TIMEMORY_UNIX)
|
||||
if(get_regex_pattern().empty()) return _line;
|
||||
if(regex_match(_line))
|
||||
return std::regex_replace(_line, get_regex().at(0), "\33[01;04;36;40m$&\33[0m");
|
||||
#endif
|
||||
return _line;
|
||||
}
|
||||
|
||||
const auto&
|
||||
get_category_regex_pattern()
|
||||
{
|
||||
static auto _pattern = []() {
|
||||
std::array<std::string, 2> _v{};
|
||||
for(const auto& itr : category_regex_keys)
|
||||
{
|
||||
if(itr.empty()) continue;
|
||||
std::string _pattern = {};
|
||||
if(itr.at(0) == '~')
|
||||
{
|
||||
_pattern = itr.substr(1);
|
||||
_v.at(1) += "|" + _pattern;
|
||||
}
|
||||
else
|
||||
{
|
||||
_pattern = itr;
|
||||
_v.at(0) += "|" + _pattern;
|
||||
}
|
||||
lerr << "Adding category regex key: '" << _pattern << "'...\n";
|
||||
}
|
||||
for(auto& itr : _v)
|
||||
if(!itr.empty()) itr = itr.substr(1);
|
||||
|
||||
return _v;
|
||||
}();
|
||||
return _pattern;
|
||||
}
|
||||
|
||||
auto
|
||||
get_category_regex()
|
||||
{
|
||||
static auto _rc = std::array<std::regex, 2>{
|
||||
std::regex(get_category_regex_pattern().at(0), get_regex_constants()),
|
||||
std::regex(get_category_regex_pattern().at(1), get_regex_constants())
|
||||
};
|
||||
return _rc;
|
||||
}
|
||||
|
||||
bool
|
||||
category_regex_match(const std::string& _line)
|
||||
{
|
||||
if(get_category_regex_pattern().at(0).empty() &&
|
||||
get_category_regex_pattern().at(1).empty())
|
||||
return true;
|
||||
|
||||
static size_t lerr_width = 0;
|
||||
lerr_width = std::max<size_t>(lerr_width, _line.length());
|
||||
std::stringstream _line_ss;
|
||||
_line_ss << "'" << _line << "'";
|
||||
|
||||
if(!get_category_regex_pattern().at(1).empty())
|
||||
{
|
||||
if(std::regex_match(_line, get_category_regex().at(1)))
|
||||
{
|
||||
lerr << std::left << std::setw(lerr_width) << _line_ss.str()
|
||||
<< " matched negating category pattern '"
|
||||
<< get_category_regex_pattern().at(1) << "'...\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if(std::regex_search(_line, get_category_regex().at(1)))
|
||||
{
|
||||
lerr << std::left << std::setw(lerr_width) << _line_ss.str()
|
||||
<< " found negating category pattern '"
|
||||
<< get_category_regex_pattern().at(1) << "'...\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(!get_category_regex_pattern().at(0).empty())
|
||||
{
|
||||
if(std::regex_match(_line, get_category_regex().at(0)))
|
||||
{
|
||||
lerr << std::left << std::setw(lerr_width) << _line_ss.str()
|
||||
<< " matched category pattern '" << get_category_regex_pattern().at(0)
|
||||
<< "'...\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
if(std::regex_search(_line, get_category_regex().at(0)))
|
||||
{
|
||||
lerr << std::left << std::setw(lerr_width) << _line_ss.str()
|
||||
<< " found category pattern '" << get_category_regex_pattern().at(0)
|
||||
<< "'...\n";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
lerr << std::left << std::setw(lerr_width) << _line_ss.str()
|
||||
<< " missing category pattern '" << get_category_regex_pattern().at(0)
|
||||
<< "'...\n";
|
||||
return false;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
bool
|
||||
is_selected(const std::string& _line)
|
||||
{
|
||||
return regex_match(_line);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
bool
|
||||
is_category_selected(const std::string& _line)
|
||||
{
|
||||
return category_regex_match(_line);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
std::string
|
||||
hl_selected(const std::string& _line)
|
||||
{
|
||||
return (regex_hl) ? regex_replace(_line) : _line;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
void
|
||||
process_categories(parser_t& p, const str_set_t& _category_options)
|
||||
{
|
||||
category_view = p.get<str_set_t>("categories");
|
||||
std::vector<std::function<void()>> _shorthand_patches{};
|
||||
for(const auto& itr : category_view)
|
||||
{
|
||||
auto _is_shorthand = [&_shorthand_patches, &_category_options,
|
||||
itr](const std::string& _prefix) {
|
||||
auto _opt = TIMEMORY_JOIN("::", _prefix, itr);
|
||||
if(_category_options.count(_opt) > 0)
|
||||
{
|
||||
_shorthand_patches.emplace_back([itr, _opt]() {
|
||||
category_view.erase(itr);
|
||||
category_view.emplace(_opt);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
if(_category_options.count(itr) == 0)
|
||||
{
|
||||
if(!_is_shorthand("component") && !_is_shorthand("settings"))
|
||||
throw std::runtime_error(
|
||||
itr + " is not a valid category. Use --list-categories to view "
|
||||
"valid categories");
|
||||
}
|
||||
}
|
||||
for(auto&& itr : _shorthand_patches)
|
||||
itr();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
bool
|
||||
exclude_setting(const std::string& _v)
|
||||
{
|
||||
if(settings_exclude.find(_v) != settings_exclude.end()) return true;
|
||||
auto itr = settings::instance()->find(_v, false);
|
||||
if(itr == settings::instance()->end()) return true;
|
||||
return itr->second->get_hidden();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
void
|
||||
dump_log()
|
||||
{
|
||||
if(debug_msg)
|
||||
{
|
||||
std::cerr << lerr.str() << std::flush;
|
||||
lerr = std::stringstream{};
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dump_log_abort(int _v)
|
||||
{
|
||||
fprintf(stderr, "\n[omnitrace-avail] Exiting with signal %i...\n", _v);
|
||||
debug_msg = true;
|
||||
dump_log();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
std::string
|
||||
remove(std::string inp, const std::set<std::string>& entries)
|
||||
{
|
||||
for(const auto& itr : entries)
|
||||
{
|
||||
auto idx = inp.find(itr);
|
||||
while(idx != std::string::npos)
|
||||
{
|
||||
inp.erase(idx, itr.length());
|
||||
idx = inp.find(itr);
|
||||
}
|
||||
}
|
||||
return inp;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
bool
|
||||
file_exists(const std::string& _fname)
|
||||
{
|
||||
struct stat _buffer;
|
||||
if(stat(_fname.c_str(), &_buffer) == 0)
|
||||
return (S_ISREG(_buffer.st_mode) != 0 || S_ISLNK(_buffer.st_mode) != 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
@@ -0,0 +1,145 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2022 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "defines.hpp"
|
||||
|
||||
#include <timemory/components/types.hpp>
|
||||
#include <timemory/mpl/concepts.hpp>
|
||||
#include <timemory/settings/types.hpp>
|
||||
#include <timemory/utility/argparse.hpp>
|
||||
#include <timemory/utility/demangle.hpp>
|
||||
#include <timemory/utility/type_list.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <regex>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
// namespaces
|
||||
|
||||
namespace regex_const = ::std::regex_constants; // NOLINT
|
||||
namespace comp = ::tim::component; // NOLINT
|
||||
using settings = ::tim::settings; // NOLINT
|
||||
using tim::demangle; // NOLINT
|
||||
using tim::type_list; // NOLINT
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
// aliases
|
||||
|
||||
template <typename Tp, size_t N>
|
||||
using array_t = ::std::array<Tp, N>;
|
||||
using string_t = ::std::string;
|
||||
using stringstream_t = ::std::stringstream;
|
||||
using str_vec_t = ::std::vector<string_t>;
|
||||
using str_set_t = ::std::set<string_t>;
|
||||
using info_type_base = ::std::tuple<string_t, bool, str_vec_t>;
|
||||
using parser_t = ::tim::argparse::argument_parser;
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
// enums
|
||||
|
||||
enum : int
|
||||
{
|
||||
VAL = 0,
|
||||
ENUM = 1,
|
||||
LANG = 2,
|
||||
CID = 3,
|
||||
FNAME = 4,
|
||||
DESC = 5,
|
||||
CATEGORY = 6,
|
||||
TOTAL = 7
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
// variables
|
||||
|
||||
constexpr size_t num_component_options = 7;
|
||||
constexpr size_t num_settings_options = 4;
|
||||
constexpr size_t num_hw_counter_options = 4;
|
||||
constexpr size_t num_dump_config_options = TOTAL;
|
||||
|
||||
extern std::string global_delim;
|
||||
extern bool csv;
|
||||
extern bool markdown;
|
||||
extern bool alphabetical;
|
||||
extern bool available_only;
|
||||
extern bool all_info;
|
||||
extern bool force_brief;
|
||||
extern bool debug_msg;
|
||||
extern bool case_insensitive;
|
||||
extern bool regex_hl;
|
||||
extern bool expand_keys;
|
||||
extern bool force_config;
|
||||
extern int32_t max_width;
|
||||
extern int32_t num_cols;
|
||||
extern int32_t min_width;
|
||||
extern int32_t padding;
|
||||
extern str_vec_t regex_keys;
|
||||
extern str_vec_t category_regex_keys;
|
||||
extern str_set_t category_view;
|
||||
extern std::stringstream lerr;
|
||||
|
||||
// explicit setting names to exclude
|
||||
extern std::set<std::string> settings_exclude;
|
||||
|
||||
// exclude some timemory settings which are not relevant to omnitrace
|
||||
// exact matches, e.g. OMNITRACE_BANNER
|
||||
extern std::string settings_rexclude_exact;
|
||||
|
||||
// leading matches, e.g. OMNITRACE_MPI_[A-Z_]+
|
||||
extern std::string settings_rexclude_begin;
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
// functions
|
||||
|
||||
bool
|
||||
is_selected(const std::string& line);
|
||||
|
||||
bool
|
||||
is_category_selected(const std::string& _line);
|
||||
|
||||
std::string
|
||||
hl_selected(const std::string& line);
|
||||
|
||||
void
|
||||
process_categories(parser_t&, const str_set_t&);
|
||||
|
||||
bool
|
||||
exclude_setting(const std::string&);
|
||||
|
||||
void
|
||||
dump_log();
|
||||
|
||||
void
|
||||
dump_log_abort(int _v);
|
||||
|
||||
std::string
|
||||
remove(std::string inp, const std::set<std::string>& entries);
|
||||
|
||||
bool
|
||||
file_exists(const std::string&);
|
||||
@@ -0,0 +1,84 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2022 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common.hpp"
|
||||
#include "defines.hpp"
|
||||
|
||||
#include <timemory/components/types.hpp>
|
||||
#include <timemory/enum.h>
|
||||
#include <timemory/utility/types.hpp>
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
template <typename Type = void>
|
||||
struct component_categories;
|
||||
|
||||
template <typename Type>
|
||||
struct component_categories
|
||||
{
|
||||
template <typename... Tp>
|
||||
void operator()(std::set<std::string>& _v, type_list<Tp...>) const
|
||||
{
|
||||
//
|
||||
auto _cleanup = [](std::string _type, const std::string& _pattern) {
|
||||
auto _pos = std::string::npos;
|
||||
while((_pos = _type.find(_pattern)) != std::string::npos)
|
||||
_type = _type.erase(_pos, _pattern.length());
|
||||
return _type;
|
||||
};
|
||||
(void) _cleanup; // unused but set if sizeof...(Tp) == 0
|
||||
|
||||
TIMEMORY_FOLD_EXPRESSION(_v.emplace(TIMEMORY_JOIN(
|
||||
"::", "component", _cleanup(tim::try_demangle<Tp>(), "tim::"))));
|
||||
}
|
||||
|
||||
void operator()(std::set<std::string>& _v) const
|
||||
{
|
||||
if constexpr(!tim::concepts::is_placeholder<Type>::value)
|
||||
(*this)(_v, tim::trait::component_apis_t<Type>{});
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct component_categories<void>
|
||||
{
|
||||
template <size_t... Idx>
|
||||
void operator()(std::set<std::string>& _v, std::index_sequence<Idx...>) const
|
||||
{
|
||||
TIMEMORY_FOLD_EXPRESSION(component_categories<comp::enumerator_t<Idx>>{}(_v));
|
||||
}
|
||||
|
||||
void operator()(std::set<std::string>& _v) const
|
||||
{
|
||||
(*this)(_v, std::make_index_sequence<TIMEMORY_COMPONENTS_END>{});
|
||||
}
|
||||
|
||||
auto operator()() const
|
||||
{
|
||||
std::set<std::string> _categories{};
|
||||
(*this)(_categories);
|
||||
return _categories;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2022 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#pragma once
|
||||
|
||||
#define TIMEMORY_DISABLE_BANNER
|
||||
#define TIMEMORY_DISABLE_COMPONENT_STORAGE_INIT
|
||||
|
||||
#include "library/config.hpp"
|
||||
#include "library/defines.hpp"
|
||||
@@ -0,0 +1,53 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2022 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common.hpp"
|
||||
#include "defines.hpp"
|
||||
|
||||
#include <timemory/components/properties.hpp>
|
||||
#include <timemory/mpl/concepts.hpp>
|
||||
#include <timemory/utility/type_list.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
|
||||
template <typename T, typename I>
|
||||
struct enumerated_list;
|
||||
|
||||
template <template <typename...> class TupT, typename... T>
|
||||
struct enumerated_list<TupT<T...>, std::index_sequence<>>
|
||||
{
|
||||
using type = type_list<T...>;
|
||||
};
|
||||
|
||||
template <template <typename...> class TupT, size_t I, typename... T, size_t... Idx>
|
||||
struct enumerated_list<TupT<T...>, std::index_sequence<I, Idx...>>
|
||||
{
|
||||
using Tp = tim::component::enumerator_t<I>;
|
||||
static constexpr bool is_nothing = tim::concepts::is_placeholder<Tp>::value;
|
||||
using type = typename enumerated_list<
|
||||
std::conditional_t<is_nothing, type_list<T...>, type_list<T..., Tp>>,
|
||||
std::index_sequence<Idx...>>::type;
|
||||
};
|
||||
@@ -0,0 +1,437 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2022 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
//
|
||||
// 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 "generate_config.hpp"
|
||||
#include "common.hpp"
|
||||
#include "defines.hpp"
|
||||
#include "info_type.hpp"
|
||||
|
||||
#include <timemory/mpl/concepts.hpp>
|
||||
#include <timemory/mpl/policy.hpp>
|
||||
#include <timemory/settings.hpp>
|
||||
#include <timemory/settings/types.hpp>
|
||||
#include <timemory/tpls/cereal/archives.hpp>
|
||||
#include <timemory/tpls/cereal/cereal.hpp>
|
||||
#include <timemory/tpls/cereal/cereal/archives/json.hpp>
|
||||
#include <timemory/tpls/cereal/cereal/archives/xml.hpp>
|
||||
#include <timemory/tpls/cereal/cereal/cereal.hpp>
|
||||
#include <timemory/utility/filepath.hpp>
|
||||
#include <timemory/utility/types.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
namespace cereal = ::tim::cereal;
|
||||
namespace filepath = ::tim::filepath;
|
||||
using settings = ::tim::settings;
|
||||
using ::tim::tsettings;
|
||||
using ::tim::type_list;
|
||||
using ::tim::policy::output_archive;
|
||||
|
||||
namespace
|
||||
{
|
||||
struct custom_setting_serializer
|
||||
{
|
||||
static std::array<bool, TOTAL> options;
|
||||
};
|
||||
|
||||
template <typename Tp>
|
||||
bool
|
||||
ignore_setting(const Tp& _v)
|
||||
{
|
||||
if(_v->get_hidden()) return true;
|
||||
if(exclude_setting(_v->get_env_name())) return true;
|
||||
if(!is_selected(_v->get_env_name()) && !is_selected(_v->get_name())) return true;
|
||||
if(available_only && !_v->get_enabled()) return true;
|
||||
if(!category_view.empty())
|
||||
{
|
||||
bool _found = false;
|
||||
for(auto& itr : _v->get_categories())
|
||||
{
|
||||
if(category_view.count(itr) > 0 ||
|
||||
category_view.count(TIMEMORY_JOIN("::", "settings", itr)) > 0)
|
||||
{
|
||||
_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!_found) return true;
|
||||
}
|
||||
if(category_view.count("deprecated") == 0 &&
|
||||
category_view.count("settings::deprecated") == 0 &&
|
||||
_v->get_categories().count("deprecated") > 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
std::array<bool, TOTAL> custom_setting_serializer::options = { false };
|
||||
|
||||
namespace tim
|
||||
{
|
||||
namespace operation
|
||||
{
|
||||
template <typename Tp>
|
||||
struct setting_serialization<Tp, custom_setting_serializer>
|
||||
{
|
||||
template <typename ArchiveT>
|
||||
void operator()(ArchiveT&, const char*, const Tp&) const
|
||||
{}
|
||||
|
||||
template <typename ArchiveT>
|
||||
void operator()(ArchiveT&, const char*, Tp&&) const
|
||||
{}
|
||||
};
|
||||
//
|
||||
template <typename Tp>
|
||||
struct setting_serialization<tsettings<Tp>, custom_setting_serializer>
|
||||
{
|
||||
using value_type = tsettings<Tp>;
|
||||
|
||||
template <typename ArchiveT>
|
||||
void operator()(ArchiveT& _ar, value_type& _val) const
|
||||
{
|
||||
static_assert(concepts::is_output_archive<ArchiveT>::value,
|
||||
"Requires an output archive");
|
||||
|
||||
if(ignore_setting(&_val)) return;
|
||||
|
||||
auto _save = std::shared_ptr<value_type>{};
|
||||
if constexpr(concepts::is_string_type<Tp>::value)
|
||||
{
|
||||
if(_val.get_name() != "time_format")
|
||||
_val.set(settings::format(_val.get(), settings::instance()->get_tag()));
|
||||
if(_val.get_name() == "config_file")
|
||||
{
|
||||
_save = std::make_shared<value_type>(_val);
|
||||
_val.set(Tp{});
|
||||
}
|
||||
}
|
||||
|
||||
if(all_info)
|
||||
{
|
||||
_ar(cereal::make_nvp(_val.get_env_name().c_str(), _val));
|
||||
}
|
||||
else
|
||||
{
|
||||
Tp _v = _val.get();
|
||||
_ar.setNextName(_val.get_env_name().c_str());
|
||||
_ar.startNode();
|
||||
_ar(cereal::make_nvp("name", _val.get_name()));
|
||||
_ar(cereal::make_nvp("value", _v));
|
||||
if(custom_setting_serializer::options[DESC])
|
||||
_ar(cereal::make_nvp("description", _val.get_description()));
|
||||
if(custom_setting_serializer::options[CATEGORY])
|
||||
_ar(cereal::make_nvp("description", _val.get_categories()));
|
||||
if(custom_setting_serializer::options[VAL])
|
||||
_ar(cereal::make_nvp("choices", _val.get_choices()));
|
||||
_ar.finishNode();
|
||||
}
|
||||
|
||||
if(_save) _val.set(_save->get());
|
||||
}
|
||||
};
|
||||
} // namespace operation
|
||||
} // namespace tim
|
||||
|
||||
template <typename... Tp>
|
||||
void push(type_list<Tp...>)
|
||||
{
|
||||
OMNITRACE_FOLD_EXPRESSION(
|
||||
settings::push_serialize_map_callback<Tp, custom_setting_serializer>());
|
||||
OMNITRACE_FOLD_EXPRESSION(
|
||||
settings::push_serialize_data_callback<Tp, custom_setting_serializer>(
|
||||
type_list<std::string>{}));
|
||||
}
|
||||
|
||||
template <typename... Tp>
|
||||
void pop(type_list<Tp...>)
|
||||
{
|
||||
OMNITRACE_FOLD_EXPRESSION(
|
||||
settings::pop_serialize_map_callback<Tp, custom_setting_serializer>());
|
||||
OMNITRACE_FOLD_EXPRESSION(
|
||||
settings::pop_serialize_data_callback<Tp, custom_setting_serializer>(
|
||||
type_list<std::string>{}));
|
||||
}
|
||||
|
||||
void
|
||||
update_choices();
|
||||
|
||||
void
|
||||
generate_config(std::string _config_file, const std::set<std::string>& _config_fmts,
|
||||
const std::array<bool, TOTAL>& _options)
|
||||
{
|
||||
custom_setting_serializer::options = _options;
|
||||
|
||||
_config_file = settings::format(_config_file, settings::instance()->get_tag());
|
||||
bool _absolute = _config_file.at(0) == '/';
|
||||
auto _dirs = tim::delimit(_config_file, "/\\/");
|
||||
_config_file = _dirs.back();
|
||||
_dirs.pop_back();
|
||||
|
||||
std::string _output_dir = ".";
|
||||
if(!_dirs.empty() && !(_dirs.size() == 1 && _dirs.at(0) == "."))
|
||||
{
|
||||
_output_dir = std::string{ (_absolute) ? "/" : "" } + _dirs.front();
|
||||
_dirs.erase(_dirs.begin());
|
||||
for(const auto& itr : _dirs)
|
||||
_output_dir = TIMEMORY_JOIN('/', _output_dir, itr);
|
||||
}
|
||||
_output_dir += "/";
|
||||
|
||||
std::string _txt_ext = ".cfg";
|
||||
for(std::string itr : { ".cfg", ".txt", ".json", ".xml" })
|
||||
{
|
||||
auto _pos = _config_file.rfind(itr);
|
||||
if(_pos == _config_file.length() - itr.length())
|
||||
{
|
||||
if(itr == ".cfg" || itr == ".txt") _txt_ext = itr;
|
||||
_config_file = _config_file.substr(0, _pos);
|
||||
}
|
||||
}
|
||||
|
||||
update_choices();
|
||||
|
||||
using json_t = cereal::PrettyJSONOutputArchive;
|
||||
using xml_t = cereal::XMLOutputArchive;
|
||||
|
||||
// stores the original serializer and replaces it with the custom one
|
||||
push(type_list<json_t, xml_t>{});
|
||||
|
||||
static std::time_t _time{ std::time(nullptr) };
|
||||
|
||||
auto _serialize = [](auto&& _ar) {
|
||||
auto _settings = settings::shared_instance();
|
||||
_ar->setNextName(TIMEMORY_PROJECT_NAME);
|
||||
_ar->startNode();
|
||||
(*_ar)(cereal::make_nvp("version", std::string{ OMNITRACE_VERSION_STRING }));
|
||||
(*_ar)(cereal::make_nvp("date", tim::get_local_datetime("%F_%H.%M", &_time)));
|
||||
settings::serialize_settings(*_ar);
|
||||
_ar->finishNode();
|
||||
};
|
||||
|
||||
auto _open = [](std::ofstream& _ofs, const std::string& _fname,
|
||||
const std::string& _type) -> std::ofstream& {
|
||||
if(file_exists(_fname))
|
||||
{
|
||||
if(force_config)
|
||||
{
|
||||
if(settings::verbose() >= 1)
|
||||
std::cout << "[omnitrace-avail] File '" << _fname
|
||||
<< "' exists. Overwrite force...\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "[omnitrace-avail] File '" << _fname
|
||||
<< "' exists. Overwrite? " << std::flush;
|
||||
std::string _response = {};
|
||||
std::cin >> _response;
|
||||
if(!tim::get_bool(_response, false)) std::exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if(filepath::open(_ofs, _fname))
|
||||
{
|
||||
if(settings::verbose() >= 0)
|
||||
printf("[omnitrace-avail] Outputting %s configuration file '%s'...\n",
|
||||
_type.c_str(), _fname.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error(
|
||||
TIMEMORY_JOIN(" ", "Error opening", _type, "output file:", _fname));
|
||||
}
|
||||
return _ofs;
|
||||
};
|
||||
|
||||
if(_config_fmts.count("json") > 0)
|
||||
{
|
||||
std::stringstream _ss{};
|
||||
output_archive<cereal::PrettyJSONOutputArchive>::indent_length() = 4;
|
||||
_serialize(output_archive<cereal::PrettyJSONOutputArchive>::get(_ss));
|
||||
auto _fname = settings::compose_output_filename(_config_file, ".json", false, -1,
|
||||
true, _output_dir);
|
||||
std::ofstream ofs{};
|
||||
_open(ofs, _fname, "JSON") << _ss.str() << "\n";
|
||||
}
|
||||
|
||||
if(_config_fmts.count("xml") > 0)
|
||||
{
|
||||
std::stringstream _ss{};
|
||||
output_archive<cereal::XMLOutputArchive>::indent() = true;
|
||||
_serialize(output_archive<cereal::XMLOutputArchive>::get(_ss));
|
||||
auto _fname = settings::compose_output_filename(_config_file, ".xml", false, -1,
|
||||
true, _output_dir);
|
||||
std::ofstream ofs{};
|
||||
_open(ofs, _fname, "XML") << _ss.str() << "\n";
|
||||
}
|
||||
|
||||
if(_config_fmts.count("txt") > 0)
|
||||
{
|
||||
std::stringstream _ss{};
|
||||
auto _settings = settings::shared_instance();
|
||||
size_t _w = min_width;
|
||||
|
||||
std::vector<std::shared_ptr<tim::vsettings>> _data{};
|
||||
for(const auto& itr : *_settings)
|
||||
{
|
||||
if(exclude_setting(itr.second->get_env_name())) continue;
|
||||
for(const auto& citr : itr.second->get_categories())
|
||||
if(citr == "deprecated") continue;
|
||||
if(ignore_setting(itr.second)) continue;
|
||||
_data.emplace_back(itr.second);
|
||||
}
|
||||
|
||||
if(alphabetical)
|
||||
std::sort(_data.begin(), _data.end(), [](auto _lhs, auto _rhs) {
|
||||
return _lhs->get_name() < _rhs->get_name();
|
||||
});
|
||||
else
|
||||
{
|
||||
std::sort(_data.begin(), _data.end(), [](auto _lhs, auto _rhs) {
|
||||
auto _lomni = _lhs->get_categories().count("omnitrace") > 0;
|
||||
auto _romni = _rhs->get_categories().count("omnitrace") > 0;
|
||||
if(_lomni && !_romni) return true;
|
||||
if(_romni && !_lomni) return false;
|
||||
for(const auto* itr :
|
||||
{ "OMNITRACE_CONFIG", "OMNITRACE_MODE", "OMNITRACE_USE_PERFETTO",
|
||||
"OMNITRACE_USE_TIMEMORY", "OMNITRACE_USE_SAMPLING",
|
||||
"OMNITRACE_USE_PROCESS_SAMPLING", "OMNITRACE_USE_ROCTRACER",
|
||||
"OMNITRACE_USE_ROCM_SMI", "OMNITRACE_USE_KOKKOSP",
|
||||
"OMNITRACE_USE_OMPT", "OMNITRACE_USE", "OMNITRACE_OUTPUT" })
|
||||
{
|
||||
if(_lhs->get_env_name().find(itr) == 0 &&
|
||||
_rhs->get_env_name().find(itr) != 0)
|
||||
return true;
|
||||
if(_rhs->get_env_name().find(itr) == 0 &&
|
||||
_lhs->get_env_name().find(itr) != 0)
|
||||
return false;
|
||||
}
|
||||
return _lhs->get_name() < _rhs->get_name();
|
||||
});
|
||||
}
|
||||
|
||||
for(const auto& itr : _data)
|
||||
{
|
||||
_w = std::max(_w, itr->get_env_name().length());
|
||||
}
|
||||
|
||||
for(const auto& itr : _data)
|
||||
{
|
||||
if(exclude_setting(itr->get_env_name())) continue;
|
||||
|
||||
auto _has_info =
|
||||
(all_info || _options[DESC] || _options[CATEGORY] || _options[VAL]);
|
||||
|
||||
if(_has_info) _ss << "\n# name:\n# " << itr->get_name() << "\n#\n";
|
||||
|
||||
if(_options[DESC] || all_info)
|
||||
{
|
||||
_ss << "# description:\n";
|
||||
auto _desc = tim::delimit(itr->get_description(), " \n");
|
||||
std::stringstream _line{};
|
||||
_line << "# ";
|
||||
auto _write = [&_line, &_ss, _w](std::string_view _str) {
|
||||
if(_line.str().length() + _str.length() + 1 >= _w)
|
||||
{
|
||||
_ss << _line.str() << "\n";
|
||||
_line = std::stringstream{};
|
||||
_line << "# ";
|
||||
}
|
||||
_line << " " << _str;
|
||||
};
|
||||
for(auto& itr : _desc)
|
||||
_write(itr);
|
||||
_ss << _line.str() << "\n#\n";
|
||||
}
|
||||
if(_options[CATEGORY] || all_info)
|
||||
{
|
||||
_ss << "# categories:\n";
|
||||
for(const auto& itr : itr->get_categories())
|
||||
_ss << "# " << itr << "\n";
|
||||
_ss << "#\n";
|
||||
}
|
||||
if((_options[VAL] || all_info) && !itr->get_choices().empty())
|
||||
{
|
||||
_ss << "# choices:\n";
|
||||
for(const auto& itr : itr->get_choices())
|
||||
_ss << "# " << itr << "\n";
|
||||
_ss << "#\n";
|
||||
}
|
||||
if(_has_info) _ss << "\n";
|
||||
_ss << std::left << std::setw(_w + 10) << itr->get_env_name() << " = ";
|
||||
auto _v = itr->as_string();
|
||||
if(itr->get_name() == "config_file") _v = {};
|
||||
if(!_v.empty() && expand_keys && itr->get_name() != "time_format")
|
||||
_v = settings::format(_v, _settings->get_tag());
|
||||
_ss << _v << "\n";
|
||||
}
|
||||
auto _fname = settings::compose_output_filename(_config_file, _txt_ext, false, -1,
|
||||
true, _output_dir);
|
||||
std::ofstream ofs{};
|
||||
_open(ofs, _fname, "text")
|
||||
<< "# auto-generated by omnitrace-avail (version " << OMNITRACE_VERSION_STRING
|
||||
<< ") on " << tim::get_local_datetime("%F @ %H:%M", &_time) << "\n\n"
|
||||
<< _ss.str() << "\n";
|
||||
}
|
||||
|
||||
// restores the original serializer
|
||||
pop(type_list<json_t, xml_t>{});
|
||||
}
|
||||
|
||||
void
|
||||
update_choices()
|
||||
{
|
||||
std::vector<info_type> _info = get_component_info<TIMEMORY_NATIVE_COMPONENTS_END>();
|
||||
|
||||
if(settings::verbose() >= 2 || settings::debug())
|
||||
printf("[omnitrace-avail] # of component found: %zu\n", _info.size());
|
||||
|
||||
_info.erase(std::remove_if(_info.begin(), _info.end(),
|
||||
[](const auto& itr) {
|
||||
if(!itr.is_available()) return true;
|
||||
// NOLINTNEXTLINE
|
||||
for(const auto& nitr :
|
||||
{ "cuda", "cupti", "nvtx", "roofline", "_bundle",
|
||||
"data_integer", "data_unsigned", "data_floating",
|
||||
"printer" })
|
||||
{
|
||||
if(itr.name().find(nitr) != std::string::npos)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}),
|
||||
_info.end());
|
||||
|
||||
std::vector<std::string> _component_choices = {};
|
||||
_component_choices.reserve(_info.size());
|
||||
for(const auto& itr : _info)
|
||||
_component_choices.emplace_back(itr.id_type());
|
||||
if(settings::verbose() >= 2 || settings::debug())
|
||||
printf("[omnitrace-avail] # of component choices: %zu\n",
|
||||
_component_choices.size());
|
||||
settings::shared_instance()
|
||||
->find("OMNITRACE_TIMEMORY_COMPONENTS")
|
||||
->second->set_choices(_component_choices);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2022 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
void
|
||||
generate_config(std::string _config_file, const std::set<std::string>& _config_fmts,
|
||||
const std::array<bool, TOTAL>&);
|
||||
@@ -0,0 +1,229 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2022 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common.hpp"
|
||||
#include "defines.hpp"
|
||||
#include "get_categories.hpp"
|
||||
#include "info_type.hpp"
|
||||
|
||||
#include <timemory/components/metadata.hpp>
|
||||
#include <timemory/components/properties.hpp>
|
||||
#include <timemory/defines.h>
|
||||
#include <timemory/enum.h>
|
||||
#include <timemory/mpl/type_traits.hpp>
|
||||
#include <timemory/utility/demangle.hpp>
|
||||
#include <timemory/utility/type_list.hpp>
|
||||
#include <timemory/variadic/macros.hpp>
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
struct unknown
|
||||
{};
|
||||
|
||||
template <typename T, typename U = typename T::value_type>
|
||||
constexpr bool
|
||||
available_value_type_alias(int)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T, typename U = unknown>
|
||||
constexpr bool
|
||||
available_value_type_alias(long)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Type, bool>
|
||||
struct component_value_type;
|
||||
|
||||
template <typename Type>
|
||||
struct component_value_type<Type, true>
|
||||
{
|
||||
using type = typename Type::value_type;
|
||||
};
|
||||
|
||||
template <typename Type>
|
||||
struct component_value_type<Type, false>
|
||||
{
|
||||
using type = unknown;
|
||||
};
|
||||
|
||||
template <typename Type>
|
||||
using component_value_type_t =
|
||||
typename component_value_type<Type, available_value_type_alias<Type>(0)>::type;
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
template <typename Type = void>
|
||||
struct get_availability;
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
template <typename Type>
|
||||
struct get_availability
|
||||
{
|
||||
using this_type = get_availability<Type>;
|
||||
using metadata_t = ::tim::component::metadata<Type>;
|
||||
using property_t = ::tim::component::properties<Type>;
|
||||
|
||||
static info_type get_info();
|
||||
auto operator()() const { return get_info(); }
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
template <typename... Types>
|
||||
struct get_availability<type_list<Types...>>
|
||||
{
|
||||
using data_type = std::vector<info_type>;
|
||||
|
||||
static data_type get_info(data_type& _v)
|
||||
{
|
||||
TIMEMORY_FOLD_EXPRESSION(_v.emplace_back(get_availability<Types>::get_info()));
|
||||
return _v;
|
||||
}
|
||||
|
||||
static data_type get_info()
|
||||
{
|
||||
data_type _v{};
|
||||
return get_info(_v);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
decltype(auto) operator()(Args&&... _args)
|
||||
{
|
||||
return get_info(std::forward<Args>(_args)...);
|
||||
}
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
template <typename Type>
|
||||
info_type
|
||||
get_availability<Type>::get_info()
|
||||
{
|
||||
using namespace tim;
|
||||
using value_type = component_value_type_t<Type>;
|
||||
using category_types = typename trait::component_apis<Type>::type;
|
||||
|
||||
auto _cleanup = [](std::string _type, const std::string& _pattern) {
|
||||
auto _pos = std::string::npos;
|
||||
while((_pos = _type.find(_pattern)) != std::string::npos)
|
||||
_type.erase(_pos, _pattern.length());
|
||||
return _type;
|
||||
};
|
||||
auto _replace = [](std::string _type, const std::string& _pattern,
|
||||
const std::string& _with) {
|
||||
auto _pos = std::string::npos;
|
||||
while((_pos = _type.find(_pattern)) != std::string::npos)
|
||||
_type.replace(_pos, _pattern.length(), _with);
|
||||
return _type;
|
||||
};
|
||||
|
||||
bool has_metadata = metadata_t::specialized();
|
||||
bool has_properties = property_t::specialized();
|
||||
bool is_available = trait::is_available<Type>::value;
|
||||
bool file_output = trait::generates_output<Type>::value;
|
||||
auto name = component::metadata<Type>::name();
|
||||
auto label = (file_output)
|
||||
? ((has_metadata) ? metadata_t::label() : Type::get_label())
|
||||
: std::string("");
|
||||
auto description =
|
||||
(has_metadata) ? metadata_t::description() : Type::get_description();
|
||||
auto data_type = demangle<value_type>();
|
||||
string_t enum_type = property_t::enum_string();
|
||||
string_t id_type = property_t::id();
|
||||
auto ids_set = property_t::ids();
|
||||
|
||||
if(!has_properties)
|
||||
{
|
||||
enum_type = "";
|
||||
id_type = "";
|
||||
ids_set.clear();
|
||||
}
|
||||
string_t ids_str = {};
|
||||
{
|
||||
auto itr = ids_set.begin();
|
||||
string_t db = (markdown) ? "`\"" : (csv) ? "" : "\"";
|
||||
string_t de = (markdown) ? "\"`" : (csv) ? "" : "\"";
|
||||
if(has_metadata) description += ". " + metadata_t::extra_description();
|
||||
description += ".";
|
||||
while(itr->empty())
|
||||
++itr;
|
||||
if(itr != ids_set.end())
|
||||
ids_str = TIMEMORY_JOIN("", TIMEMORY_JOIN("", db, *itr++, de));
|
||||
for(; itr != ids_set.end(); ++itr)
|
||||
{
|
||||
if(!itr->empty())
|
||||
ids_str = TIMEMORY_JOIN(", ", ids_str, TIMEMORY_JOIN("", db, *itr, de));
|
||||
}
|
||||
}
|
||||
|
||||
string_t categories = get_categories(category_types{});
|
||||
|
||||
#if 0
|
||||
auto _remove_typelist = [](std::string _tmp) {
|
||||
if(_tmp.empty()) return _tmp;
|
||||
auto _key = std::string{ "type_list" };
|
||||
auto _idx = _tmp.find(_key);
|
||||
if(_idx == std::string::npos) return _tmp;
|
||||
_idx = _tmp.find('<', _idx);
|
||||
_tmp = _tmp.substr(_idx + 1);
|
||||
_idx = _tmp.find_last_of('>');
|
||||
_tmp = _tmp.substr(0, _idx);
|
||||
if(_tmp.empty()) return _tmp;
|
||||
// strip trailing whitespaces
|
||||
while((_idx = _tmp.find_last_of(' ')) == _tmp.length() - 1)
|
||||
_tmp = _tmp.substr(0, _idx);
|
||||
return _tmp;
|
||||
};
|
||||
auto apis = _remove_typelist(demangle<trait::component_apis_t<Type>>());
|
||||
if(!apis.empty()) description += ". APIs: " + apis;
|
||||
#endif
|
||||
|
||||
description = _replace(_replace(description, ". .", "."), "..", ".");
|
||||
data_type = _replace(_cleanup(data_type, "::__1"), "> >", ">>");
|
||||
return info_type{ name, is_available,
|
||||
str_vec_t{ data_type, enum_type, id_type, ids_str, label,
|
||||
description, categories } };
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
template <>
|
||||
struct get_availability<void>
|
||||
{
|
||||
template <typename... Tp, typename... Args>
|
||||
decltype(auto) operator()(tim::type_list<Tp...>, Args&&... _args) const
|
||||
{
|
||||
return get_availability<tim::type_list<Tp...>>{}(std::forward<Args>(_args)...);
|
||||
}
|
||||
|
||||
template <typename Tp, typename... Args>
|
||||
decltype(auto) operator()(Args&&... _args) const
|
||||
{
|
||||
return get_availability<tim::type_list<Tp>>{}(std::forward<Args>(_args)...);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,60 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2022 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
#include <timemory/utility/demangle.hpp>
|
||||
#include <timemory/utility/type_list.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
template <typename... Tp>
|
||||
auto get_categories(type_list<Tp...>)
|
||||
{
|
||||
auto _cleanup = [](std::string _type, const std::string& _pattern) {
|
||||
auto _pos = std::string::npos;
|
||||
while((_pos = _type.find(_pattern)) != std::string::npos)
|
||||
_type.erase(_pos, _pattern.length());
|
||||
return _type;
|
||||
};
|
||||
(void) _cleanup; // unused but set if sizeof...(Tp) == 0
|
||||
|
||||
auto _vec = str_vec_t{ _cleanup(demangle<Tp>(), "tim::")... };
|
||||
std::sort(_vec.begin(), _vec.end(), [](const auto& lhs, const auto& rhs) {
|
||||
// prioritize project category
|
||||
auto lpos = lhs.find("project::");
|
||||
auto rpos = rhs.find("project::");
|
||||
return (lpos == rpos) ? (lhs < rhs) : (lpos < rpos);
|
||||
});
|
||||
std::stringstream _ss{};
|
||||
for(auto&& itr : _vec)
|
||||
{
|
||||
_ss << ", " << itr;
|
||||
}
|
||||
std::string _v = _ss.str();
|
||||
if(!_v.empty()) return _v.substr(2);
|
||||
return _v;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2022 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
//
|
||||
// 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 "info_type.hpp"
|
||||
#include "enumerated_list.hpp"
|
||||
#include "get_availability.hpp"
|
||||
|
||||
#include "library/api.hpp"
|
||||
#include "library/components/backtrace.hpp"
|
||||
#include "library/components/fork_gotcha.hpp"
|
||||
#include "library/components/mpi_gotcha.hpp"
|
||||
#include "library/components/omnitrace.hpp"
|
||||
#include "library/components/pthread_gotcha.hpp"
|
||||
#include "library/components/roctracer.hpp"
|
||||
#include "library/components/user_region.hpp"
|
||||
|
||||
#include <timemory/components/definition.hpp>
|
||||
#include <timemory/enum.h>
|
||||
#include <timemory/utility/macros.hpp>
|
||||
|
||||
#include <utility>
|
||||
|
||||
template <size_t EndV>
|
||||
std::vector<info_type>
|
||||
get_component_info()
|
||||
{
|
||||
using index_seq_t = std::make_index_sequence<EndV>;
|
||||
using enum_list_t = typename enumerated_list<tim::type_list<>, index_seq_t>::type;
|
||||
|
||||
auto _info = std::vector<info_type>{};
|
||||
return get_availability<>{}(enum_list_t{}, _info);
|
||||
}
|
||||
|
||||
template std::vector<info_type>
|
||||
get_component_info<TIMEMORY_NATIVE_COMPONENTS_END>();
|
||||
|
||||
template std::vector<info_type>
|
||||
get_component_info<TIMEMORY_COMPONENTS_END>();
|
||||
@@ -0,0 +1,75 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2022 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
#include <timemory/enum.h>
|
||||
#include <timemory/utility/macros.hpp>
|
||||
|
||||
#include <utility>
|
||||
|
||||
struct info_type : info_type_base
|
||||
{
|
||||
TIMEMORY_DEFAULT_OBJECT(info_type)
|
||||
|
||||
template <typename... Args>
|
||||
info_type(Args&&... _args)
|
||||
: info_type_base{ std::forward<Args>(_args)... }
|
||||
{}
|
||||
|
||||
const auto& name() const { return std::get<0>(*this); }
|
||||
auto is_available() const { return std::get<1>(*this); }
|
||||
const auto& info() const { return std::get<2>(*this); }
|
||||
const auto& data_type() const { return info().at(0); }
|
||||
const auto& enum_type() const { return info().at(1); }
|
||||
const auto& id_type() const { return info().at(2); }
|
||||
const auto& id_strings() const { return info().at(3); }
|
||||
const auto& label() const { return info().at(4); }
|
||||
const auto& description() const { return info().at(5); }
|
||||
const auto& categories() const { return info().at(6); }
|
||||
|
||||
bool valid() const { return !name().empty() && info().size() >= 6; }
|
||||
|
||||
bool operator<(const info_type& rhs) const { return name() < rhs.name(); }
|
||||
bool operator!=(const info_type& rhs) const { return !(*this == rhs); }
|
||||
bool operator==(const info_type& rhs) const
|
||||
{
|
||||
if(info().size() != rhs.info().size()) return false;
|
||||
for(size_t i = 0; i < info().size(); ++i)
|
||||
{
|
||||
if(info().at(i) != rhs.info().at(i)) return false;
|
||||
}
|
||||
return name() == rhs.name() && is_available() == rhs.is_available();
|
||||
}
|
||||
};
|
||||
|
||||
template <size_t EndV>
|
||||
std::vector<info_type>
|
||||
get_component_info();
|
||||
|
||||
extern template std::vector<info_type>
|
||||
get_component_info<TIMEMORY_NATIVE_COMPONENTS_END>();
|
||||
|
||||
extern template std::vector<info_type>
|
||||
get_component_info<TIMEMORY_COMPONENTS_END>();
|
||||
@@ -125,7 +125,7 @@ omnitrace_add_bin_test(
|
||||
NAME omnitrace-avail-help
|
||||
TARGET omnitrace-avail
|
||||
ARGS --help
|
||||
LABELS omnitrace-avail
|
||||
LABELS "omnitrace-avail"
|
||||
TIMEOUT 45
|
||||
PASS_REGEX
|
||||
".*\\\[omnitrace-avail\\\] Usage:.*\\\[CATEGORIES\\\].*\\\[VIEW OPTIONS\\\].*\\\[COLUMN OPTIONS\\\].*\\\[WIDTH OPTIONS\\\].*\\\[OUTPUT OPTIONS\\\].*"
|
||||
@@ -135,7 +135,7 @@ omnitrace_add_bin_test(
|
||||
NAME omnitrace-avail-all-csv
|
||||
TARGET omnitrace-avail
|
||||
ARGS --all --csv --csv-separator "#"
|
||||
LABELS omnitrace-avail
|
||||
LABELS "omnitrace-avail"
|
||||
TIMEOUT 45
|
||||
PASS_REGEX
|
||||
"COMPONENT#AVAILABLE#VALUE_TYPE#STRING_IDS#FILENAME#DESCRIPTION#CATEGORY#.*ENVIRONMENT VARIABLE#VALUE#DATA TYPE#DESCRIPTION#CATEGORIES#.*HARDWARE COUNTER#AVAILABLE#DESCRIPTION#"
|
||||
@@ -145,7 +145,7 @@ omnitrace_add_bin_test(
|
||||
NAME omnitrace-avail-filter-wall-clock-available
|
||||
TARGET omnitrace-avail
|
||||
ARGS -r wall_clock -C --available
|
||||
LABELS omnitrace-avail
|
||||
LABELS "omnitrace-avail"
|
||||
TIMEOUT 45
|
||||
PASS_REGEX
|
||||
"\\\|[-]+\\\|\n\\\|[ ]+COMPONENT[ ]+\\\|\n\\\|[-]+\\\|\n\\\| (wall_clock)[ ]+\\\|\n\\\| (sampling_wall_clock)[ ]+\\\|\n\\\|[-]+\\\|"
|
||||
@@ -155,7 +155,7 @@ omnitrace_add_bin_test(
|
||||
NAME omnitrace-avail-category-filter-omnitrace
|
||||
TARGET omnitrace-avail
|
||||
ARGS --categories settings::omnitrace --brief
|
||||
LABELS omnitrace-avail
|
||||
LABELS "omnitrace-avail"
|
||||
TIMEOUT 45
|
||||
PASS_REGEX "OMNITRACE_(SETTINGS_DESC|OUTPUT_FILE|OUTPUT_PREFIX)"
|
||||
FAIL_REGEX
|
||||
@@ -166,7 +166,7 @@ omnitrace_add_bin_test(
|
||||
NAME omnitrace-avail-category-filter-timemory
|
||||
TARGET omnitrace-avail
|
||||
ARGS --categories settings::timemory --brief
|
||||
LABELS omnitrace-avail
|
||||
LABELS "omnitrace-avail"
|
||||
TIMEOUT 45
|
||||
PASS_REGEX
|
||||
"OMNITRACE_(ADD_SECONDARY|SCIENTIFIC|PRECISION|MEMORY_PRECISION|TIMING_PRECISION)"
|
||||
@@ -184,7 +184,32 @@ omnitrace_add_bin_test(
|
||||
~PERFETTO
|
||||
--csv
|
||||
--brief
|
||||
LABELS omnitrace-avail
|
||||
LABELS "omnitrace-avail"
|
||||
TIMEOUT 45
|
||||
PASS_REGEX "ENVIRONMENT VARIABLE,[ \n]+OMNITRACE_USE_PID,[ \n]+"
|
||||
FAIL_REGEX "OMNITRACE_USE_PERFETTO")
|
||||
|
||||
string(REPLACE "+" "\\\+" _AVAIL_CFG_PATH
|
||||
"${PROJECT_BINARY_DIR}/omnitrace-tests-output/omnitrace-avail/omnitrace-")
|
||||
omnitrace_add_bin_test(
|
||||
NAME omnitrace-avail-write-config
|
||||
TARGET omnitrace-avail
|
||||
ARGS -G %env{PWD}%/omnitrace-tests-output/omnitrace-avail/omnitrace-test.cfg -F txt
|
||||
json xml --force --all
|
||||
TIMEOUT 45
|
||||
LABELS "omnitrace-avail"
|
||||
PASS_REGEX
|
||||
"Outputting JSON configuration file '${_AVAIL_CFG_PATH}test\\\.json'(.*)Outputting XML configuration file '${_AVAIL_CFG_PATH}test\\\.xml'(.*)Outputting text configuration file '${_AVAIL_CFG_PATH}test\\\.cfg'(.*)"
|
||||
)
|
||||
|
||||
omnitrace_add_bin_test(
|
||||
NAME omnitrace-avail-write-config-tweak
|
||||
TARGET omnitrace-avail
|
||||
ARGS -G %env{PWD}%/omnitrace-tests-output/omnitrace-avail/omnitrace-tweak.cfg -F txt
|
||||
json xml --force
|
||||
TIMEOUT 45
|
||||
LABELS "omnitrace-avail"
|
||||
ENVIRONMENT "OMNITRACE_USE_PERFETTO=OFF;OMNITRACE_USE_TIMEMORY=ON"
|
||||
PASS_REGEX
|
||||
"Outputting JSON configuration file '${_AVAIL_CFG_PATH}tweak\\\.json'(.*)Outputting XML configuration file '${_AVAIL_CFG_PATH}tweak\\\.xml'(.*)Outputting text configuration file '${_AVAIL_CFG_PATH}tweak\\\.cfg'(.*)"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user