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>
Dieser Commit ist enthalten in:
systems-assistant[bot]
2025-08-19 22:01:04 -04:00
committet von GitHub
Ursprung 351d598869
Commit 1f86010ca2
40 geänderte Dateien mit 3432 neuen und 1184 gelöschten Zeilen
@@ -44,6 +44,7 @@
#include "core/perfetto_fwd.hpp"
#include "core/rocpd/data_processor.hpp"
#include "core/timemory.hpp"
#include "core/trace_cache/cache_manager.hpp"
#include "core/utility.hpp"
#include "library/causal/data.hpp"
#include "library/causal/experiment.hpp"
@@ -328,37 +329,17 @@ read_command_line(pid_t _pid)
}
void
rocprofsys_preinit_rocpd()
rocprofsys_preinit_cache()
{
auto& _data_processor = rocpd::data_processor::get_instance();
const auto& _n_info = node_info::get_instance();
auto _cmd_line = read_command_line(getpid());
auto& _agent_manager = agent_manager::get_instance();
auto _cmd_line = read_command_line(getpid());
if(_cmd_line.empty())
{
_cmd_line.emplace_back("rocprofiler-systems");
}
_data_processor.insert_node_info(
_n_info.id, _n_info.hash, _n_info.machine_id.c_str(), _n_info.system_name.c_str(),
_n_info.node_name.c_str(), _n_info.release.c_str(), _n_info.version.c_str(),
_n_info.machine.c_str(), _n_info.domain_name.c_str());
_data_processor.insert_process_info(_n_info.id, getppid(), getpid(), 0, 0, 0, 0,
_cmd_line[0].c_str(), "{}");
const auto& agents = _agent_manager.get_agents();
for(const auto& rocpd_agent : agents)
{
auto _base_id = rocpd::data_processor::get_instance().insert_agent(
_n_info.id, getpid(),
((rocpd_agent->type == agent_type::GPU) ? "GPU" : "CPU"),
rocpd_agent->node_id, rocpd_agent->logical_node_id,
rocpd_agent->logical_node_type_id, rocpd_agent->id, rocpd_agent->name.c_str(),
rocpd_agent->model_name.c_str(), rocpd_agent->vendor_name.c_str(),
rocpd_agent->product_name.c_str(), "");
rocpd_agent->base_id = _base_id;
}
trace_cache::get_metadata_registry().set_process(
{ getpid(), getppid(), _cmd_line.at(0) });
}
void
@@ -534,7 +515,7 @@ rocprofsys_init_tooling_hidden(void)
#if !(ROCPROFSYS_USE_ROCM > 0)
rocprofsys_preinit_cpu_agents();
#endif
if(get_use_rocpd()) rocprofsys_preinit_rocpd();
rocprofsys_preinit_cache();
if(get_use_process_sampling())
{
@@ -776,10 +757,16 @@ rocprofsys_finalize_hidden(void)
rocprofiler_sdk::shutdown();
}
#endif
auto& _manager = rocprofsys::trace_cache::cache_manager::get_instance();
_manager.shutdown();
_manager.post_process();
#if ROCPROFSYS_USE_ROCM > 0
if(get_use_rocpd())
{
rocpd::data_processor::get_instance().flush();
}
#endif
set_state(State::Finalized);
std::quick_exit(EXIT_SUCCESS);
return;
@@ -880,6 +867,12 @@ rocprofsys_finalize_hidden(void)
}
#endif
{
auto& _manager = rocprofsys::trace_cache::cache_manager::get_instance();
_manager.shutdown();
_manager.post_process();
}
ROCPROFSYS_DEBUG_F("Stopping and destroying instrumentation bundles...\n");
for(size_t i = 0; i < thread_info::get_peak_num_threads(); ++i)
{
@@ -1070,10 +1063,12 @@ rocprofsys_finalize_hidden(void)
[](int) {});
common::destroy_static_objects();
#if ROCPROFSYS_USE_ROCM > 0
if(get_use_rocpd())
{
rocpd::data_processor::get_instance().flush();
}
#endif
}
//======================================================================================//
@@ -27,6 +27,8 @@
// THE SOFTWARE.
#include "core/agent.hpp"
#include "core/trace_cache/cache_manager.hpp"
#include "core/trace_cache/cache_utility.hpp"
#if defined(NDEBUG)
# undef NDEBUG
#endif
@@ -41,6 +43,7 @@
#include "core/perfetto.hpp"
#include "core/rocpd/data_processor.hpp"
#include "core/state.hpp"
#include "core/trace_cache/metadata_registry.hpp"
#include "library/amd_smi.hpp"
#include "library/runtime.hpp"
#include "library/thread_info.hpp"
@@ -85,34 +88,31 @@ get_data_processor()
}
void
rocpd_initialize_category()
metadata_initialize_category()
{
get_data_processor().insert_category(ROCPROFSYS_CATEGORY_AMD_SMI,
trait::name<category::amd_smi>::value);
trace_cache::get_metadata_registry().add_string(
trait::name<category::amd_smi>::value);
}
void
rocpd_initialize_smi_tracks()
metadata_initialize_smi_tracks()
{
auto& data_processor = get_data_processor();
auto& n_info = node_info::get_instance();
const auto thread_id = std::nullopt; // Internal thread ID for amd-smi
const auto thread_id = std::nullopt;
data_processor.insert_track(trait::name<category::amd_smi_mm_busy>::value, n_info.id,
getpid(), thread_id);
data_processor.insert_track(trait::name<category::amd_smi_power>::value, n_info.id,
getpid(), thread_id);
data_processor.insert_track(trait::name<category::amd_smi_temp>::value, n_info.id,
getpid(), thread_id);
data_processor.insert_track(trait::name<category::amd_smi_memory_usage>::value,
n_info.id, getpid(), thread_id);
trace_cache::get_metadata_registry().add_track(
{ trait::name<category::amd_smi_mm_busy>::value, thread_id, "{}" });
trace_cache::get_metadata_registry().add_track(
{ trait::name<category::amd_smi_power>::value, thread_id, "{}" });
trace_cache::get_metadata_registry().add_track(
{ trait::name<category::amd_smi_temp>::value, thread_id, "{}" });
trace_cache::get_metadata_registry().add_track(
{ trait::name<category::amd_smi_memory_usage>::value, thread_id, "{}" });
}
void
rocpd_initialize_smi_pmc(size_t gpu_id)
metadata_initialize_smi_pmc(size_t gpu_id)
{
auto& data_processor = get_data_processor();
// find the proper values for a following definitions
// TODO: Find the proper values for a following definitions
size_t EVENT_CODE = 0;
size_t INSTANCE_ID = 0;
const char* LONG_DESCRIPTION = "";
@@ -121,34 +121,33 @@ rocpd_initialize_smi_pmc(size_t gpu_id)
const char* EXPRESSION = "";
const char* CELSIUS_DEGREES = "\u00B0C";
auto ni = node_info::get_instance();
const auto* TARGET_ARCH = "GPU";
const char* TARGET_ARCH = "GPU";
auto& _agent_manager = agent_manager::get_instance();
auto base_id = _agent_manager.get_agent_by_id(gpu_id, agent_type::GPU).base_id;
trace_cache::get_metadata_registry().add_pmc_info(
{ agent_type::GPU, gpu_id, TARGET_ARCH, EVENT_CODE, INSTANCE_ID,
trait::name<category::amd_smi_mm_busy>::value, "Busy",
trait::name<category::amd_smi_mm_busy>::description, LONG_DESCRIPTION,
COMPONENT, trace_cache::PERCENTAGE, rocprofsys::trace_cache::ABSOLUTE, BLOCK,
EXPRESSION, 0, 0, "{}" });
data_processor.insert_pmc_description(
ni.id, getpid(), base_id, TARGET_ARCH, EVENT_CODE, INSTANCE_ID,
trait::name<category::amd_smi_mm_busy>::value, "Busy",
trait::name<category::amd_smi_mm_busy>::description, LONG_DESCRIPTION, COMPONENT,
"%", "ABS", BLOCK, EXPRESSION, 0, 0);
trace_cache::get_metadata_registry().add_pmc_info(
{ agent_type::GPU, gpu_id, TARGET_ARCH, EVENT_CODE, INSTANCE_ID,
trait::name<category::amd_smi_temp>::value, "Temp",
trait::name<category::amd_smi_temp>::description, LONG_DESCRIPTION, COMPONENT,
CELSIUS_DEGREES, rocprofsys::trace_cache::ABSOLUTE, BLOCK, EXPRESSION, 0, 0 });
data_processor.insert_pmc_description(
ni.id, getpid(), base_id, TARGET_ARCH, EVENT_CODE, INSTANCE_ID,
trait::name<category::amd_smi_temp>::value, "Temp",
trait::name<category::amd_smi_temp>::description, LONG_DESCRIPTION, COMPONENT,
CELSIUS_DEGREES, "ABS", BLOCK, EXPRESSION, 0, 0);
trace_cache::get_metadata_registry().add_pmc_info(
{ agent_type::GPU, gpu_id, TARGET_ARCH, EVENT_CODE, INSTANCE_ID,
trait::name<category::amd_smi_power>::value, "Pow",
trait::name<category::amd_smi_power>::description, LONG_DESCRIPTION, COMPONENT,
"W", rocprofsys::trace_cache::ABSOLUTE, BLOCK, EXPRESSION, 0, 0 });
data_processor.insert_pmc_description(
ni.id, getpid(), base_id, TARGET_ARCH, EVENT_CODE, INSTANCE_ID,
trait::name<category::amd_smi_power>::value, "Pow",
trait::name<category::amd_smi_power>::description, LONG_DESCRIPTION, COMPONENT,
"w", "ABS", BLOCK, EXPRESSION, 0, 0);
data_processor.insert_pmc_description(
ni.id, getpid(), base_id, TARGET_ARCH, EVENT_CODE, INSTANCE_ID,
trait::name<category::amd_smi_memory_usage>::value, "MemUsg",
trait::name<category::amd_smi_memory_usage>::description, LONG_DESCRIPTION,
COMPONENT, "MB", "ABS", BLOCK, EXPRESSION, 0, 0);
trace_cache::get_metadata_registry().add_pmc_info(
{ agent_type::GPU, gpu_id, TARGET_ARCH, EVENT_CODE, INSTANCE_ID,
trait::name<category::amd_smi_memory_usage>::value, "MemUsg",
trait::name<category::amd_smi_memory_usage>::description, LONG_DESCRIPTION,
COMPONENT, tim::units::mem_repr(tim::units::megabyte),
rocprofsys::trace_cache::ABSOLUTE, BLOCK, EXPRESSION, 0, 0 });
}
void
@@ -159,10 +158,14 @@ rocpd_process_smi_pmc_events(const uint32_t device_id, const amd_smi::settings&
if(!(settings.busy || settings.temp || settings.power || settings.mem_usage)) return;
auto& data_processor = get_data_processor();
auto event_id = data_processor.insert_event(ROCPROFSYS_CATEGORY_AMD_SMI, 0, 0, 0);
const auto* _name = trait::name<category::amd_smi>::value;
auto name_primary_key = data_processor.insert_string(_name);
auto event_id = data_processor.insert_event(name_primary_key, 0, 0, 0);
auto& _agent_manager = agent_manager::get_instance();
auto base_id = _agent_manager.get_agent_by_id(device_id, agent_type::GPU).base_id;
auto base_id =
_agent_manager.get_agent_by_type_index(device_id, agent_type::GPU).base_id;
auto insert_event_and_sample = [&](bool enabled, const char* name, double value) {
if(!enabled) return;
@@ -392,10 +395,12 @@ config()
for(auto itr : data::device_list)
data::get_initial().at(itr).sample(itr);
if(get_use_rocpd())
metadata_initialize_category();
metadata_initialize_smi_tracks();
for(const auto& _dev_id : data::device_list)
{
rocpd_initialize_category();
rocpd_initialize_smi_tracks();
metadata_initialize_smi_pmc(_dev_id);
}
}
@@ -483,11 +488,6 @@ data::post_process(uint32_t _dev_id)
auto use_perfetto = get_use_perfetto();
auto use_rocpd = get_use_rocpd();
if(use_rocpd)
{
rocpd_initialize_smi_pmc(_dev_id);
}
for(auto& itr : _amd_smi)
{
using counter_track = perfetto_counter_track<data>;
@@ -788,6 +788,7 @@ setup()
is_initialized() = true;
data::setup();
} catch(std::runtime_error& _e)
{
ROCPROFSYS_VERBOSE(0, "Exception thrown when initializing amd-smi: %s\n",
@@ -23,6 +23,7 @@
#include "library/components/backtrace_metrics.hpp"
#include "core/agent.hpp"
#include "core/agent_manager.hpp"
#include "core/common.hpp"
#include "core/components/fwd.hpp"
#include "core/config.hpp"
#include "core/debug.hpp"
@@ -167,7 +168,141 @@ get_enabled(tim::type_list<Tp...>)
(_v.set(_n++, trait::runtime_enabled<Tp>::get()), ...);
return _v;
}
void
rocpd_init_categories()
{
static bool _is_initialized = false;
if(_is_initialized) return;
auto& data_processor = get_data_processor();
data_processor.insert_string(trait::name<category::thread_cpu_time>::value);
data_processor.insert_string(trait::name<category::thread_peak_memory>::value);
data_processor.insert_string(trait::name<category::thread_context_switch>::value);
data_processor.insert_string(trait::name<category::thread_page_fault>::value);
data_processor.insert_string(trait::name<category::thread_hardware_counter>::value);
_is_initialized = true;
}
template <typename Category>
void
rocpd_init_tracks(int64_t _tid)
{
auto& data_processor = get_data_processor();
auto& n_info = node_info::get_instance();
const auto& t_info = thread_info::get(_tid, SequentTID);
auto _tid_name = JOIN("", '[', _tid, ']');
auto thread_idx = data_processor.insert_thread_info(
n_info.id, getppid(), getpid(), t_info->index_data->system_value,
JOIN(" ", "Thread", _tid).c_str(), t_info->get_start(), t_info->get_stop(), "{}");
if constexpr(std::is_same_v<Category, category::thread_hardware_counter>)
{
// Initialize hw_counter_tracks and create one track for each hardware counter
auto _hw_cnt_labels = *get_papi_labels(_tid);
for(auto& itr : _hw_cnt_labels)
{
std::string _desc = tim::papi::get_event_info(itr).short_descr;
if(_desc.empty()) _desc = itr;
ROCPROFSYS_CI_THROW(_desc.empty(), "Empty description for %s\n", itr.c_str());
std::string track_name = JOIN(' ', "Thread", _desc, _tid_name, "(S)");
data_processor.insert_track(track_name.c_str(), n_info.id, getpid(),
thread_idx, "{}");
}
}
else
data_processor.insert_track(
JOIN('_', trait::name<Category>::value, _tid_name).c_str(), n_info.id,
getpid(), thread_idx, "{}");
}
template <typename Category>
void
rocpd_initialize_backtrace_metrics_pmc(size_t dev_id, const char* units, int64_t _tid)
{
auto& data_processor = get_data_processor();
auto _tid_name = JOIN("", '[', _tid, ']');
size_t EVENT_CODE = 0;
size_t INSTANCE_ID = 0;
const char* LONG_DESCRIPTION = "";
const char* COMPONENT = "";
const char* BLOCK = "";
const char* EXPRESSION = "";
auto ni = node_info::get_instance();
const auto TARGET_ARCH = "CPU";
auto& agent_mngr = agent_manager::get_instance();
auto base_id = agent_mngr.get_agent_by_id(dev_id, agent_type::CPU).base_id;
if constexpr(std::is_same_v<Category, category::thread_hardware_counter>)
{
auto _hw_cnt_labels = *get_papi_labels(_tid);
for(auto& itr : _hw_cnt_labels)
{
std::string _desc = tim::papi::get_event_info(itr).short_descr;
if(_desc.empty()) _desc = itr;
ROCPROFSYS_CI_THROW(_desc.empty(), "Empty description for %s\n", itr.c_str());
std::string track_name = JOIN(' ', "Thread", _desc, _tid_name, "(S)");
data_processor.insert_pmc_description(
ni.id, getpid(), base_id, TARGET_ARCH, EVENT_CODE, INSTANCE_ID,
track_name.c_str(), trait::name<Category>::value,
trait::name<Category>::description, LONG_DESCRIPTION, COMPONENT, units,
"ABS", BLOCK, EXPRESSION, 0, 0);
}
}
else
data_processor.insert_pmc_description(
ni.id, getpid(), base_id, TARGET_ARCH, EVENT_CODE, INSTANCE_ID,
JOIN("_", trait::name<Category>::value, _tid_name).c_str(),
trait::name<Category>::value, trait::name<Category>::description,
LONG_DESCRIPTION, COMPONENT, units, "ABS", BLOCK, EXPRESSION, 0, 0);
}
template <typename Category, typename Value>
void
rocpd_process_backtrace_metrics_events(const uint32_t device_id, uint64_t timestamp,
Value value, int64_t _tid)
{
auto& data_processor = get_data_processor();
auto _tid_name = JOIN("", '[', _tid, ']');
auto string_primary_key = data_processor.insert_string(trait::name<Category>::value);
auto event_id = data_processor.insert_event(string_primary_key, 0, 0, 0);
auto& agent_mngr = agent_manager::get_instance();
auto base_id = agent_mngr.get_agent_by_id(device_id, agent_type::CPU).base_id;
auto insert_event_and_sample = [&](const char* _name, double _value) {
data_processor.insert_pmc_event(event_id, base_id, _name, _value);
data_processor.insert_sample(_name, timestamp, event_id);
};
if constexpr(std::is_same_v<Category, category::thread_hardware_counter>)
{
auto _hw_cnt_labels = *get_papi_labels(_tid);
const auto& hw_counters =
static_cast<backtrace_metrics::hw_counter_data_t>(value);
for(size_t i = 0; i < _hw_cnt_labels.size() && i < hw_counters.size(); ++i)
{
std::string _desc = tim::papi::get_event_info(_hw_cnt_labels[i]).short_descr;
if(_desc.empty()) _desc = _hw_cnt_labels[i];
std::string track_name = JOIN(' ', "Thread", _desc, _tid_name, "(S)");
insert_event_and_sample(track_name.c_str(), hw_counters.at(i));
}
}
else
insert_event_and_sample(
JOIN("_", trait::name<Category>::value, _tid_name).c_str(), value);
}
} // namespace
void
backtrace_metrics::sample(int)
{
@@ -337,146 +472,6 @@ backtrace_metrics::fini_perfetto(int64_t _tid, valid_array_t _valid)
}
}
void
rocpd_init_categories()
{
static bool _is_initialized = false;
if(_is_initialized) return;
get_data_processor().insert_category(
category_enum_id<category::thread_cpu_time>::value,
trait::name<category::thread_cpu_time>::value);
get_data_processor().insert_category(
category_enum_id<category::thread_peak_memory>::value,
trait::name<category::thread_peak_memory>::value);
get_data_processor().insert_category(
category_enum_id<category::thread_context_switch>::value,
trait::name<category::thread_context_switch>::value);
get_data_processor().insert_category(
category_enum_id<category::thread_page_fault>::value,
trait::name<category::thread_page_fault>::value);
get_data_processor().insert_category(
category_enum_id<category::thread_hardware_counter>::value,
trait::name<category::thread_hardware_counter>::value);
_is_initialized = true;
}
template <typename Category>
void
rocpd_init_tracks(int64_t _tid)
{
auto& data_processor = get_data_processor();
auto& n_info = node_info::get_instance();
const auto& t_info = thread_info::get(_tid, SequentTID);
auto _tid_name = JOIN("", '[', _tid, ']');
auto thread_idx = data_processor.insert_thread_info(
n_info.id, getppid(), getpid(), t_info->index_data->system_value,
JOIN(" ", "Thread", _tid).c_str(), t_info->get_start(), t_info->get_stop(), "{}");
if constexpr(std::is_same_v<Category, category::thread_hardware_counter>)
{
// Initialize hw_counter_tracks and create one track for each hardware counter
auto _hw_cnt_labels = *get_papi_labels(_tid);
for(auto& itr : _hw_cnt_labels)
{
std::string _desc = tim::papi::get_event_info(itr).short_descr;
if(_desc.empty()) _desc = itr;
ROCPROFSYS_CI_THROW(_desc.empty(), "Empty description for %s\n", itr.c_str());
std::string track_name = JOIN(' ', "Thread", _desc, _tid_name, "(S)");
data_processor.insert_track(track_name.c_str(), n_info.id, getpid(),
thread_idx, "{}");
}
}
else
data_processor.insert_track(
JOIN('_', trait::name<Category>::value, _tid_name).c_str(), n_info.id,
getpid(), thread_idx, "{}");
}
template <typename Category>
void
rocpd_initialize_backtrace_metrics_pmc(size_t dev_id, const char* units, int64_t _tid)
{
auto& data_processor = get_data_processor();
auto _tid_name = JOIN("", '[', _tid, ']');
size_t EVENT_CODE = 0;
size_t INSTANCE_ID = 0;
const char* LONG_DESCRIPTION = "";
const char* COMPONENT = "";
const char* BLOCK = "";
const char* EXPRESSION = "";
auto ni = node_info::get_instance();
const auto* TARGET_ARCH = "CPU";
auto& _agent_manager = agent_manager::get_instance();
auto _base_id = _agent_manager.get_agent_by_id(dev_id, agent_type::CPU).base_id;
if constexpr(std::is_same_v<Category, category::thread_hardware_counter>)
{
auto _hw_cnt_labels = *get_papi_labels(_tid);
for(auto& itr : _hw_cnt_labels)
{
std::string _desc = tim::papi::get_event_info(itr).short_descr;
if(_desc.empty()) _desc = itr;
ROCPROFSYS_CI_THROW(_desc.empty(), "Empty description for %s\n", itr.c_str());
std::string track_name = JOIN(' ', "Thread", _desc, _tid_name, "(S)");
data_processor.insert_pmc_description(
ni.id, getpid(), _base_id, TARGET_ARCH, EVENT_CODE, INSTANCE_ID,
track_name.c_str(), trait::name<Category>::value,
trait::name<Category>::description, LONG_DESCRIPTION, COMPONENT, units,
"ABS", BLOCK, EXPRESSION, 0, 0);
}
}
else
data_processor.insert_pmc_description(
ni.id, getpid(), _base_id, TARGET_ARCH, EVENT_CODE, INSTANCE_ID,
JOIN("_", trait::name<Category>::value, _tid_name).c_str(),
trait::name<Category>::value, trait::name<Category>::description,
LONG_DESCRIPTION, COMPONENT, units, "ABS", BLOCK, EXPRESSION, 0, 0);
}
template <typename Category, typename Value>
void
rocpd_process_backtrace_metrics_events(const uint32_t device_id, uint64_t timestamp,
Value value, int64_t _tid)
{
auto& data_processor = get_data_processor();
auto _tid_name = JOIN("", '[', _tid, ']');
auto event_id =
data_processor.insert_event(category_enum_id<Category>::value, 0, 0, 0);
auto& agent_mngr = agent_manager::get_instance();
auto base_id = agent_mngr.get_agent_by_id(device_id, agent_type::CPU).base_id;
auto insert_event_and_sample = [&](const char* name, double _value) {
data_processor.insert_pmc_event(event_id, base_id, name, _value);
data_processor.insert_sample(name, timestamp, event_id);
};
if constexpr(std::is_same_v<Category, category::thread_hardware_counter>)
{
auto _hw_cnt_labels = *get_papi_labels(_tid);
const auto& _hw_counters =
static_cast<backtrace_metrics::hw_counter_data_t>(value);
for(size_t i = 0; i < _hw_cnt_labels.size() && i < _hw_counters.size(); ++i)
{
std::string _desc = tim::papi::get_event_info(_hw_cnt_labels[i]).short_descr;
if(_desc.empty()) _desc = _hw_cnt_labels[i];
std::string track_name = JOIN(' ', "Thread", _desc, _tid_name, "(S)");
insert_event_and_sample(track_name.c_str(), _hw_counters.at(i));
}
}
else
insert_event_and_sample(
JOIN("_", trait::name<Category>::value, _tid_name).c_str(), value);
}
void
backtrace_metrics::init_rocpd(int64_t _tid, valid_array_t _valid)
{
@@ -641,8 +636,10 @@ backtrace_metrics::post_process_perfetto(int64_t _tid, uint64_t _ts) const
}
void
backtrace_metrics::post_process_rocpd(int64_t _tid, uint64_t _ts) const
backtrace_metrics::post_process_rocpd([[maybe_unused]] int64_t _tid,
[[maybe_unused]] uint64_t _ts) const
{
#if ROCPROFSYS_USE_ROCM > 0
auto is_category_enabled = [&](const auto& _category) { return (*this)(_category); };
if(is_category_enabled(category::thread_cpu_time{}))
@@ -675,6 +672,7 @@ backtrace_metrics::post_process_rocpd(int64_t _tid, uint64_t _ts) const
hw_counter_data_t>(0, _ts, m_hw_counter,
_tid);
}
#endif
}
} // namespace component
} // namespace rocprofsys
@@ -26,7 +26,8 @@
#include "core/config.hpp"
#include "core/node_info.hpp"
#include "core/perfetto.hpp"
#include "core/rocpd/data_processor.hpp"
#include "core/trace_cache/cache_manager.hpp"
#include "core/trace_cache/sample_type.hpp"
#include "library/tracing.hpp"
#include <timemory/units.hpp>
@@ -76,41 +77,25 @@ write_perfetto_counter_track(uint64_t _val)
namespace
{
rocpd::data_processor&
get_data_processor()
{
return rocpd::data_processor::get_instance();
}
void
rocpd_initialize_comm_data_categories()
metadata_initialize_comm_data_categories()
{
static bool _is_initialized = false;
if(_is_initialized) return;
get_data_processor().insert_category(category_enum_id<category::comm_data>::value,
trait::name<category::comm_data>::value);
#if defined(ROCPROFSYS_USE_MPI)
get_data_processor().insert_category(category_enum_id<category::mpi>::value,
trait::name<category::mpi>::value);
#endif
#if defined(ROCPROFSYS_USE_RCCL)
get_data_processor().insert_category(category_enum_id<category::rocm_rccl>::value,
trait::name<category::rocm_rccl>::value);
#endif
trace_cache::get_metadata_registry().add_string(
trait::name<category::comm_data>::value);
trace_cache::get_metadata_registry().add_string(trait::name<category::mpi>::value);
_is_initialized = true;
}
template <typename Track>
void
rocpd_initialize_track()
metadata_initialize_track()
{
auto& n_info = node_info::get_instance();
auto thread_id = std::nullopt;
auto _init_track = [&](const char* label) {
ROCPROFSYS_VERBOSE(3, "INSERT_TRACK label: %s, node ID: %d, Process ID: %d",
label, n_info.id, getpid());
get_data_processor().insert_track(label, n_info.id, getpid(), thread_id);
auto _init_track = [&](const char* label) {
trace_cache::get_metadata_registry().add_track({ label, std::nullopt, "{}" });
};
static std::once_flag _once{};
@@ -118,9 +103,8 @@ rocpd_initialize_track()
}
void
rocpd_initialize_comm_data_pmc()
metadata_initialize_comm_data_pmc()
{
[[maybe_unused]] auto& data_processor = get_data_processor();
// find the proper values for a following definitions
[[maybe_unused]] size_t EVENT_CODE = 0;
[[maybe_unused]] size_t INSTANCE_ID = 0;
@@ -131,56 +115,28 @@ rocpd_initialize_comm_data_pmc()
[[maybe_unused]] constexpr const char* MSG = "bytes";
[[maybe_unused]] constexpr const auto* TARGET_ARCH = "CPU";
auto ni = node_info::get_instance();
constexpr const auto DEVICE_ID = 0; // Assuming CPU device ID is 0
auto& _agent_manager = agent_manager::get_instance();
[[maybe_unused]] auto base_id =
_agent_manager.get_agent_by_id(DEVICE_ID, agent_type::CPU).base_id;
[[maybe_unused]] constexpr const auto DEVICE_ID = 0; // Assuming CPU device ID is 0
#if defined(ROCPROFSYS_USE_MPI)
data_processor.insert_pmc_description(
ni.id, getpid(), base_id, TARGET_ARCH, EVENT_CODE, INSTANCE_ID,
comm_data::mpi_send::label, "Tracks MPI Send communication data sizes",
trait::name<category::mpi>::description, LONG_DESCRIPTION, COMPONENT, MSG, "ABS",
BLOCK, EXPRESSION, 0, 0);
data_processor.insert_pmc_description(
ni.id, getpid(), base_id, TARGET_ARCH, EVENT_CODE, INSTANCE_ID,
comm_data::mpi_recv::label, "Tracks MPI Receive communication data sizes",
trait::name<category::mpi>::description, LONG_DESCRIPTION, COMPONENT, MSG, "ABS",
BLOCK, EXPRESSION, 0, 0);
#endif
#if defined(ROCPROFSYS_USE_RCCL)
data_processor.insert_pmc_description(
ni.id, getpid(), base_id, TARGET_ARCH, EVENT_CODE, INSTANCE_ID, rccl_send::label,
"Tracks RCCL Send communication data sizes",
trait::name<category::rocm_rccl>::description, LONG_DESCRIPTION, COMPONENT, MSG,
"ABS", BLOCK, EXPRESSION, 0, 0);
data_processor.insert_pmc_description(
ni.id, getpid(), base_id, TARGET_ARCH, EVENT_CODE, INSTANCE_ID, rccl_recv::label,
"Tracks RCCL Receive communication data sizes",
trait::name<category::rocm_rccl>::description, LONG_DESCRIPTION, COMPONENT, MSG,
"ABS", BLOCK, EXPRESSION, 0, 0);
trace_cache::get_metadata_registry().add_pmc_info(
{ agent_type::CPU, DEVICE_ID, TARGET_ARCH, EVENT_CODE, INSTANCE_ID,
comm_data::mpi_send::label, "Tracks MPI communication data sizes",
trait::name<category::mpi>::description, LONG_DESCRIPTION, COMPONENT, MSG,
rocprofsys::trace_cache::ABSOLUTE, BLOCK, EXPRESSION, 0, 0 });
trace_cache::get_metadata_registry().add_pmc_info(
{ agent_type::CPU, DEVICE_ID, TARGET_ARCH, EVENT_CODE, INSTANCE_ID,
comm_data::mpi_recv::label, "Tracks MPI communication data sizes",
trait::name<category::mpi>::description, LONG_DESCRIPTION, COMPONENT, MSG,
rocprofsys::trace_cache::ABSOLUTE, BLOCK, EXPRESSION, 0, 0 });
#endif
}
template <typename Track>
void
rocpd_process_cpu_usage_events(const uint32_t device_id, int bytes)
cache_comm_data_events(const uint32_t device_id, int bytes)
{
auto& data_processor = get_data_processor();
auto event_id = data_processor.insert_event(
category_enum_id<category::comm_data>::value, 0, 0, 0);
auto& agents = agent_manager::get_instance();
auto agent = agents.get_agent_by_id(device_id, agent_type::CPU);
auto insert_event_and_sample = [&](const char* name, uint64_t timestamp,
double value) {
data_processor.insert_pmc_event(event_id, agent.device_id, name, value);
data_processor.insert_sample(name, timestamp, event_id);
};
auto agent = agents.get_agent_by_type_index(device_id, agent_type::CPU);
static std::mutex _mutex{};
static uint64_t value = 0;
@@ -190,8 +146,20 @@ rocpd_process_cpu_usage_events(const uint32_t device_id, int bytes)
_now = rocprofsys::tracing::now<uint64_t>();
bytes = (value += bytes);
}
const std::string track_name = Track::label;
const size_t timestamp_ns = _now;
const std::string event_metadata = "{}";
const size_t stack_id = 0;
const size_t parent_stack_id = 0;
const size_t correlation_id = 0;
const std::string call_stack = "{}";
const std::string line_info = "{}";
const size_t agent_handle = agent.handle;
insert_event_and_sample(Track::label, _now, bytes);
trace_cache::get_buffer_storage().store(
trace_cache::entry_type::pmc_event_with_sample, track_name.c_str(), timestamp_ns,
event_metadata.c_str(), stack_id, parent_stack_id, correlation_id,
call_stack.c_str(), line_info.c_str(), agent_handle, track_name.c_str(), value);
}
} // namespace
@@ -199,10 +167,14 @@ rocpd_process_cpu_usage_events(const uint32_t device_id, int bytes)
void
comm_data::start()
{
if(get_use_rocpd())
{
rocpd_initialize_comm_data_categories();
rocpd_initialize_comm_data_pmc();
metadata_initialize_comm_data_categories();
metadata_initialize_comm_data_pmc();
#if defined(ROCPROFSYS_USE_MPI)
metadata_initialize_track<mpi_send>();
metadata_initialize_track<mpi_recv>();
#endif
}
}
@@ -248,10 +220,8 @@ comm_data::audit(const gotcha_data& _data, audit::incoming, const void*, int cou
write_perfetto_counter_track<mpi_send>(count * _size);
if(get_use_rocpd())
{
rocpd_initialize_track<mpi_send>();
rocpd_process_cpu_usage_events<mpi_send>(0, count * _size);
cache_comm_data_events<mpi_send>(0, count * _size);
}
if(rocprofsys::get_use_timemory())
@@ -276,10 +246,8 @@ comm_data::audit(const gotcha_data& _data, audit::incoming, void*, int count,
if(get_use_perfetto()) write_perfetto_counter_track<mpi_recv>(count * _size);
if(get_use_rocpd())
{
rocpd_initialize_track<mpi_recv>();
rocpd_process_cpu_usage_events<mpi_recv>(0, count * _size);
cache_comm_data_events<mpi_recv>(0, count * _size);
}
if(rocprofsys::get_use_timemory())
@@ -304,10 +272,8 @@ comm_data::audit(const gotcha_data& _data, audit::incoming, const void*, int cou
if(get_use_perfetto()) write_perfetto_counter_track<mpi_send>(count * _size);
if(get_use_rocpd())
{
rocpd_initialize_track<mpi_send>();
rocpd_process_cpu_usage_events<mpi_send>(0, count * _size);
cache_comm_data_events<mpi_send>(0, count * _size);
}
if(rocprofsys::get_use_timemory())
@@ -332,10 +298,8 @@ comm_data::audit(const gotcha_data& _data, audit::incoming, void*, int count,
if(get_use_perfetto()) write_perfetto_counter_track<mpi_recv>(count * _size);
if(get_use_rocpd())
{
rocpd_initialize_track<mpi_recv>();
rocpd_process_cpu_usage_events<mpi_recv>(0, count * _size);
cache_comm_data_events<mpi_recv>(0, count * _size);
}
if(rocprofsys::get_use_timemory())
@@ -360,10 +324,8 @@ comm_data::audit(const gotcha_data& _data, audit::incoming, void*, int count,
if(get_use_perfetto()) write_perfetto_counter_track<mpi_send>(count * _size);
if(get_use_rocpd())
{
rocpd_initialize_track<mpi_send>();
rocpd_process_cpu_usage_events<mpi_send>(0, count * _size);
cache_comm_data_events<mpi_send>(0, count * _size);
}
if(rocprofsys::get_use_timemory())
@@ -389,12 +351,9 @@ comm_data::audit(const gotcha_data& _data, audit::incoming, const void*, void*,
write_perfetto_counter_track<mpi_send>(count * _size);
}
if(get_use_rocpd())
{
rocpd_initialize_track<mpi_send>();
rocpd_initialize_track<mpi_recv>();
rocpd_process_cpu_usage_events<mpi_recv>(0, count * _size);
rocpd_process_cpu_usage_events<mpi_send>(0, count * _size);
cache_comm_data_events<mpi_recv>(0, count * _size);
cache_comm_data_events<mpi_send>(0, count * _size);
}
if(rocprofsys::get_use_timemory()) add(_data, count * _size);
@@ -416,10 +375,9 @@ comm_data::audit(const gotcha_data& _data, audit::incoming, const void*, int sen
write_perfetto_counter_track<mpi_recv>(recvcount * _recv_size);
}
if(get_use_rocpd())
{
rocpd_process_cpu_usage_events<mpi_send>(0, sendcount * _send_size);
rocpd_process_cpu_usage_events<mpi_recv>(0, recvcount * _send_size);
cache_comm_data_events<mpi_send>(0, sendcount * _send_size);
cache_comm_data_events<mpi_recv>(0, recvcount * _send_size);
}
if(rocprofsys::get_use_timemory())
@@ -467,10 +425,9 @@ comm_data::audit(const gotcha_data& _data, audit::incoming, const void*, int sen
write_perfetto_counter_track<mpi_recv>(recvcount * _recv_size);
}
if(get_use_rocpd())
{
rocpd_process_cpu_usage_events<mpi_send>(0, sendcount * _send_size);
rocpd_process_cpu_usage_events<mpi_recv>(0, recvcount * _send_size);
cache_comm_data_events<mpi_send>(0, sendcount * _send_size);
cache_comm_data_events<mpi_recv>(0, recvcount * _send_size);
}
if(rocprofsys::get_use_timemory())
@@ -501,10 +458,9 @@ comm_data::audit(const gotcha_data& _data, audit::incoming, const void*, int sen
write_perfetto_counter_track<mpi_recv>(recvcount * _recv_size);
}
if(get_use_rocpd())
{
rocpd_process_cpu_usage_events<mpi_send>(0, sendcount * _send_size);
rocpd_process_cpu_usage_events<mpi_recv>(0, recvcount * _recv_size);
cache_comm_data_events<mpi_send>(0, sendcount * _send_size);
cache_comm_data_events<mpi_recv>(0, recvcount * _recv_size);
}
if(rocprofsys::get_use_timemory())
@@ -29,6 +29,8 @@
#include "core/node_info.hpp"
#include "core/perfetto.hpp"
#include "core/rocpd/data_processor.hpp"
#include "core/timemory.hpp"
#include "core/trace_cache/cache_manager.hpp"
#include "library/components/cpu_freq.hpp"
#include "library/thread_info.hpp"
@@ -91,54 +93,45 @@ get_data_processor()
}
void
rocpd_initialize_cpu_freq_category()
metadata_initialize_cpu_freq_category()
{
get_data_processor().insert_category(ROCPROFSYS_CATEGORY_CPU_FREQ,
trait::name<category::cpu_freq>::value);
trace_cache::get_metadata_registry().add_string(
trait::name<category::cpu_freq>::value);
}
void
rocpd_initialize_cpu_freq_tracks()
metadata_initialize_cpu_freq_tracks()
{
auto& data_processor = get_data_processor();
auto& n_info = node_info::get_instance();
const auto thread_idx = std::nullopt; // Internal thread ID for cpu-freq
do_for_enabled_cpus([&](size_t cpu_id) {
data_processor.insert_track(
get_cpu_freq_track_name<category::cpu_freq>(cpu_id).c_str(), n_info.id,
getpid(), thread_idx);
trace_cache::get_metadata_registry().add_track(
{ get_cpu_freq_track_name<category::cpu_freq>(cpu_id).c_str(), std::nullopt,
"{}" });
});
}
void
rocpd_initialize_cpu_usage_tracks()
metadata_initialize_cpu_usage_tracks()
{
auto& data_processor = get_data_processor();
auto& n_info = node_info::get_instance();
const auto thread_idx = std::nullopt; // Internal thread ID for cpu-freq
data_processor.insert_track(trait::name<category::process_page>::value, n_info.id,
getpid(), thread_idx);
data_processor.insert_track(trait::name<category::process_virt>::value, n_info.id,
getpid(), thread_idx);
data_processor.insert_track(trait::name<category::process_peak>::value, n_info.id,
getpid(), thread_idx);
data_processor.insert_track(trait::name<category::process_context_switch>::value,
n_info.id, getpid(), thread_idx);
data_processor.insert_track(trait::name<category::process_page_fault>::value,
n_info.id, getpid(), thread_idx);
data_processor.insert_track(trait::name<category::process_user_mode_time>::value,
n_info.id, getpid(), thread_idx);
data_processor.insert_track(trait::name<category::process_kernel_mode_time>::value,
n_info.id, getpid(), thread_idx);
trace_cache::get_metadata_registry().add_track(
{ trait::name<category::process_page>::value, std::nullopt, "{}" });
trace_cache::get_metadata_registry().add_track(
{ trait::name<category::process_virt>::value, std::nullopt, "{}" });
trace_cache::get_metadata_registry().add_track(
{ trait::name<category::process_peak>::value, std::nullopt, "{}" });
trace_cache::get_metadata_registry().add_track(
{ trait::name<category::process_context_switch>::value, std::nullopt, "{}" });
trace_cache::get_metadata_registry().add_track(
{ trait::name<category::process_page_fault>::value, std::nullopt, "{}" });
trace_cache::get_metadata_registry().add_track(
{ trait::name<category::process_user_mode_time>::value, std::nullopt, "{}" });
trace_cache::get_metadata_registry().add_track(
{ trait::name<category::process_kernel_mode_time>::value, std::nullopt, "{}" });
}
void
rocpd_initialize_cpu_freq_pmc(size_t dev_id)
metadata_initialize_cpu_freq_pmc(size_t dev_id)
{
auto& data_processor = get_data_processor();
// find the proper values for a following definitions
// TODO: Find the proper values for a following definitions
size_t EVENT_CODE = 0;
size_t INSTANCE_ID = 0;
const char* LONG_DESCRIPTION = "";
@@ -150,58 +143,56 @@ rocpd_initialize_cpu_freq_pmc(size_t dev_id)
auto ni = node_info::get_instance();
const auto* TARGET_ARCH = "CPU";
auto& _agent_manager = agent_manager::get_instance();
auto base_id = _agent_manager.get_agent_by_id(dev_id, agent_type::CPU).base_id;
do_for_enabled_cpus([&](size_t cpu_id) {
data_processor.insert_pmc_description(
ni.id, getpid(), base_id, TARGET_ARCH, EVENT_CODE, INSTANCE_ID,
get_cpu_freq_track_name<category::cpu_freq>(cpu_id).c_str(), "Frequency",
trait::name<category::cpu_freq>::description, LONG_DESCRIPTION, COMPONENT,
component::cpu_freq::display_unit().c_str(), "ABS", BLOCK, EXPRESSION, 0, 0);
trace_cache::get_metadata_registry().add_pmc_info(
{ agent_type::CPU, dev_id, TARGET_ARCH, EVENT_CODE, INSTANCE_ID,
get_cpu_freq_track_name<category::cpu_freq>(cpu_id).c_str(), "Frequency",
trait::name<category::cpu_freq>::description, LONG_DESCRIPTION, COMPONENT,
component::cpu_freq::display_unit().c_str(),
rocprofsys::trace_cache::ABSOLUTE, BLOCK, EXPRESSION, 0, 0 });
});
data_processor.insert_pmc_description(
ni.id, getpid(), base_id, TARGET_ARCH, EVENT_CODE, INSTANCE_ID,
trait::name<category::process_page>::value, "Memory Usage",
trait::name<category::process_page>::description, LONG_DESCRIPTION, COMPONENT,
MEMORY, "ABS", BLOCK, EXPRESSION, 0, 0);
trace_cache::get_metadata_registry().add_pmc_info(
{ agent_type::CPU, dev_id, TARGET_ARCH, EVENT_CODE, INSTANCE_ID,
trait::name<category::process_page>::value, "Memory Usage",
trait::name<category::process_page>::description, LONG_DESCRIPTION, COMPONENT,
MEMORY, rocprofsys::trace_cache::ABSOLUTE, BLOCK, EXPRESSION, 0, 0 });
data_processor.insert_pmc_description(
ni.id, getpid(), base_id, TARGET_ARCH, EVENT_CODE, INSTANCE_ID,
trait::name<category::process_virt>::value, "Virtual Memory Usage",
trait::name<category::process_virt>::description, LONG_DESCRIPTION, COMPONENT,
MEMORY, "ABS", BLOCK, EXPRESSION, 0, 0);
trace_cache::get_metadata_registry().add_pmc_info(
{ agent_type::CPU, dev_id, TARGET_ARCH, EVENT_CODE, INSTANCE_ID,
trait::name<category::process_virt>::value, "Virtual Memory Usage",
trait::name<category::process_virt>::description, LONG_DESCRIPTION, COMPONENT,
MEMORY, rocprofsys::trace_cache::ABSOLUTE, BLOCK, EXPRESSION, 0, 0 });
data_processor.insert_pmc_description(
ni.id, getpid(), base_id, TARGET_ARCH, EVENT_CODE, INSTANCE_ID,
trait::name<category::process_peak>::value, "Peak Memory",
trait::name<category::process_peak>::description, LONG_DESCRIPTION, COMPONENT,
MEMORY, "ABS", BLOCK, EXPRESSION, 0, 0);
trace_cache::get_metadata_registry().add_pmc_info(
{ agent_type::CPU, dev_id, TARGET_ARCH, EVENT_CODE, INSTANCE_ID,
trait::name<category::process_peak>::value, "Peak Memory",
trait::name<category::process_peak>::description, LONG_DESCRIPTION, COMPONENT,
MEMORY, rocprofsys::trace_cache::ABSOLUTE, BLOCK, EXPRESSION, 0, 0 });
data_processor.insert_pmc_description(
ni.id, getpid(), base_id, TARGET_ARCH, EVENT_CODE, INSTANCE_ID,
trait::name<category::process_context_switch>::value, "Context Switches",
trait::name<category::process_context_switch>::description, LONG_DESCRIPTION,
COMPONENT, "", "ABS", BLOCK, EXPRESSION, 0, 0);
trace_cache::get_metadata_registry().add_pmc_info(
{ agent_type::CPU, dev_id, TARGET_ARCH, EVENT_CODE, INSTANCE_ID,
trait::name<category::process_context_switch>::value, "Context Switches",
trait::name<category::process_context_switch>::description, LONG_DESCRIPTION,
COMPONENT, "", rocprofsys::trace_cache::ABSOLUTE, BLOCK, EXPRESSION, 0, 0 });
data_processor.insert_pmc_description(
ni.id, getpid(), base_id, TARGET_ARCH, EVENT_CODE, INSTANCE_ID,
trait::name<category::process_page_fault>::value, "Page Faults",
trait::name<category::process_page_fault>::description, LONG_DESCRIPTION,
COMPONENT, "", "ABS", BLOCK, EXPRESSION, 0, 0);
trace_cache::get_metadata_registry().add_pmc_info(
{ agent_type::CPU, dev_id, TARGET_ARCH, EVENT_CODE, INSTANCE_ID,
trait::name<category::process_page_fault>::value, "Page Faults",
trait::name<category::process_page_fault>::description, LONG_DESCRIPTION,
COMPONENT, "", rocprofsys::trace_cache::ABSOLUTE, BLOCK, EXPRESSION, 0, 0 });
data_processor.insert_pmc_description(
ni.id, getpid(), base_id, TARGET_ARCH, EVENT_CODE, INSTANCE_ID,
trait::name<category::process_user_mode_time>::value, "User Time",
trait::name<category::process_user_mode_time>::description, LONG_DESCRIPTION,
COMPONENT, TIME, "ABS", BLOCK, EXPRESSION, 0, 0);
trace_cache::get_metadata_registry().add_pmc_info(
{ agent_type::CPU, dev_id, TARGET_ARCH, EVENT_CODE, INSTANCE_ID,
trait::name<category::process_user_mode_time>::value, "User Time",
trait::name<category::process_user_mode_time>::description, LONG_DESCRIPTION,
COMPONENT, TIME, rocprofsys::trace_cache::ABSOLUTE, BLOCK, EXPRESSION, 0, 0 });
data_processor.insert_pmc_description(
ni.id, getpid(), base_id, TARGET_ARCH, EVENT_CODE, INSTANCE_ID,
trait::name<category::process_kernel_mode_time>::value, "Kernel Time",
trait::name<category::process_kernel_mode_time>::description, LONG_DESCRIPTION,
COMPONENT, TIME, "ABS", BLOCK, EXPRESSION, 0, 0);
trace_cache::get_metadata_registry().add_pmc_info(
{ agent_type::CPU, dev_id, TARGET_ARCH, EVENT_CODE, INSTANCE_ID,
trait::name<category::process_kernel_mode_time>::value, "Kernel Time",
trait::name<category::process_kernel_mode_time>::description, LONG_DESCRIPTION,
COMPONENT, TIME, rocprofsys::trace_cache::ABSOLUTE, BLOCK, EXPRESSION, 0, 0 });
}
void
@@ -211,11 +202,13 @@ rocpd_process_cpu_usage_events(const uint32_t device_id, uint64_t timestamp,
double context_switch, double page_fault, double user_time,
double kernel_time)
{
auto& data_processor = get_data_processor();
auto event_id = data_processor.insert_event(ROCPROFSYS_CATEGORY_CPU_FREQ, 0, 0, 0);
auto& data_processor = get_data_processor();
const auto* _name = trait::name<category::cpu_freq>::value;
auto name_primary_key = data_processor.insert_string(_name);
auto event_id = data_processor.insert_event(name_primary_key, 0, 0, 0);
auto& agent_mngr = agent_manager::get_instance();
auto base_id = agent_mngr.get_agent_by_id(device_id, agent_type::CPU).base_id;
auto base_id = agent_mngr.get_agent_by_type_index(device_id, agent_type::CPU).base_id;
auto insert_event_and_sample = [&](const char* name, double value) {
data_processor.insert_pmc_event(event_id, base_id, name, value);
@@ -258,6 +251,21 @@ setup()
category::process_page_fault, category::process_user_mode_time,
category::process_kernel_mode_time>{});
}
metadata_initialize_cpu_freq_category();
metadata_initialize_cpu_usage_tracks();
metadata_initialize_cpu_freq_tracks();
// `get_enabled_cpus()` returns the number of cores enabled for monitoring but
// the actual device_id is 0, since there is a single device available. And
// the agents seems to be assigned per device basis not per core.
// TODO: `get_enabled_cpus()` should be fixed in the future to align with GPU
// implementation.
auto cpu_agents = agent_manager::get_instance().get_agents_by_type(agent_type::CPU);
for(auto& agent : cpu_agents)
{
metadata_initialize_cpu_freq_pmc(agent->device_id);
}
}
void
@@ -343,25 +351,6 @@ post_process()
auto& enabled_cpus = component::cpu_freq::get_enabled_cpus();
if(get_use_rocpd())
{
rocpd_initialize_cpu_freq_category();
rocpd_initialize_cpu_usage_tracks();
rocpd_initialize_cpu_freq_tracks();
// `get_enabled_cpus()` returns the number of cores enabled for monitoring but the
// actually device_id is 0, since there is a single device available. And the
// agents seems to be assigned per device basis not per core.
// TODO: `get_enabled_cpus()` should be fixed in the future to align with GPU
// implementation.
auto cpu_agents =
agent_manager::get_instance().get_agents_by_type(agent_type::CPU);
for(auto& agent : cpu_agents)
{
rocpd_initialize_cpu_freq_pmc(agent->device_id);
}
}
auto _process_frequencies = [](size_t _idx, size_t _offset) {
using freq_track = perfetto_counter_track<category::cpu_freq>;
@@ -31,10 +31,12 @@
#include "core/defines.hpp"
#include "core/node_info.hpp"
#include "core/perfetto.hpp"
#include "core/rocpd/data_processor.hpp"
#include "core/rocpd/json.hpp"
#include "core/trace_cache/cache_manager.hpp"
#include "core/trace_cache/sample_type.hpp"
#include "library/components/category_region.hpp"
#include "library/runtime.hpp"
#include <optional>
#include <timemory/api/kokkosp.hpp>
#include <timemory/backends/process.hpp>
@@ -157,47 +159,41 @@ violates_name_rules(Arg&& _arg, Args&&... _args)
namespace
{
rocprofsys::rocpd::data_processor&
get_data_processor()
{
return rocprofsys::rocpd::data_processor::get_instance();
}
void
rocpd_initialize_kokkos_category()
metadata_initialize_kokkos_category()
{
get_data_processor().insert_category(
rocprofsys::category_enum_id<category::kokkos>::value,
rocprofsys::trace_cache::get_metadata_registry().add_string(
rocprofsys::trait::name<category::kokkos>::value);
}
void
rocpd_initialize_kokkos_track()
metadata_initialize_kokkos_track()
{
auto& data_processor = get_data_processor();
auto& n_info = rocprofsys::node_info::get_instance();
auto thread_id = std::nullopt;
data_processor.insert_track(rocprofsys::trait::name<category::kokkos>::value,
n_info.id, getpid(), thread_id);
rocprofsys::trace_cache::get_metadata_registry().add_track(
{ rocprofsys::trait::name<category::kokkos>::value, std::nullopt, "{}" });
}
void
rocpd_process_kokkos_event(const char* name, const char* event_type, const char* target,
uint64_t timestamp_ns)
cache_kokkos_event(const char* name, const char* event_type, const char* target,
uint64_t timestamp_ns)
{
auto& data_processor = get_data_processor();
auto event_metadata = rocpd::json::create();
auto event_metadata = rocpd::json::create();
event_metadata->set("name", name);
event_metadata->set("event_type", event_type);
event_metadata->set("target", target);
auto event_id = data_processor.insert_event(
rocprofsys::category_enum_id<category::kokkos>::value, 0, 0, 0, "{}", "{}",
event_metadata->to_string().c_str());
data_processor.insert_sample(rocprofsys::trait::name<category::kokkos>::value,
timestamp_ns, event_id, "{}");
const size_t stack_id = 0;
const size_t parent_stack_id = 0;
const size_t correlation_id = 0;
const char* call_stack = "{}";
const char* line_info = "{}";
rocprofsys::trace_cache::get_buffer_storage().store(
rocprofsys::trace_cache::entry_type::in_time_sample,
rocprofsys::trait::name<category::kokkos>::value, timestamp_ns,
event_metadata->to_string().c_str(), stack_id, parent_stack_id, correlation_id,
call_stack, line_info);
}
} // namespace
@@ -308,11 +304,8 @@ extern "C"
rocprofsys_init_hidden(_mode.c_str(), false, _arg0.c_str());
rocprofsys_push_trace_hidden("kokkos_main");
if(rocprofsys::get_use_rocpd())
{
rocpd_initialize_kokkos_category();
rocpd_initialize_kokkos_track();
}
metadata_initialize_kokkos_category();
metadata_initialize_kokkos_track();
}
setup_kernel_logger();
@@ -619,12 +612,8 @@ extern "C"
kokkosp::profiler_t<kokkosp_region>{ _name }.mark();
}
if(rocprofsys::config::get_use_rocpd())
{
rocpd_process_kokkos_event(JOIN(" ", _kp_prefix, label).c_str(),
"[dual_view_sync]",
(is_device) ? "device" : "host", timestamp);
}
cache_kokkos_event(JOIN(" ", _kp_prefix, label).c_str(), "[dual_view_sync]",
(is_device) ? "device" : "host", timestamp);
}
void kokkosp_dual_view_modify(const char* label, const void* const, bool is_device)
@@ -648,12 +637,8 @@ extern "C"
kokkosp::profiler_t<kokkosp_region>{ _name }.mark();
}
if(rocprofsys::config::get_use_rocpd())
{
rocpd_process_kokkos_event(JOIN(" ", _kp_prefix, label).c_str(),
"[dual_view_modify]",
(is_device) ? "device" : "host", timestamp);
}
cache_kokkos_event(JOIN(" ", _kp_prefix, label).c_str(), "[dual_view_modify]",
(is_device) ? "device" : "host", timestamp);
}
//----------------------------------------------------------------------------------//
@@ -20,24 +20,31 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#include "library/rocprofiler-sdk.hpp"
#include "core/rocprofiler-sdk.hpp"
#include "api.hpp"
#include "common/synchronized.hpp"
#include "core/common.hpp"
#include "core/config.hpp"
#include "core/containers/stable_vector.hpp"
#include "core/debug.hpp"
#include "core/gpu.hpp"
#include "core/perfetto.hpp"
#include "core/rocprofiler-sdk.hpp"
#include "core/rocpd/json.hpp"
#include "core/state.hpp"
#include "core/trace_cache/buffer_storage.hpp"
#include "core/trace_cache/cache_manager.hpp"
#include "core/trace_cache/metadata_registry.hpp"
#include "core/trace_cache/sample_type.hpp"
#include "library/amd_smi.hpp"
#include "library/components/category_region.hpp"
#include "library/rocprofiler-sdk.hpp"
#include "library/rocprofiler-sdk/counters.hpp"
#include "library/rocprofiler-sdk/fwd.hpp"
#include "library/rocprofiler-sdk/rccl.hpp"
#include "library/thread_info.hpp"
#include "library/tracing.hpp"
#include <algorithm>
#include <timemory/components/timing/wall_clock.hpp>
#include <timemory/hash/types.hpp>
#include <timemory/unwind/processed_entry.hpp>
@@ -247,7 +254,7 @@ create_agent_profile(rocprofiler_agent_id_t agent_id,
ROCPROFSYS_ABORT_F(
"Unable to find all counters for agent %i (gpu-%li, %s) in %s. Found: %s\n",
tool_agent_v->agent->node_id, tool_agent_v->device_id,
tool_agent_v->agent->name, requested_counters.c_str(),
tool_agent_v->agent->name.c_str(), requested_counters.c_str(),
found_counters.c_str());
}
@@ -270,6 +277,12 @@ get_kernel_symbol_info(uint64_t _kernel_id)
return tool_data->get_kernel_symbol_info(_kernel_id);
}
const rocprofiler_callback_tracing_code_object_load_data_t*
get_code_object_info(uint64_t _code_object_id)
{
return tool_data->get_code_object_info(_code_object_id);
}
// Implementation of rocprofiler_callback_tracing_operation_args_cb_t
int
save_args(rocprofiler_callback_tracing_kind_t /*kind*/, int32_t /*operation*/,
@@ -283,6 +296,22 @@ save_args(rocprofiler_callback_tracing_kind_t /*kind*/, int32_t /*operation*/,
return 0;
}
// Additional implementation of rocprofiler_callback_tracing_operation_args_cb_t
// for iterating through arguments in a callback for rocpd_arg table in database
int
iterate_args_callback(rocprofiler_callback_tracing_kind_t /*kind*/, int32_t /*operation*/,
uint32_t arg_number, const void* const /*arg_value_addr*/,
int32_t /*arg_indirection_count*/, const char* arg_type,
const char* arg_name, const char* arg_value_str,
int32_t /*arg_dereference_count*/, void* data)
{
auto* _data = static_cast<function_args_t*>(data);
if(arg_type && arg_name && arg_value_str)
_data->emplace_back(
argument_info{ arg_number, demangle(arg_type), arg_name, arg_value_str });
return 0;
}
auto&
get_marker_pushed_ranges()
{
@@ -299,6 +328,294 @@ get_marker_started_ranges()
return _v;
}
template <typename Tp, typename... Args>
Tp*
as_pointer(Args&&... _args)
{
return new Tp{ std::forward<Args>(_args)... };
}
template <typename... Tp>
void
consume_args(Tp&&...)
{}
auto
get_backtrace(std::optional<std::vector<tim::unwind::processed_entry>>& _bt_data)
{
auto backtrace = ::rocpd::json::create();
if(_bt_data && !_bt_data->empty())
{
const std::string _unk = "??";
size_t _bt_cnt = 0;
for(const auto& itr : *_bt_data)
{
auto _linfo = itr.lineinfo.get();
const auto* _func = (itr.name.empty()) ? &_unk : &itr.name;
const auto* _loc = (_linfo && !_linfo.location.empty())
? &_linfo.location
: ((itr.location.empty()) ? &_unk : &itr.location);
auto _line =
(_linfo && _linfo.line > 0)
? join("", _linfo.line)
: ((itr.lineno == 0) ? std::string{ "?" } : join("", itr.lineno));
auto _entry = join("", demangle(*_func), " @ ",
join(':', ::basename(_loc->c_str()), _line));
backtrace->set(join("", "frame#", _bt_cnt++), _entry);
}
}
return backtrace;
}
template <typename CorrelationIdType>
uint64_t
get_parent_stack_id([[maybe_unused]] const CorrelationIdType& correlation_id)
{
#if(ROCPROFILER_VERSION >= 700)
if constexpr(std::is_same_v<rocprofiler_correlation_id_t, CorrelationIdType>)
{
return correlation_id.ancestor;
}
else
{
return 0;
}
#else
return 0;
#endif
}
auto
get_extdata(const rocprofiler_callback_tracing_record_t& record)
{
constexpr auto message_key = "message";
auto args = callback_arg_array_t{};
auto extdata = ::rocpd::json::create();
rocprofiler_iterate_callback_tracing_kind_operation_args(record, save_args, 2, &args);
for(auto [key, val] : args)
{
if(key == message_key)
{
extdata->set(key, val);
}
}
return extdata;
}
struct scope_destructor
{
/// \fn scope_destructor(FuncT&& _fini, InitT&& _init)
/// \tparam FuncT "std::function<void()> or void (*)()"
/// \tparam InitT "std::function<void()> or void (*)()"
/// \param _fini Function to execute when object is destroyed
/// \param _init Function to execute when object is created (optional)
///
/// \brief Provides a utility to perform an operation when exiting a scope.
template <typename FuncT, typename InitT = void (*)()>
scope_destructor(FuncT&& _fini, InitT&& _init = []() {});
~scope_destructor() { m_functor(); }
// delete copy operations
scope_destructor(const scope_destructor&) = delete;
scope_destructor& operator=(const scope_destructor&) = delete;
// allow move operations
scope_destructor(scope_destructor&& rhs) noexcept;
scope_destructor& operator=(scope_destructor&& rhs) noexcept;
private:
std::function<void()> m_functor = []() {};
};
template <typename FuncT, typename InitT>
scope_destructor::scope_destructor(FuncT&& _fini, InitT&& _init)
: m_functor{ std::forward<FuncT>(_fini) }
{
_init();
}
inline scope_destructor::scope_destructor(scope_destructor&& rhs) noexcept
: m_functor{ std::move(rhs.m_functor) }
{
rhs.m_functor = []() {};
}
inline scope_destructor&
scope_destructor::operator=(scope_destructor&& rhs) noexcept
{
if(this != &rhs)
{
m_functor = std::move(rhs.m_functor);
rhs.m_functor = []() {};
}
return *this;
}
using kernel_rename_stack_t = std::stack<uint64_t>;
thread_local auto thread_dispatch_rename = as_pointer<kernel_rename_stack_t>();
thread_local auto thread_dispatch_rename_dtor = scope_destructor{ []() {
delete thread_dispatch_rename;
thread_dispatch_rename = nullptr;
} };
template <typename Category>
void
cache_category()
{
trace_cache::get_metadata_registry().add_string(trait::name<Category>::value);
}
void
cache_add_thread_info(uint64_t tid)
{
trace_cache::get_metadata_registry().add_thread_info(
{ getppid(), getpid(), tid, 0, 0, "{}" });
}
void
cache_add_track(const char* track_name, uint64_t tid)
{
trace_cache::get_metadata_registry().add_track({ track_name, tid, "{}" });
}
size_t
get_mem_copy_dst_address(
[[maybe_unused]] const rocprofiler_buffer_tracing_memory_copy_record_t& record)
{
#if(ROCPROFILER_VERSION >= 700)
return record.dst_address.value;
#else
return 0;
#endif
}
size_t
get_mem_copy_src_address(
[[maybe_unused]] const rocprofiler_buffer_tracing_memory_copy_record_t& record)
{
#if(ROCPROFILER_VERSION >= 700)
return record.src_address.value;
#else
return 0;
#endif
}
#if(ROCPROFILER_VERSION >= 600)
size_t
get_mem_alloc_address(
[[maybe_unused]] const rocprofiler_buffer_tracing_memory_allocation_record_t& record)
{
# if(ROCPROFILER_VERSION >= 700)
return record.address.value;
# else
return static_cast<size_t>(record.address.handle);
# endif
}
#endif
// clang-format off
void
cache_region(const rocprofiler_callback_tracing_record_t* record,
const rocprofiler_timestamp_t start_timestamp,
const rocprofiler_timestamp_t end_timestamp, const std::string& call_stack,
const std::string& args_str, const std::string& category)
{
trace_cache::get_buffer_storage().store(
trace_cache::entry_type::region,
record->thread_id,
static_cast<int32_t>(record->kind),
static_cast<int32_t>(record->operation),
record->correlation_id.internal,
get_parent_stack_id(record->correlation_id),
start_timestamp,
end_timestamp,
call_stack.c_str(),
args_str.c_str(),
category.c_str());
}
void
cache_kernel_dispatch(rocprofiler_buffer_tracing_kernel_dispatch_record_t* record)
{
auto stream_handle = get_stream_id(record).handle;
auto queue_handle = record->dispatch_info.queue_id.handle;
trace_cache::get_metadata_registry().add_queue(queue_handle);
trace_cache::get_metadata_registry().add_stream(stream_handle);
trace_cache::get_buffer_storage().store(
trace_cache::entry_type::kernel_dispatch,
record->start_timestamp,
record->end_timestamp,
record->thread_id,
record->dispatch_info.agent_id.handle,
record->dispatch_info.kernel_id,
record->dispatch_info.dispatch_id,
record->dispatch_info.queue_id.handle,
record->correlation_id.internal,
get_parent_stack_id(record->correlation_id),
record->dispatch_info.private_segment_size,
record->dispatch_info.group_segment_size,
record->dispatch_info.workgroup_size.x,
record->dispatch_info.workgroup_size.y,
record->dispatch_info.workgroup_size.z,
record->dispatch_info.grid_size.x,
record->dispatch_info.grid_size.y,
record->dispatch_info.grid_size.z,
stream_handle);
}
void
cache_memory_copy(rocprofiler_buffer_tracing_memory_copy_record_t* record)
{
auto stream_handle = get_stream_id(record).handle;
trace_cache::get_buffer_storage().store(
trace_cache::entry_type::memory_copy,
record->start_timestamp,
record->end_timestamp,
record->thread_id,
record->dst_agent_id.handle,
record->src_agent_id.handle,
static_cast<int32_t>(record->kind),
static_cast<int32_t>(record->operation),
record->bytes,
record->correlation_id.internal,
get_parent_stack_id(record->correlation_id),
get_mem_copy_dst_address(*record),
get_mem_copy_src_address(*record),
stream_handle);
}
#if (ROCPROFILER_VERSION >= 600)
void
cache_memory_allocation(rocprofiler_buffer_tracing_memory_allocation_record_t* record)
{
auto stream_handle = get_stream_id(record).handle;
trace_cache::get_metadata_registry().add_stream(stream_handle);
trace_cache::get_buffer_storage().store(
trace_cache::entry_type::memory_alloc,
record->start_timestamp,
record->end_timestamp,
record->thread_id,
record->agent_id.handle,
static_cast<int32_t>(record->kind),
static_cast<int32_t>(record->operation),
record->allocation_size,
record->correlation_id.internal,
get_parent_stack_id(record->correlation_id),
get_mem_alloc_address(*record),
stream_handle);
}
#endif
// clang-format on
template <typename CategoryT>
void
tool_tracing_callback_start(CategoryT, rocprofiler_callback_tracing_record_t record,
@@ -391,7 +708,8 @@ tool_tracing_callback_stop(
{
ROCPROFSYS_CONDITIONAL_ABORT_F(
get_marker_started_ranges().empty(),
"roctxRangeStop does not have corresponding roctxRangeStart on "
"roctxRangeStop does not have corresponding roctxRangeStart "
"on "
"this thread");
auto _hash = get_marker_started_ranges().back().first;
@@ -473,8 +791,9 @@ tool_tracing_callback_stop(
join(':', ::basename(_loc->c_str()), _line));
if(_bt_cnt < 10)
{
// Prepend zero for better ordering in UI. Only one zero
// is ever necessary since stack depth is limited to 16.
// Prepend zero for better ordering in UI. Only one
// zero is ever necessary since stack depth is limited
// to 16.
tracing::add_perfetto_annotation(
ctx, join("", "frame#0", _bt_cnt++), _entry);
}
@@ -493,6 +812,33 @@ tool_tracing_callback_stop(
tracing::add_perfetto_annotation(ctx, "end_ns", _end_ts);
});
}
// Insert callback trace into database
auto args = function_args_t{};
rocprofiler_iterate_callback_tracing_kind_operation_args(
record, iterate_args_callback, 2, &args);
auto call_stack = get_backtrace(_bt_data);
uint64_t _beg_ts = user_data->value;
uint64_t _end_ts = ts;
{
cache_category<CategoryT>();
cache_add_thread_info(record.thread_id);
std::string args_str;
std::for_each(args.begin(), args.end(), [&args_str](const argument_info& arg) {
const auto* delimiter = ";;";
std::stringstream ss;
ss << arg.arg_number << delimiter << arg.arg_type << delimiter << arg.arg_name
<< delimiter << arg.arg_value << delimiter;
args_str.append(ss.str());
});
cache_region(&record, _beg_ts, _end_ts, call_stack->to_string(), args_str,
trait::name<CategoryT>::value);
}
}
void
@@ -535,6 +881,7 @@ tool_code_object_callback(rocprofiler_callback_tracing_record_t record,
_data.emplace_back(
code_object_callback_record_t{ ts, record, data_v });
});
trace_cache::get_metadata_registry().add_code_object(data_v);
}
else if(record.operation ==
ROCPROFILER_CODE_OBJECT_DEVICE_KERNEL_SYMBOL_REGISTER)
@@ -545,6 +892,7 @@ tool_code_object_callback(rocprofiler_callback_tracing_record_t record,
_data.emplace_back(
new kernel_symbol_callback_record_t{ ts, record, data_v });
});
trace_cache::get_metadata_registry().add_kernel_symbol(data_v);
}
}
return;
@@ -635,7 +983,6 @@ tool_tracing_callback(rocprofiler_callback_tracing_record_t record,
case ROCPROFILER_CALLBACK_TRACING_MEMORY_COPY:
#if(ROCPROFILER_VERSION >= 600)
case ROCPROFILER_CALLBACK_TRACING_OMPT:
case ROCPROFILER_CALLBACK_TRACING_MEMORY_ALLOCATION:
case ROCPROFILER_CALLBACK_TRACING_RUNTIME_INITIALIZATION:
#endif
#if(ROCPROFILER_VERSION >= 700)
@@ -646,6 +993,12 @@ tool_tracing_callback(rocprofiler_callback_tracing_record_t record,
record.kind);
break;
}
default:
{
ROCPROFSYS_CI_ABORT(true, "Unhandled callback record: \n\t%s\n",
info.str().c_str());
break;
}
}
}
else if(record.phase == ROCPROFILER_CALLBACK_PHASE_EXIT)
@@ -657,8 +1010,11 @@ tool_tracing_callback(rocprofiler_callback_tracing_record_t record,
constexpr bool bt_with_signal_frame = true;
auto _bt_data = std::optional<backtrace_entry_vec_t>{};
auto use_perfetto =
(config::get_use_perfetto() && config::get_perfetto_annotations());
auto use_rocpd = config::get_use_rocpd();
if(config::get_use_perfetto() && config::get_perfetto_annotations() &&
if((use_perfetto || use_rocpd) &&
tool_data->backtrace_operations.at(record.kind).count(record.operation) > 0)
{
auto _backtrace = tim::get_unw_stack<bt_stack_depth, bt_ignore_depth,
@@ -735,7 +1091,6 @@ tool_tracing_callback(rocprofiler_callback_tracing_record_t record,
case ROCPROFILER_CALLBACK_TRACING_MEMORY_COPY:
#if(ROCPROFILER_VERSION >= 600)
case ROCPROFILER_CALLBACK_TRACING_OMPT:
case ROCPROFILER_CALLBACK_TRACING_MEMORY_ALLOCATION:
case ROCPROFILER_CALLBACK_TRACING_RUNTIME_INITIALIZATION:
#endif
#if(ROCPROFILER_VERSION >= 700)
@@ -746,27 +1101,41 @@ tool_tracing_callback(rocprofiler_callback_tracing_record_t record,
record.kind);
break;
}
default:
{
ROCPROFSYS_CI_ABORT(true, "Unhandled callback record\n\t%s\n",
info.str().c_str());
break;
}
}
}
else if(record.phase == ROCPROFILER_CALLBACK_PHASE_NONE)
{
if(record.kind == ROCPROFILER_CALLBACK_TRACING_KERNEL_DISPATCH &&
record.operation == ROCPROFILER_KERNEL_DISPATCH_COMPLETE)
switch(record.kind)
{
auto* _data =
static_cast<rocprofiler_callback_tracing_kernel_dispatch_data_t*>(
record.payload);
case ROCPROFILER_CALLBACK_TRACING_KERNEL_DISPATCH:
{
if(record.operation == ROCPROFILER_KERNEL_DISPATCH_COMPLETE)
{
auto* _data =
static_cast<rocprofiler_callback_tracing_kernel_dispatch_data_t*>(
record.payload);
// save for post-processing
get_kernel_dispatch_timestamps().emplace(
_data->dispatch_info.dispatch_id,
timing_interval{ _data->start_timestamp, _data->end_timestamp });
}
else
{
ROCPROFSYS_WARNING_F(
1, "tool_tracing_callback: unhandled PHASE_NONE callback record\n\t%s\n",
info.str().c_str());
// save for post-processing
get_kernel_dispatch_timestamps().emplace(
_data->dispatch_info.dispatch_id,
timing_interval{ _data->start_timestamp, _data->end_timestamp });
}
}
break;
default:
{
ROCPROFSYS_WARNING_F(1,
"tool_tracing_callback: unhandled PHASE_NONE "
"callback record\n\t%s\n",
info.str().c_str());
}
break;
}
}
else
@@ -820,10 +1189,20 @@ tool_tracing_buffered(rocprofiler_context_id_t /*context*/,
uint64_t _stream_id = get_stream_id(record).handle;
if(_stream_id == 0)
{
// kernel is not associated with a HIP stream
// kernel_dispatch is not associated with a HIP stream
_group_by_queue = true;
}
{
cache_category<category::rocm_kernel_dispatch>();
cache_add_thread_info(record->thread_id);
cache_add_track(JOIN("", "GPU Kernel Dispatch [", _agent->device_id,
"] Queue ", _queue_id.handle)
.c_str(),
record->thread_id);
cache_kernel_dispatch(record);
}
if(get_use_timemory())
{
const auto& _tinfo = thread_info::get(record->thread_id, SystemTID);
@@ -937,6 +1316,20 @@ tool_tracing_buffered(rocprofiler_context_id_t /*context*/,
_group_by_queue = true;
}
{
size_t thread_idx = record->thread_id;
std::string track_name;
track_name =
JOIN("", "GPU Memory Copy to Agent [",
_dst_agent->logical_node_id, "] Thread ", thread_idx);
cache_category<category::rocm_memory_copy>();
cache_add_track(track_name.c_str(), record->thread_id);
cache_memory_copy(record);
}
if(get_use_timemory())
{
const auto& _tinfo = thread_info::get(record->thread_id, SystemTID);
@@ -1005,6 +1398,26 @@ tool_tracing_buffered(rocprofiler_context_id_t /*context*/,
}
}
}
#if(ROCPROFILER_VERSION >= 600)
else if(header->kind == ROCPROFILER_BUFFER_TRACING_MEMORY_ALLOCATION)
{
auto* record =
static_cast<rocprofiler_buffer_tracing_memory_allocation_record_t*>(
header->payload);
{
cache_category<category::rocm_memory_allocate>();
cache_add_thread_info(record->thread_id);
cache_memory_allocation(record);
}
}
#endif
else if(header->kind == ROCPROFILER_BUFFER_TRACING_HSA_CORE_API ||
header->kind == ROCPROFILER_BUFFER_TRACING_HSA_AMD_EXT_API)
{
// Not handling those buffered events
continue;
}
else
{
ROCPROFSYS_THROW(
@@ -1098,10 +1511,10 @@ counter_record_callback(rocprofiler_dispatch_counting_service_data_t dispatch_da
ROCPROFSYS_CONDITIONAL_ABORT_F(
!_agent, "unable to find tool agent for agent (id=%zu)\n",
_agent_id.handle);
ROCPROFSYS_CONDITIONAL_ABORT_F(
!_info,
"unable to find counter info for counter (id=%zu) on agent (id=%zu)\n",
itr.first.handle, _agent_id.handle);
ROCPROFSYS_CONDITIONAL_ABORT_F(!_info,
"unable to find counter info for counter "
"(id=%zu) on agent (id=%zu)\n",
itr.first.handle, _agent_id.handle);
auto _dev_id = static_cast<uint32_t>(_agent->device_id);
@@ -1159,7 +1572,6 @@ void
flush()
{
if(!tool_data) return;
for(auto itr : tool_data->get_buffers())
{
if(itr.handle > 0)
@@ -1268,6 +1680,24 @@ tool_init(rocprofiler_client_finalize_t fini_func, void* user_data)
_data->primary_ctx, ROCPROFILER_CALLBACK_TRACING_CODE_OBJECT, nullptr, 0,
tool_code_object_callback, _data));
auto external_corr_id_request_kinds =
std::array<rocprofiler_external_correlation_id_request_kind_t, 3>{
ROCPROFILER_EXTERNAL_CORRELATION_REQUEST_KERNEL_DISPATCH,
ROCPROFILER_EXTERNAL_CORRELATION_REQUEST_MEMORY_COPY,
#if(ROCPROFILER_VERSION >= 600)
ROCPROFILER_EXTERNAL_CORRELATION_REQUEST_MEMORY_ALLOCATION
#endif
};
// Insert the default stream and queue info to ensure that the default entry is
{
trace_cache::get_metadata_registry().add_stream(0);
trace_cache::get_metadata_registry().add_queue(0);
}
// ROCPROFILER_CALL(rocprofiler_configure_callback_tracing_service(
// _data->primary_ctx, ROCPROFILER_CALLBACK_TRACING_CODE_OBJECT, nullptr, 0,
// tool_code_object_callback, _data));
for(auto itr : {
ROCPROFILER_CALLBACK_TRACING_HSA_CORE_API,
ROCPROFILER_CALLBACK_TRACING_HSA_AMD_EXT_API,
@@ -1296,17 +1726,8 @@ tool_init(rocprofiler_client_finalize_t fini_func, void* user_data)
}
}
constexpr auto buffer_size = 8192;
constexpr auto watermark = 7936;
// Configure external correlation id request service for kernel dispatch
// and memory copy.
auto external_corr_id_request_kinds =
std::array<rocprofiler_external_correlation_id_request_kind_t, 2>{
ROCPROFILER_EXTERNAL_CORRELATION_REQUEST_KERNEL_DISPATCH,
ROCPROFILER_EXTERNAL_CORRELATION_REQUEST_MEMORY_COPY
};
constexpr auto buffer_size = 16 * 4096;
constexpr auto watermark = 15 * 4096;
ROCPROFILER_CALL(rocprofiler_configure_external_correlation_id_request_service(
_data->primary_ctx, external_corr_id_request_kinds.data(),
@@ -1334,7 +1755,8 @@ tool_init(rocprofiler_client_finalize_t fini_func, void* user_data)
_data->primary_ctx, ROCPROFILER_BUFFER_TRACING_KERNEL_DISPATCH, nullptr, 0,
_data->kernel_dispatch_buffer));
}
// ROCPROFILER_BUFFER_TRACING_HSA_CORE_API, ///< @see
// ::rocprofiler_hsa_core_api_id_t ROCPROFILER_BUFFER_TRACING_HSA_AMD_EXT_API,
if(_buffered_domain.count(ROCPROFILER_BUFFER_TRACING_MEMORY_COPY) > 0)
{
ROCPROFILER_CALL(rocprofiler_create_buffer(
@@ -1347,19 +1769,39 @@ tool_init(rocprofiler_client_finalize_t fini_func, void* user_data)
_data->memory_copy_buffer));
}
#if(ROCPROFILER_VERSION >= 600)
if(_buffered_domain.count(ROCPROFILER_BUFFER_TRACING_MEMORY_ALLOCATION) > 0)
{
ROCPROFILER_CALL(rocprofiler_create_buffer(
_data->primary_ctx, buffer_size, watermark,
ROCPROFILER_BUFFER_POLICY_LOSSLESS, tool_tracing_buffered, tool_data,
&_data->memory_alloc_buffer));
if(_data->memory_alloc_buffer.handle == 0UL)
{
ROCPROFSYS_CI_ABORT(true, "Failed to create memory allocation buffer\n");
}
auto _ops =
rocprofiler_sdk::get_operations(ROCPROFILER_BUFFER_TRACING_MEMORY_ALLOCATION);
ROCPROFILER_CALL(rocprofiler_configure_buffer_tracing_service(
_data->primary_ctx, ROCPROFILER_BUFFER_TRACING_MEMORY_ALLOCATION, nullptr, 0,
_data->memory_alloc_buffer));
}
#endif
if(!_counter_events.empty())
{
for(const auto& itr : _data->gpu_agents)
{
const auto& _agent_id = rocprofiler_agent_id_t{ itr.agent->handle };
_data->agent_events.emplace(
itr.agent->id,
create_agent_profile(itr.agent->id, _counter_events, _data));
_agent_id, create_agent_profile(_agent_id, _counter_events, _data));
}
ROCPROFILER_CALL(rocprofiler_create_context(&_data->counter_ctx));
auto _operations = std::array<rocprofiler_tracing_operation_t, 1>{
ROCPROFILER_KERNEL_DISPATCH_COMPLETE
ROCPROFILER_KERNEL_DISPATCH_COMPLETE,
};
ROCPROFILER_CALL(rocprofiler_configure_callback_tracing_service(
@@ -1393,8 +1835,9 @@ tool_init(rocprofiler_client_finalize_t fini_func, void* user_data)
}
}
// throwaway context for handling the profiler control API. If primary_ctx were used,
// we would get profiler pause callback but never get profiler resume callback
// throwaway context for handling the profiler control API. If primary_ctx were
// used, we would get profiler pause callback but never get profiler resume
// callback
{
auto _local_ctx = rocprofiler_context_id_t{ 0 };
ROCPROFILER_CALL(rocprofiler_create_context(&_local_ctx));
@@ -1405,8 +1848,8 @@ tool_init(rocprofiler_client_finalize_t fini_func, void* user_data)
if(!is_valid(_data->primary_ctx))
{
// notify rocprofiler that initialization failed and all the contexts, buffers,
// etc. created should be ignored
// notify rocprofiler that initialization failed and all the contexts,
// buffers, etc. created should be ignored
return -1;
}
@@ -1454,13 +1897,7 @@ tool_fini(void* callback_data)
void
setup()
{
if(int status = 0;
rocprofiler_is_initialized(&status) == ROCPROFILER_STATUS_SUCCESS && status == 0)
{
ROCPROFILER_CALL(rocprofiler_force_configure(&rocprofiler_configure));
}
}
{}
void
shutdown()
@@ -91,15 +91,17 @@ get_agent_counter_info(const tool_agent_vec_t& _agents)
for(auto itr : _agents)
{
ROCPROFILER_CALL(rocprofiler_iterate_agent_supported_counters(
itr.agent->id, counters_supported_callback, &_data));
const auto& _agent_id = rocprofiler_agent_id_t{ itr.agent->handle };
std::sort(_data.at(itr.agent->id).begin(), _data.at(itr.agent->id).end(),
ROCPROFILER_CALL(rocprofiler_iterate_agent_supported_counters(
_agent_id, counters_supported_callback, &_data));
std::sort(_data.at(_agent_id).begin(), _data.at(_agent_id).end(),
[](const auto& lhs, const auto& rhs) {
return (lhs.id.handle < rhs.id.handle);
});
for(auto& citr : _data.at(itr.agent->id))
for(auto& citr : _data.at(_agent_id))
{
std::sort(citr.dimension_info.begin(), citr.dimension_info.end(),
[](const auto& lhs, const auto& rhs) { return (lhs.id < rhs.id); });
@@ -123,38 +125,16 @@ client_data::initialize()
buffered_tracing_info = rocprofiler::sdk::get_buffer_tracing_names();
callback_tracing_info = rocprofiler::sdk::get_callback_tracing_names();
static constexpr auto supported_agent_info_version = ROCPROFILER_AGENT_INFO_VERSION_0;
rocprofiler_query_available_agents_cb_t iterate_cb =
[](rocprofiler_agent_version_t version, const void** agents_arr,
size_t num_agents, void* user_data) {
ROCPROFSYS_CONDITIONAL_ABORT(version != supported_agent_info_version,
"rocprofiler agent info version != expected "
"agent info version (=%i). value: %i\n",
supported_agent_info_version, version);
auto _agents_v = std::vector<rocprofiler_agent_v0_t>{};
for(size_t i = 0; i < num_agents; ++i)
{
const auto* _agent =
static_cast<const rocprofiler_agent_v0_t*>(agents_arr[i]);
_agents_v.emplace_back(*_agent);
}
auto* tool_data_v = as_client_data(user_data);
tool_data_v->set_agents(std::move(_agents_v));
return ROCPROFILER_STATUS_SUCCESS;
};
ROCPROFILER_CALL(rocprofiler_query_available_agents(
supported_agent_info_version, iterate_cb, sizeof(rocprofiler_agent_t), this));
set_agents();
}
void
client_data::initialize_event_info()
{
if(agents.empty()) initialize();
if(agent_manager::get_instance().get_agents().empty())
{
initialize();
}
if(agent_counter_info.size() != gpu_agents.size())
agent_counter_info = get_agent_counter_info(gpu_agents);
@@ -166,14 +146,15 @@ client_data::initialize_event_info()
for(const auto& aitr : gpu_agents)
{
auto _dev_index = aitr.device_id;
auto _device_qualifier_sym = JOIN("", ":device=", _dev_index);
auto _device_qualifier =
auto _dev_index = aitr.device_id;
const auto& _agent_id = rocprofiler_agent_id_t{ aitr.agent->handle };
auto _device_qualifier_sym = JOIN("", ":device=", _dev_index);
auto _device_qualifier =
tim::hardware_counters::qualifier{ true, static_cast<int>(_dev_index),
_device_qualifier_sym,
JOIN(" ", "Device", _dev_index) };
auto _counter_info = agent_counter_info.at(aitr.agent->id);
auto _counter_info = agent_counter_info.at(_agent_id);
std::sort(_counter_info.begin(), _counter_info.end(),
[](const rocprofiler_tool_counter_info_t& lhs,
const rocprofiler_tool_counter_info_t& rhs) {
@@ -248,23 +229,20 @@ client_data::initialize_event_info()
}
void
client_data::set_agents(agent_vec_t&& _agents_v)
client_data::set_agents()
{
agents = std::move(_agents_v);
auto& agent_mngr = agent_manager::get_instance();
std::sort(agents.begin(), agents.end(),
[](const auto& lhs, const auto& rhs) { return lhs.node_id < rhs.node_id; });
auto fill_agents = [&](agent_type type, std::vector<tool_agent>& out) {
const auto& _agents = agent_mngr.get_agents_by_type(type);
for(const auto& agent : _agents)
{
out.emplace_back(tool_agent{ agent->device_type_index, agent.get() });
}
};
cpu_agents.clear();
gpu_agents.clear();
for(const auto& itr : agents)
{
if(itr.type == ROCPROFILER_AGENT_TYPE_CPU)
cpu_agents.emplace_back(tool_agent{ cpu_agents.size(), &itr });
else if(itr.type == ROCPROFILER_AGENT_TYPE_GPU)
gpu_agents.emplace_back(tool_agent{ gpu_agents.size(), &itr });
}
fill_agents(agent_type::GPU, gpu_agents);
fill_agents(agent_type::CPU, cpu_agents);
}
} // namespace rocprofiler_sdk
} // namespace rocprofsys
@@ -23,6 +23,7 @@
#pragma once
#include "common/synchronized.hpp"
#include "core/agent_manager.hpp"
#include "core/timemory.hpp"
#include <rocprofiler-sdk/agent.h>
@@ -50,6 +51,8 @@ using kernel_symbol_map_t =
std::unordered_map<rocprofiler_kernel_id_t, kernel_symbol_data_t>;
using callback_arg_array_t = std::vector<std::pair<std::string, std::string>>;
using rocprofsys_agent_t = agent;
struct code_object_callback_record_t
{
uint64_t timestamp = 0;
@@ -88,8 +91,8 @@ struct rocprofiler_tool_counter_info_t : rocprofiler_counter_info_v0_t
struct tool_agent
{
uint64_t device_id = 0;
const rocprofiler_agent_v0_t* agent = nullptr;
uint64_t device_id = 0;
const rocprofsys_agent_t* agent = nullptr;
};
struct timing_interval
@@ -98,6 +101,16 @@ struct timing_interval
rocprofiler_timestamp_t end = 0;
};
struct argument_info
{
uint32_t arg_number = 0;
std::string arg_type = {};
std::string arg_name = {};
std::string arg_value = {};
};
using function_args_t = std::vector<argument_info>;
using agent_counter_info_map_t =
std::unordered_map<rocprofiler_agent_id_t,
std::vector<rocprofiler_tool_counter_info_t>>;
@@ -117,7 +130,7 @@ using backtrace_operation_map_t =
struct client_data
{
static constexpr size_t num_buffers = 3;
static constexpr size_t num_buffers = 4;
static constexpr size_t num_contexts = 2;
using buffer_name_info_t = rocprofiler::sdk::buffer_name_info_t<std::string_view>;
@@ -134,8 +147,8 @@ struct client_data
rocprofiler_context_id_t counter_ctx = { 0 };
rocprofiler_buffer_id_t kernel_dispatch_buffer = { 0 };
rocprofiler_buffer_id_t memory_copy_buffer = { 0 };
rocprofiler_buffer_id_t memory_alloc_buffer = { 0 };
rocprofiler_buffer_id_t counter_collection_buffer = { 0 };
std::vector<rocprofiler_agent_v0_t> agents = {};
std::vector<tool_agent> cpu_agents = {};
std::vector<tool_agent> gpu_agents = {};
std::vector<hardware_counter_info> events_info = {};
@@ -150,14 +163,16 @@ struct client_data
void initialize();
void initialize_event_info();
void set_agents(agent_vec_t&& agents);
void set_agents();
context_id_vec_t get_contexts() const;
buffer_id_vec_t get_buffers() const;
const rocprofiler_agent_t* get_agent(rocprofiler_agent_id_t _id) const;
const rocprofsys_agent_t* get_agent(rocprofiler_agent_id_t _id) const;
const tool_agent* get_gpu_tool_agent(rocprofiler_agent_id_t id) const;
const kernel_symbol_data_t* get_kernel_symbol_info(uint64_t _kernel_id) const;
const rocprofiler_tool_counter_info_t* get_tool_counter_info(
rocprofiler_agent_id_t _agent_id, rocprofiler_counter_id_t _counter_id) const;
const rocprofiler_callback_tracing_code_object_load_data_t* get_code_object_info(
uint64_t code_object_id) const;
};
inline client_data::context_id_vec_t
@@ -175,23 +190,24 @@ client_data::get_buffers() const
return buffer_id_vec_t{
kernel_dispatch_buffer,
memory_copy_buffer,
memory_alloc_buffer,
counter_collection_buffer,
};
}
inline const rocprofiler_agent_t*
inline const rocprofsys_agent_t*
client_data::get_agent(rocprofiler_agent_id_t _id) const
{
for(const auto& itr : agents)
if(itr.id == _id) return &itr;
return nullptr;
const auto& agent = agent_manager::get_instance().get_agent_by_handle(_id.handle);
return &agent;
}
inline const tool_agent*
client_data::get_gpu_tool_agent(rocprofiler_agent_id_t id) const
{
for(const auto& itr : gpu_agents)
if(id == itr.agent->id) return &itr;
if(id.handle == itr.agent->handle) return &itr;
return nullptr;
}
@@ -223,6 +239,24 @@ client_data::get_tool_counter_info(rocprofiler_agent_id_t _agent_id,
return nullptr;
}
inline const rocprofiler_callback_tracing_code_object_load_data_t*
client_data::get_code_object_info(uint64_t code_object_id) const
{
return code_object_records.rlock(
[code_object_id](const auto& _data)
-> const rocprofiler_callback_tracing_code_object_load_data_t* {
for(const auto& itr : _data)
{
if(code_object_id == itr.payload.code_object_id)
{
return &itr.payload;
break;
}
}
return nullptr;
});
}
inline constexpr client_data*
as_client_data(void* _ptr)
{
@@ -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