Skip to content

[XPTI] Added new class xpti::framework::tracepoint_t #4462

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 25 additions & 9 deletions xpti/include/xpti_data_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ enum class payload_flag_t {
ColumnInfoAvailable = 1 << 4,
/// Caller/Callee stack trace available when source/kernel info not available
StackTraceAvailable = 1 << 5,
/// Payload has been registered with the framework
PayloadRegistered = 1 << 15,
// A 64-bit hash is already available for this payload
HashAvailable = 2 << 16
};
Expand Down Expand Up @@ -172,7 +174,9 @@ struct payload_t {
source_file = nullptr; ///< Invalid source file string pointer
line_no = invalid_id; ///< Invalid line number
column_no = invalid_id; ///< Invalid column number
flags = (uint64_t)payload_flag_t::CodePointerAvailable;
if (codeptr) {
flags = (uint64_t)payload_flag_t::CodePointerAvailable;
}
}

// If neither an address or the fully identifyable source file name and
Expand All @@ -184,15 +188,21 @@ struct payload_t {
code_ptr_va = nullptr;
name = func_name; ///< Invalid name string pointer
source_file = nullptr; ///< Invalid source file string pointer
flags = (uint64_t)(payload_flag_t::NameAvailable);
if (func_name) {
flags = (uint64_t)(payload_flag_t::NameAvailable);
}
}

payload_t(const char *func_name, void *codeptr) {
code_ptr_va = codeptr;
name = func_name; ///< Invalid name string pointer
source_file = nullptr; ///< Invalid source file string pointer
flags = (uint64_t)payload_flag_t::NameAvailable |
(uint64_t)payload_flag_t::CodePointerAvailable;
if (func_name) {
flags = (uint64_t)(payload_flag_t::NameAvailable);
}
if (codeptr) {
flags |= (uint64_t)payload_flag_t::CodePointerAvailable;
}
}

// When the end user opts out of preserving the code location information and
Expand Down Expand Up @@ -228,11 +238,17 @@ struct payload_t {
source_file = sf;
line_no = line;
column_no = col;
flags = (uint64_t)payload_flag_t::NameAvailable |
(uint64_t)payload_flag_t::SourceFileAvailable |
(uint64_t)payload_flag_t::LineInfoAvailable |
(uint64_t)payload_flag_t::ColumnInfoAvailable |
(uint64_t)payload_flag_t::CodePointerAvailable;
if (kname) {
flags = (uint64_t)payload_flag_t::NameAvailable;
}
if (sf) {
flags |= (uint64_t)payload_flag_t::SourceFileAvailable |
(uint64_t)payload_flag_t::LineInfoAvailable |
(uint64_t)payload_flag_t::ColumnInfoAvailable;
}
if (codeptr) {
flags |= (uint64_t)payload_flag_t::CodePointerAvailable;
}
}

