Callback tracing for kernel dispatches + External correlation ID request service (#682)

* Support ROCPROFILER_CALLBACK_TRACING_KERNEL_DISPATCH

* Fix doxygen

* Update callback tracing

- temporary hacks for kind operation name and iterate kind operations

* Update source/include/rocprofiler-sdk

- introduce sequence id for kernel dispatches

* Update lib/rocprofiler-sdk (seq id)

- support sequence id passing

* Update tests (seq id)

- testing for sequence ids

* Cleanup include/rocprofiler-sdk/fwd.h

* Misc cleanup

* External Correlation ID Request Service (#699)

* External correlation ID request service

- callback requesting an external correlation ID instead of fetching from top of pushed external correlation ID stack

* Update external correlation id request support

- pass internal correlation ID in callback
- async copy generates a correlation ID if none already exists
- added external correlation ID request support for scratch memory tracing
- updated scratch memory tracing to use tracing:: functions

* Update hsa/queue.hpp

- new line at EOF

* Misc tweaks

- remove unnecessary logging in agent.cpp
- correlation_id::add_ref_count check for retirement
- finalization check in HSA queue AsyncSignalHandler

* Improve assertion failure logging in misc tests

* Update include/rocprofiler-sdk/fwd.h

- remove rocprofiler_record_counter_header_t

* Move lib/rocprofiler-sdk/tracing.hpp into lib/rocprofiler-sdk/tracing/ folder

* Update lib/rocprofiler-sdk/hsa/*

- hsa::get_hsa_status_string
- queue_info_session.hpp header
- rocprofiler_packet.hpp

* Update lib/rocprofiler-sdk/{counters,hip,marker}

- execute_phase_exit_callbacks tweaks
- queue_info_session tweaks

* Move rocprofiler_kernel_dispatch_operation_t to include/rocprofiler-sdk/fwd.h

* Update rocprofiler_buffer_tracing_kernel_dispatch_record_t

- add operation field and thread_id field

* Add lib/rocprofiler-sdk/kernel_dispatch

- enum <-> string mapping for kernel dispatch
- tracing implementations

* Update lib/rocprofiler-sdk/CMakeLists.txt

- tracing and kernel dispatch sub-directories

* Update lib/rocprofiler-sdk/{buffer,callback}_tracing.cpp

- invoke rocprofiler::kernel_tracing functions

* Update tests/common/serialization.hpp

- support operation and thread_id fields for rocprofiler_buffer_tracing_kernel_dispatch_record_t

* Update tests/tools/json-tool.cpp

- use external correlation id request service

* Rename sequence_id to dispatch_id
This commit is contained in:
Jonathan R. Madsen
2024-04-11 19:49:49 -05:00
committed by GitHub
parent 0f5c575435
commit 56030018dc
46 changed files with 2297 additions and 955 deletions
+49 -138
View File
@@ -29,6 +29,7 @@
#include "lib/rocprofiler-sdk/hip/types.hpp"
#include "lib/rocprofiler-sdk/hip/utils.hpp"
#include "lib/rocprofiler-sdk/registration.hpp"
#include "lib/rocprofiler-sdk/tracing/tracing.hpp"
#include <rocprofiler-sdk/buffer.h>
#include <rocprofiler-sdk/callback_tracing.h>
@@ -179,57 +180,6 @@ hip_api_impl<TableIdx, OpIdx>::exec(FuncT&& _func, Args&&... args)
return get_default_retval<return_type>();
}
namespace
{
using correlation_service = context::correlation_tracing_service;
struct callback_context_data
{
const context::context* ctx = nullptr;
rocprofiler_callback_tracing_record_t record = {};
rocprofiler_user_data_t user_data = {.value = 0};
};
struct buffered_context_data
{
const context::context* ctx = nullptr;
rocprofiler_user_data_t external_correlation = {};
};
constexpr auto empty_user_data = rocprofiler_user_data_t{.value = 0};
void
populate_contexts(rocprofiler_callback_tracing_kind_t callback_domain_idx,
rocprofiler_buffer_tracing_kind_t buffered_domain_idx,
int operation_idx,
std::vector<callback_context_data>& callback_contexts,
std::vector<buffered_context_data>& buffered_contexts)
{
auto active_contexts = context::context_array_t{};
auto thr_id = common::get_tid();
for(const auto* itr : context::get_active_contexts(active_contexts))
{
if(!itr) continue;
if(itr->callback_tracer)
{
// if the given domain + op is not enabled, skip this context
if(itr->callback_tracer->domains(callback_domain_idx, operation_idx))
callback_contexts.emplace_back(
callback_context_data{itr, rocprofiler_callback_tracing_record_t{}});
}
if(itr->buffered_tracer)
{
// if the given domain + op is not enabled, skip this context
if(itr->buffered_tracer->domains(buffered_domain_idx, operation_idx))
buffered_contexts.emplace_back(buffered_context_data{
itr, itr->correlation_tracer.external_correlator.get(thr_id)});
}
}
}
} // namespace
template <size_t TableIdx, size_t OpIdx>
template <typename RetT, typename... Args>
RetT
@@ -239,17 +189,23 @@ hip_api_impl<TableIdx, OpIdx>::functor(Args... args)
using callback_api_data_t = typename hip_domain_info<TableIdx>::callback_data_type;
using buffered_api_data_t = typename hip_domain_info<TableIdx>::buffered_data_type;
constexpr auto external_corr_id_domain_idx =
hip_domain_info<TableIdx>::external_correlation_id_domain_idx;
LOG_IF(INFO, registration::get_fini_status() != 0) << "Executing " << info_type::name;
auto thr_id = common::get_tid();
auto callback_contexts = std::vector<callback_context_data>{};
auto buffered_contexts = std::vector<buffered_context_data>{};
constexpr auto ref_count = 2;
auto thr_id = common::get_tid();
auto callback_contexts = tracing::callback_context_data_vec_t{};
auto buffered_contexts = tracing::buffered_context_data_vec_t{};
auto external_corr_ids = tracing::external_correlation_id_map_t{};
populate_contexts(info_type::callback_domain_idx,
info_type::buffered_domain_idx,
info_type::operation_idx,
callback_contexts,
buffered_contexts);
tracing::populate_contexts(info_type::callback_domain_idx,
info_type::buffered_domain_idx,
info_type::operation_idx,
callback_contexts,
buffered_contexts,
external_corr_ids);
if(callback_contexts.empty() && buffered_contexts.empty())
{
@@ -260,25 +216,19 @@ hip_api_impl<TableIdx, OpIdx>::functor(Args... args)
return;
}
constexpr auto ref_count = 2;
auto buffer_record = common::init_public_api_struct(buffered_api_data_t{});
auto tracer_data = common::init_public_api_struct(callback_api_data_t{});
auto* corr_id = correlation_service::construct(ref_count);
auto internal_corr_id = corr_id->internal;
LOG_IF(FATAL, external_corr_ids.size() < (callback_contexts.size() + buffered_contexts.size()))
<< "missing external correlation ids";
// construct the buffered info before the callback so the callbacks are as closely wrapped
// around the function call as possible
if(!buffered_contexts.empty())
{
buffer_record.kind = info_type::buffered_domain_idx;
// external correlation will be updated right before record is placed in buffer
buffer_record.correlation_id =
rocprofiler_correlation_id_t{internal_corr_id, empty_user_data};
buffer_record.operation = info_type::operation_idx;
buffer_record.thread_id = thr_id;
}
auto buffer_record = common::init_public_api_struct(buffered_api_data_t{});
auto tracer_data = common::init_public_api_struct(callback_api_data_t{});
auto* corr_id = tracing::correlation_service::construct(ref_count);
auto internal_corr_id = corr_id->internal;
tracer_data.size = sizeof(callback_api_data_t);
tracing::populate_external_correlation_ids(external_corr_ids,
thr_id,
external_corr_id_domain_idx,
info_type::operation_idx,
internal_corr_id);
// invoke the callbacks
if(!callback_contexts.empty())
@@ -286,42 +236,22 @@ hip_api_impl<TableIdx, OpIdx>::functor(Args... args)
set_data_args(info_type::get_api_data_args(tracer_data.args),
convert_arg_type(std::forward<Args>(args))...);
for(auto& itr : callback_contexts)
{
auto& ctx = itr.ctx;
auto& record = itr.record;
auto& user_data = itr.user_data;
auto extern_corr_id_v = ctx->correlation_tracer.external_correlator.get(thr_id);
auto corr_id_v = rocprofiler_correlation_id_t{internal_corr_id, extern_corr_id_v};
record =
rocprofiler_callback_tracing_record_t{rocprofiler_context_id_t{ctx->context_idx},
thr_id,
corr_id_v,
info_type::callback_domain_idx,
info_type::operation_idx,
ROCPROFILER_CALLBACK_PHASE_ENTER,
static_cast<void*>(&tracer_data)};
auto& callback_info =
ctx->callback_tracer->callback_data.at(info_type::callback_domain_idx);
callback_info.callback(record, &user_data, callback_info.data);
// enter callback may update the external correlation id field
record.correlation_id.external =
ctx->correlation_tracer.external_correlator.get(thr_id);
}
tracing::execute_phase_enter_callbacks(callback_contexts,
thr_id,
internal_corr_id,
external_corr_ids,
info_type::callback_domain_idx,
info_type::operation_idx,
tracer_data);
}
// enter callback may update the external correlation id field
tracing::update_external_correlation_ids(
external_corr_ids, thr_id, external_corr_id_domain_idx);
// record the start timestamp as close to the function call as possible
if(!buffered_contexts.empty())
{
for(auto& itr : buffered_contexts)
{
itr.external_correlation = itr.ctx->correlation_tracer.external_correlator.get(thr_id);
}
buffer_record.start_timestamp = common::timestamp_ns();
}
@@ -340,41 +270,22 @@ hip_api_impl<TableIdx, OpIdx>::functor(Args... args)
{
set_data_retval(tracer_data.retval, _ret);
for(auto& itr : callback_contexts)
{
auto& ctx = itr.ctx;
auto& record = itr.record;
auto& user_data = itr.user_data;
record.phase = ROCPROFILER_CALLBACK_PHASE_EXIT;
record.payload = static_cast<void*>(&tracer_data);
auto& callback_info =
ctx->callback_tracer->callback_data.at(info_type::callback_domain_idx);
callback_info.callback(record, &user_data, callback_info.data);
}
tracing::execute_phase_exit_callbacks(callback_contexts,
external_corr_ids,
info_type::callback_domain_idx,
info_type::operation_idx,
tracer_data);
}
if(!buffered_contexts.empty())
{
for(auto& itr : buffered_contexts)
{
assert(itr.ctx->buffered_tracer);
auto buffer_id =
itr.ctx->buffered_tracer->buffer_data.at(info_type::buffered_domain_idx);
auto buffer_v = buffer::get_buffer(buffer_id);
if(buffer_v && buffer_v->context_id == itr.ctx->context_idx &&
buffer_v->buffer_id == buffer_id.handle)
{
// make copy of record
auto record_v = buffer_record;
// update the record with the correlation
record_v.correlation_id.external = itr.external_correlation;
buffer_v->emplace(
ROCPROFILER_BUFFER_CATEGORY_TRACING, info_type::buffered_domain_idx, record_v);
}
}
tracing::execute_buffer_record_emplace(buffered_contexts,
thr_id,
internal_corr_id,
external_corr_ids,
info_type::buffered_domain_idx,
info_type::operation_idx,
buffer_record);
}
// decrement the reference count after usage in the callback/buffers