From 51f0a6487c78bc53355365977a92faa817f9c624 Mon Sep 17 00:00:00 2001 From: Kian Cossettini Date: Tue, 24 Feb 2026 08:48:10 -0500 Subject: [PATCH 1/4] Transform "flags" arguments for certain OMPT callbacks into human readable form --- .../rocprof-sys/library/rocprofiler-sdk.cpp | 170 ++++++++++++++++-- 1 file changed, 156 insertions(+), 14 deletions(-) diff --git a/projects/rocprofiler-systems/source/lib/rocprof-sys/library/rocprofiler-sdk.cpp b/projects/rocprofiler-systems/source/lib/rocprof-sys/library/rocprofiler-sdk.cpp index edaee22cbf4f..63a81d7cf282 100644 --- a/projects/rocprofiler-systems/source/lib/rocprof-sys/library/rocprofiler-sdk.cpp +++ b/projects/rocprofiler-systems/source/lib/rocprof-sys/library/rocprofiler-sdk.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -953,6 +954,154 @@ get_kernel_dispatch_timestamps() #if(ROCPROFILER_VERSION >= 600) +/** + * @brief rocprofiler_iterate_callback_tracing_kind_operation_args wrapper for OMPT + * callbacks. + * + * Certain OMPT callbacks have a "flags" argument that contains a bitmask of flags. + * This function decodes the "flags" into a human readable form. + * Works with both callback_arg_array_t (perfetto) and function_args_t (rocpd). + */ +template +void +ompt_iterate_operation_args(const rocprofiler_callback_tracing_record_t& record, + ArgsT& args) +{ + static_assert(std::is_same_v || + std::is_same_v, + "ompt_iterate_operation_args: ArgsT must be callback_arg_array_t or " + "function_args_t"); + + auto ompt_operation_type = + static_cast(record.operation); + auto max_deref = (record.phase == ROCPROFILER_CALLBACK_PHASE_ENTER) ? 1 : 2; + + // Perform standard iteration of arguments + if constexpr(std::is_same_v) + rocprofiler_iterate_callback_tracing_kind_operation_args(record, save_args, + max_deref, &args); + else + rocprofiler_iterate_callback_tracing_kind_operation_args( + record, iterate_args_callback, max_deref, &args); + + static const auto ompt_has_flags = std::set{ + ROCPROFILER_OMPT_ID_parallel_begin, ROCPROFILER_OMPT_ID_parallel_end, + ROCPROFILER_OMPT_ID_task_create, ROCPROFILER_OMPT_ID_implicit_task, + ROCPROFILER_OMPT_ID_cancel, + }; + if(ompt_has_flags.find(ompt_operation_type) == ompt_has_flags.end()) return; + + // Extract flags value from arguments + int flags_val = 0; + for(const auto& entry : args) + { + if constexpr(std::is_same_v) + { + if(entry.first == "flags") + { + flags_val = std::stoi(entry.second); + break; + } + } + else + { + if(entry.arg_name == "flags") + { + flags_val = std::stoi(entry.arg_value); + break; + } + } + } + if(flags_val == 0) return; + + auto append = [&args](const std::string& flag_type, const std::string& key, + const std::string& val) { + if constexpr(std::is_same_v) + args.emplace_back(key, val); + else + args.emplace_back( + argument_info{ static_cast(args.size()), flag_type, key, val }); + }; + + // Textual representation of flags follows from OMPT 5.0 specification + switch(ompt_operation_type) + { + case ROCPROFILER_OMPT_ID_parallel_begin: // ompt_parallel_flag_t + case ROCPROFILER_OMPT_ID_parallel_end: // ompt_parallel_flag_t + { + const auto ft = std::string{ "ompt_parallel_flag_t" }; + if(flags_val & ompt_parallel_invoker_program) + append(ft, "invoker", "program"); + else if(flags_val & ompt_parallel_invoker_runtime) + append(ft, "invoker", "runtime"); + + if(flags_val & ompt_parallel_league) + append(ft, "invoker_cause", "teams_construct"); + else if(flags_val & ompt_parallel_team) + append(ft, "invoker_cause", "parallel_construct"); + break; + } + case ROCPROFILER_OMPT_ID_task_create: // ompt_task_flag_t + { + const auto ft = std::string{ "ompt_task_flag_t" }; + if(flags_val & ompt_task_initial) + append(ft, "classification", "initial"); + else if(flags_val & ompt_task_implicit) + append(ft, "classification", "implicit"); + else if(flags_val & ompt_task_explicit) + append(ft, "classification", "explicit"); + else if(flags_val & ompt_task_target) + append(ft, "classification", "target"); + + // Multiple/none can be set + std::string task_properties; + if(flags_val & ompt_task_undeferred) task_properties += "undeferred, "; + if(flags_val & ompt_task_untied) task_properties += "untied, "; + if(flags_val & ompt_task_final) task_properties += "final, "; + if(flags_val & ompt_task_mergeable) task_properties += "mergeable, "; + if(flags_val & ompt_task_merged) task_properties += "merged, "; + + if(!task_properties.empty()) + task_properties.erase(task_properties.size() - 2); + else + task_properties = "none"; + append(ft, "properties", task_properties); + break; + } + case ROCPROFILER_OMPT_ID_implicit_task: // initial (1) or implicit (2) + { + const auto ft = std::string{ "flags" }; + // As of now, implicit_tasks with ompt_task_initial are filtered out + if(flags_val & ompt_task_initial) + append(ft, "kind", "initial"); + else if(flags_val & ompt_task_implicit) + append(ft, "kind", "implicit"); + break; + } + case ROCPROFILER_OMPT_ID_cancel: // ompt_cancel_flag_t + { + const auto ft = std::string{ "ompt_cancel_flag_t" }; + if(flags_val & ompt_cancel_parallel) + append(ft, "construct", "parallel"); + else if(flags_val & ompt_cancel_sections) + append(ft, "construct", "sections"); + else if(flags_val & ompt_cancel_loop) + append(ft, "construct", "loop"); + else if(flags_val & ompt_cancel_taskgroup) + append(ft, "construct", "taskgroup"); + + if(flags_val & ompt_cancel_activated) + append(ft, "state", "activated"); + else if(flags_val & ompt_cancel_detected) + append(ft, "state", "detected"); + else if(flags_val & ompt_cancel_discarded_task) + append(ft, "state", "discarded_task"); + break; + } + default: break; + } +} + // An instant event is one that has its beg_ts = end_ts void ompt_cache_instant_event( @@ -960,8 +1109,7 @@ ompt_cache_instant_event( std::optional>& _bt_data) { auto args = function_args_t{}; - rocprofiler_iterate_callback_tracing_kind_operation_args( - record, iterate_args_callback, 2, &args); + ompt_iterate_operation_args(record, args); auto call_stack = get_backtrace(_bt_data); cache_category(); @@ -1017,8 +1165,7 @@ ompt_push_standard_callback(const rocprofiler_callback_tracing_record_t& record, const rocprofiler_timestamp_t& _beg_ts) { auto args = function_args_t{}; - rocprofiler_iterate_callback_tracing_kind_operation_args( - record, iterate_args_callback, 1, &args); + ompt_iterate_operation_args(record, args); get_ompt_standard_cb_storage().emplace( record.correlation_id.internal, rocprofsys_ompt_data_storage_t{ record, _beg_ts, args }); @@ -1035,8 +1182,7 @@ ompt_pop_standard_callback( if(it == get_ompt_standard_cb_storage().end()) { auto args = function_args_t{}; - rocprofiler_iterate_callback_tracing_kind_operation_args( - record, iterate_args_callback, 2, &args); + ompt_iterate_operation_args(record, args); ompt_cache_orphan_event(rocprofsys_ompt_data_storage_t{ record, _end_ts, args }, _bt_data); return; @@ -1062,8 +1208,7 @@ ompt_push_parallel_callback(const rocprofiler_callback_tracing_record_t& record, const void* parallel_data_address = payload_data->args.parallel_begin.parallel_data; auto args = function_args_t{}; - rocprofiler_iterate_callback_tracing_kind_operation_args( - record, iterate_args_callback, 1, &args); + ompt_iterate_operation_args(record, args); get_ompt_parallel_cb_storage().emplace( reinterpret_cast(parallel_data_address), rocprofsys_ompt_data_storage_t{ record, _beg_ts, args }); @@ -1085,8 +1230,7 @@ ompt_pop_parallel_callback( if(it == get_ompt_parallel_cb_storage().end()) { auto args = function_args_t{}; - rocprofiler_iterate_callback_tracing_kind_operation_args( - record, iterate_args_callback, 2, &args); + ompt_iterate_operation_args(record, args); ompt_cache_orphan_event(rocprofsys_ompt_data_storage_t{ record, _end_ts, args }, _bt_data); return; @@ -1141,8 +1285,7 @@ ompt_tracing_callback_start(rocprofiler_callback_tracing_record_t record, auto args = callback_arg_array_t{}; if(config::get_perfetto_annotations()) { - rocprofiler_iterate_callback_tracing_kind_operation_args(record, save_args, 1, - &args); + ompt_iterate_operation_args(record, args); } uint64_t _beg_ts = ts; @@ -1187,8 +1330,7 @@ ompt_tracing_callback_stop( auto args = callback_arg_array_t{}; if(config::get_perfetto_annotations()) { - rocprofiler_iterate_callback_tracing_kind_operation_args(record, save_args, 2, - &args); + ompt_iterate_operation_args(record, args); } uint64_t _end_ts = ts; From d54762a0ea6569bec6cd2d947c7776134d8bb6d8 Mon Sep 17 00:00:00 2001 From: Kian Cossettini Date: Tue, 24 Feb 2026 11:02:06 -0500 Subject: [PATCH 2/4] Apply review suggestions --- .../source/lib/rocprof-sys/library/rocprofiler-sdk.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/projects/rocprofiler-systems/source/lib/rocprof-sys/library/rocprofiler-sdk.cpp b/projects/rocprofiler-systems/source/lib/rocprof-sys/library/rocprofiler-sdk.cpp index 63a81d7cf282..8291bc1b46ad 100644 --- a/projects/rocprofiler-systems/source/lib/rocprof-sys/library/rocprofiler-sdk.cpp +++ b/projects/rocprofiler-systems/source/lib/rocprof-sys/library/rocprofiler-sdk.cpp @@ -974,7 +974,10 @@ ompt_iterate_operation_args(const rocprofiler_callback_tracing_record_t& record, auto ompt_operation_type = static_cast(record.operation); - auto max_deref = (record.phase == ROCPROFILER_CALLBACK_PHASE_ENTER) ? 1 : 2; + auto max_deref = (record.phase == ROCPROFILER_CALLBACK_PHASE_ENTER || + ompt_operation_type == ROCPROFILER_OMPT_ID_parallel_begin) + ? 1 + : 2; // Perform standard iteration of arguments if constexpr(std::is_same_v) @@ -1012,7 +1015,6 @@ ompt_iterate_operation_args(const rocprofiler_callback_tracing_record_t& record, } } } - if(flags_val == 0) return; auto append = [&args](const std::string& flag_type, const std::string& key, const std::string& val) { From deb01c60b67a6dcd033bcb2e5997551e4743b358 Mon Sep 17 00:00:00 2001 From: Kian Cossettini Date: Tue, 24 Feb 2026 12:51:36 -0500 Subject: [PATCH 3/4] Apply review suggestions --- .../rocprof-sys/library/rocprofiler-sdk.cpp | 28 ++++++++----------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/projects/rocprofiler-systems/source/lib/rocprof-sys/library/rocprofiler-sdk.cpp b/projects/rocprofiler-systems/source/lib/rocprof-sys/library/rocprofiler-sdk.cpp index 8291bc1b46ad..af460a556148 100644 --- a/projects/rocprofiler-systems/source/lib/rocprof-sys/library/rocprofiler-sdk.cpp +++ b/projects/rocprofiler-systems/source/lib/rocprof-sys/library/rocprofiler-sdk.cpp @@ -995,25 +995,20 @@ ompt_iterate_operation_args(const rocprofiler_callback_tracing_record_t& record, if(ompt_has_flags.find(ompt_operation_type) == ompt_has_flags.end()) return; // Extract flags value from arguments + auto it = std::find_if(args.begin(), args.end(), [](const auto& entry) { + if constexpr(std::is_same_v) + return entry.first == "flags"; + else + return entry.arg_name == "flags"; + }); + int flags_val = 0; - for(const auto& entry : args) + if(it != args.end()) { if constexpr(std::is_same_v) - { - if(entry.first == "flags") - { - flags_val = std::stoi(entry.second); - break; - } - } + flags_val = std::stoi(it->second); else - { - if(entry.arg_name == "flags") - { - flags_val = std::stoi(entry.arg_value); - break; - } - } + flags_val = std::stoi(it->arg_value); } auto append = [&args](const std::string& flag_type, const std::string& key, @@ -1029,7 +1024,8 @@ ompt_iterate_operation_args(const rocprofiler_callback_tracing_record_t& record, switch(ompt_operation_type) { case ROCPROFILER_OMPT_ID_parallel_begin: // ompt_parallel_flag_t - case ROCPROFILER_OMPT_ID_parallel_end: // ompt_parallel_flag_t + [[fallthrough]]; + case ROCPROFILER_OMPT_ID_parallel_end: // ompt_parallel_flag_t { const auto ft = std::string{ "ompt_parallel_flag_t" }; if(flags_val & ompt_parallel_invoker_program) From 3f18cf08325616d77b8a9b958b6aa787f75808b4 Mon Sep 17 00:00:00 2001 From: Kian Cossettini Date: Fri, 6 Mar 2026 08:44:19 -0500 Subject: [PATCH 4/4] Apply review suggestions --- .../rocprof-sys/library/rocprofiler-sdk.cpp | 50 ++++++++++++------- 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/projects/rocprofiler-systems/source/lib/rocprof-sys/library/rocprofiler-sdk.cpp b/projects/rocprofiler-systems/source/lib/rocprof-sys/library/rocprofiler-sdk.cpp index af460a556148..4c05ddf6413f 100644 --- a/projects/rocprofiler-systems/source/lib/rocprof-sys/library/rocprofiler-sdk.cpp +++ b/projects/rocprofiler-systems/source/lib/rocprof-sys/library/rocprofiler-sdk.cpp @@ -26,6 +26,7 @@ #include "library/tracing.hpp" #include +#include #include #include #include @@ -974,6 +975,8 @@ ompt_iterate_operation_args(const rocprofiler_callback_tracing_record_t& record, auto ompt_operation_type = static_cast(record.operation); + // ROCProfiler-SDK documentation recommends using 1 for the ENTER phase to avoid seg. + // faults. auto max_deref = (record.phase == ROCPROFILER_CALLBACK_PHASE_ENTER || ompt_operation_type == ROCPROFILER_OMPT_ID_parallel_begin) ? 1 @@ -994,23 +997,6 @@ ompt_iterate_operation_args(const rocprofiler_callback_tracing_record_t& record, }; if(ompt_has_flags.find(ompt_operation_type) == ompt_has_flags.end()) return; - // Extract flags value from arguments - auto it = std::find_if(args.begin(), args.end(), [](const auto& entry) { - if constexpr(std::is_same_v) - return entry.first == "flags"; - else - return entry.arg_name == "flags"; - }); - - int flags_val = 0; - if(it != args.end()) - { - if constexpr(std::is_same_v) - flags_val = std::stoi(it->second); - else - flags_val = std::stoi(it->arg_value); - } - auto append = [&args](const std::string& flag_type, const std::string& key, const std::string& val) { if constexpr(std::is_same_v) @@ -1020,7 +1006,33 @@ ompt_iterate_operation_args(const rocprofiler_callback_tracing_record_t& record, argument_info{ static_cast(args.size()), flag_type, key, val }); }; - // Textual representation of flags follows from OMPT 5.0 specification + int flags_val = 0; + auto* payload_data = + static_cast(record.payload); + if(!payload_data) return; + + // Extract flags value + switch(ompt_operation_type) + { + case ROCPROFILER_OMPT_ID_parallel_begin: + flags_val = payload_data->args.parallel_begin.flags; + break; + case ROCPROFILER_OMPT_ID_parallel_end: + flags_val = payload_data->args.parallel_end.flags; + break; + case ROCPROFILER_OMPT_ID_task_create: + flags_val = payload_data->args.task_create.flags; + break; + case ROCPROFILER_OMPT_ID_implicit_task: + flags_val = payload_data->args.implicit_task.flags; + break; + case ROCPROFILER_OMPT_ID_cancel: + flags_val = payload_data->args.cancel.flags; + break; + default: break; + } + + // Textual representation of flags adapted from OMPT 5.0 specification switch(ompt_operation_type) { case ROCPROFILER_OMPT_ID_parallel_begin: // ompt_parallel_flag_t @@ -1053,6 +1065,7 @@ ompt_iterate_operation_args(const rocprofiler_callback_tracing_record_t& record, // Multiple/none can be set std::string task_properties; + task_properties.reserve(60); if(flags_val & ompt_task_undeferred) task_properties += "undeferred, "; if(flags_val & ompt_task_untied) task_properties += "untied, "; if(flags_val & ompt_task_final) task_properties += "final, "; @@ -1424,6 +1437,7 @@ tool_tracing_callback(rocprofiler_callback_tracing_record_t record, { auto* payload_data = static_cast(record.payload); + if(!payload_data) return; switch(record.operation) { case ROCPROFILER_OMPT_ID_implicit_task: