19 #ifdef XPTI_ENABLE_INSTRUMENTATION
21 #include "xpti/xpti_trace_framework.h"
25 inline namespace _V1 {
27 #ifdef XPTI_ENABLE_INSTRUMENTATION
28 extern xpti::trace_event_data_t *GPICallEvent;
29 extern xpti::trace_event_data_t *GPIArgCallEvent;
30 extern uint8_t PiCallStreamID;
31 extern uint8_t PiDebugCallStreamID;
34 template <
PiApiKind Kind,
size_t Idx,
typename... Args>
39 #define _PI_API(api) \
40 template <> struct PiApiArgTuple<PiApiKind::api> { \
41 using type = typename function_traits<decltype(api)>::args_type; \
44 #include <sycl/detail/pi.def>
47 template <PiApiKind Kind,
size_t Idx,
typename T>
49 static void fill(
unsigned char *Dst, T &&Arg) {
52 auto RealArg = (std::tuple_element_t<Idx, ArgsTuple>)(Arg);
53 *(std::remove_cv_t<std::tuple_element_t<Idx, ArgsTuple>> *)Dst = RealArg;
57 template <
PiApiKind Kind,
size_t Idx,
typename T,
typename... Args>
59 static void fill(
unsigned char *Dst,
const T &&Arg, Args &&...Rest) {
62 auto RealArg = (std::tuple_element_t<Idx, ArgsTuple>)(Arg);
63 *(std::remove_cv_t<std::tuple_element_t<Idx, ArgsTuple>> *)Dst = RealArg;
65 Dst +
sizeof(decltype(RealArg)), std::forward<Args>(Rest)...);
69 template <
typename... Ts>
70 constexpr
size_t totalSize(
const std::tuple<Ts...> &) {
71 return (
sizeof(Ts) + ...);
74 template <
PiApiKind Kind,
typename... ArgsT>
78 constexpr
size_t TotalSize =
totalSize(ArgsTuple{});
80 std::array<unsigned char, TotalSize> ArgsData;
82 std::forward<ArgsT>(Args)...);
94 plugin(
const std::shared_ptr<sycl::detail::pi::PiPlugin> &Plugin,
95 backend UseBackend,
void *LibraryHandle)
96 : MPlugin(Plugin), MBackend(UseBackend), MLibraryHandle(LibraryHandle),
97 TracingMutex(
std::make_shared<
std::mutex>()),
98 MPluginMutex(
std::make_shared<
std::mutex>()) {}
117 template <
typename Exception = sycl::runtime_error>
119 char *message =
nullptr;
120 if (
pi_result == PI_ERROR_PLUGIN_SPECIFIC_ERROR) {
121 pi_result = call_nocheck<PiApiKind::piPluginGetLastError>(&message);
135 template <sycl::errc errc>
137 if (
pi_result == PI_ERROR_PLUGIN_SPECIFIC_ERROR) {
138 char *message =
nullptr;
139 pi_result = call_nocheck<PiApiKind::piPluginGetLastError>(&message);
156 " API failed with error: " +
173 template <
PiApiKind PiApiOffset,
typename... ArgsT>
176 #ifdef XPTI_ENABLE_INSTRUMENTATION
177 bool CorrelationIDAvailable =
false, CorrelationIDWithArgsAvailable =
false;
181 const char *PIFnName = PiCallInfo.getFuncName();
182 uint64_t CorrelationIDWithArgs = 0, CorrelationID = 0;
184 if (xptiCheckTraceEnabled(
186 (uint16_t)xpti::trace_point_type_t::function_begin)) {
188 CorrelationIDAvailable =
true;
190 unsigned char *ArgsDataPtr =
nullptr;
196 if (xptiCheckTraceEnabled(
198 (uint16_t)xpti::trace_point_type_t::function_with_args_begin)) {
199 using PackCallArgumentsTy = decltype(packCallArguments<PiApiOffset>(
200 std::forward<ArgsT>(Args)...));
203 ? packCallArguments<PiApiOffset>(std::forward<ArgsT>(Args)...)
204 : PackCallArgumentsTy{};
206 ArgsDataPtr = ArgsData.data();
208 static_cast<uint32_t
>(PiApiOffset), PIFnName, ArgsDataPtr, *MPlugin);
209 CorrelationIDWithArgsAvailable =
true;
214 std::lock_guard<std::mutex> Guard(*TracingMutex);
215 const char *FnName = PiCallInfo.getFuncName();
216 std::cout <<
"---> " << FnName <<
"(" << std::endl;
219 R = PiCallInfo.getFuncPtr(*MPlugin)(Args...);
226 std::cout <<
"API Called After Plugin Teardown, Functon Call ignored.";
231 R = PiCallInfo.getFuncPtr(*MPlugin)(Args...);
234 #ifdef XPTI_ENABLE_INSTRUMENTATION
238 if (CorrelationIDAvailable) {
242 if (CorrelationIDWithArgsAvailable) {
244 static_cast<uint32_t
>(PiApiOffset),
245 PIFnName, ArgsDataPtr, R, *MPlugin);
254 template <
PiApiKind PiApiOffset,
typename... ArgsT>
255 void call(ArgsT... Args)
const {
262 void call(ArgsT... Args)
const {
264 checkPiResult<errc>(Err);
283 auto It = std::find(PiPlatforms.begin(), PiPlatforms.end(), Platform);
284 if (It != PiPlatforms.end())
285 return It - PiPlatforms.begin();
287 PiPlatforms.push_back(Platform);
288 LastDeviceIds.push_back(0);
289 return PiPlatforms.size() - 1;
301 return LastDeviceIds[PlatformId - 1];
308 LastDeviceIds[PlatformId] = Id;
316 if (PlatformId > 0 &&
317 LastDeviceIds[PlatformId] < LastDeviceIds[PlatformId - 1])
318 LastDeviceIds[PlatformId] = LastDeviceIds[PlatformId - 1];
322 auto It = std::find(PiPlatforms.begin(), PiPlatforms.end(), Platform);
323 return It != PiPlatforms.end();
330 std::shared_ptr<sycl::detail::pi::PiPlugin> MPlugin;
332 void *MLibraryHandle;
333 std::shared_ptr<std::mutex> TracingMutex;
337 std::shared_ptr<std::mutex> MPluginMutex;
339 std::vector<sycl::detail::pi::PiPlatform> PiPlatforms;
342 std::vector<int> LastDeviceIds;
345 using PluginPtr = std::shared_ptr<plugin>;
The context class represents a SYCL context on which kernel functions may be executed.
The plugin class provides a unified interface to the underlying low-level runtimes for the device-agn...
bool hasBackend(backend Backend) const
Tells if this plugin can serve specified backend.
void reportPiError(sycl::detail::pi::PiResult pi_result, const char *context) const
plugin & operator=(const plugin &)=delete
plugin(plugin &&other) noexcept=delete
void call(ArgsT... Args) const
Calls the API, traces the call, checks the result.
const std::shared_ptr< sycl::detail::pi::PiPlugin > & getPiPluginPtr() const
plugin(const plugin &)=delete
void adjustLastDeviceId(sycl::detail::pi::PiPlatform Platform)
int getPlatformId(sycl::detail::pi::PiPlatform Platform)
int getStartingDeviceId(sycl::detail::pi::PiPlatform Platform)
void checkPiResult(sycl::detail::pi::PiResult pi_result) const
Checks return value from PI calls.
plugin & operator=(plugin &&other) noexcept=delete
bool containsPiPlatform(sycl::detail::pi::PiPlatform Platform)
const sycl::detail::pi::PiPlugin & getPiPlugin() const
void * getLibraryHandle()
void * getLibraryHandle() const
sycl::detail::pi::PiPlugin & getPiPlugin()
std::shared_ptr< std::mutex > getPluginMutex()
void setLastDeviceId(sycl::detail::pi::PiPlatform Platform, int Id)
plugin(const std::shared_ptr< sycl::detail::pi::PiPlugin > &Plugin, backend UseBackend, void *LibraryHandle)
sycl::detail::pi::PiResult call_nocheck(ArgsT... Args) const
Calls the PiApi, traces the call, and returns the result.
void call(ArgsT... Args) const
#define __SYCL_CHECK_OCL_CODE_THROW(X, EXC, STR)
#define __SYCL_CHECK_CODE_THROW_VIA_ERRC(X, ERRC)
__SYCL_EXTERN_STREAM_ATTRS ostream cout
Linked to standard output.
__SYCL_EXTERN_STREAM_ATTRS ostream clog
Linked to standard error (buffered)
void emitFunctionEndTrace(uint64_t CorrelationID, const char *FName)
Emits an XPTI trace after the PI API call has been made.
uint64_t emitFunctionBeginTrace(const char *FName)
Emits an XPTI trace before a PI API call is made.
bool trace(TraceLevel level)
uint64_t emitFunctionWithArgsBeginTrace(uint32_t FuncID, const char *FName, unsigned char *ArgsData, pi_plugin Plugin)
Notifies XPTI subscribers about PI function calls and packs call arguments.
void emitFunctionWithArgsEndTrace(uint64_t CorrelationID, uint32_t FuncID, const char *FName, unsigned char *ArgsData, pi_result Result, pi_plugin Plugin)
Notifies XPTI subscribers about PI function call result.
int unloadPlugin(void *Library)
auto packCallArguments(ArgsT &&...Args)
std::string codeToString(pi_int32 code)
constexpr size_t totalSize(const std::tuple< Ts... > &)
std::shared_ptr< plugin > PluginPtr
static sycl::event fill(sycl::queue q, void *dev_ptr, const T &pattern, size_t count)
Set pattern to the first count elements of type T starting from dev_ptr.
C++ wrapper of extern "C" PI interfaces.
_Abi const simd< _Tp, _Abi > & noexcept
static void fill(unsigned char *Dst, const T &&Arg, Args &&...Rest)
static void fill(unsigned char *Dst, T &&Arg)