Skip to content

Commit

Permalink
[SYCL][XPTI] Pass plugin information to subscribers (#4121)
Browse files Browse the repository at this point in the history
This patch makes the following additional information available to XPTI subscribers.
All streams:
- Actual major and minor versions of SYCL runtime (instead of dummy values) as well as their string variant.

`sycl.pi.debug` stream:
- Backend type, which is defined as a `uint8_t` value of `sycl::backend` enum.
- Pointer to PI plugin to provide some degree of application flow variance (e.g. query additional info about device, USM pointers, memory, etc).
  • Loading branch information
alexbatashev authored Jul 28, 2021
1 parent 904967e commit 2af0599
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 31 deletions.
7 changes: 5 additions & 2 deletions sycl/include/CL/sycl/detail/pi.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,8 +189,10 @@ void emitFunctionEndTrace(uint64_t CorrelationID, const char *FName);
/// \param FuncID is the API hash ID from PiApiID type trait.
/// \param FName The name of the PI API call.
/// \param ArgsData is a pointer to packed function call arguments.
/// \param Plugin is the plugin, which is used to make call.
uint64_t emitFunctionWithArgsBeginTrace(uint32_t FuncID, const char *FName,
unsigned char *ArgsData);
unsigned char *ArgsData,
pi_plugin Plugin);

/// Notifies XPTI subscribers about PI function call result.
///
Expand All @@ -200,9 +202,10 @@ uint64_t emitFunctionWithArgsBeginTrace(uint32_t FuncID, const char *FName,
/// \param FName The name of the PI API call.
/// \param ArgsData is a pointer to packed function call arguments.
/// \param Result is function call result value.
/// \param Plugin is the plugin, which is used to make call.
void emitFunctionWithArgsEndTrace(uint64_t CorrelationID, uint32_t FuncID,
const char *FName, unsigned char *ArgsData,
pi_result Result);
pi_result Result, pi_plugin Plugin);

