Fix deadlocks during initialization (#167)

- More to come in later commit, below is just tidying some stuff up
  - clang-tidy
  - mpi_gotcha quiet about not finding funcs
  - update to new papi config
  - sampling block_samples / unblock_samples
    - disable calling component's sample functions within sampler
  - release doesn't strip library
  - remove HSA and ROCP env variables from modulefile / setup-env
- preliminary support for LD_PRELOAD usage
- default sampling rate is 300 interrupts / second
- fixes various deadlock issues at startup
This commit is contained in:
Jonathan R. Madsen
2022-09-26 07:52:14 -05:00
zatwierdzone przez GitHub
rodzic 90ff7188f8
commit 8f36620e29
49 zmienionych plików z 866 dodań i 342 usunięć
@@ -182,29 +182,8 @@ get_availability<Type>::get_info()
}
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"), "> >", ">>");
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 } };
@@ -227,7 +227,7 @@ save_call_graph(const std::string& _fname, const std::string& _label,
_perf.stop();
if(_msg)
{
OMNITRACE_CT_DEBUG("%s\n", JOIN("", _perf).substr(4).c_str());
OMNITRACE_CT_DEBUG("%s\n", JOIN("", _perf).c_str());
}
}
@@ -281,7 +281,7 @@ save_critical_trace(const std::string& _fname, const std::string& _label,
_perf.stop();
if(_msg)
{
OMNITRACE_CT_DEBUG("%s\n", JOIN("", _perf).substr(4).c_str());
OMNITRACE_CT_DEBUG("%s\n", JOIN("", _perf).c_str());
}
}
@@ -311,7 +311,7 @@ save_call_chain_text(const std::string& _fname, const call_chain& _call_chain,
_perf.stop();
if(_msg)
{
OMNITRACE_CT_DEBUG("%s\n", JOIN("", _perf).substr(4).c_str());
OMNITRACE_CT_DEBUG("%s\n", JOIN("", _perf).c_str());
}
}
@@ -365,7 +365,7 @@ save_call_chain_json(const std::string& _fname, const std::string& _label,
_perf.stop();
if(_msg)
{
OMNITRACE_CT_DEBUG("%s\n", JOIN("", _perf).substr(4).c_str());
OMNITRACE_CT_DEBUG("%s\n", JOIN("", _perf).c_str());
}
}
@@ -847,7 +847,9 @@ compute_critical_trace()
auto _report_perf = [](auto& _perf, const char* _func, const std::string& _label) {
_perf.stop().rekey(_label);
OMNITRACE_BASIC_PRINT("[%s] %s\n", _func, JOIN("", _perf).substr(5).c_str());
auto _str = JOIN("", _perf);
if(_str.length() > 5) _str = _str.substr(5);
OMNITRACE_BASIC_PRINT("[%s] %s\n", _func, _str.c_str());
OMNITRACE_BASIC_PRINT("\n");
_perf.reset().start();
};
+1 -1
Wyświetl plik
@@ -170,7 +170,7 @@ load_info(const string_t& _label, const string_t& _iname, fmodset_t& _data, int
auto _pos = _iname.find_last_of('.');
std::string _ext = {};
if(_pos != std::string::npos) _ext = _iname.substr(_pos + 1, _iname.length());
if(_pos != std::string::npos) _ext = _iname.substr(_pos + 1);
auto _handle_error = [&]() {
std::stringstream _msg{};
+2 -1
Wyświetl plik
@@ -212,7 +212,8 @@ main(int argc, char** argv)
stderr,
"These were the last %i log entries from omnitrace. You can control the "
"number of log entries via the '--log <N>' option or OMNITRACE_LOG_COUNT "
"env variable.\n");
"env variable.\n",
num_log_entries);
if(log_ofs) log_ofs->close();
log_ofs.reset();
+2 -1
Wyświetl plik
@@ -166,7 +166,8 @@ setup_environ(int _verbose, const std::string& _search_paths = {},
.c_str(),
0);
setenv("OMNITRACE_ROCPROFILER_LIBRARY",
common::join('/', getenv(itr), "rocprofiler/lib/librocprofiler64.so")
common::join('/', getenv(itr), ROCPROFILER_METRICS_DIR,
"librocprofiler64.so")
.c_str(),
0);
break;
+9 -4
Wyświetl plik
@@ -10,11 +10,15 @@ set(CMAKE_BUILD_RPATH_USE_ORIGIN ON)
set(CMAKE_CXX_VISIBILITY_PRESET "internal")
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
find_package(Threads REQUIRED)
add_library(omnitrace-dl-library SHARED)
add_library(omnitrace::omnitrace-dl-library ALIAS omnitrace-dl-library)
target_sources(omnitrace-dl-library PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/dl.cpp
${CMAKE_CURRENT_SOURCE_DIR}/dl.hpp)
target_sources(
omnitrace-dl-library
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/dl.cpp ${CMAKE_CURRENT_SOURCE_DIR}/dl.hpp
${CMAKE_CURRENT_SOURCE_DIR}/main.c)
target_include_directories(
omnitrace-dl-library
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
@@ -24,10 +28,11 @@ target_include_directories(
target_link_libraries(
omnitrace-dl-library
PUBLIC $<BUILD_INTERFACE:${dl_LIBRARY}> $<BUILD_INTERFACE:omnitrace::common-library>
$<BUILD_INTERFACE:omnitrace::omnitrace-compile-definitions>)
$<BUILD_INTERFACE:omnitrace::omnitrace-compile-definitions>
$<BUILD_INTERFACE:Threads::Threads>)
add_target_cxx_flag_if_avail(omnitrace-dl-library "-ftls-model=global-dynamic")
add_target_cxx_flag_if_avail(omnitrace-dl-library "-g")
add_target_cxx_flag_if_avail(omnitrace-dl-library "-g3")
set_target_properties(
omnitrace-dl-library
+85
Wyświetl plik
@@ -95,6 +95,14 @@ get_omnitrace_dl_env()
: get_env("OMNITRACE_DL_VERBOSE", get_omnitrace_env());
}
inline bool
get_omnitrace_preload()
{
auto&& _preload = get_env("OMNITRACE_PRELOAD", false);
auto&& _preload_libs = get_env("LD_PRELOAD", std::string{});
return (_preload || _preload_libs.find("libomnitrace-dl.so") != std::string::npos);
}
// environment priority:
// - OMNITRACE_DL_DEBUG
// - OMNITRACE_DL_VERBOSE
@@ -216,6 +224,7 @@ struct OMNITRACE_HIDDEN_API indirect
int _info_verbose = 2;
// Initialize all pointers
OMNITRACE_DLSYM(omnitrace_init_library_f, m_omnihandle, "omnitrace_init_library");
OMNITRACE_DLSYM(omnitrace_init_tooling_f, m_omnihandle, "omnitrace_init_tooling");
OMNITRACE_DLSYM(omnitrace_init_f, m_omnihandle, "omnitrace_init");
OMNITRACE_DLSYM(omnitrace_finalize_f, m_omnihandle, "omnitrace_finalize");
OMNITRACE_DLSYM(omnitrace_set_env_f, m_omnihandle, "omnitrace_set_env");
@@ -280,6 +289,11 @@ struct OMNITRACE_HIDDEN_API indirect
OMNITRACE_DLSYM(hsa_on_unload_f, m_omnihandle, "OnUnload");
#endif
#if OMNITRACE_USE_ROCPROFILER > 0
OMNITRACE_DLSYM(rocp_on_load_tool_prop_f, m_omnihandle, "OnLoadToolProp");
OMNITRACE_DLSYM(rocp_on_unload_tool_f, m_omnihandle, "OnUnloadTool");
#endif
#if OMNITRACE_USE_OMPT == 0
_warn_verbose = 5;
#else
@@ -311,6 +325,7 @@ struct OMNITRACE_HIDDEN_API indirect
public:
// omnitrace functions
void (*omnitrace_init_library_f)(void) = nullptr;
void (*omnitrace_init_tooling_f)(void) = nullptr;
void (*omnitrace_init_f)(const char*, bool, const char*) = nullptr;
void (*omnitrace_finalize_f)(void) = nullptr;
void (*omnitrace_set_env_f)(const char*, const char*) = nullptr;
@@ -364,11 +379,21 @@ public:
void (*hsa_on_unload_f)() = nullptr;
#endif
// ROCP functions
#if OMNITRACE_USE_ROCPROFILER > 0
void (*rocp_on_load_tool_prop_f)(rocprofiler_settings* settings) = nullptr;
void (*rocp_on_unload_tool_f)() = nullptr;
#endif
// OpenMP functions
#if defined(OMNITRACE_USE_OMPT) && OMNITRACE_USE_OMPT > 0
ompt_start_tool_result_t* (*ompt_start_tool_f)(unsigned int, const char*);
#endif
auto get_omni_library() const { return m_omnilib; }
auto get_user_library() const { return m_userlib; }
auto get_dl_library() const { return m_dllib; }
private:
void* m_omnihandle = nullptr;
void* m_userhandle = nullptr;
@@ -483,6 +508,11 @@ extern "C"
OMNITRACE_DL_INVOKE(get_indirect().omnitrace_init_library_f);
}
void omnitrace_init_tooling(void)
{
OMNITRACE_DL_INVOKE(get_indirect().omnitrace_init_tooling_f);
}
void omnitrace_init(const char* a, bool b, const char* c)
{
if(dl::get_inited() && dl::get_finied())
@@ -837,6 +867,24 @@ extern "C"
void OnUnload() { return OMNITRACE_DL_INVOKE(get_indirect().hsa_on_unload_f); }
#endif
//----------------------------------------------------------------------------------//
//
// ROCP
//
//----------------------------------------------------------------------------------//
#if OMNITRACE_USE_ROCTRACER > 0
void OnLoadToolProp(rocprofiler_settings* settings)
{
return OMNITRACE_DL_INVOKE(get_indirect().rocp_on_load_tool_prop_f, settings);
}
void OnUnloadTool()
{
return OMNITRACE_DL_INVOKE(get_indirect().rocp_on_unload_tool_f);
}
#endif
//----------------------------------------------------------------------------------//
//
// OMPT
@@ -852,3 +900,40 @@ extern "C"
}
#endif
}
namespace omnitrace
{
inline namespace dl
{
namespace
{
bool
omnitrace_preload() OMNITRACE_HIDDEN_API;
bool
omnitrace_preload()
{
auto _preloaded = get_omnitrace_preload();
auto _enabled = get_env("OMNITRACE_ENABLED", true);
static bool _once = false;
if(_once) return _preloaded;
_once = true;
if(_preloaded && _enabled)
{
OMNITRACE_DL_LOG(0, "[%s] invoking %s(%s)\n", __FUNCTION__, "omnitrace_init",
::omnitrace::join(::omnitrace::QuoteStrings{}, ", ", "sampling",
false, "main")
.c_str());
omnitrace_init("sampling", false, "omnitrace");
omnitrace_init_tooling();
}
return _preloaded;
}
bool _handle_preload = omnitrace::dl::omnitrace_preload();
} // namespace
} // namespace dl
} // namespace omnitrace
+12
Wyświetl plik
@@ -57,6 +57,10 @@
# define OMNITRACE_USE_ROCTRACER 0
#endif
#if !defined(OMNITRACE_USE_ROCPROFILER)
# define OMNITRACE_USE_ROCPROFILER 0
#endif
//--------------------------------------------------------------------------------------//
//
// omnitrace symbols
@@ -66,6 +70,7 @@
extern "C"
{
void omnitrace_init_library(void) OMNITRACE_PUBLIC_API;
void omnitrace_init_tooling(void) OMNITRACE_PUBLIC_API;
void omnitrace_init(const char*, bool, const char*) OMNITRACE_PUBLIC_API;
void omnitrace_finalize(void) OMNITRACE_PUBLIC_API;
void omnitrace_set_env(const char* env_name,
@@ -156,6 +161,13 @@ extern "C"
const char* const* failed_tool_names) OMNITRACE_PUBLIC_API;
void OnUnload() OMNITRACE_PUBLIC_API;
# endif
# if OMNITRACE_USE_ROCPROFILER > 0
// ROCP
struct rocprofiler_settings;
void OnLoadToolProp(rocprofiler_settings* settings) OMNITRACE_PUBLIC_API;
void OnUnloadTool() OMNITRACE_PUBLIC_API;
# endif
#endif
}
+115
Wyświetl plik
@@ -0,0 +1,115 @@
// 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.
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
extern void
omnitrace_finalize(void);
extern void
omnitrace_push_trace(const char* name);
extern void
omnitrace_pop_trace(const char* name);
// extern void
// omnitrace_update_env(char*** envp);
extern void
omnitrace_init_tooling(void);
extern void
omnitrace_init(const char*, bool, const char*);
// Trampoline for the real main()
static int (*main_real)(int, char**, char**);
int
omnitrace_main(int argc, char** argv, char** envp)
{
// prevent re-entry
static int _reentry = 0;
if(_reentry > 0) return -1;
_reentry = 1;
// set the relevant environment variables
// omnitrace_update_env(&envp);
const char* mode = getenv("OMNITRACE_MODE");
omnitrace_init(mode ? mode : "sampling", false, argv[0]);
omnitrace_init_tooling();
omnitrace_push_trace("main(int argc, char** argv)");
int ret = main_real(argc, argv, envp);
omnitrace_pop_trace("main(int argc, char** argv)");
omnitrace_finalize();
return ret;
}
typedef int
(*omnitrace_libc_start_main)(int (*)(int, char**, char**), int, char**,
int (*)(int, char**, char**), void (*)(void),
void (*)(void), void*);
int
__libc_start_main(int (*_main)(int, char**, char**), int _argc, char** _argv,
int (*_init)(int, char**, char**), void (*_fini)(void),
void (*_rtld_fini)(void), void* _stack_end)
{
// prevent re-entry
static int _reentry = 0;
if(_reentry > 0) return -1;
_reentry = 1;
// get the address of this function
void* _this_func = __builtin_return_address(0);
// Save the real main function address
main_real = _main;
// Find the real __libc_start_main()
omnitrace_libc_start_main user_main = dlsym(RTLD_NEXT, "__libc_start_main");
if(user_main && user_main != _this_func)
{
//if(strcmp(_argv[0], "mpirun") == 0)
// return user_main(_main, _argc, _argv, _init, _fini, _rtld_fini,
// _stack_end);
//else
// call omnitrace main function wrapper
return user_main(omnitrace_main, _argc, _argv, _init, _fini, _rtld_fini, _stack_end);
}
else
{
fputs("Error! omnitrace could not find __libc_start_main!", stderr);
return -1;
}
}
+6
Wyświetl plik
@@ -72,6 +72,12 @@ omnitrace_init_library(void)
omnitrace_init_library_hidden();
}
extern "C" void
omnitrace_init_tooling(void)
{
omnitrace_init_tooling_hidden();
}
extern "C" void
omnitrace_init(const char* _mode, bool _rewrite, const char* _arg0)
{
+3
Wyświetl plik
@@ -34,6 +34,9 @@ extern "C"
/// handles configuration logic
void omnitrace_init_library(void) OMNITRACE_PUBLIC_API;
/// handles configuration logic
void omnitrace_init_tooling(void) OMNITRACE_PUBLIC_API;
/// starts gotcha wrappers
void omnitrace_init(const char*, bool, const char*) OMNITRACE_PUBLIC_API;
+101 -110
Wyświetl plik
@@ -48,8 +48,10 @@
#include "library/tracing.hpp"
#include <timemory/hash/types.hpp>
#include <timemory/manager/manager.hpp>
#include <timemory/operations/types/file_output_message.hpp>
#include <timemory/sampling/signals.hpp>
#include <timemory/settings/types.hpp>
#include <timemory/utility/backtrace.hpp>
#include <timemory/utility/procfs/maps.hpp>
@@ -62,6 +64,21 @@ using namespace omnitrace;
//======================================================================================//
namespace omnitrace
{
namespace perfetto
{
// declare this here bc it has a tendency to cause namespace ambiguities
void
setup();
void
start();
} // namespace perfetto
} // namespace omnitrace
//======================================================================================//
namespace
{
auto
@@ -78,6 +95,9 @@ ensure_finalization(bool _static_init = false)
if(!get_env("OMNITRACE_COLORIZED_LOG", true)) tim::log::colorized() = false;
(void) tim::manager::instance();
(void) tim::settings::shared_instance();
if(!_static_init)
{
OMNITRACE_DEBUG_F("\n");
@@ -167,12 +187,14 @@ omnitrace_set_env_hidden(const char* env_name, const char* env_val)
tim::set_env(env_name, env_val, 0);
OMNITRACE_CONDITIONAL_THROW(
_success && get_state() >= State::Init &&
(config::get_is_continuous_integration() || get_debug_init()),
"omnitrace_set_env(\"%s\", \"%s\") called after omnitrace was initialized. state "
"= %s",
env_name, env_val, std::to_string(get_state()).c_str());
if(_success && get_state() >= State::Init)
{
OMNITRACE_WARNING_F(
0,
"omnitrace_set_env(\"%s\", \"%s\") called after omnitrace was initialized. "
"state = %s. This environment variable will have no effect\n",
env_name, env_val, std::to_string(get_state()).c_str());
}
}
//======================================================================================//
@@ -184,7 +206,15 @@ omnitrace_set_env_hidden(const char* env_name, const char* env_val)
namespace
{
bool _set_mpi_called = false;
std::function<void()> _preinit_callback = []() {};
std::function<void()> _preinit_callback = []() { get_preinit_bundle()->start(); };
void
omnitrace_preinit_hidden()
{
// run once and discard
_preinit_callback();
_preinit_callback = []() {};
}
} // namespace
extern "C" void
@@ -215,15 +245,18 @@ omnitrace_set_mpi_hidden(bool use, bool attached)
trait::runtime_enabled<mpi_gotcha_t>::set(false);
}
OMNITRACE_CONDITIONAL_THROW(
get_state() >= State::Init &&
(config::get_is_continuous_integration() || get_debug_init()),
"omnitrace_set_mpi(use=%s, attached=%s) called after omnitrace was initialized. "
"state = %s",
std::to_string(use).c_str(), std::to_string(attached).c_str(),
std::to_string(get_state()).c_str());
if(get_state() >= State::Init)
{
OMNITRACE_WARNING_F(
0,
"omnitrace_set_mpi(use=%s, attached=%s) called after omnitrace was "
"initialized. state = %s. MPI support may not be properly initialized. Use "
"OMNITRACE_USE_MPIP=ON and OMNITRACE_USE_PID=ON to ensure full support\n",
std::to_string(use).c_str(), std::to_string(attached).c_str(),
std::to_string(get_state()).c_str());
}
_preinit_callback();
omnitrace_preinit_hidden();
}
//======================================================================================//
@@ -351,21 +384,29 @@ omnitrace_init_tooling_hidden()
sampling::unblock_signals();
}
get_main_bundle()->start();
OMNITRACE_DEBUG_F("State: %s -> State::Active\n",
std::to_string(get_state()).c_str());
set_state(State::Active); // set to active as very last operation
} };
OMNITRACE_SCOPED_SAMPLING_ON_CHILD_THREADS(false);
// perfetto initialization
if(get_use_perfetto())
{
OMNITRACE_VERBOSE_F(1, "Setting up Perfetto...\n");
omnitrace::perfetto::setup();
}
// ideally these have already been started
omnitrace_preinit_hidden();
// start these gotchas once settings have been initialized
get_init_bundle()->start();
if(get_use_sampling()) sampling::block_signals();
if(get_use_critical_trace())
{
// initialize the thread pool
(void) tasking::critical_trace::get_task_group();
}
tasking::setup();
if(get_use_timemory())
{
@@ -396,56 +437,6 @@ omnitrace_init_tooling_hidden()
}
}
perfetto::TracingInitArgs args{};
perfetto::TraceConfig cfg{};
perfetto::protos::gen::TrackEventConfig track_event_cfg{};
// perfetto initialization
if(get_use_perfetto())
{
// environment settings
auto shmem_size_hint = get_perfetto_shmem_size_hint();
auto buffer_size = get_perfetto_buffer_size();
auto _policy =
get_perfetto_fill_policy() == "discard"
? perfetto::protos::gen::TraceConfig_BufferConfig_FillPolicy_DISCARD
: perfetto::protos::gen::TraceConfig_BufferConfig_FillPolicy_RING_BUFFER;
auto* buffer_config = cfg.add_buffers();
buffer_config->set_size_kb(buffer_size);
buffer_config->set_fill_policy(_policy);
std::set<std::string> _available_categories = {};
std::set<std::string> _disabled_categories = {};
for(auto itr : { OMNITRACE_PERFETTO_CATEGORIES })
_available_categories.emplace(itr.name);
auto _enabled_categories = config::get_perfetto_categories();
for(const auto& itr : _available_categories)
{
if(!_enabled_categories.empty() && _enabled_categories.count(itr) == 0)
_disabled_categories.emplace(itr);
}
for(const auto& itr : _disabled_categories)
{
OMNITRACE_VERBOSE_F(1, "Disabling perfetto track event category: %s\n",
itr.c_str());
track_event_cfg.add_disabled_categories(itr);
}
auto* ds_cfg = cfg.add_data_sources()->mutable_config();
ds_cfg->set_name("track_event"); // this MUST be track_event
ds_cfg->set_track_event_config_raw(track_event_cfg.SerializeAsString());
args.shmem_size_hint_kb = shmem_size_hint;
if(get_backend() != "inprocess") args.backends |= perfetto::kSystemBackend;
if(get_backend() != "system") args.backends |= perfetto::kInProcessBackend;
perfetto::Tracing::Initialize(args);
perfetto::TrackEvent::Register();
}
if(get_use_ompt())
{
OMNITRACE_VERBOSE_F(1, "Setting up OMPT...\n");
@@ -460,24 +451,7 @@ omnitrace_init_tooling_hidden()
if(get_use_perfetto() && !is_system_backend())
{
#if defined(CUSTOM_DATA_SOURCE)
// Add the following:
perfetto::DataSourceDescriptor dsd{};
dsd.set_name("com.example.custom_data_source");
CustomDataSource::Register(dsd);
auto* ds_cfg = cfg.add_data_sources()->mutable_config();
ds_cfg->set_name("com.example.custom_data_source");
CustomDataSource::Trace([](CustomDataSource::TraceContext ctx) {
auto packet = ctx.NewTracePacket();
packet->set_timestamp(perfetto::TrackEvent::GetTraceTimeNs());
packet->set_for_testing()->set_str("Hello world!");
PRINT_HERE("%s", "Trace");
});
#endif
auto& tracing_session = tracing::get_trace_session();
tracing_session = perfetto::Tracing::NewTrace();
tracing_session->Setup(cfg);
tracing_session->StartBlocking();
omnitrace::perfetto::start();
}
// if static objects are destroyed in the inverse order of when they are
@@ -521,13 +495,20 @@ omnitrace_init_hidden(const char* _mode, bool _is_binary_rewrite, const char* _a
(void) tracing::push_count();
(void) tracing::pop_count();
OMNITRACE_CONDITIONAL_THROW(
get_state() >= State::Init &&
(config::get_is_continuous_integration() || get_debug_init()),
"omnitrace_init(mode=%s, is_binary_rewrite=%s, argv0=%s) called after omnitrace "
"was initialized. state = %s",
_mode, std::to_string(_is_binary_rewrite).c_str(), _argv0,
std::to_string(get_state()).c_str());
if(get_state() >= State::Init)
{
if(std::string_view{ _mode } != "trace" && std::string_view{ _mode } != "Trace")
{
OMNITRACE_WARNING_F(
0,
"omnitrace_init(mode=%s, is_binary_rewrite=%s, argv0=%s) "
"called after omnitrace was initialized. state = %s. Mode-based settings "
"(via -M <MODE> passed to omnitrace exe) may not be properly "
"configured.\n",
_mode, std::to_string(_is_binary_rewrite).c_str(), _argv0,
std::to_string(get_state()).c_str());
}
}
tracing::get_finalization_functions().emplace_back([_argv0]() {
OMNITRACE_CI_THROW(get_state() != State::Active,
@@ -555,13 +536,9 @@ omnitrace_init_hidden(const char* _mode, bool _is_binary_rewrite, const char* _a
tim::set_env("OMNITRACE_MODE", _mode, 0);
config::is_binary_rewrite() = _is_binary_rewrite;
if(!_set_mpi_called)
if(_set_mpi_called)
{
_preinit_callback = []() { get_preinit_bundle()->start(); };
}
else
{
get_preinit_bundle()->start();
omnitrace_preinit_hidden();
}
}
@@ -586,6 +563,9 @@ omnitrace_finalize_hidden(void)
if(get_verbose() >= 0 || get_debug()) fprintf(stderr, "\n");
OMNITRACE_VERBOSE_F(0, "finalizing...\n");
sampling::block_samples();
thread_info::set_stop(comp::wall_clock::record());
tim::sampling::block_signals(get_sampling_signals(),
@@ -779,10 +759,6 @@ omnitrace_finalize_hidden(void)
if(get_use_critical_trace() || (get_use_rocm_smi() && get_use_roctracer()))
{
OMNITRACE_VERBOSE_F(1, "Generating the critical trace...\n");
// (potentially) increase the thread-pool size since application
// shouldn't be using threads during finalization
tasking::initialize_threadpool(std::min<uint64_t>(
{ std::thread::hardware_concurrency(), get_thread_pool_size(), 8 }));
for(size_t i = 0; i < max_supported_threads; ++i)
{
@@ -790,7 +766,10 @@ omnitrace_finalize_hidden(void)
thread_data<critical_trace::hash_ids, critical_trace::id>;
if(critical_trace_hash_data::instances().at(i))
{
OMNITRACE_DEBUG_F("Copying the hash id data for thread %zu...\n", i);
critical_trace::add_hash_id(*critical_trace_hash_data::instances().at(i));
}
}
for(size_t i = 0; i < max_supported_threads; ++i)
@@ -798,7 +777,11 @@ omnitrace_finalize_hidden(void)
using critical_trace_chain_data = thread_data<critical_trace::call_chain>;
if(critical_trace_chain_data::instances().at(i))
{
OMNITRACE_DEBUG_F(
"Updating the critical trace call-chains for thread %zu...\n", i);
critical_trace::update(i); // launch update task
}
}
OMNITRACE_VERBOSE_F(1, "Waiting on critical trace updates...\n");
@@ -813,9 +796,6 @@ omnitrace_finalize_hidden(void)
if(get_use_critical_trace())
{
// make sure outstanding hash tasks completed before compute
tasking::join();
// launch compute task
OMNITRACE_VERBOSE_F(1, "launching critical trace compute task...\n");
critical_trace::compute();
@@ -837,7 +817,7 @@ omnitrace_finalize_hidden(void)
bool _perfetto_output_error = false;
if(get_use_perfetto() && !is_system_backend())
{
auto& tracing_session = tracing::get_trace_session();
auto& tracing_session = tracing::get_perfetto_session();
OMNITRACE_CI_THROW(tracing_session == nullptr,
"Null pointer to the tracing session");
@@ -845,7 +825,7 @@ omnitrace_finalize_hidden(void)
OMNITRACE_VERBOSE_F(0, "Finalizing perfetto...\n");
// Make sure the last event is closed for this example.
perfetto::TrackEvent::Flush();
::perfetto::TrackEvent::Flush();
tracing_session->FlushBlocking();
OMNITRACE_VERBOSE_F(3, "Stopping the blocking perfetto trace session...\n");
@@ -934,9 +914,18 @@ omnitrace_finalize_hidden(void)
tim::cereal::make_nvp("memory_maps", _maps));
});
auto _manager = tim::manager::instance();
if(_manager) _manager->set_write_metadata(-1);
OMNITRACE_VERBOSE_F(1, "Finalizing timemory...\n");
tim::timemory_finalize();
if(_manager)
{
_manager->write_metadata(settings::get_global_output_prefix(), "omnitrace",
settings::default_process_suffix());
}
if(_perfetto_output_error)
{
OMNITRACE_THROW("Error opening perfetto output file: %s",
@@ -965,4 +954,6 @@ namespace
// this might call finalization before perfetto ends the tracing session
// but static variable in omnitrace_init_tooling_hidden is more likely
auto _ensure_finalization = ensure_finalization(true);
auto _manager = tim::manager::instance();
auto _settings = tim::settings::shared_instance();
} // namespace
@@ -156,7 +156,7 @@ using name = perfetto_category<Tp...>;
OMNITRACE_PERFETTO_CATEGORY(category::thread_hardware_counter), \
OMNITRACE_PERFETTO_CATEGORY(category::kernel_hardware_counter), \
OMNITRACE_PERFETTO_CATEGORY(category::numa), \
perfetto::Category("timemory").SetDescription("Events from the timemory API")
::perfetto::Category("timemory").SetDescription("Events from the timemory API")
#if defined(TIMEMORY_USE_PERFETTO)
# define TIMEMORY_PERFETTO_CATEGORIES OMNITRACE_PERFETTO_CATEGORIES
@@ -20,6 +20,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#include "library/common.hpp"
#include "library/components/ensure_storage.hpp"
#include "library/components/fwd.hpp"
#include "library/config.hpp"
@@ -72,40 +73,25 @@ namespace omnitrace
{
namespace component
{
std::vector<std::string>
std::vector<backtrace::entry_type>
backtrace::get() const
{
std::vector<std::string> _v = {};
std::vector<entry_type> _v = {};
if(size() == 0) return _v;
_v.reserve(m_data.size());
for(const auto& itr : m_data.call_stack)
{
if(!itr) continue;
#if defined(OMNITRACE_CI) && OMNITRACE_CI > 0
std::string _name = {};
_name.reserve(1024);
const char* _addr = _name.data();
_name = itr->get_name(m_data.context, _name);
OMNITRACE_CONDITIONAL_PRINT(
_name.data() != _addr,
"[backtrace::get()] processing unw_get_proc_name_from_ip for '%s' "
"caused a reallocation. Before=%p, After=%p\n",
_name.c_str(), _addr, _name.data());
#else
auto _name = itr->get_name(m_data.context);
#endif
if(!_name.empty()) _v.emplace_back(_name);
static auto _cache = cache_type{};
auto_lock_t _lk{ type_mutex<backtrace>() };
_v = m_data.get(&_cache, true);
}
// put the bottom of the call-stack on top
std::reverse(_v.begin(), _v.end());
//
auto _known_excludes =
std::set<std::string>{ "funlockfile", "killpg", "__restore_rt" };
// remove some known functions which are by-products of interrupts
while(!_v.empty() && _known_excludes.find(_v.back()) != _known_excludes.end())
while(!_v.empty() && _known_excludes.find(_v.back().name) != _known_excludes.end())
_v.pop_back();
return _v;
@@ -124,7 +110,7 @@ backtrace::description()
}
std::vector<std::string>
backtrace::filter_and_patch(const std::vector<std::string>& _data)
backtrace::filter_and_patch(const std::vector<entry_type>& _data)
{
// check whether the call-stack entry should be used. -1 means break, 0 means continue
auto _use_label = [](std::string_view _lbl) -> short {
@@ -160,7 +146,7 @@ backtrace::filter_and_patch(const std::vector<std::string>& _data)
auto _ret = std::vector<std::string>{};
for(const auto& itr : _data)
{
auto _name = tim::demangle(_patch_label(itr));
auto _name = tim::demangle(_patch_label(itr.name));
auto _use = _use_label(_name);
if(_use == -1) break;
if(_use == 0) continue;
@@ -31,6 +31,7 @@
#include <timemory/components/base.hpp>
#include <timemory/macros/language.hpp>
#include <timemory/mpl/concepts.hpp>
#include <timemory/utility/unwind.hpp>
#include <timemory/variadic/types.hpp>
#include <array>
@@ -51,6 +52,8 @@ struct backtrace
static constexpr size_t stack_depth = OMNITRACE_MAX_UNWIND_DEPTH;
using data_t = tim::unwind::stack<stack_depth>;
using cache_type = typename data_t::cache_type;
using entry_type = tim::unwind::processed_entry;
using clock_type = std::chrono::steady_clock;
using value_type = void;
using system_clock = std::chrono::system_clock;
@@ -67,15 +70,15 @@ struct backtrace
backtrace& operator=(const backtrace&) = default;
backtrace& operator=(backtrace&&) noexcept = default;
static std::vector<std::string> filter_and_patch(const std::vector<std::string>&);
static std::vector<std::string> filter_and_patch(const std::vector<entry_type>&);
static void start();
static void stop();
void sample(int = -1);
bool empty() const;
size_t size() const;
std::vector<std::string> get() const;
void sample(int = -1);
bool empty() const;
size_t size() const;
std::vector<entry_type> get() const;
private:
data_t m_data = {};
@@ -162,6 +162,12 @@ backtrace_metrics::sample(int)
{
assert(get_papi_vector(_tid).get() != nullptr);
m_hw_counter = get_papi_vector(_tid)->record();
// const auto& _cfg = get_papi_vector(_tid)->get_config();
// std::cerr << "Config: ";
// for(size_t i = 0; i < _cfg->size; ++i)
// std::cerr << "[" << _cfg->labels.at(i) << "|" << _cfg->event_names.at(i)
// << "|" << _cfg->event_codes.at(i) << "]";
// std::cerr << "\n";
}
}
}
@@ -188,7 +194,8 @@ backtrace_metrics::configure(bool _setup, int64_t _tid)
{
using common_type_t = typename hw_counters::common_type;
get_papi_vector(_tid)->start();
*get_papi_labels(_tid) = comp::papi_common::get_events<common_type_t>();
*get_papi_labels(_tid) =
comp::papi_common<common_type_t>::get_config()->labels;
}
}
}
@@ -216,19 +216,19 @@ private:
return _t;
}
static auto&& add(const gotcha_data& _data, data_type value)
static auto add(const gotcha_data& _data, data_type value)
{
tracker_t _t{ std::string_view{ _data.tool_id.c_str() } };
return add(_t, value);
}
static auto&& add(std::string&& _name, data_type value)
static auto add(std::string&& _name, data_type value)
{
tracker_t _t{ _name };
return add(_t, value);
}
static auto&& add(std::string_view _name, data_type value)
static auto add(std::string_view _name, data_type value)
{
tracker_t _t{ _name };
return add(_t, value);
@@ -38,6 +38,8 @@ namespace component
{
struct exit_gotcha : tim::component::base<exit_gotcha, void>
{
static constexpr size_t gotcha_capacity = 3;
using gotcha_data = tim::component::gotcha_data;
using exit_func_t = void (*)(int);
using abort_func_t = void (*)();
@@ -61,5 +63,6 @@ struct exit_gotcha : tim::component::base<exit_gotcha, void>
};
} // namespace component
using exit_gotcha_t = tim::component::gotcha<3, std::tuple<>, component::exit_gotcha>;
using exit_gotcha_t = tim::component::gotcha<component::exit_gotcha::gotcha_capacity,
std::tuple<>, component::exit_gotcha>;
} // namespace omnitrace
@@ -33,6 +33,8 @@ namespace component
// this is used to wrap fork()
struct fork_gotcha : comp::base<fork_gotcha, void>
{
static constexpr size_t gotcha_capacity = 1;
using gotcha_data_t = comp::gotcha_data;
TIMEMORY_DEFAULT_OBJECT(fork_gotcha)
@@ -56,5 +58,6 @@ struct fork_gotcha : comp::base<fork_gotcha, void>
} // namespace component
using fork_gotcha_t =
comp::gotcha<4, tim::component_tuple<component::fork_gotcha>, project::omnitrace>;
comp::gotcha<component::fork_gotcha::gotcha_capacity,
tim::component_tuple<component::fork_gotcha>, project::omnitrace>;
} // namespace omnitrace
@@ -138,6 +138,16 @@ auto reject_bindings = strset_t{};
void
mpi_gotcha::configure()
{
// don't emit warnings for missing MPI functions unless debug or verbosity >= 3
if(get_verbose_env() < 3 && !get_debug_env())
{
for(size_t i = 0; i < mpi_gotcha_t::capacity(); ++i)
{
auto* itr = mpi_gotcha_t::at(i);
if(itr) itr->verbose = -1;
}
}
mpi_gotcha_t::get_initializer() = []() {
mpi_gotcha_t::template configure<0, int, int*, char***>("MPI_Init");
mpi_gotcha_t::template configure<1, int, int*, char***, int, int*>(
@@ -280,6 +290,8 @@ mpi_gotcha::audit(const gotcha_data_t& _data, audit::outgoing, int _retval)
{
OMNITRACE_BASIC_DEBUG_F("%s() returned %i\n", _data.tool_id.c_str(), (int) _retval);
if(!settings::use_output_suffix()) settings::use_output_suffix() = true;
if(_retval == tim::mpi::success_v && _data.tool_id.find("MPI_Init") == 0)
{
omnitrace_mpi_set_attr();
@@ -40,6 +40,7 @@
#include <ostream>
#include <pthread.h>
#include <utility>
namespace omnitrace
{
@@ -132,13 +133,14 @@ stop_bundle(bundle_t& _bundle, int64_t _tid, Args&&... _args)
//--------------------------------------------------------------------------------------//
pthread_create_gotcha::wrapper::wrapper(routine_t _routine, void* _arg,
bool _enable_sampling, int64_t _parent,
promise_t* _p)
bool _enable_sampling, bool _offset,
int64_t _parent, promise_t _p)
: m_enable_sampling{ _enable_sampling }
, m_offset{ _offset }
, m_parent_tid{ _parent }
, m_routine{ _routine }
, m_arg{ _arg }
, m_promise{ _p }
, m_promise{ std::move(_p) }
{}
void*
@@ -188,10 +190,10 @@ pthread_create_gotcha::wrapper::operator()() const
auto _active = (get_state() == ::omnitrace::State::Active && bundles != nullptr &&
bundles_mutex != nullptr);
if(_active && !_coverage)
const auto& _info = thread_info::init(m_offset);
if(_active && !_coverage && !m_offset)
{
const auto& _tid_index = thread_info::init();
_tid = _tid_index->index_data->sequent_value;
_tid = _info->index_data->sequent_value;
threading::set_thread_name(TIMEMORY_JOIN(" ", "Thread", _tid).c_str());
if(!thread_bundle_data_t::instances().at(_tid))
{
@@ -217,10 +219,6 @@ pthread_create_gotcha::wrapper::operator()() const
sampling::unblock_signals();
}
}
else
{
thread_info::init(true);
}
// notify the wrapper that all internal work is completed
if(m_promise) m_promise->set_value();
@@ -292,7 +290,8 @@ pthread_create_gotcha::shutdown()
bundles->clear();
OMNITRACE_BASIC_VERBOSE(
2 && _ndangling > 0,
1,
// 2 && _ndangling > 0,
"[pthread_create_gotcha::shutdown] cleaned up %lu dangling bundles\n",
_ndangling);
}
@@ -300,6 +299,8 @@ pthread_create_gotcha::shutdown()
void
pthread_create_gotcha::shutdown(int64_t _tid)
{
if(_tid == 0) shutdown();
if(is_shutdown && *is_shutdown) return;
if(!bundles_mutex || !bundles) return;
@@ -323,23 +324,51 @@ pthread_create_gotcha::set_data(wrappee_t _v)
// pthread_create
int
pthread_create_gotcha::operator()(pthread_t* thread, const pthread_attr_t* attr,
void* (*start_routine)(void*), void* arg) const
void* (*func)(void*), void* arg) const
{
auto _disabled = (get_thread_state() == ThreadState::Disabled);
auto _enabled = (get_thread_state() == ThreadState::Enabled);
auto _bundle = std::optional<bundle_t>{};
auto _tid = utility::get_thread_index();
auto _thr_state = get_thread_state();
auto _glob_state = get_state();
auto _mode = get_mode();
auto _disabled = (_thr_state == ThreadState::Disabled);
auto _enabled = (_thr_state == ThreadState::Enabled);
auto _bundle = std::optional<bundle_t>{};
auto _sample_child = sampling_enabled_on_child_threads();
auto _active = (_glob_state == ::omnitrace::State::Active && !_disabled);
const auto& _info = thread_info::init(!_active || !_sample_child || _disabled);
OMNITRACE_SCOPED_THREAD_STATE(ThreadState::Internal);
auto _active = (get_state() == ::omnitrace::State::Active && !_disabled);
auto _coverage = (get_mode() == Mode::Coverage);
auto _use_sampling = get_use_sampling();
auto _sample_child = sampling_enabled_on_child_threads();
auto _tid = utility::get_thread_index();
auto _use_bundle = (_active && !_coverage);
const auto& _info = thread_info::init(!_active || !_sample_child || _disabled);
auto _enable_sampling =
(!_disabled && _enabled && _sample_child && _use_sampling && !_info->is_offset);
auto _coverage = (_mode == Mode::Coverage);
auto _use_sampling = get_use_sampling();
auto _offset = (!_enabled || !_active || _info->is_offset);
auto _use_bundle = (_active && !_coverage && !_offset);
auto _enable_sampling =
(_use_sampling && _sample_child && _active && !_coverage && !_offset);
static bool debug_threading_get_id =
get_env<bool>(TIMEMORY_SETTINGS_PREFIX "DEBUG_THREADING_GET_ID", false);
auto _verbose = (debug_threading_get_id) ? 0 : 3;
OMNITRACE_VERBOSE(
_verbose,
"Creating new thread :: global_state=%s, thread_state=%s, mode=%s, active=%s, "
"coverage=%s, use_sampling=%s, sample_children=%s, tid=%li, use_bundle=%s, "
"enable_sampling=%s, thread_info=(%s)...\n",
std::to_string(_glob_state).c_str(), std::to_string(_thr_state).c_str(),
std::to_string(_mode).c_str(), std::to_string(_active).c_str(),
std::to_string(_coverage).c_str(), std::to_string(_use_sampling).c_str(),
std::to_string(_sample_child).c_str(), _tid, std::to_string(_use_bundle).c_str(),
std::to_string(_enable_sampling).c_str(), JOIN("", *_info).c_str());
if(debug_threading_get_id)
{
timemory_print_demangled_backtrace<8>(std::cerr, std::string{},
std::string{ "threading::get_id() [id=" } +
std::to_string(_tid) +
std::string{ "]" },
std::string{ " " }, false);
}
if(_active && !_disabled && !_info->is_offset)
{
@@ -348,13 +377,16 @@ pthread_create_gotcha::operator()(pthread_t* thread, const pthread_attr_t* attr,
}
// ensure that cpu cid stack exists on the parent thread if active
if(_active && !_coverage) get_cpu_cid_stack();
if(_active && !_coverage)
{
OMNITRACE_DEBUG("blocking signals...\n");
get_cpu_cid_stack();
}
set_thread_state(ThreadState::Disabled);
auto _blocked = get_sampling_signals();
auto _promise = std::promise<void>{};
auto _fut = _promise.get_future();
auto* _wrap = new wrapper(start_routine, arg, _enable_sampling, _tid, &_promise);
auto _promise = (_active) ? std::make_shared<std::promise<void>>() : promise_t{};
auto* _wrap = new wrapper(func, arg, _enable_sampling, _offset, _tid, _promise);
set_thread_state(ThreadState::Internal);
// block the signals in entire process
@@ -367,15 +399,18 @@ pthread_create_gotcha::operator()(pthread_t* thread, const pthread_attr_t* attr,
if(_use_bundle)
{
_bundle = bundle_t{ "pthread_create" };
start_bundle(*_bundle, audit::incoming{}, thread, attr, start_routine, arg);
start_bundle(*_bundle, audit::incoming{}, thread, attr, func, arg);
}
// create the thread
auto _ret = (*m_wrappee)(thread, attr, &wrapper::wrap, static_cast<void*>(_wrap));
// wait for thread to set promise
OMNITRACE_DEBUG("waiting for child to signal it is setup...\n");
_fut.wait();
if(_promise)
{
OMNITRACE_DEBUG("waiting for child to signal it is setup...\n");
_promise->get_future().wait_for(std::chrono::milliseconds{ 500 });
}
if(_use_bundle) stop_bundle(*_bundle, threading::get_id(), audit::outgoing{}, _ret);
@@ -36,24 +36,26 @@ namespace component
{
struct pthread_create_gotcha : tim::component::base<pthread_create_gotcha, void>
{
static constexpr size_t gotcha_capacity = 1;
using routine_t = void* (*) (void*);
using wrappee_t = int (*)(pthread_t*, const pthread_attr_t*, routine_t, void*);
using promise_t = std::shared_ptr<std::promise<void>>;
struct wrapper
{
using promise_t = std::promise<void>;
wrapper(routine_t _routine, void* _arg, bool, int64_t, promise_t*);
wrapper(routine_t _routine, void* _arg, bool, bool, int64_t, promise_t);
void* operator()() const;
static void* wrap(void* _arg);
private:
bool m_enable_sampling = false;
int64_t m_parent_tid = 0;
routine_t m_routine = nullptr;
void* m_arg = nullptr;
promise_t* m_promise = nullptr;
bool m_enable_sampling = false;
bool m_offset = false;
int64_t m_parent_tid = 0;
routine_t m_routine = nullptr;
void* m_arg = nullptr;
promise_t m_promise = {};
};
TIMEMORY_DEFAULT_OBJECT(pthread_create_gotcha)
@@ -77,6 +79,7 @@ private:
};
using pthread_create_gotcha_t =
tim::component::gotcha<2, std::tuple<>, pthread_create_gotcha>;
tim::component::gotcha<pthread_create_gotcha::gotcha_capacity, std::tuple<>,
pthread_create_gotcha>;
} // namespace component
} // namespace omnitrace
@@ -169,6 +169,10 @@ roctracer::setup()
for(auto& itr : roctracer_setup_routines())
itr.second();
// make sure all async callbacks are allocated
for(size_t i = 0; i < max_supported_threads; ++i)
hip_exec_activity_callbacks(i);
OMNITRACE_VERBOSE_F(1, "roctracer is setup\n");
}
+8 -8
Wyświetl plik
@@ -235,7 +235,7 @@ configure_settings(bool _init)
OMNITRACE_HIP_VERSION_PATCH);
#endif
static auto _config = settings::shared_instance();
auto _config = settings::shared_instance();
// if using timemory, default to perfetto being off
auto _default_perfetto_v =
@@ -338,7 +338,7 @@ configure_settings(bool _init)
OMNITRACE_CONFIG_SETTING(
double, "OMNITRACE_SAMPLING_FREQ",
"Number of software interrupts per second when OMNITTRACE_USE_SAMPLING=ON", 10.0,
"Number of software interrupts per second when OMNITTRACE_USE_SAMPLING=ON", 300.0,
"sampling", "process_sampling");
OMNITRACE_CONFIG_SETTING(double, "OMNITRACE_SAMPLING_CPUTIME_FREQ",
@@ -452,12 +452,12 @@ configure_settings(bool _init)
OMNITRACE_CONFIG_SETTING(bool, "OMNITRACE_TRACE_THREAD_RW_LOCKS",
"Enable tracing calls to pthread_rwlock_* functions. May "
"cause deadlocks with ROCm-enabled OpenMPI.",
true, "backend", "parallelism", "gotcha", "advanced");
false, "backend", "parallelism", "gotcha", "advanced");
OMNITRACE_CONFIG_SETTING(bool, "OMNITRACE_TRACE_THREAD_SPIN_LOCKS",
"Enable tracing calls to pthread_spin_* functions. May "
"cause deadlocks with MPI distributions.",
true, "backend", "parallelism", "gotcha", "advanced");
false, "backend", "parallelism", "gotcha", "advanced");
OMNITRACE_CONFIG_SETTING(
bool, "OMNITRACE_SAMPLING_KEEP_INTERNAL",
@@ -600,7 +600,7 @@ configure_settings(bool _init)
_config->get_papi_events() = "PAPI_TOT_CYC";
// settings native to timemory but critically and/or extensively used by omnitrace
auto _add_omnitrace_category = [](auto itr) {
auto _add_omnitrace_category = [&_config](auto itr) {
if(itr != _config->end())
{
auto _categories = itr->second->get_categories();
@@ -617,7 +617,7 @@ configure_settings(bool _init)
_add_omnitrace_category(_config->find("OMNITRACE_OUTPUT_PREFIX"));
_add_omnitrace_category(_config->find("OMNITRACE_OUTPUT_PATH"));
auto _add_advanced_category = [](const std::string& _name) {
auto _add_advanced_category = [&_config](const std::string& _name) {
auto itr = _config->find(_name);
if(itr != _config->end())
{
@@ -690,7 +690,7 @@ configure_settings(bool _init)
OMNITRACE_BASIC_VERBOSE(0,
"In order to enable PAPI support, run 'echo N | sudo tee "
"/proc/sys/kernel/perf_event_paranoid' where N is < 2\n");
tim::trait::runtime_enabled<comp::papi_common>::set(false);
tim::trait::runtime_enabled<comp::papi_common<void>>::set(false);
tim::trait::runtime_enabled<comp::papi_array_t>::set(false);
tim::trait::runtime_enabled<comp::papi_vector>::set(false);
tim::trait::runtime_enabled<comp::cpu_roofline_flops>::set(false);
@@ -1500,7 +1500,7 @@ get_use_pid()
bool&
get_use_mpip()
{
static bool _v = tim::get_env("OMNITRACE_USE_MPIP", false, false);
static bool _v = tim::get_env("OMNITRACE_USE_MPIP", true, false);
return _v;
}
@@ -62,6 +62,7 @@ using call_graph_preorder_itr_t = typename call_graph_t::pre_order_iterator;
hash_ids complete_hash_ids{};
call_chain complete_call_chain{};
std::mutex complete_call_mutex{};
std::mutex tasking_mutex{};
void
update_critical_path(call_chain _chain, int64_t _tid);
@@ -549,6 +550,7 @@ add_hash_id(const hash_ids& _labels)
{
OMNITRACE_SCOPED_THREAD_STATE(ThreadState::Internal);
if(!tasking::critical_trace::get_task_group().pool()) return;
std::unique_lock<std::mutex> _lk{ tasking_mutex };
tasking::critical_trace::get_task_group().exec([_labels]() {
static std::mutex _mtx{};
_mtx.lock();
@@ -579,7 +581,8 @@ update(int64_t _tid)
if(!get_use_critical_trace() && !get_use_rocm_smi()) return;
OMNITRACE_SCOPED_THREAD_STATE(ThreadState::Internal);
if(!tasking::critical_trace::get_task_group().pool()) return;
call_chain _data{};
std::unique_lock<std::mutex> _lk{ tasking_mutex };
call_chain _data{};
std::swap(_data, *critical_trace::get(_tid));
tasking::critical_trace::get_task_group().exec(update_critical_path, _data, _tid);
}
@@ -590,6 +593,7 @@ compute(int64_t _tid)
update(_tid);
OMNITRACE_SCOPED_THREAD_STATE(ThreadState::Internal);
if(!tasking::critical_trace::get_task_group().pool()) return;
std::unique_lock<std::mutex> _lk{ tasking_mutex };
tasking::critical_trace::get_task_group().exec(compute_critical_trace);
}
@@ -867,6 +871,7 @@ get_entries(int64_t _ts, const std::function<bool(const entry&)>& _eval)
size_t _n = 0;
std::vector<std::pair<std::string, entry>> _v{};
if(!tasking::critical_trace::get_task_group().pool()) return _v;
std::unique_lock<std::mutex> _lk{ tasking_mutex };
tasking::critical_trace::get_task_group().exec(_func, &_v, &_n);
tasking::critical_trace::get_task_group().join();
OMNITRACE_DEBUG("critical_trace::%s :: found %zu out of %zu entries at %li...\n",
@@ -24,10 +24,37 @@
#include "library/runtime.hpp"
#include "library/state.hpp"
#include <timemory/log/color.hpp>
#include <timemory/utility/filepath.hpp>
namespace omnitrace
{
namespace debug
{
namespace
{
struct source_location_history
{
std::array<source_location, 10> data = {};
size_t size = 0;
};
auto&
get_source_location_history()
{
static thread_local auto _v = source_location_history{};
return _v;
}
} // namespace
void
set_source_location(source_location&& _v)
{
auto& _hist = get_source_location_history();
auto _idx = _hist.size++;
_hist.data.at(_idx % _hist.data.size()) = _v;
}
lock::lock()
: m_lk{ tim::type_mutex<decltype(std::cerr)>(), std::defer_lock }
{
@@ -46,5 +73,16 @@ lock::~lock()
pop_thread_state();
}
}
FILE*
get_file()
{
static FILE* _v = []() {
auto&& _fname = tim::get_env<std::string>("OMNITRACE_LOG_FILE", "");
tim::log::colorized() = _fname.empty();
return (_fname.empty()) ? stderr : tim::filepath::fopen(_fname, "w");
}();
return _v;
}
} // namespace debug
} // namespace omnitrace
+125 -21
Wyświetl plik
@@ -71,14 +71,27 @@ get_critical_trace_debug() OMNITRACE_HOT;
namespace debug
{
struct source_location
{
std::string_view function = {};
std::string_view file = {};
int line = 0;
};
//
void
set_source_location(source_location&&);
//
FILE*
get_file();
//
inline void
flush()
{
fprintf(stdout, "%s", ::tim::log::color::end());
fflush(stdout);
std::cout << ::tim::log::color::end() << std::flush;
fprintf(stderr, "%s", ::tim::log::color::end());
fflush(stderr);
fprintf(::omnitrace::debug::get_file(), "%s", ::tim::log::color::end());
fflush(::omnitrace::debug::get_file());
std::cerr << ::tim::log::color::end() << std::flush;
}
//
@@ -135,6 +148,16 @@ get_chars(T&& _c, std::index_sequence<Idx...>)
# define OMNITRACE_DEBUG_THREAD_IDENTIFIER ::tim::threading::get_id()
#endif
#if !defined(OMNITRACE_SOURCE_LOCATION)
# define OMNITRACE_SOURCE_LOCATION \
::omnitrace::debug::source_location { __PRETTY_FUNCTION__, __FILE__, __LINE__ }
#endif
#if !defined(OMNITRACE_RECORD_SOURCE_LOCATION)
# define OMNITRACE_RECORD_SOURCE_LOCATION \
::omnitrace::debug::set_source_location(OMNITRACE_SOURCE_LOCATION)
#endif
#if defined(__clang__) || (__GNUC__ < 9)
# define OMNITRACE_FUNCTION \
std::string{ __FUNCTION__ } \
@@ -164,7 +187,7 @@ get_chars(T&& _c, std::index_sequence<Idx...>)
//--------------------------------------------------------------------------------------//
#define OMNITRACE_FPRINTF_STDERR_COLOR(COLOR) \
fprintf(stderr, "%s", ::tim::log::color::COLOR())
fprintf(::omnitrace::debug::get_file(), "%s", ::tim::log::color::COLOR())
//--------------------------------------------------------------------------------------//
@@ -175,10 +198,10 @@ get_chars(T&& _c, std::index_sequence<Idx...>)
::omnitrace::debug::flush(); \
::omnitrace::debug::lock _lk{}; \
OMNITRACE_FPRINTF_STDERR_COLOR(info); \
fprintf(stderr, "[omnitrace][%i][%li]%s", OMNITRACE_DEBUG_PROCESS_IDENTIFIER, \
OMNITRACE_DEBUG_THREAD_IDENTIFIER, \
fprintf(::omnitrace::debug::get_file(), "[omnitrace][%i][%li]%s", \
OMNITRACE_DEBUG_PROCESS_IDENTIFIER, OMNITRACE_DEBUG_THREAD_IDENTIFIER, \
::omnitrace::debug::is_bracket(__VA_ARGS__) ? "" : " "); \
fprintf(stderr, __VA_ARGS__); \
fprintf(::omnitrace::debug::get_file(), __VA_ARGS__); \
::omnitrace::debug::flush(); \
}
@@ -189,9 +212,9 @@ get_chars(T&& _c, std::index_sequence<Idx...>)
::omnitrace::debug::flush(); \
::omnitrace::debug::lock _lk{}; \
OMNITRACE_FPRINTF_STDERR_COLOR(info); \
fprintf(stderr, "[omnitrace]%s", \
fprintf(::omnitrace::debug::get_file(), "[omnitrace]%s", \
::omnitrace::debug::is_bracket(__VA_ARGS__) ? "" : " "); \
fprintf(stderr, __VA_ARGS__); \
fprintf(::omnitrace::debug::get_file(), __VA_ARGS__); \
::omnitrace::debug::flush(); \
}
@@ -202,11 +225,11 @@ get_chars(T&& _c, std::index_sequence<Idx...>)
::omnitrace::debug::flush(); \
::omnitrace::debug::lock _lk{}; \
OMNITRACE_FPRINTF_STDERR_COLOR(info); \
fprintf(stderr, "[omnitrace][%i][%li][%s]%s", \
fprintf(::omnitrace::debug::get_file(), "[omnitrace][%i][%li][%s]%s", \
OMNITRACE_DEBUG_PROCESS_IDENTIFIER, OMNITRACE_DEBUG_THREAD_IDENTIFIER, \
OMNITRACE_FUNCTION, \
::omnitrace::debug::is_bracket(__VA_ARGS__) ? "" : " "); \
fprintf(stderr, __VA_ARGS__); \
fprintf(::omnitrace::debug::get_file(), __VA_ARGS__); \
::omnitrace::debug::flush(); \
}
@@ -217,9 +240,66 @@ get_chars(T&& _c, std::index_sequence<Idx...>)
::omnitrace::debug::flush(); \
::omnitrace::debug::lock _lk{}; \
OMNITRACE_FPRINTF_STDERR_COLOR(info); \
fprintf(stderr, "[omnitrace][%s]%s", OMNITRACE_FUNCTION, \
fprintf(::omnitrace::debug::get_file(), "[omnitrace][%s]%s", OMNITRACE_FUNCTION, \
::omnitrace::debug::is_bracket(__VA_ARGS__) ? "" : " "); \
fprintf(stderr, __VA_ARGS__); \
fprintf(::omnitrace::debug::get_file(), __VA_ARGS__); \
::omnitrace::debug::flush(); \
}
//--------------------------------------------------------------------------------------//
#define OMNITRACE_CONDITIONAL_WARN(COND, ...) \
if((COND) && ::omnitrace::config::get_debug_tid() && \
::omnitrace::config::get_debug_pid()) \
{ \
::omnitrace::debug::flush(); \
::omnitrace::debug::lock _lk{}; \
OMNITRACE_FPRINTF_STDERR_COLOR(warning); \
fprintf(::omnitrace::debug::get_file(), "[omnitrace][%i][%li]%s", \
OMNITRACE_DEBUG_PROCESS_IDENTIFIER, OMNITRACE_DEBUG_THREAD_IDENTIFIER, \
::omnitrace::debug::is_bracket(__VA_ARGS__) ? "" : " "); \
fprintf(::omnitrace::debug::get_file(), __VA_ARGS__); \
::omnitrace::debug::flush(); \
}
#define OMNITRACE_CONDITIONAL_BASIC_WARN(COND, ...) \
if((COND) && ::omnitrace::config::get_debug_tid() && \
::omnitrace::config::get_debug_pid()) \
{ \
::omnitrace::debug::flush(); \
::omnitrace::debug::lock _lk{}; \
OMNITRACE_FPRINTF_STDERR_COLOR(warning); \
fprintf(::omnitrace::debug::get_file(), "[omnitrace]%s", \
::omnitrace::debug::is_bracket(__VA_ARGS__) ? "" : " "); \
fprintf(::omnitrace::debug::get_file(), __VA_ARGS__); \
::omnitrace::debug::flush(); \
}
#define OMNITRACE_CONDITIONAL_WARN_F(COND, ...) \
if((COND) && ::omnitrace::config::get_debug_tid() && \
::omnitrace::config::get_debug_pid()) \
{ \
::omnitrace::debug::flush(); \
::omnitrace::debug::lock _lk{}; \
OMNITRACE_FPRINTF_STDERR_COLOR(warning); \
fprintf(::omnitrace::debug::get_file(), "[omnitrace][%i][%li][%s]%s", \
OMNITRACE_DEBUG_PROCESS_IDENTIFIER, OMNITRACE_DEBUG_THREAD_IDENTIFIER, \
OMNITRACE_FUNCTION, \
::omnitrace::debug::is_bracket(__VA_ARGS__) ? "" : " "); \
fprintf(::omnitrace::debug::get_file(), __VA_ARGS__); \
::omnitrace::debug::flush(); \
}
#define OMNITRACE_CONDITIONAL_BASIC_WARN_F(COND, ...) \
if((COND) && ::omnitrace::config::get_debug_tid() && \
::omnitrace::config::get_debug_pid()) \
{ \
::omnitrace::debug::flush(); \
::omnitrace::debug::lock _lk{}; \
OMNITRACE_FPRINTF_STDERR_COLOR(warning); \
fprintf(::omnitrace::debug::get_file(), "[omnitrace][%s]%s", OMNITRACE_FUNCTION, \
::omnitrace::debug::is_bracket(__VA_ARGS__) ? "" : " "); \
fprintf(::omnitrace::debug::get_file(), __VA_ARGS__); \
::omnitrace::debug::flush(); \
}
@@ -267,10 +347,10 @@ get_chars(T&& _c, std::index_sequence<Idx...>)
{ \
::omnitrace::debug::flush(); \
OMNITRACE_FPRINTF_STDERR_COLOR(fatal); \
fprintf(stderr, "[omnitrace][%i][%li]%s", OMNITRACE_DEBUG_PROCESS_IDENTIFIER, \
OMNITRACE_DEBUG_THREAD_IDENTIFIER, \
fprintf(::omnitrace::debug::get_file(), "[omnitrace][%i][%li]%s", \
OMNITRACE_DEBUG_PROCESS_IDENTIFIER, OMNITRACE_DEBUG_THREAD_IDENTIFIER, \
::omnitrace::debug::is_bracket(__VA_ARGS__) ? "" : " "); \
fprintf(stderr, __VA_ARGS__); \
fprintf(::omnitrace::debug::get_file(), __VA_ARGS__); \
::omnitrace::debug::flush(); \
::omnitrace::set_state(::omnitrace::State::Finalized); \
::tim::disable_signal_detection(); \
@@ -283,9 +363,9 @@ get_chars(T&& _c, std::index_sequence<Idx...>)
{ \
::omnitrace::debug::flush(); \
OMNITRACE_FPRINTF_STDERR_COLOR(fatal); \
fprintf(stderr, "[omnitrace]%s", \
fprintf(::omnitrace::debug::get_file(), "[omnitrace]%s", \
::omnitrace::debug::is_bracket(__VA_ARGS__) ? "" : " "); \
fprintf(stderr, __VA_ARGS__); \
fprintf(::omnitrace::debug::get_file(), __VA_ARGS__); \
::omnitrace::debug::flush(); \
::omnitrace::set_state(::omnitrace::State::Finalized); \
::tim::disable_signal_detection(); \
@@ -298,11 +378,11 @@ get_chars(T&& _c, std::index_sequence<Idx...>)
{ \
::omnitrace::debug::flush(); \
OMNITRACE_FPRINTF_STDERR_COLOR(fatal); \
fprintf(stderr, "[omnitrace][%i][%li][%s]%s", \
fprintf(::omnitrace::debug::get_file(), "[omnitrace][%i][%li][%s]%s", \
OMNITRACE_DEBUG_PROCESS_IDENTIFIER, OMNITRACE_DEBUG_THREAD_IDENTIFIER, \
OMNITRACE_FUNCTION, \
::omnitrace::debug::is_bracket(__VA_ARGS__) ? "" : " "); \
fprintf(stderr, __VA_ARGS__); \
fprintf(::omnitrace::debug::get_file(), __VA_ARGS__); \
::omnitrace::debug::flush(); \
::omnitrace::set_state(::omnitrace::State::Finalized); \
::tim::disable_signal_detection(); \
@@ -315,9 +395,9 @@ get_chars(T&& _c, std::index_sequence<Idx...>)
{ \
::omnitrace::debug::flush(); \
OMNITRACE_FPRINTF_STDERR_COLOR(fatal); \
fprintf(stderr, "[omnitrace][%s]%s", OMNITRACE_FUNCTION, \
fprintf(::omnitrace::debug::get_file(), "[omnitrace][%s]%s", OMNITRACE_FUNCTION, \
::omnitrace::debug::is_bracket(__VA_ARGS__) ? "" : " "); \
fprintf(stderr, __VA_ARGS__); \
fprintf(::omnitrace::debug::get_file(), __VA_ARGS__); \
::omnitrace::debug::flush(); \
::omnitrace::set_state(::omnitrace::State::Finalized); \
::tim::disable_signal_detection(); \
@@ -427,6 +507,30 @@ get_chars(T&& _c, std::index_sequence<Idx...>)
(::omnitrace::get_verbose_env() >= LEVEL), \
__VA_ARGS__)
//--------------------------------------------------------------------------------------//
//
// Warning macros
//
//--------------------------------------------------------------------------------------//
#define OMNITRACE_WARNING(LEVEL, ...) \
OMNITRACE_CONDITIONAL_WARN( \
::omnitrace::get_debug() || (::omnitrace::get_verbose() >= LEVEL), __VA_ARGS__)
#define OMNITRACE_BASIC_WARNING(LEVEL, ...) \
OMNITRACE_CONDITIONAL_BASIC_WARN(::omnitrace::get_debug_env() || \
(::omnitrace::get_verbose_env() >= LEVEL), \
__VA_ARGS__)
#define OMNITRACE_WARNING_F(LEVEL, ...) \
OMNITRACE_CONDITIONAL_WARN_F( \
::omnitrace::get_debug() || (::omnitrace::get_verbose() >= LEVEL), __VA_ARGS__)
#define OMNITRACE_BASIC_WARNING_F(LEVEL, ...) \
OMNITRACE_CONDITIONAL_BASIC_WARN_F(::omnitrace::get_debug_env() || \
(::omnitrace::get_verbose_env() >= LEVEL), \
__VA_ARGS__)
//--------------------------------------------------------------------------------------//
//
// Basic print macros (basic means it will not provide PID/RANK or TID) and will not
@@ -21,6 +21,88 @@
// SOFTWARE.
#include "library/perfetto.hpp"
#include "library/config.hpp"
#include "library/tracing.hpp"
namespace omnitrace
{
namespace perfetto
{
void
setup()
{
auto args = ::perfetto::TracingInitArgs{};
auto track_event_cfg = ::perfetto::protos::gen::TrackEventConfig{};
auto& cfg = tracing::get_perfetto_config();
// environment settings
auto shmem_size_hint = get_perfetto_shmem_size_hint();
auto buffer_size = get_perfetto_buffer_size();
auto _policy =
get_perfetto_fill_policy() == "discard"
? ::perfetto::protos::gen::TraceConfig_BufferConfig_FillPolicy_DISCARD
: ::perfetto::protos::gen::TraceConfig_BufferConfig_FillPolicy_RING_BUFFER;
auto* buffer_config = cfg.add_buffers();
buffer_config->set_size_kb(buffer_size);
buffer_config->set_fill_policy(_policy);
std::set<std::string> _available_categories = {};
std::set<std::string> _disabled_categories = {};
for(auto itr : { OMNITRACE_PERFETTO_CATEGORIES })
_available_categories.emplace(itr.name);
auto _enabled_categories = config::get_perfetto_categories();
for(const auto& itr : _available_categories)
{
if(!_enabled_categories.empty() && _enabled_categories.count(itr) == 0)
_disabled_categories.emplace(itr);
}
for(const auto& itr : _disabled_categories)
{
OMNITRACE_VERBOSE_F(1, "Disabling perfetto track event category: %s\n",
itr.c_str());
track_event_cfg.add_disabled_categories(itr);
}
auto* ds_cfg = cfg.add_data_sources()->mutable_config();
ds_cfg->set_name("track_event"); // this MUST be track_event
ds_cfg->set_track_event_config_raw(track_event_cfg.SerializeAsString());
args.shmem_size_hint_kb = shmem_size_hint;
if(get_backend() != "inprocess") args.backends |= ::perfetto::kSystemBackend;
if(get_backend() != "system") args.backends |= ::perfetto::kInProcessBackend;
::perfetto::Tracing::Initialize(args);
::perfetto::TrackEvent::Register();
}
void
start()
{
#if defined(CUSTOM_DATA_SOURCE)
// Add the following:
::perfetto::DataSourceDescriptor dsd{};
dsd.set_name("com.example.custom_data_source");
CustomDataSource::Register(dsd);
auto* ds_cfg = cfg.add_data_sources()->mutable_config();
ds_cfg->set_name("com.example.custom_data_source");
CustomDataSource::Trace([](CustomDataSource::TraceContext ctx) {
auto packet = ctx.NewTracePacket();
packet->set_timestamp(::perfetto::TrackEvent::GetTraceTimeNs());
packet->set_for_testing()->set_str("Hello world!");
PRINT_HERE("%s", "Trace");
});
#endif
auto& cfg = tracing::get_perfetto_config();
auto& tracing_session = tracing::get_perfetto_session();
tracing_session = ::perfetto::Tracing::NewTrace();
tracing_session->Setup(cfg);
tracing_session->StartBlocking();
}
} // namespace perfetto
} // namespace omnitrace
PERFETTO_TRACK_EVENT_STATIC_STORAGE();
@@ -106,8 +106,7 @@ sampler::poll(std::atomic<State>* _state, nsec_t _interval, promise_t* _ready)
itr->sample();
get_sampler_is_sampling().store(false);
if(_has_duration && _now >= _end) break;
while(_now < std::chrono::steady_clock::now())
_now += _interval;
_now = std::chrono::steady_clock::now() + _interval;
}
// ensure this is always false
@@ -167,16 +166,13 @@ sampler::setup()
auto _freq = get_process_sampling_freq();
uint64_t _msec_freq = (1.0 / _freq) * 1.0e3;
promise_t _prom{};
auto _fut = _prom.get_future();
polling_finished = std::make_unique<promise_t>();
OMNITRACE_SCOPED_SAMPLING_ON_CHILD_THREADS(false);
set_state(State::PreInit);
get_thread() = std::make_unique<std::thread>(&poll<msec_t>, &get_sampler_state(),
msec_t{ _msec_freq }, &_prom);
_fut.wait();
msec_t{ _msec_freq }, nullptr);
set_state(State::Active);
}
+4 -1
Wyświetl plik
@@ -123,7 +123,10 @@ get_thread_pool_state()
void
setup()
{}
{
OMNITRACE_SCOPED_THREAD_STATE(ThreadState::Internal);
(void) get_thread_pool();
}
void
join()
+3 -6
Wyświetl plik
@@ -163,6 +163,9 @@ extern "C"
bool OnLoad(HsaApiTable* table, uint64_t runtime_version, uint64_t failed_tool_count,
const char* const* failed_tool_names)
{
tim::consume_parameters(table, runtime_version, failed_tool_count,
failed_tool_names);
OMNITRACE_BASIC_VERBOSE_F(2 || rocm::on_load_trace, "Loading...\n");
OMNITRACE_SCOPED_SAMPLING_ON_CHILD_THREADS(false);
@@ -172,9 +175,6 @@ extern "C"
roctracer_is_init() = true;
OMNITRACE_BASIC_VERBOSE_F(1 || rocm::on_load_trace, "Loading ROCm tooling...\n");
tim::consume_parameters(table, runtime_version, failed_tool_count,
failed_tool_names);
if(!config::settings_are_configured() && get_state() < State::Active)
omnitrace_init_tooling_hidden();
@@ -326,9 +326,6 @@ extern "C"
void OnUnload()
{
OMNITRACE_BASIC_VERBOSE_F(2 || rocm::on_load_trace, "Unloading...\n");
rocm_smi::set_state(State::Finalized);
comp::roctracer::shutdown();
comp::rocprofiler::shutdown();
omnitrace_finalize_hidden();
OMNITRACE_BASIC_VERBOSE_F(2 || rocm::on_load_trace, "Unloading... Done\n");
}
@@ -536,7 +536,7 @@ HsaRsrcFactory::GetCpuAgentInfo(uint32_t idx, const AgentInfo** agent_info)
//
// @return bool true if successful, false otherwise
//
bool
bool // NOLINTNEXTLINE(readability-convert-member-functions-to-static)
HsaRsrcFactory::CreateQueue(const AgentInfo* agent_info, uint32_t num_pkts,
hsa_queue_t** queue)
{
@@ -550,7 +550,7 @@ HsaRsrcFactory::CreateQueue(const AgentInfo* agent_info, uint32_t num_pkts,
// @param value Initial value of signal object
// @param signal Output parameter updated with handle of signal object
// @return bool true if successful, false otherwise
bool
bool // NOLINTNEXTLINE(readability-convert-member-functions-to-static)
HsaRsrcFactory::CreateSignal(uint32_t value, hsa_signal_t* signal)
{
hsa_status_t status;
@@ -563,7 +563,7 @@ HsaRsrcFactory::CreateSignal(uint32_t value, hsa_signal_t* signal)
// @param agent_info Agent from whose memory region to allocate
// @param size Size of memory in terms of bytes
// @return uint8_t* Pointer to buffer, null if allocation fails.
uint8_t*
uint8_t* // NOLINTNEXTLINE(readability-convert-member-functions-to-static)
HsaRsrcFactory::AllocateLocalMemory(const AgentInfo* agent_info, size_t size)
{
hsa_status_t status = HSA_STATUS_ERROR;
@@ -647,7 +647,7 @@ HsaRsrcFactory::AllocateCmdMemory(const AgentInfo* agent_info, size_t size)
void
HsaRsrcFactory::SignalWait(const hsa_signal_t& signal) const
{
while(1)
while(true)
{
const hsa_signal_value_t signal_value = hsa_api_.hsa_signal_wait_scacquire(
signal, HSA_SIGNAL_CONDITION_LT, 1, timeout_, HSA_WAIT_STATE_BLOCKED);
@@ -714,7 +714,7 @@ HsaRsrcFactory::FreeMemory(void* ptr)
// @param code_desc Handle of finalized Code Descriptor that could
// be used to submit for execution
// @return bool true if successful, false otherwise
bool
bool // NOLINTNEXTLINE(readability-convert-member-functions-to-static)
HsaRsrcFactory::LoadAndFinalize(const AgentInfo* agent_info, const char* brig_path,
const char* kernel_name, hsa_executable_t* executable,
hsa_executable_symbol_t* code_desc)
+13 -3
Wyświetl plik
@@ -26,6 +26,7 @@
#include "library/debug.hpp"
#include "library/defines.hpp"
#include "library/thread_data.hpp"
#include "library/thread_info.hpp"
#include "library/utility.hpp"
#include <timemory/backends/dmp.hpp>
@@ -65,9 +66,18 @@ get_sampling_on_child_threads_history(int64_t _idx = utility::get_thread_index()
bool&
sampling_on_child_threads()
{
static thread_local bool _v = get_sampling_on_child_threads_history().empty()
? false
: get_sampling_on_child_threads_history().back();
static const auto& _thr_info = thread_info::get();
// if the thread is offset, disable by default
// if the global state is not active or the thread state is not enabled, disable by
// default if there is no history, disable by default (first thread) otherwise,
// inherit the last state
static thread_local bool _v =
(_thr_info) ? !_thr_info->is_offset
: (get_state() != State::Active || get_thread_state() != ThreadState::Enabled)
? false
: (get_sampling_on_child_threads_history().empty()
? false
: get_sampling_on_child_threads_history().back());
return _v;
}
} // namespace
+14 -1
Wyświetl plik
@@ -136,7 +136,8 @@ get_signal_names(Tp&& _v)
_sig_names += std::get<0>(tim::signal_settings::get_info(
static_cast<tim::sys_signal>(itr))) +
" ";
return _sig_names.substr(0, _sig_names.length() - 1);
return (_sig_names.empty()) ? _sig_names
: _sig_names.substr(0, _sig_names.length() - 1);
}
unique_ptr_t<sampler_t>&
@@ -418,6 +419,18 @@ shutdown()
return configure(false);
}
void
block_samples()
{
trait::runtime_enabled<sampler_t>::set(false);
}
void
unblock_samples()
{
trait::runtime_enabled<sampler_t>::set(true);
}
void
block_signals(std::set<int> _signals)
{
@@ -66,12 +66,17 @@ setup();
std::set<int>
shutdown();
void
block_samples();
void
unblock_samples();
void block_signals(std::set<int> = {});
void unblock_signals(std::set<int> = {});
void
post_process();
} // namespace sampling
} // namespace omnitrace
@@ -47,9 +47,9 @@ get_index_data(int64_t _tid)
}
auto
init_index_data(bool _offset = false)
init_index_data(int64_t _tid, bool _offset = false)
{
auto& itr = get_index_data(utility::get_thread_index());
auto& itr = get_index_data(_tid);
if(!itr)
{
threading::offset_this_id(_offset);
@@ -76,20 +76,20 @@ const auto unknown_thread = std::optional<thread_info>{};
const std::optional<thread_info>&
thread_info::init(bool _offset)
{
auto& _instances = thread_info_data_t::instances();
auto _tid = utility::get_thread_index();
auto _init = [&] {
static thread_local bool _once = false;
auto& _instances = thread_info_data_t::instances();
auto _tid = utility::get_thread_index();
if(!_once && (_once = true))
{
threading::offset_this_id(_offset);
std::optional<thread_info>& _info = _instances.at(_tid);
_info = thread_info{};
_info->is_offset = threading::offset_this_id();
_info->index_data = init_index_data(_info->is_offset);
auto& _info = _instances.at(_tid);
_info = thread_info{};
_info->is_offset = threading::offset_this_id();
_info->index_data = init_index_data(_tid, _info->is_offset);
_info->lifetime.first = tim::get_clock_real_now<uint64_t, std::nano>();
if(_info->is_offset) set_thread_state(ThreadState::Disabled);
};
static thread_local std::once_flag _once{};
std::call_once(_once, _init);
}
return _instances.at(_tid);
}
+11 -4
Wyświetl plik
@@ -27,11 +27,18 @@ namespace omnitrace
{
namespace tracing
{
std::unique_ptr<perfetto::TracingSession>&
get_trace_session()
perfetto::TraceConfig&
get_perfetto_config()
{
static auto _session = std::unique_ptr<perfetto::TracingSession>{};
return _session;
static auto _v = ::perfetto::TraceConfig{};
return _v;
}
std::unique_ptr<perfetto::TracingSession>&
get_perfetto_session()
{
static auto _v = std::unique_ptr<perfetto::TracingSession>{};
return _v;
}
std::vector<std::function<void()>>&
@@ -43,8 +43,11 @@ namespace tracing
{
using interval_data_instances = thread_data<std::vector<bool>>;
perfetto::TraceConfig&
get_perfetto_config();
std::unique_ptr<perfetto::TracingSession>&
get_trace_session();
get_perfetto_session();
std::vector<std::function<void()>>&
get_finalization_functions();