From 009516048c69d2b63c933407f52266720a8219d3 Mon Sep 17 00:00:00 2001 From: Kevin Huck Date: Wed, 16 Oct 2024 11:24:55 -0700 Subject: [PATCH] Adding support for handling the taskstubs schedule event The schedule event includes arguments to the task, those are now propagated to the gtrace output. Also, the memory transfer event also includes the source and destination information in the trace data. This requires the latest version of the taskstubs API headers. --- src/apex/apex_types.h | 12 ++++ src/apex/task_wrapper.hpp | 9 +++ src/apex/taskstubs_implementation.cpp | 89 +++++++++++++++++++++++++-- src/apex/trace_event_listener.cpp | 38 ++++++++++-- 4 files changed, 137 insertions(+), 11 deletions(-) diff --git a/src/apex/apex_types.h b/src/apex/apex_types.h index bfa7a8f9..9375d608 100644 --- a/src/apex/apex_types.h +++ b/src/apex/apex_types.h @@ -184,6 +184,18 @@ typedef enum _profile_type { APEX_COUNTER /*!< This profile is a sampled counter */ } apex_profile_type; +/** The type of task_wrapper argument + * + */ +typedef enum _argument_type { + APEX_LONG_INTEGER_TYPE = 0, + APEX_UNSIGNED_LONG_INTEGER_TYPE = 0, + APEX_DOUBLE_TYPE, + APEX_STRING_TYPE, + APEX_POINTER_TYPE, + APEX_ARRAY_TYPE +} apex_argument_type_t; + /** * The profile object for a timer in APEX. */ diff --git a/src/apex/task_wrapper.hpp b/src/apex/task_wrapper.hpp index 11f8d737..2842771e 100644 --- a/src/apex/task_wrapper.hpp +++ b/src/apex/task_wrapper.hpp @@ -24,6 +24,7 @@ struct task_wrapper; #include #include "dependency_tree.hpp" #include "apex_clock.hpp" +#include namespace apex { @@ -89,6 +90,14 @@ struct task_wrapper { */ bool explicit_trace_start; task_state_t state; +/** + \brief Vector of arguments to the task, optional data from taskStubs implementation + only used by the google trace events format output. + */ + using argument = std::variant; + std::vector argument_types; + std::vector arguments; + std::vector argument_names; /** \brief Constructor. */ diff --git a/src/apex/taskstubs_implementation.cpp b/src/apex/taskstubs_implementation.cpp index f98f8f7a..7c4efbc7 100644 --- a/src/apex/taskstubs_implementation.cpp +++ b/src/apex/taskstubs_implementation.cpp @@ -102,15 +102,17 @@ std::shared_ptr safeLookup( void safeErase( tasktimer_guid_t guid) { + APEX_UNUSED(guid); return; /* getMyMap().erase(guid); + */ { std::scoped_lock lock{mtx()}; getCommonMap().erase(guid); } //safePrint("Destroyed", guid); - */ + return; } extern "C" { @@ -186,10 +188,56 @@ extern "C" { apex_timer == nullptr ? "unknown" : apex_timer->task_id->get_name().c_str()); static bool& over = apex::get_program_over(); if (over) return; - // TODO: handle the schedule event, somehow - APEX_UNUSED(timer); - APEX_UNUSED(arguments); - APEX_UNUSED(argument_count); + for (uint64_t i = 0 ; i < argument_count ; i++) { + switch (arguments[i].type) { + case TASKTIMER_LONG_INTEGER_TYPE: { + apex::task_wrapper::argument tmp = (int64_t)arguments[i].l_value; + apex_timer->arguments.push_back(tmp); + apex_timer->argument_types.push_back(APEX_LONG_INTEGER_TYPE); + break; + } + case TASKTIMER_UNSIGNED_LONG_INTEGER_TYPE: { + apex::task_wrapper::argument tmp = (uint64_t)arguments[i].u_value; + apex_timer->arguments.push_back(tmp); + apex_timer->argument_types.push_back(APEX_UNSIGNED_LONG_INTEGER_TYPE); + break; + } + case TASKTIMER_DOUBLE_TYPE: { + apex::task_wrapper::argument tmp = arguments[i].d_value; + apex_timer->arguments.push_back(tmp); + apex_timer->argument_types.push_back(APEX_DOUBLE_TYPE); + break; + } + case TASKTIMER_STRING_TYPE: { + apex::task_wrapper::argument tmp = std::string(arguments[i].c_value); + apex_timer->arguments.push_back(tmp); + apex_timer->argument_types.push_back(APEX_STRING_TYPE); + break; + } + case TASKTIMER_POINTER_TYPE: { + apex::task_wrapper::argument tmp = arguments[i].p_value; + apex_timer->arguments.push_back(tmp); + apex_timer->argument_types.push_back(APEX_POINTER_TYPE); + break; + } + case TASKTIMER_ARRAY_TYPE: { + apex::task_wrapper::argument tmp = arguments[i].a_value; + apex_timer->arguments.push_back(tmp); + apex_timer->argument_types.push_back(APEX_ARRAY_TYPE); + break; + } + default: + break; + } + if (arguments[i].name != nullptr) { + apex_timer->argument_names.push_back(std::string(arguments[i].name)); + } else { + std::string tmpname{"arg["}; + tmpname = tmpname + std::to_string(i+2); // add two, because GUID and parent GUID are 0,1 + tmpname = tmpname + "]"; + apex_timer->argument_names.push_back(tmpname); + } + } } void tasktimer_start_impl( @@ -332,10 +380,41 @@ extern "C" { const void* dest_ptr) { std::shared_ptr parent = safeLookup(guid, "data transfer"); auto task = apex::new_task("data xfer", 0, parent); + const auto getspace = [](tasktimer_execution_space_p& space) { + std::stringstream ss; + ss << (space->type == TASKTIMER_DEVICE_CPU ? "CPU " : "GPU "); + ss << space->device_id << "," << space->instance_id; + return ss.str(); + }; + /* source_type */ + task->arguments.push_back(apex::task_wrapper::argument(std::string(getspace(source_type)))); + task->argument_types.push_back(APEX_STRING_TYPE); + task->argument_names.push_back("source_type"); + /* source_name */ + task->arguments.push_back(apex::task_wrapper::argument(std::string(source_name))); + task->argument_types.push_back(APEX_STRING_TYPE); + task->argument_names.push_back("source_name"); + /* source_ptr */ + task->arguments.push_back(apex::task_wrapper::argument((void*)source_ptr)); + task->argument_types.push_back(APEX_POINTER_TYPE); + task->argument_names.push_back("source_ptr"); + /* dest_type */ + task->arguments.push_back(apex::task_wrapper::argument(std::string(getspace(dest_type)))); + task->argument_types.push_back(APEX_STRING_TYPE); + task->argument_names.push_back("dest_type"); + /* dest_name */ + task->arguments.push_back(apex::task_wrapper::argument(std::string(dest_name))); + task->argument_types.push_back(APEX_STRING_TYPE); + task->argument_names.push_back("dest_name"); + /* dest_ptr */ + task->arguments.push_back(apex::task_wrapper::argument((void*)dest_ptr)); + task->argument_types.push_back(APEX_POINTER_TYPE); + task->argument_names.push_back("dest_ptr"); timerStack(task, true); } void tasktimer_data_transfer_stop_impl(tasktimer_guid_t guid) { + APEX_UNUSED(guid); timerStack(nullptr, false); } diff --git a/src/apex/trace_event_listener.cpp b/src/apex/trace_event_listener.cpp index abacefca..bbad4ab2 100644 --- a/src/apex/trace_event_listener.cpp +++ b/src/apex/trace_event_listener.cpp @@ -252,12 +252,38 @@ inline void trace_event_listener::_common_stop(std::shared_ptr &p) { } else { std::string pguid = parents_to_string(p->tt_ptr); ss << "{\"name\":\"" << p->get_task_id()->get_name() - << "\",\"cat\":\"CPU\"" - << ",\"ph\":\"X\",\"pid\":" - << saved_node_id << ",\"tid\":" << _tid - << ",\"ts\":" << p->get_start_us() << ",\"dur\":" - << p->get_stop_us() - p->get_start_us() - << ",\"args\":{\"GUID\":" << p->guid << ",\"Parent GUID\":" << pguid << "}},\n"; + << "\",\"cat\":\"CPU\"" + << ",\"ph\":\"X\",\"pid\":" + << saved_node_id << ",\"tid\":" << _tid + << ",\"ts\":" << p->get_start_us() << ",\"dur\":" + << p->get_stop_us() - p->get_start_us() + << ",\"args\":{\"GUID\":" << p->guid << ",\"Parent GUID\":" << pguid; + for (size_t a = 0 ; a < p->tt_ptr->arguments.size() ; a++) { + auto& arg = p->tt_ptr->arguments[a]; + switch (p->tt_ptr->argument_types[a]) { + case APEX_LONG_INTEGER_TYPE: { + ss << ",\"" << p->tt_ptr->argument_names[a] << "\":\"" << std::get(arg) << "\""; + break; + } + case APEX_DOUBLE_TYPE: { + ss << ",\"" << p->tt_ptr->argument_names[a] << "\":\"" << std::get(arg) << "\""; + break; + } + case APEX_STRING_TYPE: { + ss << ",\"" << p->tt_ptr->argument_names[a] << "\":\"" << std::get(arg) << "\""; + break; + } + case APEX_POINTER_TYPE: + case APEX_ARRAY_TYPE: { + ss << ",\"" << p->tt_ptr->argument_names[a] << "\":\"" << std::hex << std::get(arg) << "\""; + break; + } + default: { + break; + } + } + } + ss << "}},\n"; } #if APEX_HAVE_PAPI int i = 0;