// A wrapper for passing around byte array properties
class ByteArray {
Expand Down
20 changes: 13 additions & 7 deletions sycl/source/detail/pi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <CL/sycl/detail/device_filter.hpp>
#include <CL/sycl/detail/pi.hpp>
#include <CL/sycl/detail/stl_type_traits.hpp>
#include <CL/sycl/version.hpp>
#include <detail/config.hpp>
#include <detail/global_handler.hpp>
#include <detail/plugin.hpp>
Expand All @@ -36,6 +37,10 @@
#include "xpti_trace_framework.h"
#endif

#define STR(x) #x
#define SYCL_VERSION_STR \
"sycl " STR(__LIBSYCL_MAJOR_VERSION) "." STR(__LIBSYCL_MINOR_VERSION)

__SYCL_INLINE_NAMESPACE(cl) {
namespace sycl {
namespace detail {
Expand All @@ -50,9 +55,9 @@ xpti_td *GPICallEvent = nullptr;
xpti_td *GPIArgCallEvent = nullptr;
/// Constants being used as placeholder until one is able to reliably get the
/// version of the SYCL runtime
constexpr uint32_t GMajVer = 1;
constexpr uint32_t GMinVer = 0;
constexpr const char *GVerStr = "sycl 1.0";
constexpr uint32_t GMajVer = __LIBSYCL_MAJOR_VERSION;
constexpr uint32_t GMinVer = __LIBSYCL_MINOR_VERSION;
constexpr const char *GVerStr = SYCL_VERSION_STR;
#endif // XPTI_ENABLE_INSTRUMENTATION

template <cl::sycl::backend BE>
Expand Down Expand Up @@ -138,15 +143,16 @@ void emitFunctionEndTrace(uint64_t CorrelationID, const char *FName) {
}

uint64_t emitFunctionWithArgsBeginTrace(uint32_t FuncID, const char *FuncName,
unsigned char *ArgsData) {
unsigned char *ArgsData,
pi_plugin Plugin) {
uint64_t CorrelationID = 0;
#ifdef XPTI_ENABLE_INSTRUMENTATION
if (xptiTraceEnabled()) {
uint8_t StreamID = xptiRegisterStream(SYCL_PIDEBUGCALL_STREAM_NAME);
CorrelationID = xptiGetUniqueId();

xpti::function_with_args_t Payload{FuncID, FuncName, ArgsData, nullptr,
nullptr};
&Plugin};

xptiNotifySubscribers(
StreamID, (uint16_t)xpti::trace_point_type_t::function_with_args_begin,
Expand All @@ -158,13 +164,13 @@ uint64_t emitFunctionWithArgsBeginTrace(uint32_t FuncID, const char *FuncName,

void emitFunctionWithArgsEndTrace(uint64_t CorrelationID, uint32_t FuncID,
const char *FuncName, unsigned char *ArgsData,
pi_result Result) {
pi_result Result, pi_plugin Plugin) {
#ifdef XPTI_ENABLE_INSTRUMENTATION
if (xptiTraceEnabled()) {
uint8_t StreamID = xptiRegisterStream(SYCL_PIDEBUGCALL_STREAM_NAME);

xpti::function_with_args_t Payload{FuncID, FuncName, ArgsData, &Result,
nullptr};
&Plugin};

xptiNotifySubscribers(
StreamID, (uint16_t)xpti::trace_point_type_t::function_with_args_end,
Expand Down
4 changes: 2 additions & 2 deletions sycl/source/detail/plugin.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ class plugin {
auto ArgsData =
packCallArguments<PiApiOffset>(std::forward<ArgsT>(Args)...);
uint64_t CorrelationIDWithArgs = pi::emitFunctionWithArgsBeginTrace(
static_cast<uint32_t>(PiApiOffset), PIFnName, ArgsData.data());
static_cast<uint32_t>(PiApiOffset), PIFnName, ArgsData.data(), MPlugin);
#endif
RT::PiResult R;
if (pi::trace(pi::TraceLevel::PI_TRACE_CALLS)) {
Expand All @@ -165,7 +165,7 @@ class plugin {
pi::emitFunctionEndTrace(CorrelationID, PIFnName);
pi::emitFunctionWithArgsEndTrace(CorrelationIDWithArgs,
static_cast<uint32_t>(PiApiOffset),
PIFnName, ArgsData.data(), R);
PIFnName, ArgsData.data(), R, MPlugin);
#endif
return R;
}
Expand Down
17 changes: 10 additions & 7 deletions sycl/tools/pi-trace/pi_trace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,13 @@ XPTI_CALLBACK_API void xptiTraceInit(unsigned int /*major_version*/,
tpCallback);

#define _PI_API(api) \
ArgHandler.set##_##api([](auto &&... Args) { \
std::cout << "---> " << #api << "(" \
<< "\n"; \
sycl::detail::pi::printArgs(Args...); \
std::cout << ") ---> "; \
});
ArgHandler.set##_##api( \
[](const pi_plugin &, std::optional<pi_result>, auto &&... Args) { \
std::cout << "---> " << #api << "(" \
<< "\n"; \
sycl::detail::pi::printArgs(Args...); \
std::cout << ") ---> "; \
});
#include <CL/sycl/detail/pi.def>
#undef _PI_API
}
Expand All @@ -77,8 +78,10 @@ XPTI_CALLBACK_API void tpCallback(uint16_t TraceType,

const auto *Data =
static_cast<const xpti::function_with_args_t *>(UserData);
const auto *Plugin = static_cast<pi_plugin *>(Data->user_data);

ArgHandler.handle(Data->function_id, Data->args_data);
ArgHandler.handle(Data->function_id, *Plugin, std::nullopt,
Data->args_data);
std::cout << *static_cast<pi_result *>(Data->ret_data) << "\n";
}
}
22 changes: 16 additions & 6 deletions sycl/tools/xpti_helpers/pi_arguments_handler.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
//==---------- pi_arguments_handler.hpp - PI call arguments handler --------==//
// i
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
Expand All @@ -12,6 +13,7 @@
#include <CL/sycl/detail/type_traits.hpp>

#include <functional>
#include <optional>
#include <tuple>

__SYCL_INLINE_NAMESPACE(cl) {
Expand Down Expand Up @@ -41,7 +43,8 @@ inline TupleT unpack(char *Data,
template <typename T> struct to_function {};

template <typename... Args> struct to_function<std::tuple<Args...>> {
using type = std::function<void(Args...)>;
using type =
std::function<void(const pi_plugin &, std::optional<pi_result>, Args...)>;
};

/// PiArgumentsHandler is a helper class to process incoming XPTI function call
Expand All @@ -59,10 +62,11 @@ template <typename... Args> struct to_function<std::tuple<Args...>> {
/// See sycl/tools/pi-trace/ for an example.
class PiArgumentsHandler {
public:
void handle(uint32_t ID, void *ArgsData) {
void handle(uint32_t ID, const pi_plugin &Plugin,
std::optional<pi_result> Result, void *ArgsData) {
#define _PI_API(api) \
if (ID == static_cast<uint32_t>(detail::PiApiKind::api)) { \
MHandler##_##api(ArgsData); \
MHandler##_##api(Plugin, Result, ArgsData); \
return; \
}
#include <CL/sycl/detail/pi.def>
Expand All @@ -73,21 +77,27 @@ class PiArgumentsHandler {
void set##_##api( \
const typename to_function<typename detail::function_traits<decltype( \
api)>::args_type>::type &Handler) { \
MHandler##_##api = [Handler](void *Data) { \
MHandler##_##api = [Handler](const pi_plugin &Plugin, \
std::optional<pi_result> Res, void *Data) { \
using TupleT = \
typename detail::function_traits<decltype(api)>::args_type; \
TupleT Tuple = unpack<TupleT>( \
(char *)Data, \
std::make_index_sequence<std::tuple_size<TupleT>::value>{}); \
std::apply(Handler, Tuple); \
const auto Wrapper = [&Plugin, Res, Handler](auto &... Args) { \
Handler(Plugin, Res, Args...); \
}; \
std::apply(Wrapper, Tuple); \
}; \
}
#include <CL/sycl/detail/pi.def>
#undef _PI_API

private:
#define _PI_API(api) \
std::function<void(void *)> MHandler##_##api = [](void *) {};
std::function<void(const pi_plugin &, std::optional<pi_result>, void *)> \
MHandler##_##api = \
[](const pi_plugin &, std::optional<pi_result>, void *) {};
#include <CL/sycl/detail/pi.def>
#undef _PI_API
};
Expand Down
16 changes: 9 additions & 7 deletions sycl/unittests/pi/pi_arguments_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,23 @@ TEST(PiArgumentsHandlerTest, CanUnpackArguments) {
const pi_uint32 NumPlatforms = 42;
pi_platform *Platforms = new pi_platform[NumPlatforms];

Handler.set_piPlatformsGet(
[&](pi_uint32 NP, pi_platform *Plts, pi_uint32 *Ret) {
EXPECT_EQ(NP, NumPlatforms);
EXPECT_EQ(Platforms, Plts);
EXPECT_EQ(Ret, nullptr);
});
Handler.set_piPlatformsGet([&](const pi_plugin &, std::optional<pi_result>,
pi_uint32 NP, pi_platform *Plts,
pi_uint32 *Ret) {
EXPECT_EQ(NP, NumPlatforms);
EXPECT_EQ(Platforms, Plts);
EXPECT_EQ(Ret, nullptr);
});

constexpr size_t Size = sizeof(pi_uint32) + 2 * sizeof(void *);
std::array<unsigned char, Size> Data{0};
*reinterpret_cast<pi_uint32 *>(Data.data()) = NumPlatforms;
*reinterpret_cast<pi_platform **>(Data.data() + sizeof(pi_uint32)) =
Platforms;

pi_plugin Plugin{};
uint32_t ID = static_cast<uint32_t>(sycl::detail::PiApiKind::piPlatformsGet);
Handler.handle(ID, Data.data());
Handler.handle(ID, Plugin, std::nullopt, Data.data());

delete[] Platforms;
}

0 comments on commit 2af0599

Please sign in to comment.