int32_t name_sid() const { return (int32_t)(uid.p2 & 0x00000000ffffffff); }
Expand Down
21 changes: 21 additions & 0 deletions xpti/include/xpti_trace_framework.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,17 @@ XPTI_EXPORT_API xpti::string_id_t xptiRegisterString(const char *string,
/// @return A reference to the string identified by the string ID.
XPTI_EXPORT_API const char *xptiLookupString(xpti::string_id_t id);

/// @brief Register a payload with the framework
/// @details Since a payload may contain multiple strings that may have been
/// defined on the stack, it is recommended the payload object is registered
/// with the system as soon as possible. The framework will register all the
/// strings in the payload in the string table and replace the pointers to
/// strings on the stack with the pointers from the string table that should be
/// valid for the lifetime of the application.
/// @param payload The payload object that is registered with the system.
/// @return The unique hash value for the payload.
XPTI_EXPORT_API uint64_t xptiRegisterPayload(xpti::payload_t *payload);

/// @brief Register a stream by its name and get a stream ID
/// @details When events in a given stream have to be notified to the
/// subscribers, the stream ID to which the events belong to is required. This
Expand Down Expand Up @@ -252,6 +263,14 @@ XPTI_EXPORT_API const xpti::trace_event_data_t *xptiFindEvent(uint64_t uid);
XPTI_EXPORT_API const xpti::payload_t *
xptiQueryPayload(xpti::trace_event_data_t *lookup_object);

/// @brief Retrieves the payload information associated with an universal ID
/// @details An universal ID references the unique payload it represents and
/// this function allows you to query the payload with the universal ID.
///
/// @param uid The universal ID for which the payload is to be retrieved.
/// @return The payload data structure pointer for the event.
XPTI_EXPORT_API const xpti::payload_t *xptiQueryPayloadByUID(uint64_t uid);

/// @brief Registers a callback for a trace point type
/// @details Subscribers receive notifications to the trace point types they
/// register a callback with. This function allows subscribers to register the
Expand Down Expand Up @@ -400,6 +419,7 @@ typedef void (*xpti_finalize_t)(const char *);
typedef uint64_t (*xpti_get_unique_id_t)();
typedef xpti::string_id_t (*xpti_register_string_t)(const char *, char **);
typedef const char *(*xpti_lookup_string_t)(xpti::string_id_t);
typedef uint64_t (*xpti_register_payload_t)(xpti::payload_t *);
typedef uint8_t (*xpti_register_stream_t)(const char *);
typedef xpti::result_t (*xpti_unregister_stream_t)(const char *);
typedef uint16_t (*xpti_register_user_defined_tp_t)(const char *, uint8_t);
Expand All @@ -410,6 +430,7 @@ typedef xpti::trace_event_data_t *(*xpti_make_event_t)(
typedef const xpti::trace_event_data_t *(*xpti_find_event_t)(int64_t);
typedef const xpti::payload_t *(*xpti_query_payload_t)(
xpti::trace_event_data_t *);
typedef const xpti::payload_t *(*xpti_query_payload_by_uid_t)(uint64_t uid);
typedef xpti::result_t (*xpti_register_cb_t)(uint8_t, uint16_t,
xpti::tracepoint_callback_api_t);
typedef xpti::result_t (*xpti_unregister_cb_t)(uint8_t, uint16_t,
Expand Down
115 changes: 115 additions & 0 deletions xpti/include/xpti_trace_framework.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
//
#pragma once
#include <cstdint>
#include <memory>
#include <sstream>
#include <thread>

#include "xpti_data_types.h"
#include "xpti_trace_framework.h"
Expand Down Expand Up @@ -269,6 +271,7 @@ class PlatformHelper {
} // namespace utils

namespace framework {
static thread_local uint64_t g_tls_uid = xpti::invalid_uid;
constexpr uint16_t signal = (uint16_t)xpti::trace_point_type_t::signal;
constexpr uint16_t graph_create =
(uint16_t)xpti::trace_point_type_t::graph_create;
Expand Down Expand Up @@ -317,5 +320,117 @@ class scoped_notify {
const void *m_user_data;
uint64_t m_instance;
};

// --------------- Commented section of the code -------------
//
// github.com/bombela/backward-cpp/blob/master/backward.hpp
//
// Need to figure out the process for considering 3rd party
// code that helps with addressing the gaps when the developer
// doesn't opt-in.
//------------------------------------------------------------
// #include "backward.hpp"
// class backtrace_t {
// public:
// backtrace_t(int levels = 2) {
// m_st.load_here(levels);
// m_tr.load_stacktrace(m_st);
// m_parent = m_tr.resolve(m_st[1]);
// m_curr = m_tr.resolve(m_st[0]);
// if(m_parent.source.filename) {
// m_payload = xpti::payload_t(m_curr.source.function,
// m_parent.source.filename, m_parent.source.line, 0, m_curr.addr);
// }
// else {
// m_packed_string = m_parent.source.function + std::string("::") +
// m_curr.source.function; m_payload =
// xpti::payload_t(m_curr.source.function, m_packed_string.c_str(),
// m_curr.addr);
// }
// }
//
// xpti::payload_t *payload() { return &m_payload;}
// private:
// backward::StackTrace m_st;
// backward::TraceResolver m_tr;
// backward::ResolvedTrace m_curr, m_parent;
// std::string m_packed_string;
// xpti::payload_t m_payload;
// };

/// @brief Tracepoint data type allows the construction of Universal ID
/// @details The tracepoint data type builds on the payload data type by
/// combining the functionality of payload and xpti::makeEvent() to create the
/// unique Universal ID and stash it in the TLS for use by downstream layers in
/// the SW stack.
///
/// Usage:-
/// #ifdef XPTI_TRACE_ENABLED
/// xpti::payload_t p, *payload = &p;
/// #ifdef SYCL_TOOL_PROFILE
/// // sycl::detail::code_location cLoc =
/// // sycl::detail::code_location::current();
/// if(cLoc.valid())
/// p = xpti::payload_t(cLoc.functionname(), cLoc.fileName(),
/// cLoc.lineNumber(), cLoc.columnNumber(), codeptr);
/// else
/// p = xpti::payload_t(KernelInfo.funcName(), KernelInfo.sourceFileName(),
/// KernelInfo.lineNo(), KernelInfor.columnNo(), codeptr);
/// #else
/// xpti::framework::backtrace_t b;
/// payload = b.payload();
/// #endif
/// xpti::tracepoint_t t(payload);
/// #endif
///
/// See also: xptiTracePointTest in xpti_correctness_tests.cpp
class tracepoint_t {
public:
// Constructor that makes calls to xpti API layer to register strings and
// create the Universal ID that is stored in the TLS entry for lookup
tracepoint_t(xpti::payload_t *p) : m_payload(nullptr), m_top(false) {
if (p) {
// We expect the payload input has been populated with the information
// available at that time
uint64_t uid = g_tls_uid;
if (uid != xpti::invalid_uid) {
// We already have a parent SW layer that has a tracepoint defined
m_payload = xptiQueryPayloadByUID(uid);
} else {
m_top = true;
uid = xptiRegisterPayload(p);
if (uid != xpti::invalid_uid) {
g_tls_uid = uid;
m_payload = xptiQueryPayloadByUID(uid);
}
}
}
}
~tracepoint_t() {
if (m_top) {
g_tls_uid = xpti::invalid_uid;
}
}

// The payload object that is returned will have the UID object populated and
// can be looked up in the xpti lookup APIs or be used to make an event.
const payload_t *payload() { return m_payload; }

uint64_t universal_id() {
if (m_payload &&
(m_payload->flags &
static_cast<uint64_t>(xpti::payload_flag_t::HashAvailable))) {
return m_payload->internal;
} else {
return xpti::invalid_uid;
}
}

private:
/// The payload data structure that is prepared from code_location(),
/// caller_callee string or kernel name/codepointer based on the opt-in flag.
const payload_t *m_payload;
bool m_top;
};
} // namespace framework
} // namespace xpti
24 changes: 24 additions & 0 deletions xpti/src/xpti_proxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ enum functions_t {
XPTI_ADD_METADATA,
XPTI_QUERY_METADATA,
XPTI_TRACE_ENABLED,
XPTI_REGISTER_PAYLOAD,
XPTI_QUERY_PAYLOAD_BY_UID,

// All additional functions need to appear before
// the XPTI_FW_API_COUNT enum
Expand All @@ -45,13 +47,15 @@ class ProxyLoader {
{XPTI_GET_UNIQUE_ID, "xptiGetUniqueId"},
{XPTI_REGISTER_STRING, "xptiRegisterString"},
{XPTI_LOOKUP_STRING, "xptiLookupString"},
{XPTI_REGISTER_PAYLOAD, "xptiRegisterPayload"},
{XPTI_REGISTER_STREAM, "xptiRegisterStream"},
{XPTI_UNREGISTER_STREAM, "xptiUnregisterStream"},
{XPTI_REGISTER_USER_DEFINED_TP, "xptiRegisterUserDefinedTracePoint"},
{XPTI_REGISTER_USER_DEFINED_ET, "xptiRegisterUserDefinedEventType"},
{XPTI_MAKE_EVENT, "xptiMakeEvent"},
{XPTI_FIND_EVENT, "xptiFindEvent"},
{XPTI_QUERY_PAYLOAD, "xptiQueryPayload"},
{XPTI_QUERY_PAYLOAD_BY_UID, "xptiQueryPayloadByUID"},
{XPTI_REGISTER_CALLBACK, "xptiRegisterCallback"},
{XPTI_UNREGISTER_CALLBACK, "xptiUnregisterCallback"},
{XPTI_NOTIFY_SUBSCRIBERS, "xptiNotifySubscribers"},
Expand Down Expand Up @@ -203,6 +207,16 @@ XPTI_EXPORT_API const char *xptiLookupString(xpti::string_id_t id) {
return nullptr;
}

XPTI_EXPORT_API uint64_t xptiRegisterPayload(xpti::payload_t *payload) {
if (xpti::g_loader.noErrors()) {
auto f = xpti::g_loader.functionByIndex(XPTI_REGISTER_PAYLOAD);
if (f) {
return (*(xpti_register_payload_t)f)(payload);
}
}
return xpti::invalid_uid;
}

XPTI_EXPORT_API uint8_t xptiRegisterStream(const char *stream_name) {
if (xpti::g_loader.noErrors()) {
auto f = xpti::g_loader.functionByIndex(XPTI_REGISTER_STREAM);
Expand Down Expand Up @@ -256,6 +270,16 @@ xptiQueryPayload(xpti::trace_event_data_t *lookup_object) {
return nullptr;
}

XPTI_EXPORT_API const xpti::payload_t *xptiQueryPayloadByUID(uint64_t uid) {
if (xpti::g_loader.noErrors()) {
auto f = xpti::g_loader.functionByIndex(XPTI_QUERY_PAYLOAD_BY_UID);
if (f) {
return (*(xpti_query_payload_by_uid_t)f)(uid);
}
}
return nullptr;
}

XPTI_EXPORT_API xpti::result_t
xptiRegisterCallback(uint8_t stream_id, uint16_t trace_type,
xpti::tracepoint_callback_api_t cb) {
Expand Down
Loading