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:
zatwierdzone przez
GitHub
rodzic
90ff7188f8
commit
8f36620e29
@@ -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();
|
||||
};
|
||||
|
||||
@@ -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{};
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -123,7 +123,10 @@ get_thread_pool_state()
|
||||
|
||||
void
|
||||
setup()
|
||||
{}
|
||||
{
|
||||
OMNITRACE_SCOPED_THREAD_STATE(ThreadState::Internal);
|
||||
(void) get_thread_pool();
|
||||
}
|
||||
|
||||
void
|
||||
join()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user