24 #include <sycl/version.hpp>
36 #ifdef XPTI_ENABLE_INSTRUMENTATION
39 #include "xpti/xpti_trace_framework.h"
43 inline namespace _V1 {
45 #ifdef XPTI_ENABLE_INSTRUMENTATION
49 xpti_td *GSYCLGraphEvent =
nullptr;
51 xpti_td *GPICallEvent =
nullptr;
53 xpti_td *GPIArgCallEvent =
nullptr;
54 xpti_td *GPIArgCallActiveEvent =
nullptr;
56 uint8_t PiCallStreamID = 0;
57 uint8_t PiDebugCallStreamID = 0;
62 void *ReturnOpaqueData =
nullptr;
63 const PluginPtr &Plugin = pi::getPlugin<BE>();
66 OpaqueDataParam, &ReturnOpaqueData);
68 return ReturnOpaqueData;
71 template __SYCL_EXPORT
void *
72 getPluginOpaqueData<sycl::backend::ext_intel_esimd_emulator>(
void *);
83 uint64_t CorrelationID = 0;
84 #ifdef XPTI_ENABLE_INSTRUMENTATION
115 constexpr uint16_t NotificationTraceType =
116 (uint16_t)xpti::trace_point_type_t::function_begin;
117 if (xptiCheckTraceEnabled(PiCallStreamID, NotificationTraceType)) {
118 CorrelationID = xptiGetUniqueId();
119 xptiNotifySubscribers(PiCallStreamID, NotificationTraceType, GPICallEvent,
120 nullptr, CorrelationID,
121 static_cast<const void *
>(FName));
124 return CorrelationID;
128 #ifdef XPTI_ENABLE_INSTRUMENTATION
129 constexpr uint16_t NotificationTraceType =
130 (uint16_t)xpti::trace_point_type_t::function_end;
131 if (xptiCheckTraceEnabled(PiCallStreamID, NotificationTraceType)) {
136 xptiNotifySubscribers(PiCallStreamID, NotificationTraceType, GPICallEvent,
137 nullptr, CorrelationID,
138 static_cast<const void *
>(FName));
144 unsigned char *ArgsData,
146 uint64_t CorrelationID = 0;
147 #ifdef XPTI_ENABLE_INSTRUMENTATION
148 constexpr uint16_t NotificationTraceType =
149 (uint16_t)xpti::trace_point_type_t::function_with_args_begin;
150 if (xptiCheckTraceEnabled(PiDebugCallStreamID, NotificationTraceType)) {
151 xpti::function_with_args_t Payload{FuncID, FuncName, ArgsData,
nullptr,
155 auto CodeLoc = Tls.
query();
156 xpti::payload_t PL = xpti::payload_t(
157 CodeLoc.functionName(), CodeLoc.fileName(), CodeLoc.lineNumber(),
158 CodeLoc.columnNumber(),
nullptr);
159 uint64_t InstanceNumber{};
160 assert(GPIArgCallActiveEvent ==
nullptr);
161 GPIArgCallActiveEvent =
162 xptiMakeEvent(
"Plugin interface call", &PL, xpti::trace_graph_event,
163 xpti_at::active, &InstanceNumber);
166 CorrelationID = xptiGetUniqueId();
167 xptiNotifySubscribers(PiDebugCallStreamID, NotificationTraceType,
168 GPIArgCallEvent, GPIArgCallActiveEvent, CorrelationID,
172 return CorrelationID;
176 const char *FuncName,
unsigned char *ArgsData,
178 #ifdef XPTI_ENABLE_INSTRUMENTATION
179 constexpr uint16_t NotificationTraceType =
180 (uint16_t)xpti::trace_point_type_t::function_with_args_end;
181 if (xptiCheckTraceEnabled(PiDebugCallStreamID, NotificationTraceType)) {
182 xpti::function_with_args_t Payload{FuncID, FuncName, ArgsData, &Result,
185 xptiNotifySubscribers(PiDebugCallStreamID, NotificationTraceType,
186 GPIArgCallEvent, GPIArgCallActiveEvent, CorrelationID,
188 GPIArgCallActiveEvent =
nullptr;
197 auto contextHandle =
reinterpret_cast<pi_context>(impl->getHandleRef());
198 const auto &Plugin = impl->getPlugin();
206 return "PI_PLATFORM_INFO_PROFILE";
208 return "PI_PLATFORM_INFO_VERSION";
210 return "PI_PLATFORM_INFO_NAME";
212 return "PI_PLATFORM_INFO_VENDOR";
214 return "PI_PLATFORM_INFO_EXTENSIONS";
216 return "PI_EXT_PLATFORM_INFO_BACKEND";
218 die(
"Unknown pi_platform_info value passed to "
219 "sycl::detail::pi::platformInfoToString");
223 assertion(((Flag == 0u) || ((Flag & (Flag - 1)) == 0)) &&
224 "More than one bit set");
226 std::stringstream Sstream;
230 Sstream <<
"pi_mem_flags(0)";
233 Sstream <<
"PI_MEM_FLAGS_ACCESS_RW";
236 Sstream <<
"PI_MEM_FLAGS_HOST_PTR_USE";
239 Sstream <<
"PI_MEM_FLAGS_HOST_PTR_COPY";
242 Sstream <<
"unknown pi_mem_flags bit == " << Flag;
245 return Sstream.str();
249 std::stringstream Sstream;
250 bool FoundFlag =
false;
252 auto FlagSeparator = [](
bool FoundFlag) {
return FoundFlag ?
"|" :
""; };
259 Sstream <<
"pi_mem_flags(0)";
261 for (
const auto Flag : ValidFlags) {
271 if (UnkownBits.any()) {
272 Sstream << FlagSeparator(FoundFlag)
273 <<
"unknown pi_mem_flags bits == " << UnkownBits;
277 return Sstream.str();
287 std::vector<std::pair<std::string, backend>> PluginNames;
295 if (!OdsTargetList) {
297 PluginNames.emplace_back(__SYCL_LEVEL_ZERO_PLUGIN_NAME,
301 PluginNames.emplace_back(__SYCL_UR_PLUGIN_NAME,
backend::all);
302 PluginNames.emplace_back(__SYCL_NATIVE_CPU_PLUGIN_NAME,
311 PluginNames.emplace_back(__SYCL_LEVEL_ZERO_PLUGIN_NAME,
315 PluginNames.emplace_back(__SYCL_CUDA_PLUGIN_NAME,
322 PluginNames.emplace_back(__SYCL_NATIVE_CPU_PLUGIN_NAME,
325 PluginNames.emplace_back(__SYCL_UR_PLUGIN_NAME,
backend::all);
347 const std::shared_ptr<PiPlugin> &PluginInformation) {
352 if (PluginInitializeFunction ==
nullptr)
355 int Err = PluginInitializeFunction(PluginInformation.get());
359 assert((Err == PI_SUCCESS) &&
"Unexpected error when binding to Plugin.");
368 return (TraceLevelMask & Level) == Level;
376 auto initializeHelper = []() {
380 static bool Initialized = initializeHelper();
381 std::ignore = Initialized;
390 std::vector<std::tuple<std::string, backend, void *>>
391 loadPlugins(
const std::vector<std::pair<std::string, backend>> &&PluginNames);
394 const std::vector<std::pair<std::string, backend>> PluginNames =
399 <<
"No Plugins Found." << std::endl;
402 std::vector<std::tuple<std::string, backend, void *>> LoadedPlugins =
407 for (
auto &[Name, Backend, Library] : LoadedPlugins) {
408 std::shared_ptr<PiPlugin> PluginInformation =
409 std::make_shared<PiPlugin>(
PiPlugin{
418 <<
"Check if plugin is present. "
419 <<
"Failed to load plugin: " << Name << std::endl;
424 if (!
bindPlugin(Library, PluginInformation)) {
427 <<
"Failed to bind PI APIs to the plugin: " << Name
432 PluginPtr &NewPlugin = Plugins.emplace_back(
433 std::make_shared<plugin>(PluginInformation, Backend, Library));
436 <<
"Plugin found and successfully loaded: " << Name
437 <<
" [ PluginVersion: "
438 << NewPlugin->getPiPlugin().PluginVersion <<
" ]" << std::endl;
441 #ifdef XPTI_ENABLE_INSTRUMENTATION
462 xpti::payload_t GraphPayload(
"application_graph");
463 uint64_t GraphInstanceNo;
465 xptiMakeEvent(
"application_graph", &GraphPayload, xpti::trace_graph_event,
466 xpti_at::active, &GraphInstanceNo);
467 if (GSYCLGraphEvent) {
470 xptiNotifySubscribers(StreamID, xpti::trace_graph_create,
nullptr,
471 GSYCLGraphEvent, GraphInstanceNo,
nullptr);
477 xpti::payload_t PIPayload(
"Plugin Interface Layer");
478 uint64_t PiInstanceNo;
480 xptiMakeEvent(
"PI Layer", &PIPayload, xpti::trace_algorithm_event,
481 xpti_at::active, &PiInstanceNo);
485 xpti::payload_t PIArgPayload(
486 "Plugin Interface Layer (with function arguments)");
487 uint64_t PiArgInstanceNo;
488 GPIArgCallEvent = xptiMakeEvent(
"PI Layer with arguments", &PIArgPayload,
489 xpti::trace_algorithm_event, xpti_at::active,
504 for (
auto &P : Plugins)
505 if (P->hasBackend(BE)) {
510 throw runtime_error(
"pi::getPlugin couldn't find plugin",
511 PI_ERROR_INVALID_OPERATION);
514 template __SYCL_EXPORT
const PluginPtr &getPlugin<backend::opencl>();
516 getPlugin<backend::ext_oneapi_level_zero>();
518 getPlugin<backend::ext_intel_esimd_emulator>();
519 template __SYCL_EXPORT
const PluginPtr &getPlugin<backend::ext_oneapi_cuda>();
520 template __SYCL_EXPORT
const PluginPtr &getPlugin<backend::ext_oneapi_hip>();
526 [[noreturn]]
void die(
const char *Message) {
527 std::cerr <<
"pi_die: " << Message << std::endl;
537 template <
typename ResT>
540 assert(NumBytes <=
sizeof(ResT));
543 for (
size_t I = 0; I < NumBytes; ++I) {
544 Result = (Result << 8) | static_cast<ResT>(Data[I]);
547 std::copy(Data, Data + NumBytes,
reinterpret_cast<char *
>(&Result));
554 const unsigned char *ImgData,
557 bool Is64bit = ImgData[4] == 2;
558 bool IsBigEndian = ImgData[5] == 2;
561 size_t SectionHeaderOffsetInfoOffset = Is64bit ? 0x28 : 0x20;
562 size_t SectionHeaderSizeInfoOffset = Is64bit ? 0x3A : 0x2E;
563 size_t SectionHeaderNumInfoOffset = Is64bit ? 0x3C : 0x30;
564 size_t SectionStringsHeaderIndexInfoOffset = Is64bit ? 0x3E : 0x32;
567 if (ImgSize < SectionStringsHeaderIndexInfoOffset + 2)
572 uint64_t SectionHeaderOffset = readELFValue<uint64_t>(
573 ImgData + SectionHeaderOffsetInfoOffset, Is64bit ? 8 : 4, IsBigEndian);
574 uint16_t SectionHeaderSize = readELFValue<uint16_t>(
575 ImgData + SectionHeaderSizeInfoOffset, 2, IsBigEndian);
576 uint16_t SectionHeaderNum = readELFValue<uint16_t>(
577 ImgData + SectionHeaderNumInfoOffset, 2, IsBigEndian);
578 uint16_t SectionStringsHeaderIndex = readELFValue<uint16_t>(
579 ImgData + SectionStringsHeaderIndexInfoOffset, 2, IsBigEndian);
583 if (ImgSize < SectionHeaderOffset + SectionHeaderNum * SectionHeaderSize ||
584 SectionStringsHeaderIndex >= SectionHeaderNum)
588 size_t SectionStringsInfoOffset = Is64bit ? 0x18 : 0x10;
589 const unsigned char *SectionStringsHeaderData =
590 ImgData + SectionHeaderOffset +
591 SectionStringsHeaderIndex * SectionHeaderSize;
592 uint64_t SectionStrings = readELFValue<uint64_t>(
593 SectionStringsHeaderData + SectionStringsInfoOffset, Is64bit ? 8 : 4,
595 const unsigned char *SectionStringsData = ImgData + SectionStrings;
599 for (
size_t I = 0; I < SectionHeaderNum; ++I) {
601 const unsigned char *HeaderData =
602 ImgData + SectionHeaderOffset + I * SectionHeaderSize;
603 uint32_t SectionNameOffset =
604 readELFValue<uint32_t>(HeaderData, 4, IsBigEndian);
608 const char *SectionName =
609 reinterpret_cast<const char *
>(SectionStringsData + SectionNameOffset);
610 if (SectionName == ExpectedSectionName)
619 assert(ImgSize >= 18 &&
"Not enough bytes to have an ELF header type.");
621 bool IsBigEndian = ImgData[5] == 2;
622 return readELFValue<uint16_t>(ImgData + 16, 2, IsBigEndian);
628 auto MatchMagicNumber = [&](
auto Number) {
629 return ImgSize >=
sizeof(Number) &&
630 std::memcmp(ImgData, &Number,
sizeof(Number)) == 0;
633 if (MatchMagicNumber(uint32_t{0x07230203}))
636 if (MatchMagicNumber(uint32_t{0xDEC04342}))
639 if (MatchMagicNumber(uint32_t{0x43544E49}))
645 if (ImgSize >= 18 && MatchMagicNumber(uint32_t{0x464c457F})) {
647 if (ELFHdrType == 0xFF04)
651 if (ELFHdrType == 0xFF12)
661 if (MatchMagicNumber(std::array{
'!',
'<',
'a',
'r',
'c',
'h',
'>',
'\n'}))
The context class represents a SYCL context on which kernel functions may be executed.
XPTIRegistry & getXPTIRegistry()
std::vector< PluginPtr > & getPlugins()
static GlobalHandler & instance()
static ProgramManager & getInstance()
bool kernelUsesAsan() const
static const char * get()
void initializeFrameworkOnce()
void initializeStream(const std::string &StreamName, uint32_t MajVer, uint32_t MinVer, const std::string &VerStr)
Notifies XPTI subscribers about new stream.
bool backendCompatible(backend Backend)
Data type that manages the code_location information in TLS.
const detail::code_location & query()
Query the information in the TLS slot.
__SYCL_EXTERN_STREAM_ATTRS ostream cerr
Linked to standard error (unbuffered)
std::string memFlagToString(pi_mem_flags Flag)
static bool checkELFSectionPresent(const std::string &ExpectedSectionName, const unsigned char *ImgData, size_t ImgSize)
void contextSetExtendedDeleter(const sycl::context &constext, pi_context_extended_deleter func, void *user_data)
std::string memFlagsToString(pi_mem_flags Flags)
void emitFunctionEndTrace(uint64_t CorrelationID, const char *FName)
Emits an XPTI trace after the PI API call has been made.
static void initializePlugins(std::vector< PluginPtr > &Plugins)
void * loadOsPluginLibrary(const std::string &Library)
std::vector< PluginPtr > & initialize()
void die(const char *Message)
uint64_t emitFunctionBeginTrace(const char *FName)
Emits an XPTI trace before a PI API call is made.
void assertion(bool Condition, const char *Message=nullptr)
std::vector< std::pair< std::string, backend > > findPlugins()
void * loadPlugin(const std::string &PluginPath)
PiDeviceBinaryType getBinaryImageFormat(const unsigned char *ImgData, size_t ImgSize)
Tries to determine the device binary image foramat.
bool trace(TraceLevel level)
static ResT readELFValue(const unsigned char *Data, size_t NumBytes, bool IsBigEndian)
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.
std::string platformInfoToString(pi_platform_info info)
std::shared_ptr< plugin > GlobalPlugin
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.
bool bindPlugin(void *Library, const std::shared_ptr< PiPlugin > &PluginInformation)
static uint16_t getELFHeaderType(const unsigned char *ImgData, size_t ImgSize)
::pi_device_binary_type PiDeviceBinaryType
void * getOsLibraryFuncAddress(void *Library, const std::string &FunctionName)
int unloadOsPluginLibrary(void *Library)
std::vector< std::tuple< std::string, backend, void * > > loadPlugins(const std::vector< std::pair< std::string, backend >> &&PluginNames)
int unloadPlugin(void *Library)
constexpr const char * SYCL_PIDEBUGCALL_STREAM_NAME
constexpr const char * SYCL_STREAM_NAME
static const PluginPtr & getPlugin(backend Backend)
decltype(Obj::impl) getSyclObjImpl(const Obj &SyclObject)
void * getPluginOpaqueData(void *opaquedata_arg)
std::shared_ptr< plugin > PluginPtr
constexpr const char * SYCL_PICALL_STREAM_NAME
void copy(handler &CGH, const T *Src, T *Dest, size_t Count)
static constexpr pi_device_binary_type PI_DEVICE_BINARY_TYPE_LLVMIR_BITCODE
#define _PI_H_VERSION_STRING
static constexpr pi_device_binary_type PI_DEVICE_BINARY_TYPE_NATIVE
pi_result piextPluginGetOpaqueData(void *opaque_data_param, void **opaque_data_return)
API to get Plugin internal data, opaque to SYCL RT.
@ PI_PLATFORM_INFO_VENDOR
@ PI_PLATFORM_INFO_EXTENSIONS
@ PI_PLATFORM_INFO_PROFILE
@ PI_EXT_PLATFORM_INFO_BACKEND
@ PI_PLATFORM_INFO_VERSION
constexpr pi_mem_flags PI_MEM_FLAGS_HOST_PTR_COPY
static constexpr pi_device_binary_type PI_DEVICE_BINARY_TYPE_SPIRV
constexpr pi_mem_flags PI_MEM_FLAGS_HOST_PTR_USE
void(* pi_context_extended_deleter)(void *user_data)
pi_result piPluginInit(pi_plugin *plugin_info)
@ _PI_SANITIZE_TYPE_ADDRESS
constexpr pi_mem_flags PI_MEM_FLAGS_ACCESS_RW
pi_result piextContextSetExtendedDeleter(pi_context context, pi_context_extended_deleter func, void *user_data)
static constexpr pi_device_binary_type PI_DEVICE_BINARY_TYPE_NONE
C++ wrapper of extern "C" PI interfaces.