Skip to content

Commit

Permalink
[XPTI] Allow arbitrary data types in metadata (intel#4998)
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexander Batashev authored Feb 3, 2022
1 parent 8aa15c1 commit fd50ead
Show file tree
Hide file tree
Showing 23 changed files with 1,042 additions and 122 deletions.
34 changes: 29 additions & 5 deletions sycl/doc/SYCLInstrumentationUsingXPTI.md

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions sycl/source/detail/device_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,13 @@ bool device_impl::isAssertFailSupported() const {
return MIsAssertFailSupported;
}

std::string device_impl::getDeviceName() const {
std::call_once(MDeviceNameFlag,
[this]() { MDeviceName = get_info<info::device::name>(); });

return MDeviceName;
}

} // namespace detail
} // namespace sycl
} // __SYCL_INLINE_NAMESPACE(cl)
5 changes: 5 additions & 0 deletions sycl/source/detail/device_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <detail/platform_impl.hpp>

#include <memory>
#include <mutex>

__SYCL_INLINE_NAMESPACE(cl) {
namespace sycl {
Expand Down Expand Up @@ -225,6 +226,8 @@ class device_impl {

bool isAssertFailSupported() const;

std::string getDeviceName() const;

private:
explicit device_impl(pi_native_handle InteropDevice, RT::PiDevice Device,
PlatformImplPtr Platform, const plugin &Plugin);
Expand All @@ -234,6 +237,8 @@ class device_impl {
bool MIsHostDevice;
PlatformImplPtr MPlatform;
bool MIsAssertFailSupported = false;
mutable std::string MDeviceName;
mutable std::once_flag MDeviceNameFlag;
}; // class device_impl

} // namespace detail
Expand Down
10 changes: 5 additions & 5 deletions sycl/source/detail/queue_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,12 +231,12 @@ void *queue_impl::instrumentationProlog(const detail::code_location &CodeLoc,
DevStr = "ACCELERATOR";
else
DevStr = "UNKNOWN";
xptiAddMetadata(WaitEvent, "sycl_device", DevStr.c_str());
xpti::addMetadata(WaitEvent, "sycl_device", DevStr);
if (HasSourceInfo) {
xptiAddMetadata(WaitEvent, "sym_function_name", CodeLoc.functionName());
xptiAddMetadata(WaitEvent, "sym_source_file_name", CodeLoc.fileName());
xptiAddMetadata(WaitEvent, "sym_line_no",
std::to_string(CodeLoc.lineNumber()).c_str());
xpti::addMetadata(WaitEvent, "sym_function_name", CodeLoc.functionName());
xpti::addMetadata(WaitEvent, "sym_source_file_name", CodeLoc.fileName());
xpti::addMetadata(WaitEvent, "sym_line_no",
std::to_string(CodeLoc.lineNumber()));
}
xptiNotifySubscribers(StreamID, xpti::trace_wait_begin, nullptr, WaitEvent,
QWaitInstanceNo,
Expand Down
184 changes: 119 additions & 65 deletions sycl/source/detail/scheduler/commands.cpp

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions sycl/source/detail/scheduler/commands.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <cstdint>
#include <deque>
#include <memory>
#include <optional>
#include <set>
#include <unordered_set>
#include <vector>
Expand Down Expand Up @@ -161,9 +162,9 @@ class Command {
/// instrumentation to report these dependencies as edges.
void resolveReleaseDependencies(std::set<Command *> &list);
/// Creates an edge event when the dependency is a command.
void emitEdgeEventForCommandDependence(Command *Cmd, void *ObjAddr,
const std::string &Prefix,
bool IsCommand);
void emitEdgeEventForCommandDependence(
Command *Cmd, void *ObjAddr, bool IsCommand,
std::optional<access::mode> AccMode = std::nullopt);
/// Creates an edge event when the dependency is an event.
void emitEdgeEventForEventDependence(Command *Cmd, RT::PiEvent &EventAddr);
/// Creates a signal event with the enqueued kernel event handle.
Expand Down
2 changes: 1 addition & 1 deletion xpti/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ set(CMAKE_CXX_STANDARD 14)

set(XPTI_DIR ${CMAKE_CURRENT_LIST_DIR})
# Setting the same version as SYCL
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

option(XPTI_ENABLE_WERROR OFF)

Expand Down
19 changes: 18 additions & 1 deletion xpti/include/xpti/xpti_data_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ enum class payload_flag_t {
using trace_point_t = uint16_t;
using event_type_t = uint16_t;
using string_id_t = int32_t;
using object_id_t = int32_t;

using safe_flag_t = std::atomic<bool>;
using safe_uint64_t = std::atomic<uint64_t>;
Expand All @@ -113,7 +114,7 @@ using safe_uint16_t = std::atomic<uint16_t>;
using safe_int64_t = std::atomic<int64_t>;
using safe_int32_t = std::atomic<int32_t>;
using safe_int16_t = std::atomic<int16_t>;
using metadata_t = std::unordered_map<string_id_t, string_id_t>;
using metadata_t = std::unordered_map<string_id_t, object_id_t>;

#define XPTI_EVENT(val) xpti::event_type_t(val)
#define XPTI_TRACE_POINT_BEGIN(val) xpti::trace_point_t(val << 1 | 0)
Expand All @@ -123,6 +124,12 @@ using metadata_t = std::unordered_map<string_id_t, string_id_t>;
#define XPTI_PACK16_RET32(value1, value2) ((value1 << 16) | value2)
#define XPTI_PACK32_RET64(value1, value2) (((uint64_t)value1 << 32) | value2)

struct object_data_t {
size_t size;
const char *data;
uint8_t type;
};

/// @brief Payload data structure that is optional for trace point callback
/// API
/// @details The payload structure, if determined at compile time, can deliver
Expand Down Expand Up @@ -479,6 +486,16 @@ enum class trace_activity_type_t {
sleep_activity = 1 << 3
};

/// Provides hints to the tools on how to interpret unknown metadata values.
enum class metadata_type_t {
binary = 0,
string = 1,
signed_integer = 2,
unsigned_integer = 3,
floating = 4,
boolean = 5
};

struct reserved_data_t {
/// Has a reference to the associated payload field for an event
payload_t *payload = nullptr;
Expand Down
35 changes: 32 additions & 3 deletions xpti/include/xpti/xpti_trace_framework.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,32 @@ 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 an object to the object table
///
/// @details All object in the XPTI framework are referred to by their object
/// IDs and this method allow you to register an object and get the object ID
/// for it. This lifetime of this object reference is equal to the lifetime of
/// the XPTI framework.
/// @param data Raw bytes of data to be registered with the object table. If the
/// object already exists in the table, the previous ID is returned.
/// @param size Size in bytes of the object.
/// @param type One of xpti::metadata_type_t values. These only serve as a hint
/// to the tools for processing unknown values.
/// @return The ID of the object being registered. If an error occurs
/// during registration, xpti::invalid_id is returned.
XPTI_EXPORT_API xpti::object_id_t xptiRegisterObject(const char *data,
size_t size, uint8_t type);

/// @brief Lookup an object in the object table with its ID
///
/// @details All object in the XPTI framework are referred to by their object
/// IDs and this method allows you to lookup an object by its object ID. The
/// lifetime of the returned object reference is equal to the lifetime of the
/// XPTI framework.
/// @param id The ID of the object to lookup.
/// @return A reference to the object identified by the object ID.
XPTI_EXPORT_API xpti::object_data_t xptiLookupObject(xpti::object_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
Expand Down Expand Up @@ -389,14 +415,14 @@ xptiNotifySubscribers(uint8_t stream_id, uint16_t trace_type,
///
/// @param e The event for which the metadata is being added
/// @param key The key that identifies the metadata as a string
/// @param value The value for the key as a string
/// @param value_id The value for the key as an ID of a registered object.
/// @return The result code which can be one of:
/// 1. XPTI_RESULT_SUCCESS when the add is successful
/// 2. XPTI_RESULT_INVALIDARG when the inputs are invalid
/// 3. XPTI_RESULT_DUPLICATE when the key-value pair already exists
XPTI_EXPORT_API xpti::result_t xptiAddMetadata(xpti::trace_event_data_t *e,
const char *key,
const char *value);
xpti::object_id_t value_id);

/// @brief Query the metadata table for a given event
/// @details In order to retrieve metadata information for a given event, you
Expand Down Expand Up @@ -453,6 +479,9 @@ typedef void (*xpti_set_universal_id_t)(uint64_t uid);
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 xpti::string_id_t (*xpti_register_object_t)(const char *, size_t,
uint8_t);
typedef xpti::object_data_t (*xpti_lookup_object_t)(xpti::object_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 *);
Expand All @@ -473,7 +502,7 @@ typedef xpti::result_t (*xpti_notify_subscribers_t)(
uint8_t, uint16_t, xpti::trace_event_data_t *, xpti::trace_event_data_t *,
uint64_t instance, const void *temporal_user_data);
typedef xpti::result_t (*xpti_add_metadata_t)(xpti::trace_event_data_t *,
const char *, const char *);
const char *, xpti::object_id_t);
typedef xpti::metadata_t *(*xpti_query_metadata_t)(xpti::trace_event_data_t *);
typedef bool (*xpti_trace_enabled_t)();
}
161 changes: 161 additions & 0 deletions xpti/include/xpti/xpti_trace_framework.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
#pragma once

#include <atomic>
#include <cassert>
#include <cstdint>
#include <cstring>
#include <memory>
#include <sstream>
#include <thread>
Expand Down Expand Up @@ -306,6 +308,165 @@ struct finally {

} // namespace utils

template <typename T>
inline result_t addMetadata(trace_event_data_t *Event, const std::string &Key,
const T &Data) {
static_assert(std::is_trivially_copyable_v<T>,
"T must be trivially copyable");
static_assert(!std::is_same_v<T, const char *>);

const uint8_t Type = [] {
if (std::is_same_v<bool, T>) {
return static_cast<uint8_t>(metadata_type_t::boolean);
}
if (std::numeric_limits<T>::is_integer &&
std::numeric_limits<T>::is_signed) {
return static_cast<uint8_t>(metadata_type_t::signed_integer);
}
if (std::numeric_limits<T>::is_integer &&
!std::numeric_limits<T>::is_signed) {
return static_cast<uint8_t>(metadata_type_t::unsigned_integer);
}
if (std::numeric_limits<T>::is_specialized &&
!std::numeric_limits<T>::is_integer) {
return static_cast<uint8_t>(metadata_type_t::floating);
}

return static_cast<uint8_t>(metadata_type_t::binary);
}();

object_id_t Value = xptiRegisterObject(reinterpret_cast<const char *>(&Data),
sizeof(Data), Type);
return xptiAddMetadata(Event, Key.c_str(), Value);
}

template <>
inline result_t addMetadata<std::string>(trace_event_data_t *Event,
const std::string &Key,
const std::string &Data) {
const uint8_t Type = static_cast<uint8_t>(metadata_type_t::string);
object_id_t Value = xptiRegisterObject(Data.c_str(), Data.size(), Type);
return xptiAddMetadata(Event, Key.c_str(), Value);
}

template <>
inline result_t addMetadata<const char *>(trace_event_data_t *Event,
const std::string &Key,
const char *const &Data) {
const uint8_t Type = static_cast<uint8_t>(metadata_type_t::string);
object_id_t Value = xptiRegisterObject(Data, strlen(Data), Type);
return xptiAddMetadata(Event, Key.c_str(), Value);
}

template <typename T>
inline std::pair<std::string_view, T>
getMetadata(const metadata_t::value_type &MD) {
static_assert(std::is_trivially_copyable<T>::value,
"T must be trivially copyable");

object_data_t RawData = xptiLookupObject(MD.second);
assert(RawData.size == sizeof(T));

T Value = *reinterpret_cast<const T *>(RawData.data);

const char *Key = xptiLookupString(MD.first);

return std::make_pair(std::string_view(Key), Value);
}

template <>
inline std::pair<std::string_view, std::string>
getMetadata(const metadata_t::value_type &MD) {
object_data_t RawData = xptiLookupObject(MD.second);

std::string Value(RawData.data, RawData.size);

const char *Key = xptiLookupString(MD.first);

return std::make_pair(std::string_view(Key), Value);
}

template <>
inline std::pair<std::string_view, std::string_view>
getMetadata(const metadata_t::value_type &MD) {
object_data_t RawData = xptiLookupObject(MD.second);

std::string_view Value(RawData.data, RawData.size);

const char *Key = xptiLookupString(MD.first);

return std::make_pair(std::string_view(Key), Value);
}

inline std::string readMetadata(const metadata_t::value_type &MD) {
object_data_t RawData = xptiLookupObject(MD.second);

if (RawData.type == static_cast<uint8_t>(metadata_type_t::binary)) {
return std::string("Binary data, size: ") + std::to_string(RawData.size);
}

if (RawData.type == static_cast<uint8_t>(metadata_type_t::boolean)) {
bool Value = *reinterpret_cast<const bool *>(RawData.data);
return Value ? "true" : "false";
}

if (RawData.type == static_cast<uint8_t>(metadata_type_t::signed_integer)) {
if (RawData.size == 1) {
auto I = *reinterpret_cast<const int8_t *>(RawData.data);
return std::to_string(I);
}
if (RawData.size == 2) {
auto I = *reinterpret_cast<const int16_t *>(RawData.data);
return std::to_string(I);
}
if (RawData.size == 4) {
auto I = *reinterpret_cast<const int32_t *>(RawData.data);
return std::to_string(I);
}
if (RawData.size == 8) {
auto I = *reinterpret_cast<const int64_t *>(RawData.data);
return std::to_string(I);
}
}

if (RawData.type == static_cast<uint8_t>(metadata_type_t::unsigned_integer)) {
if (RawData.size == 1) {
auto I = *reinterpret_cast<const uint8_t *>(RawData.data);
return std::to_string(I);
}
if (RawData.size == 2) {
auto I = *reinterpret_cast<const uint16_t *>(RawData.data);
return std::to_string(I);
}
if (RawData.size == 4) {
auto I = *reinterpret_cast<const uint32_t *>(RawData.data);
return std::to_string(I);
}
if (RawData.size == 8) {
auto I = *reinterpret_cast<const uint64_t *>(RawData.data);
return std::to_string(I);
}
}

if (RawData.type == static_cast<uint8_t>(metadata_type_t::floating)) {
if (RawData.size == 4) {
auto F = *reinterpret_cast<const float *>(RawData.data);
return std::to_string(F);
}
if (RawData.size == 8) {
auto F = *reinterpret_cast<const double *>(RawData.data);
return std::to_string(F);
}
}

if (RawData.type == static_cast<uint8_t>(metadata_type_t::string)) {
return std::string(RawData.data, RawData.size);
}

return std::string("Unknown metadata type, size ") +
std::to_string(RawData.size);
}

namespace framework {
constexpr uint16_t signal = (uint16_t)xpti::trace_point_type_t::signal;
constexpr uint16_t graph_create =
Expand Down
Loading

0 comments on commit fd50ead

Please sign in to comment.