diff --git a/external/timemory b/external/timemory index a1538e4352..04a8679c09 160000 --- a/external/timemory +++ b/external/timemory @@ -1 +1 @@ -Subproject commit a1538e4352d99a8f1758d8d70ec107be11a101d7 +Subproject commit 04a8679c09a3e6bf36968fe4fd93573ac46cbe3b diff --git a/scripts/run-ci.py b/scripts/run-ci.py index 1e07efb5d1..cbb8c83cce 100755 --- a/scripts/run-ci.py +++ b/scripts/run-ci.py @@ -247,7 +247,7 @@ if __name__ == "__main__": "-S", os.path.join(args.binary_dir, "dashboard.cmake"), "--output-on-failure", - "-V", + "-VV", ] + ctest_args, check=True, diff --git a/source/lib/omnitrace/CMakeLists.txt b/source/lib/omnitrace/CMakeLists.txt index 8ac2cb909f..2356c720f3 100644 --- a/source/lib/omnitrace/CMakeLists.txt +++ b/source/lib/omnitrace/CMakeLists.txt @@ -56,8 +56,8 @@ add_library(omnitrace::omnitrace-object-library ALIAS omnitrace-object-library) target_sources( omnitrace-object-library - PRIVATE ${CMAKE_CURRENT_LIST_DIR}/library.cpp ${CMAKE_CURRENT_LIST_DIR}/api.cpp - ${CMAKE_CURRENT_LIST_DIR}/api.hpp) + PRIVATE ${CMAKE_CURRENT_LIST_DIR}/library.cpp ${CMAKE_CURRENT_LIST_DIR}/regions.cpp + ${CMAKE_CURRENT_LIST_DIR}/api.cpp ${CMAKE_CURRENT_LIST_DIR}/api.hpp) add_subdirectory(library) diff --git a/source/lib/omnitrace/api.cpp b/source/lib/omnitrace/api.cpp index 4a1062eed6..aa39254dfe 100644 --- a/source/lib/omnitrace/api.cpp +++ b/source/lib/omnitrace/api.cpp @@ -46,7 +46,7 @@ omnitrace_push_region(const char* _name) omnitrace_push_region_hidden(_name); } catch(std::exception& _e) { - OMNITRACE_VERBOSE_F(1, "Exception caught: %s\n", _e.what()); + OMNITRACE_WARNING_F(1, "Exception caught: %s\n", _e.what()); return -1; } return 0; @@ -60,7 +60,7 @@ omnitrace_pop_region(const char* _name) omnitrace_pop_region_hidden(_name); } catch(std::exception& _e) { - OMNITRACE_VERBOSE_F(1, "Exception caught: %s\n", _e.what()); + OMNITRACE_WARNING_F(1, "Exception caught: %s\n", _e.what()); return -1; } return 0; @@ -77,7 +77,7 @@ omnitrace_push_category_region(omnitrace_category_t _category, const char* _name _annotation_count); } catch(std::exception& _e) { - OMNITRACE_VERBOSE_F(1, "Exception caught: %s\n", _e.what()); + OMNITRACE_WARNING_F(1, "Exception caught: %s\n", _e.what()); return -1; } return 0; @@ -94,7 +94,7 @@ omnitrace_pop_category_region(omnitrace_category_t _category, const char* _name, _annotation_count); } catch(std::exception& _e) { - OMNITRACE_VERBOSE_F(1, "Exception caught: %s\n", _e.what()); + OMNITRACE_WARNING_F(1, "Exception caught: %s\n", _e.what()); return -1; } return 0; diff --git a/source/lib/omnitrace/library.cpp b/source/lib/omnitrace/library.cpp index 17cd6e133b..b9da944497 100644 --- a/source/lib/omnitrace/library.cpp +++ b/source/lib/omnitrace/library.cpp @@ -26,7 +26,6 @@ #include "api.hpp" #include "common/setup.hpp" -#include "library/components/category_region.hpp" #include "library/components/exit_gotcha.hpp" #include "library/components/fork_gotcha.hpp" #include "library/components/fwd.hpp" @@ -152,132 +151,6 @@ using Device = critical_trace::Device; using Phase = critical_trace::Phase; } // namespace -//======================================================================================// - -extern "C" void -omnitrace_push_trace_hidden(const char* name) -{ - component::category_region::start(name); -} - -extern "C" void -omnitrace_pop_trace_hidden(const char* name) -{ - component::category_region::stop(name); -} - -//======================================================================================// -/// -/// -/// -//======================================================================================// - -extern "C" void -omnitrace_push_region_hidden(const char* name) -{ - component::category_region::start(name); -} - -extern "C" void -omnitrace_pop_region_hidden(const char* name) -{ - component::category_region::stop(name); -} - -//======================================================================================// -/// -/// -/// -//======================================================================================// - -namespace omnitrace -{ -namespace -{ -template -void -invoke_category_region_start(omnitrace_category_t _category, const char* name, - omnitrace_annotation_t* _annotations, - size_t _annotation_count, std::index_sequence) -{ - static_assert(Idx > OMNITRACE_CATEGORY_NONE && Idx < OMNITRACE_CATEGORY_LAST, - "Error! index sequence should only contain values which are greater " - "than OMNITRACE_CATEGORY_NONE and less than OMNITRACE_CATEGORY_LAST"); - - if(_category == Idx) - { - using category_type = category_type_id_t; - component::category_region::start( - name, [&](::perfetto::EventContext ctx) { - if(_annotations) - { - for(size_t i = 0; i < _annotation_count; ++i) - tracing::add_perfetto_annotation(ctx, _annotations[i]); - } - }); - } - else - { - constexpr size_t remaining = sizeof...(Tail); - if constexpr(remaining > 0) - invoke_category_region_start(_category, name, _annotations, _annotation_count, - std::index_sequence{}); - } -} -} // namespace - -template -void -invoke_category_region_stop(omnitrace_category_t _category, const char* name, - omnitrace_annotation_t* _annotations, - size_t _annotation_count, std::index_sequence) -{ - static_assert(Idx > OMNITRACE_CATEGORY_NONE && Idx < OMNITRACE_CATEGORY_LAST, - "Error! index sequence should only contain values which are greater " - "than OMNITRACE_CATEGORY_NONE and less than OMNITRACE_CATEGORY_LAST"); - - if(_category == Idx) - { - using category_type = category_type_id_t; - component::category_region::stop( - name, [&](::perfetto::EventContext ctx) { - if(_annotations) - { - for(size_t i = 0; i < _annotation_count; ++i) - tracing::add_perfetto_annotation(ctx, _annotations[i]); - } - }); - } - else - { - constexpr size_t remaining = sizeof...(Tail); - if constexpr(remaining > 0) - invoke_category_region_stop(_category, name, _annotations, _annotation_count, - std::index_sequence{}); - } -} -} // namespace omnitrace - -extern "C" void -omnitrace_push_category_region_hidden(omnitrace_category_t _category, const char* name, - omnitrace_annotation_t* _annotations, - size_t _annotation_count) -{ - invoke_category_region_start( - _category, name, _annotations, _annotation_count, - utility::make_index_sequence_range<1, OMNITRACE_CATEGORY_LAST>{}); -} - -extern "C" void -omnitrace_pop_category_region_hidden(omnitrace_category_t _category, const char* name, - omnitrace_annotation_t* _annotations, - size_t _annotation_count) -{ - invoke_category_region_stop( - _category, name, _annotations, _annotation_count, - utility::make_index_sequence_range<1, OMNITRACE_CATEGORY_LAST>{}); -} - //======================================================================================// /// /// diff --git a/source/lib/omnitrace/library/components/category_region.hpp b/source/lib/omnitrace/library/components/category_region.hpp index f89f3e2838..7b85e26ff2 100644 --- a/source/lib/omnitrace/library/components/category_region.hpp +++ b/source/lib/omnitrace/library/components/category_region.hpp @@ -91,6 +91,9 @@ template void category_region::start(std::string_view name, Args&&... args) { + // skip if category is disabled + if(!trait::runtime_enabled::get()) return; + // unconditionally return if thread is disabled or finalized if(get_thread_state() == ThreadState::Disabled) return; if(get_state() == State::Finalized) return; @@ -167,6 +170,9 @@ template void category_region::stop(std::string_view name, Args&&... args) { + // skip if category is disabled + if(!trait::runtime_enabled::get()) return; + if(get_thread_state() == ThreadState::Disabled) return; OMNITRACE_SCOPED_THREAD_STATE(ThreadState::Internal); @@ -249,10 +255,16 @@ void category_region::audit(const gotcha_data_t& _data, audit::incoming, Args&&... _args) { + // skip if category is disabled + if(!trait::runtime_enabled::get()) return; + start(_data.tool_id.c_str(), [&](perfetto::EventContext ctx) { - int64_t _n = 0; - OMNITRACE_FOLD_EXPRESSION(tracing::add_perfetto_annotation( - ctx, tim::try_demangle>(), _args, _n++)); + if(config::get_perfetto_annotations()) + { + int64_t _n = 0; + OMNITRACE_FOLD_EXPRESSION(tracing::add_perfetto_annotation( + ctx, tim::try_demangle>(), _args, _n++)); + } }); } @@ -262,7 +274,13 @@ void category_region::audit(const gotcha_data_t& _data, audit::outgoing, Args&&... _args) { - stop(_data.tool_id.c_str(), "return", JOIN(", ", _args...)); + // skip if category is disabled + if(!trait::runtime_enabled::get()) return; + + stop(_data.tool_id.c_str(), [&](perfetto::EventContext ctx) { + if(config::get_perfetto_annotations()) + tracing::add_perfetto_annotation(ctx, "return", JOIN(", ", _args...)); + }); } template @@ -271,10 +289,16 @@ void category_region::audit(std::string_view _name, audit::incoming, Args&&... _args) { + // skip if category is disabled + if(!trait::runtime_enabled::get()) return; + start(_name.data(), [&](perfetto::EventContext ctx) { - int64_t _n = 0; - OMNITRACE_FOLD_EXPRESSION(tracing::add_perfetto_annotation( - ctx, tim::try_demangle>(), _args, _n++)); + if(config::get_perfetto_annotations()) + { + int64_t _n = 0; + OMNITRACE_FOLD_EXPRESSION(tracing::add_perfetto_annotation( + ctx, tim::try_demangle>(), _args, _n++)); + } }); } @@ -284,7 +308,13 @@ void category_region::audit(std::string_view _name, audit::outgoing, Args&&... _args) { - stop(_name.data(), "return", JOIN(", ", _args...)); + // skip if category is disabled + if(!trait::runtime_enabled::get()) return; + + stop(_name.data(), [&](perfetto::EventContext ctx) { + if(config::get_perfetto_annotations()) + tracing::add_perfetto_annotation(ctx, "return", JOIN(", ", _args...)); + }); } template diff --git a/source/lib/omnitrace/library/components/pthread_create_gotcha.cpp b/source/lib/omnitrace/library/components/pthread_create_gotcha.cpp index 7da8fc8a8f..79898a3398 100644 --- a/source/lib/omnitrace/library/components/pthread_create_gotcha.cpp +++ b/source/lib/omnitrace/library/components/pthread_create_gotcha.cpp @@ -419,7 +419,8 @@ pthread_create_gotcha::operator()(pthread_t* thread, const pthread_attr_t* attr, _promise->get_future().wait_for(std::chrono::milliseconds{ 500 }); } - if(_use_bundle) stop_bundle(*_bundle, threading::get_id(), audit::outgoing{}, _ret); + if(_use_bundle) + stop_bundle(*_bundle, _info->index_data->sequent_value, audit::outgoing{}, _ret); // unblock the signals in the entire process if(_enable_sampling && !_blocked.empty()) diff --git a/source/lib/omnitrace/library/config.cpp b/source/lib/omnitrace/library/config.cpp index 62038d721b..808da6691b 100644 --- a/source/lib/omnitrace/library/config.cpp +++ b/source/lib/omnitrace/library/config.cpp @@ -588,6 +588,13 @@ configure_settings(bool _init) "data", "advanced") ->set_choices(get_available_perfetto_categories>()); + OMNITRACE_CONFIG_SETTING(bool, "OMNITRACE_PERFETTO_ANNOTATIONS", + "Include debug annotations in perfetto trace. When enabled, " + "this feature will encode information such as the values of " + "the function arguments (when available). Disabling this " + "feature may dramatically reduce the size of the trace", + true, "perfetto", "data", "debugging", "advanced"); + OMNITRACE_CONFIG_SETTING( uint64_t, "OMNITRACE_THREAD_POOL_SIZE", "Max number of threads for processing background tasks", @@ -1741,6 +1748,13 @@ get_perfetto_categories() return _ret; } +bool +get_perfetto_annotations() +{ + static auto _v = get_config()->find("OMNITRACE_PERFETTO_ANNOTATIONS"); + return static_cast&>(*_v->second).get(); +} + uint64_t get_critical_trace_update_freq() { diff --git a/source/lib/omnitrace/library/config.hpp b/source/lib/omnitrace/library/config.hpp index c6863097ff..886c32da21 100644 --- a/source/lib/omnitrace/library/config.hpp +++ b/source/lib/omnitrace/library/config.hpp @@ -247,6 +247,9 @@ get_perfetto_fill_policy(); std::set get_perfetto_categories(); +bool +get_perfetto_annotations() OMNITRACE_HOT; + uint64_t get_critical_trace_update_freq(); diff --git a/source/lib/omnitrace/library/roctracer.cpp b/source/lib/omnitrace/library/roctracer.cpp index 15c91e97d9..a50b6337fd 100644 --- a/source/lib/omnitrace/library/roctracer.cpp +++ b/source/lib/omnitrace/library/roctracer.cpp @@ -305,9 +305,21 @@ hsa_api_callback(uint32_t domain, uint32_t cid, const void* callback_data, void* uint64_t _beg_ts = begin_timestamp; uint64_t _end_ts = end_timestamp; tracing::push_perfetto_ts(category::rocm_hsa{}, _name, _beg_ts, - "begin_ns", _beg_ts); + [&](perfetto::EventContext ctx) { + if(config::get_perfetto_annotations()) + { + tracing::add_perfetto_annotation( + ctx, "begin_ns", _beg_ts); + } + }); tracing::pop_perfetto_ts(category::rocm_hsa{}, _name, _end_ts, - "end_ns", _end_ts); + [&](perfetto::EventContext ctx) { + if(config::get_perfetto_annotations()) + { + tracing::add_perfetto_annotation( + ctx, "end_ns", _end_ts); + } + }); } if(get_use_timemory()) @@ -378,8 +390,20 @@ hsa_activity_callback(uint32_t op, activity_record_t* record, void* arg) { uint64_t _beg = _beg_ns; uint64_t _end = _end_ns; - tracing::push_perfetto_ts(category::device_hsa{}, *_name, _beg, "begin_ns", _beg); - tracing::pop_perfetto_ts(category::device_hsa{}, *_name, _end, "end_ns", _end); + tracing::push_perfetto_ts( + category::device_hsa{}, *_name, _beg, [&](perfetto::EventContext ctx) { + if(config::get_perfetto_annotations()) + { + tracing::add_perfetto_annotation(ctx, "begin_ns", _beg); + } + }); + tracing::pop_perfetto_ts( + category::device_hsa{}, *_name, _end, [&](perfetto::EventContext ctx) { + if(config::get_perfetto_annotations()) + { + tracing::add_perfetto_annotation(ctx, "end_ns", _end); + } + }); } auto _func = [_beg_ns, _end_ns, _name]() { @@ -701,9 +725,19 @@ hip_api_callback(uint32_t domain, uint32_t cid, const void* callback_data, void* auto _api_id = static_cast(cid); tracing::push_perfetto_ts( category::rocm_hip{}, op_name, _ts, perfetto::Flow::ProcessScoped(_cid), - "begin_ns", static_cast(_ts), "pcid", _parent_cid, "cid", _cid, - "device", _device_id, "tid", _tid, "depth", _depth, "corr_id", _corr_id, - "args", hip_api_string(_api_id, data)); + [&](perfetto::EventContext ctx) { + if(config::get_perfetto_annotations()) + { + tracing::add_perfetto_annotation(ctx, "begin_ns", _ts); + tracing::add_perfetto_annotation(ctx, "pcid", _parent_cid); + tracing::add_perfetto_annotation(ctx, "device", _device_id); + tracing::add_perfetto_annotation(ctx, "tid", _tid); + tracing::add_perfetto_annotation(ctx, "depth", _depth); + tracing::add_perfetto_annotation(ctx, "corr_id", _corr_id); + tracing::add_perfetto_annotation(ctx, "args", + hip_api_string(_api_id, data)); + } + }); } if(get_use_timemory()) { @@ -739,8 +773,13 @@ hip_api_callback(uint32_t domain, uint32_t cid, const void* callback_data, void* if(get_use_perfetto()) { - tracing::pop_perfetto_ts(category::rocm_hip{}, op_name, _ts, "end_ns", - static_cast(_ts)); + tracing::pop_perfetto_ts( + category::rocm_hip{}, op_name, _ts, [&](perfetto::EventContext ctx) { + if(config::get_perfetto_annotations()) + { + tracing::add_perfetto_annotation(ctx, "end_ns", _ts); + } + }); } if(get_use_timemory()) { @@ -916,14 +955,33 @@ hip_activity_callback(const char* begin, const char* end, void*) assert(_end_ns >= _beg_ns); tracing::push_perfetto_ts( category::device_hip{}, _kernel_names.at(_name).c_str(), _beg_ns, - perfetto::Flow::ProcessScoped(_cid), "begin_ns", _beg_ns, "corr_id", - record->correlation_id, "device", _devid, "queue", _queid, "pid", - record->process_id, "tid", _tid, "op", _op_id_names.at(record->op)); - tracing::pop_perfetto_ts(category::device_hip{}, "", _end_ns, "end_ns", - _end_ns); + perfetto::Flow::ProcessScoped(_cid), [&](perfetto::EventContext ctx) { + if(config::get_perfetto_annotations()) + { + tracing::add_perfetto_annotation(ctx, "begin_ns", _beg_ns); + tracing::add_perfetto_annotation(ctx, "corr_id", _corr_id); + tracing::add_perfetto_annotation(ctx, "device", _devid); + tracing::add_perfetto_annotation(ctx, "queue", _queid); + tracing::add_perfetto_annotation(ctx, "tid", _tid); + tracing::add_perfetto_annotation(ctx, "op", + _op_id_names.at(record->op)); + } + }); + tracing::pop_perfetto_ts( + category::device_hip{}, "", _end_ns, [&](perfetto::EventContext ctx) { + if(config::get_perfetto_annotations()) + { + tracing::add_perfetto_annotation(ctx, "end_ns", _end_ns); + } + }); // for some reason, this is necessary to make sure very last one ends - tracing::pop_perfetto_ts(category::device_hip{}, "", _end_ns, "end_ns", - _end_ns); + tracing::pop_perfetto_ts( + category::device_hip{}, "", _end_ns, [&](perfetto::EventContext ctx) { + if(config::get_perfetto_annotations()) + { + tracing::add_perfetto_annotation(ctx, "end_ns", _end_ns); + } + }); } if(_critical_trace) diff --git a/source/lib/omnitrace/library/sampling.cpp b/source/lib/omnitrace/library/sampling.cpp index bbf580dda8..97f56596f4 100644 --- a/source/lib/omnitrace/library/sampling.cpp +++ b/source/lib/omnitrace/library/sampling.cpp @@ -823,7 +823,13 @@ post_process_perfetto(int64_t _tid, const bundle_t* _init, _init->get()->get_timestamp(), _beg_ns); tracing::push_perfetto_ts(category::sampling{}, "samples [omnitrace]", _beg_ns, - "begin_ns", _beg_ns); + [&](perfetto::EventContext ctx) { + if(config::get_perfetto_annotations()) + { + tracing::add_perfetto_annotation( + ctx, "begin_ns", _beg_ns); + } + }); auto _as_hex = [](auto _v) { return JOIN("", "0x", std::hex, _v); }; @@ -855,13 +861,24 @@ post_process_perfetto(int64_t _tid, const bundle_t* _init, tracing::push_perfetto_ts( category::sampling{}, _name, _beg, [&](perfetto::EventContext ctx) { - tracing::add_perfetto_annotation(ctx, "begin_ns", _beg); - tracing::add_perfetto_annotation(ctx, "lineinfo", _info); - tracing::add_perfetto_annotation(ctx, "inlined", - (_n++ > 0)); + if(config::get_perfetto_annotations()) + { + tracing::add_perfetto_annotation(ctx, "begin_ns", + _beg); + tracing::add_perfetto_annotation(ctx, "lineinfo", + _info); + tracing::add_perfetto_annotation(ctx, "inlined", + (_n++ > 0)); + } + }); + tracing::pop_perfetto_ts( + category::sampling{}, _name, _end, + [&](perfetto::EventContext ctx) { + if(config::get_perfetto_annotations()) + { + tracing::add_perfetto_annotation(ctx, "end_ns", _end); + } }); - tracing::pop_perfetto_ts(category::sampling{}, _name, _end, - "end_ns", _end); } } else @@ -870,38 +887,53 @@ post_process_perfetto(int64_t _tid, const bundle_t* _init, tracing::push_perfetto_ts( category::sampling{}, _name, _beg, [&](perfetto::EventContext ctx) { - tracing::add_perfetto_annotation(ctx, "begin_ns", _beg); - tracing::add_perfetto_annotation(ctx, "file", iitr.location); - tracing::add_perfetto_annotation(ctx, "pc", - _as_hex(iitr.address)); - tracing::add_perfetto_annotation(ctx, "line_address", - _as_hex(iitr.line_address)); - - if(iitr.lineinfo) + if(config::get_perfetto_annotations()) { - auto _lines = iitr.lineinfo.lines; - std::reverse(_lines.begin(), _lines.end()); - size_t _n = 0; - for(const auto& litr : _lines) + tracing::add_perfetto_annotation(ctx, "begin_ns", _beg); + tracing::add_perfetto_annotation(ctx, "file", + iitr.location); + tracing::add_perfetto_annotation(ctx, "pc", + _as_hex(iitr.address)); + tracing::add_perfetto_annotation( + ctx, "line_address", _as_hex(iitr.line_address)); + if(iitr.lineinfo) { - auto _label = JOIN('-', "lineinfo", _n++); - tracing::add_perfetto_annotation( - ctx, _label.c_str(), - JOIN('@', demangle(litr.name), - JOIN(':', litr.location, litr.line))); + auto _lines = iitr.lineinfo.lines; + std::reverse(_lines.begin(), _lines.end()); + size_t _n = 0; + for(const auto& litr : _lines) + { + auto _label = JOIN('-', "lineinfo", _n++); + tracing::add_perfetto_annotation( + ctx, _label.c_str(), + JOIN('@', demangle(litr.name), + JOIN(':', litr.location, litr.line))); + } } } }); - tracing::pop_perfetto_ts(category::sampling{}, _name, _end, "end_ns", - _end); + tracing::pop_perfetto_ts(category::sampling{}, _name, _end, + [&](perfetto::EventContext ctx) { + if(config::get_perfetto_annotations()) + { + tracing::add_perfetto_annotation( + ctx, "end_ns", _end); + } + }); } } _last_ts = _bt_ts->get_timestamp(); } tracing::pop_perfetto_ts(category::sampling{}, "samples [omnitrace]", _end_ns, - "end_ns", _end_ns); + [&](perfetto::EventContext ctx) { + if(config::get_perfetto_annotations()) + { + tracing::add_perfetto_annotation(ctx, "end_ns", + _end_ns); + } + }); }; auto _processing_thread = threading::get_tid(); diff --git a/source/lib/omnitrace/library/tracing.hpp b/source/lib/omnitrace/library/tracing.hpp index add14d7107..167e04abf7 100644 --- a/source/lib/omnitrace/library/tracing.hpp +++ b/source/lib/omnitrace/library/tracing.hpp @@ -31,9 +31,12 @@ #include "library/runtime.hpp" #include "library/sampling.hpp" #include "library/timemory.hpp" +#include "library/tracing/annotation.hpp" #include "library/utility.hpp" #include +#include +#include #include @@ -159,43 +162,43 @@ template inline void push_timemory(CategoryT, const char* name, Args&&... args) { - if(trait::runtime_enabled::get()) - { - auto& _data = tracing::get_instrumentation_bundles(); - // this generates a hash for the raw string array - auto _hash = tim::add_hash_id(tim::string_view_t{ name }); - auto* _bundle = _data.allocator.allocate(1); - _data.bundles.emplace_back(_bundle); - _data.allocator.construct(_bundle, _hash); - _bundle->start(std::forward(args)...); - } + // skip if category is disabled + if(!trait::runtime_enabled::get()) return; + + auto& _data = tracing::get_instrumentation_bundles(); + // this generates a hash for the raw string array + auto _hash = tim::add_hash_id(tim::string_view_t{ name }); + auto* _bundle = _data.allocator.allocate(1); + _data.bundles.emplace_back(_bundle); + _data.allocator.construct(_bundle, _hash); + _bundle->start(std::forward(args)...); } template inline void pop_timemory(CategoryT, const char* name, Args&&... args) { - if(trait::runtime_enabled::get()) + // skip if category is disabled + if(!trait::runtime_enabled::get()) return; + + auto _hash = tim::hash::get_hash_id(tim::string_view_t{ name }); + auto& _data = tracing::get_instrumentation_bundles(); + if(_data.bundles.empty()) { - auto _hash = tim::hash::get_hash_id(tim::string_view_t{ name }); - auto& _data = tracing::get_instrumentation_bundles(); - if(_data.bundles.empty()) + OMNITRACE_DEBUG("[%s] skipped %s :: empty bundle stack\n", "omnitrace_pop_trace", + name); + return; + } + for(size_t i = _data.bundles.size(); i > 0; --i) + { + auto*& _v = _data.bundles.at(i - 1); + if(_v->get_hash() == _hash) { - OMNITRACE_DEBUG("[%s] skipped %s :: empty bundle stack\n", - "omnitrace_pop_trace", name); - return; - } - for(size_t i = _data.bundles.size(); i > 0; --i) - { - auto*& _v = _data.bundles.at(i - 1); - if(_v->get_hash() == _hash) - { - _v->stop(std::forward(args)...); - _data.allocator.destroy(_v); - _data.allocator.deallocate(_v, 1); - _data.bundles.erase(_data.bundles.begin() + (i - 1)); - break; - } + _v->stop(std::forward(args)...); + _data.allocator.destroy(_v); + _data.allocator.deallocate(_v, 1); + _data.bundles.erase(_data.bundles.begin() + (i - 1)); + break; } } } @@ -204,24 +207,78 @@ template inline void push_perfetto(CategoryT, const char* name, Args&&... args) { + // skip if category is disabled + if(!trait::runtime_enabled::get()) return; + uint64_t _ts = comp::wall_clock::record(); - TRACE_EVENT_BEGIN(trait::name::value, perfetto::StaticString(name), _ts, - "begin_ns", _ts, std::forward(args)...); + if constexpr(sizeof...(Args) == 1 && + std::is_invocable::value) + { + if(config::get_perfetto_annotations()) + { + TRACE_EVENT_BEGIN(trait::name::value, perfetto::StaticString(name), + _ts, "begin_ns", _ts, std::forward(args)...); + } + else + { + TRACE_EVENT_BEGIN(trait::name::value, perfetto::StaticString(name), + _ts, std::forward(args)...); + } + } + else + { + TRACE_EVENT_BEGIN(trait::name::value, perfetto::StaticString(name), + _ts, std::forward(args)..., + [&](perfetto::EventContext ctx) { + if(config::get_perfetto_annotations()) + { + tracing::add_perfetto_annotation(ctx, "begin_ns", _ts); + } + }); + } } template inline void pop_perfetto(CategoryT, const char*, Args&&... args) { + // skip if category is disabled + if(!trait::runtime_enabled::get()) return; + uint64_t _ts = comp::wall_clock::record(); - TRACE_EVENT_END(trait::name::value, _ts, "end_ns", _ts, - std::forward(args)...); + if constexpr(sizeof...(Args) == 1 && + std::is_invocable::value) + { + if(config::get_perfetto_annotations()) + { + TRACE_EVENT_END(trait::name::value, _ts, "end_ns", _ts, + std::forward(args)...); + } + else + { + TRACE_EVENT_END(trait::name::value, _ts, + std::forward(args)...); + } + } + else + { + TRACE_EVENT_END(trait::name::value, _ts, std::forward(args)..., + [&](perfetto::EventContext ctx) { + if(config::get_perfetto_annotations()) + { + tracing::add_perfetto_annotation(ctx, "end_ns", _ts); + } + }); + } } template inline void push_perfetto_ts(CategoryT, const char* name, uint64_t _ts, Args&&... args) { + // skip if category is disabled + if(!trait::runtime_enabled::get()) return; + TRACE_EVENT_BEGIN(trait::name::value, perfetto::StaticString(name), _ts, std::forward(args)...); } @@ -230,6 +287,9 @@ template inline void pop_perfetto_ts(CategoryT, const char*, uint64_t _ts, Args&&... args) { + // skip if category is disabled + if(!trait::runtime_enabled::get()) return; + TRACE_EVENT_END(trait::name::value, _ts, std::forward(args)...); } } // namespace tracing diff --git a/source/lib/omnitrace/regions.cpp b/source/lib/omnitrace/regions.cpp new file mode 100644 index 0000000000..8a3b4a7d9e --- /dev/null +++ b/source/lib/omnitrace/regions.cpp @@ -0,0 +1,173 @@ +// MIT License +// +// Copyright (c) 2022 Advanced Micro Devices, Inc. All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#include "api.hpp" +#include "library/categories.hpp" +#include "library/components/category_region.hpp" +#include "library/config.hpp" +#include "library/tracing.hpp" + +#if defined(__GNUC__) && (__GNUC__ == 7) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif + +namespace omnitrace +{ +namespace impl +{ +namespace +{ +template +void +invoke_category_region_start(omnitrace_category_t _category, const char* name, + omnitrace_annotation_t* _annotations, + size_t _annotation_count, std::index_sequence) +{ + static_assert(Idx > OMNITRACE_CATEGORY_NONE && Idx < OMNITRACE_CATEGORY_LAST, + "Error! index sequence should only contain values which are greater " + "than OMNITRACE_CATEGORY_NONE and less than OMNITRACE_CATEGORY_LAST"); + + if(_category == Idx) + { + using category_type = category_type_id_t; + + // skip if category is disabled + if(!trait::runtime_enabled::get()) return; + + component::category_region::start( + name, [&](::perfetto::EventContext ctx) { + if(_annotations && config::get_perfetto_annotations()) + { + for(size_t i = 0; i < _annotation_count; ++i) + tracing::add_perfetto_annotation(ctx, _annotations[i]); + } + }); + } + else + { + constexpr size_t remaining = sizeof...(Tail); + if constexpr(remaining > 0) + invoke_category_region_start(_category, name, _annotations, _annotation_count, + std::index_sequence{}); + } +} + +template +void +invoke_category_region_stop(omnitrace_category_t _category, const char* name, + omnitrace_annotation_t* _annotations, + size_t _annotation_count, std::index_sequence) +{ + static_assert(Idx > OMNITRACE_CATEGORY_NONE && Idx < OMNITRACE_CATEGORY_LAST, + "Error! index sequence should only contain values which are greater " + "than OMNITRACE_CATEGORY_NONE and less than OMNITRACE_CATEGORY_LAST"); + + if(_category == Idx) + { + using category_type = category_type_id_t; + + // skip if category is disabled + if(!trait::runtime_enabled::get()) return; + + component::category_region::stop( + name, [&](::perfetto::EventContext ctx) { + if(_annotations && config::get_perfetto_annotations()) + { + for(size_t i = 0; i < _annotation_count; ++i) + tracing::add_perfetto_annotation(ctx, _annotations[i]); + } + }); + } + else + { + constexpr size_t remaining = sizeof...(Tail); + if constexpr(remaining > 0) + invoke_category_region_stop(_category, name, _annotations, _annotation_count, + std::index_sequence{}); + } +} +} // namespace +} // namespace impl +} // namespace omnitrace + +//======================================================================================// + +extern "C" void +omnitrace_push_trace_hidden(const char* name) +{ + omnitrace::component::category_region::start(name); +} + +extern "C" void +omnitrace_pop_trace_hidden(const char* name) +{ + omnitrace::component::category_region::stop(name); +} + +//======================================================================================// +/// +/// +/// +//======================================================================================// + +extern "C" void +omnitrace_push_region_hidden(const char* name) +{ + omnitrace::component::category_region::start(name); +} + +extern "C" void +omnitrace_pop_region_hidden(const char* name) +{ + omnitrace::component::category_region::stop(name); +} + +//======================================================================================// +/// +/// +/// +//======================================================================================// + +extern "C" void +omnitrace_push_category_region_hidden(omnitrace_category_t _category, const char* name, + omnitrace_annotation_t* _annotations, + size_t _annotation_count) +{ + omnitrace::impl::invoke_category_region_start( + _category, name, _annotations, _annotation_count, + omnitrace::utility::make_index_sequence_range<1, OMNITRACE_CATEGORY_LAST>{}); +} + +extern "C" void +omnitrace_pop_category_region_hidden(omnitrace_category_t _category, const char* name, + omnitrace_annotation_t* _annotations, + size_t _annotation_count) +{ + omnitrace::impl::invoke_category_region_stop( + _category, name, _annotations, _annotation_count, + omnitrace::utility::make_index_sequence_range<1, OMNITRACE_CATEGORY_LAST>{}); +} + +#if defined(__GNUC__) && (__GNUC__ == 7) +# pragma GCC diagnostic pop +#endif