ROCpd support [Part 2] (#109)
* Rocpd part 2, caching * Fix shadowed variables * backward compatibility * Fixed designated initializers * Fix timemory include * Remove benchmark & Fix build issues for rhel * Add missing bracket * Fix shadowing and pedantic * Fix pedantic pt2 * Fix duplicated SDK calls * Add decay in get_size_impl * Rename sample cache to trace cache * Add cache storage supported types * Resolving track naming in sampling module * fix sampling of flushing thread * fix sampling of flushing thread 2 * throw exception upon store while buffer storage is not running * Prevent fork crashing * Fix rebase issue * Applied suggestions from code review * Change flushing thread to use PTL * Fix agent creation order * Fix stream id ci throw * Remove force setup of rocprofiler-sdk * Code cleanup * Change initialization for agent * Add missing namespace * Fix the mismatch within the tool_agent->device_id * Switch from using handle to use agent type index * Fix pmc info comparator in metadata registry --------- Co-authored-by: Aleksandar <aleksandar.djordjevic@amd.com> Co-authored-by: Milan Radosavljevic <milan.radosavljevic@amd.com> Co-authored-by: Marjan Antic <marantic@amd.com>
This commit is contained in:
committed by
GitHub
parent
351d598869
commit
1f86010ca2
@@ -31,13 +31,13 @@
|
||||
#include "core/rocpd/data_processor.hpp"
|
||||
#include "core/rocpd/json.hpp"
|
||||
#include "core/state.hpp"
|
||||
#include "core/trace_cache/cache_manager.hpp"
|
||||
#include "core/utility.hpp"
|
||||
#include "library/components/backtrace.hpp"
|
||||
#include "library/components/backtrace_metrics.hpp"
|
||||
#include "library/components/backtrace_timestamp.hpp"
|
||||
#include "library/components/callchain.hpp"
|
||||
#include "library/perf.hpp"
|
||||
#include "library/ptl.hpp"
|
||||
#include "library/runtime.hpp"
|
||||
#include "library/thread_data.hpp"
|
||||
#include "library/thread_info.hpp"
|
||||
@@ -59,6 +59,7 @@
|
||||
#include <timemory/mpl/quirks.hpp>
|
||||
#include <timemory/mpl/type_traits.hpp>
|
||||
#include <timemory/operations.hpp>
|
||||
#include <timemory/process/threading.hpp>
|
||||
#include <timemory/sampling/allocator.hpp>
|
||||
#include <timemory/sampling/overflow.hpp>
|
||||
#include <timemory/sampling/sampler.hpp>
|
||||
@@ -83,6 +84,7 @@
|
||||
#include <regex>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
|
||||
#include <pthread.h>
|
||||
@@ -227,46 +229,65 @@ get_data_processor()
|
||||
return rocpd::data_processor::get_instance();
|
||||
}
|
||||
|
||||
template <typename Category>
|
||||
std::string
|
||||
get_track_name(const thread_info& _thread_info)
|
||||
{
|
||||
size_t thread_id = _thread_info.index_data->system_value;
|
||||
size_t sequent_value = _thread_info.index_data->sequent_value;
|
||||
constexpr auto sample_type =
|
||||
std::is_same_v<Category, category::timer_sampling> ? "Timer" : "Overflow";
|
||||
return JOIN(" ", "Thread", sequent_value, sample_type, "(S)", thread_id);
|
||||
}
|
||||
|
||||
void
|
||||
rocpd_initialize_sampling_category()
|
||||
{
|
||||
static bool _is_initialized = false;
|
||||
if(_is_initialized) return;
|
||||
|
||||
auto& data_processor = get_data_processor();
|
||||
data_processor.insert_category(ROCPROFSYS_CATEGORY_SAMPLING,
|
||||
trait::name<category::sampling>::value);
|
||||
data_processor.insert_category(ROCPROFSYS_CATEGORY_OVERFLOW_SAMPLING,
|
||||
trait::name<category::overflow_sampling>::value);
|
||||
data_processor.insert_category(ROCPROFSYS_CATEGORY_TIMER_SAMPLING,
|
||||
trait::name<category::timer_sampling>::value);
|
||||
trace_cache::get_metadata_registry().add_string(
|
||||
trait::name<category::sampling>::value);
|
||||
trace_cache::get_metadata_registry().add_string(
|
||||
trait::name<category::overflow_sampling>::value);
|
||||
trace_cache::get_metadata_registry().add_string(
|
||||
trait::name<category::timer_sampling>::value);
|
||||
|
||||
_is_initialized = true;
|
||||
}
|
||||
|
||||
size_t
|
||||
void
|
||||
rocpd_initialize_thread_info(size_t tid)
|
||||
{
|
||||
const auto& _thread_info = thread_info::get(tid, SequentTID);
|
||||
ROCPROFSYS_CI_THROW(!_thread_info, "No valid thread info for tid=%li\n", tid);
|
||||
if(!_thread_info) return -1;
|
||||
if(!_thread_info) return;
|
||||
|
||||
auto& data_processor = get_data_processor();
|
||||
auto& n_info = node_info::get_instance();
|
||||
|
||||
return data_processor.insert_thread_info(
|
||||
n_info.id, getppid(), getpid(), _thread_info->index_data->system_value,
|
||||
threading::get_thread_name().c_str(), _thread_info->get_start(),
|
||||
_thread_info->get_stop(), "{}");
|
||||
trace_cache::get_metadata_registry().add_thread_info(
|
||||
{ getppid(), getpid(),
|
||||
static_cast<size_t>(_thread_info->index_data->system_value),
|
||||
static_cast<uint32_t>(_thread_info->get_start()),
|
||||
static_cast<uint32_t>(_thread_info->get_stop()), "{}" });
|
||||
}
|
||||
|
||||
void
|
||||
rocpd_init_track(const char* track_name, int64_t tid)
|
||||
rocpd_init_track(int64_t tid)
|
||||
{
|
||||
auto& data_processor = get_data_processor();
|
||||
auto& n_info = node_info::get_instance();
|
||||
const auto& _thread_info = thread_info::get(tid, SequentTID);
|
||||
ROCPROFSYS_CI_THROW(!_thread_info, "No valid thread info for tid=%li\n", tid);
|
||||
if(!_thread_info) return;
|
||||
|
||||
data_processor.insert_track(track_name, n_info.id, getpid(), tid, "{}");
|
||||
size_t thread_id = _thread_info->index_data->system_value;
|
||||
|
||||
const auto& _timer_track_name =
|
||||
get_track_name<category::timer_sampling>(*_thread_info);
|
||||
const auto& _overflow_track_name =
|
||||
get_track_name<category::overflow_sampling>(*_thread_info);
|
||||
|
||||
trace_cache::get_metadata_registry().add_track(
|
||||
{ _timer_track_name, thread_id, "{}" });
|
||||
trace_cache::get_metadata_registry().add_track(
|
||||
{ _overflow_track_name, thread_id, "{}" });
|
||||
}
|
||||
|
||||
template <typename Category>
|
||||
@@ -275,11 +296,12 @@ rocpd_insert_region(size_t thread_id, size_t start_time, size_t end_time, size_t
|
||||
const char* track, const char* call_stack = "{}",
|
||||
const char* line_info = "{}", const char* extdata = "{}")
|
||||
{
|
||||
auto& data_processor = get_data_processor();
|
||||
auto& n_info = node_info::get_instance();
|
||||
auto& data_processor = get_data_processor();
|
||||
auto& n_info = node_info::get_instance();
|
||||
auto string_primary_key = data_processor.insert_string(trait::name<Category>::value);
|
||||
|
||||
auto event_id = data_processor.insert_event(category_enum_id<Category>::value, 0, 0,
|
||||
0, call_stack, line_info, extdata);
|
||||
auto event_id = data_processor.insert_event(string_primary_key, 0, 0, 0, call_stack,
|
||||
line_info, extdata);
|
||||
|
||||
data_processor.insert_region(n_info.id, getpid(), thread_id, start_time, end_time,
|
||||
name_id, event_id);
|
||||
@@ -849,6 +871,9 @@ configure(bool _setup, int64_t _tid)
|
||||
}
|
||||
}
|
||||
}
|
||||
rocpd_initialize_sampling_category();
|
||||
rocpd_initialize_thread_info(_tid);
|
||||
rocpd_init_track(_tid);
|
||||
|
||||
*_running = true;
|
||||
sampling::get_sampler_init(_tid)->sample();
|
||||
@@ -1403,7 +1428,7 @@ post_process_perfetto(int64_t _tid, const std::vector<timer_sampling_data>& _tim
|
||||
{
|
||||
auto _ncur = _ncount++;
|
||||
// the begin/end + HW counters will be same for entire call-stack so only
|
||||
// annotate the top and the bottom functons to keep the data consumption
|
||||
// annotate the top and the bottom functions to keep the data consumption
|
||||
// low
|
||||
bool _include_common = (_ncur == 0 || _ncur + 1 == itr.m_stack.size());
|
||||
|
||||
@@ -1707,14 +1732,14 @@ rocpd_post_process_overflow_data(
|
||||
.first->c_str();
|
||||
auto main_name_id = data_processor.insert_string(_main_name);
|
||||
|
||||
const auto& _track_name =
|
||||
JOIN(" ", "Thread", _thread_info->index_data->sequent_value, "Overflow",
|
||||
"(S)", _thread_info->index_data->system_value);
|
||||
size_t thread_id = _thread_info->index_data->system_value;
|
||||
|
||||
auto thread_primary_key = data_processor.map_thread_id_to_primary_key(thread_id);
|
||||
const auto _track_name =
|
||||
get_track_name<category::overflow_sampling>(*_thread_info);
|
||||
|
||||
auto thread_idx = rocpd_initialize_thread_info(_tid);
|
||||
rocpd_init_track(_track_name.c_str(), thread_idx);
|
||||
rocpd_insert_region<category::overflow_sampling>(
|
||||
thread_idx, _beg_ns, _end_ns, main_name_id, _track_name.c_str());
|
||||
thread_primary_key, _beg_ns, _end_ns, main_name_id, _track_name.c_str());
|
||||
|
||||
for(const auto& itr : _overflow_data)
|
||||
{
|
||||
@@ -1729,7 +1754,7 @@ rocpd_post_process_overflow_data(
|
||||
static_strings.emplace(demangle(iitr.name)).first->c_str();
|
||||
auto name_id = data_processor.insert_string(_name);
|
||||
rocpd_insert_region<category::overflow_sampling>(
|
||||
thread_idx, _beg, _end, name_id, _track_name.c_str(),
|
||||
thread_primary_key, _beg, _end, name_id, _track_name.c_str(),
|
||||
generate_call_stack_json(iitr).c_str(),
|
||||
generate_line_info_json(iitr).c_str());
|
||||
}
|
||||
@@ -1738,9 +1763,11 @@ rocpd_post_process_overflow_data(
|
||||
}
|
||||
|
||||
void
|
||||
rocpd_post_process_backtrace_metrics(int64_t _tid,
|
||||
const std::vector<timer_sampling_data>& _timer_data)
|
||||
rocpd_post_process_backtrace_metrics(
|
||||
[[maybe_unused]] int64_t _tid,
|
||||
[[maybe_unused]] const std::vector<timer_sampling_data>& _timer_data)
|
||||
{
|
||||
#if ROCPROFSYS_USE_ROCM > 0
|
||||
auto _valid_metrics = backtrace_metrics::valid_array_t{};
|
||||
|
||||
for(const auto& itr : _timer_data)
|
||||
@@ -1752,17 +1779,20 @@ rocpd_post_process_backtrace_metrics(int64_t _ti
|
||||
{
|
||||
ROCPROFSYS_VERBOSE(3 || get_debug_sampling(),
|
||||
"[%li] Post-processing metrics for rocpd...\n", _tid);
|
||||
backtrace_metrics::init_rocpd(_tid, _valid_metrics);
|
||||
backtrace_metrics::init_rocpd(_tid, _valid_metrics); // move to setup
|
||||
for(const auto& itr : _timer_data)
|
||||
itr.m_metrics.post_process_rocpd(_tid, 0.5 * (itr.m_beg + itr.m_end));
|
||||
backtrace_metrics::fini_rocpd(_tid, _valid_metrics);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
rocpd_post_process_timer_data(int64_t _tid,
|
||||
const std::vector<timer_sampling_data>& _timer_data)
|
||||
rocpd_post_process_timer_data(
|
||||
[[maybe_unused]] int64_t _tid,
|
||||
[[maybe_unused]] const std::vector<timer_sampling_data>& _timer_data)
|
||||
{
|
||||
#if ROCPROFSYS_USE_ROCM > 0
|
||||
auto& data_processor = get_data_processor();
|
||||
|
||||
const auto& _thread_info = thread_info::get(_tid, SequentTID);
|
||||
@@ -1776,15 +1806,14 @@ rocpd_post_process_timer_data(int64_t _tid,
|
||||
auto _beg_ns = std::max(_timer_data.front().m_beg, _thread_info->get_start());
|
||||
auto _end_ns = std::min(_timer_data.back().m_end, _thread_info->get_stop());
|
||||
|
||||
const auto _track_name =
|
||||
JOIN(" ", "Thread", _thread_info->index_data->sequent_value, "(S)",
|
||||
_thread_info->index_data->system_value);
|
||||
const auto _track_name = get_track_name<category::timer_sampling>(*_thread_info);
|
||||
|
||||
auto thread_primary_key = data_processor.map_thread_id_to_primary_key(
|
||||
_thread_info->index_data->system_value);
|
||||
|
||||
auto thread_idx = rocpd_initialize_thread_info(_tid);
|
||||
rocpd_init_track(_track_name.c_str(), thread_idx);
|
||||
const auto main_name_id = data_processor.insert_string("samples [rocprof-sys]");
|
||||
rocpd_insert_region<category::timer_sampling>(thread_idx, _beg_ns, _end_ns,
|
||||
main_name_id, _track_name.c_str());
|
||||
rocpd_insert_region<category::timer_sampling>(
|
||||
thread_primary_key, _beg_ns, _end_ns, main_name_id, _track_name.c_str());
|
||||
|
||||
auto _labels = backtrace_metrics::get_hw_counter_labels(_tid);
|
||||
for(const auto& itr : _timer_data)
|
||||
@@ -1798,7 +1827,7 @@ rocpd_post_process_timer_data(int64_t _tid,
|
||||
{
|
||||
auto _ncur = _ncount++;
|
||||
// the begin/end + HW counters will be same for entire call-stack so only
|
||||
// annotate the top and the bottom functons to keep the data consumption
|
||||
// annotate the top and the bottom functions to keep the data consumption
|
||||
// low
|
||||
bool _include_common = (_ncur == 0 || _ncur + 1 == itr.m_stack.size());
|
||||
|
||||
@@ -1832,8 +1861,9 @@ rocpd_post_process_timer_data(int64_t _tid,
|
||||
inlined_call_stack->set("inlined", "true");
|
||||
|
||||
rocpd_insert_region<category::timer_sampling>(
|
||||
thread_idx, _beg, _end, inlined_name_id, _track_name.c_str(),
|
||||
inlined_call_stack->to_string().c_str(), "{}",
|
||||
thread_primary_key, _beg, _end, inlined_name_id,
|
||||
_track_name.c_str(), inlined_call_stack->to_string().c_str(),
|
||||
"{}",
|
||||
// Only include HW counters for first inlined function
|
||||
(_n == 0) ? hw_counter_json.c_str() : "{}");
|
||||
}
|
||||
@@ -1843,22 +1873,28 @@ rocpd_post_process_timer_data(int64_t _tid,
|
||||
const auto* _name = static_strings.emplace(iitr.name).first->c_str();
|
||||
const auto name_id = data_processor.insert_string(_name);
|
||||
rocpd_insert_region<category::timer_sampling>(
|
||||
thread_idx, _beg, _end, name_id, _track_name.c_str(),
|
||||
thread_primary_key, _beg, _end, name_id, _track_name.c_str(),
|
||||
generate_call_stack_json(iitr).c_str(),
|
||||
generate_line_info_json(iitr).c_str(), hw_counter_json.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
post_process_rocpd(int64_t _tid, const std::vector<timer_sampling_data>& _timer_data,
|
||||
const std::vector<overflow_sampling_data>& _overflow_data)
|
||||
{
|
||||
rocpd_initialize_sampling_category();
|
||||
#if ROCPROFSYS_USE_ROCM > 0
|
||||
rocpd_post_process_overflow_data(_tid, _overflow_data);
|
||||
rocpd_post_process_timer_data(_tid, _timer_data);
|
||||
#else
|
||||
(void) _tid;
|
||||
(void) _timer_data;
|
||||
(void) _overflow_data;
|
||||
#endif
|
||||
}
|
||||
|
||||
struct sampling_initialization
|
||||
|
||||
Reference in New Issue
Block a user