DPC++ Runtime
Runtime libraries for oneAPI DPC++
xpti_registry.hpp
Go to the documentation of this file.
1 //==---------- xpti_registry.hpp ----- XPTI Stream Registry ----------------==//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #pragma once
10 
11 #include <mutex>
12 #include <string>
13 #include <unordered_set>
14 
15 #include <sycl/detail/common.hpp>
16 #include <sycl/version.hpp>
17 
18 #ifdef XPTI_ENABLE_INSTRUMENTATION
19 // Include the headers necessary for emitting
20 // traces using the trace framework
21 #include "xpti/xpti_trace_framework.hpp"
22 #endif
23 
24 namespace sycl {
25 inline namespace _V1 {
26 namespace detail {
27 // We define a sycl stream name and this will be used by the instrumentation
28 // framework
29 inline constexpr const char *SYCL_STREAM_NAME = "sycl";
30 // Stream name being used for traces generated from the SYCL plugin layer
31 inline constexpr const char *SYCL_PICALL_STREAM_NAME = "sycl.pi";
32 // Stream name being used for traces generated from PI calls. This stream
33 // contains information about function arguments.
34 inline constexpr const char *SYCL_PIDEBUGCALL_STREAM_NAME = "sycl.pi.debug";
35 inline constexpr auto SYCL_MEM_ALLOC_STREAM_NAME =
36  "sycl.experimental.mem_alloc";
37 
38 #ifdef XPTI_ENABLE_INSTRUMENTATION
39 extern uint8_t GBufferStreamID;
40 extern uint8_t GImageStreamID;
41 extern uint8_t GMemAllocStreamID;
42 extern xpti::trace_event_data_t *GMemAllocEvent;
43 extern xpti::trace_event_data_t *GSYCLGraphEvent;
44 
45 // We will pick a global constant so that the pointer in TLS never goes stale
46 inline constexpr auto XPTI_QUEUE_INSTANCE_ID_KEY = "queue_id";
47 
48 #define STR(x) #x
49 #define SYCL_VERSION_STR \
50  "sycl " STR(__LIBSYCL_MAJOR_VERSION) "." STR(__LIBSYCL_MINOR_VERSION)
51 
54 constexpr uint32_t GMajVer = __LIBSYCL_MAJOR_VERSION;
55 constexpr uint32_t GMinVer = __LIBSYCL_MINOR_VERSION;
56 constexpr const char *GVerStr = SYCL_VERSION_STR;
57 #endif
58 
59 // Stream name being used to notify about buffer objects.
60 inline constexpr const char *SYCL_BUFFER_STREAM_NAME =
61  "sycl.experimental.buffer";
62 
63 // Stream name being used to notify about image objects.
64 inline constexpr const char *SYCL_IMAGE_STREAM_NAME = "sycl.experimental.image";
65 
66 class XPTIRegistry {
67 public:
69 #ifdef XPTI_ENABLE_INSTRUMENTATION
70  std::call_once(MInitialized, [this] {
71  xptiFrameworkInitialize();
72  // SYCL buffer events
73  GBufferStreamID = xptiRegisterStream(SYCL_BUFFER_STREAM_NAME);
74  this->initializeStream(SYCL_BUFFER_STREAM_NAME, 0, 1, "0.1");
75  // SYCL image events
76  GImageStreamID = xptiRegisterStream(SYCL_IMAGE_STREAM_NAME);
77  this->initializeStream(SYCL_IMAGE_STREAM_NAME, 0, 1, "0.1");
78 
79  // Memory allocation events
80  GMemAllocStreamID = xptiRegisterStream(SYCL_MEM_ALLOC_STREAM_NAME);
81  this->initializeStream(SYCL_MEM_ALLOC_STREAM_NAME, 0, 1, "0.1");
82  xpti::payload_t MAPayload("SYCL Memory Allocations Layer");
83  uint64_t MAInstanceNo = 0;
84  GMemAllocEvent = xptiMakeEvent("SYCL Memory Allocations", &MAPayload,
85  xpti::trace_algorithm_event,
86  xpti_at::active, &MAInstanceNo);
87  });
88 #endif
89  }
90 
97  void initializeStream(const std::string &StreamName, uint32_t MajVer,
98  uint32_t MinVer, const std::string &VerStr) {
99 #ifdef XPTI_ENABLE_INSTRUMENTATION
100  MActiveStreams.insert(StreamName);
101  xptiInitialize(StreamName.c_str(), MajVer, MinVer, VerStr.c_str());
102 #endif // XPTI_ENABLE_INSTRUMENTATION
103  }
104 
106 #ifdef XPTI_ENABLE_INSTRUMENTATION
107  for (const auto &StreamName : MActiveStreams) {
108  xptiFinalize(StreamName.c_str());
109  }
110  xptiFrameworkFinalize();
111 #endif // XPTI_ENABLE_INSTRUMENTATION
112  }
113 
114  static void bufferConstructorNotification(const void *,
115  const detail::code_location &,
116  const void *, const void *,
117  uint32_t, uint32_t, size_t[3]);
118  static void bufferAssociateNotification(const void *, const void *);
119  static void bufferReleaseNotification(const void *, const void *);
120  static void bufferDestructorNotification(const void *);
121  static void bufferAccessorNotification(const void *, const void *, uint32_t,
122  uint32_t,
123  const detail::code_location &);
124 
125  static void sampledImageConstructorNotification(const void *,
126  const detail::code_location &,
127  const void *, uint32_t,
128  size_t[3], uint32_t, uint32_t,
129  uint32_t, uint32_t);
130  static void sampledImageDestructorNotification(const void *);
131 
133  const void *, const detail::code_location &, const void *, uint32_t,
134  size_t[3], uint32_t);
135  static void unsampledImageDestructorNotification(const void *);
136 
137  static void unsampledImageAccessorNotification(const void *, const void *,
138  uint32_t, uint32_t,
139  const void *, uint32_t,
140  const detail::code_location &);
141  static void
142  unsampledImageHostAccessorNotification(const void *, const void *, uint32_t,
143  const void *, uint32_t,
144  const detail::code_location &);
145  static void sampledImageAccessorNotification(const void *, const void *,
146  uint32_t, const void *, uint32_t,
147  const detail::code_location &);
148  static void
149  sampledImageHostAccessorNotification(const void *, const void *, const void *,
150  uint32_t, const detail::code_location &);
151 
152 private:
153  std::unordered_set<std::string> MActiveStreams;
154  std::once_flag MInitialized;
155 
156 #ifdef XPTI_ENABLE_INSTRUMENTATION
157  static xpti::trace_event_data_t *
158  createTraceEvent(const void *Obj, const void *ObjName, uint64_t &IId,
159  const detail::code_location &CodeLoc,
160  uint16_t TraceEventType);
161 #endif // XPTI_ENABLE_INSTRUMENTATION
162 };
163 
167 #if XPTI_ENABLE_INSTRUMENTATION
168 class XPTIScope {
169 public:
170  using TracePoint = xpti::framework::tracepoint_t;
180  XPTIScope(void *CodePtr, uint16_t TraceType, const char *StreamName,
181  uint64_t InstanceID, const char *UserData)
182  : MUserData(UserData), MStreamID(0), MInstanceID(InstanceID),
183  MScopedNotify(false), MTraceType(0) {
185  auto TData = Tls.query();
186  // If TLS is not set, we can still genertate universal IDs with user data
187  // and CodePtr information
188  const char *FuncName = TData.functionName();
189  if (!TData.functionName() && !TData.fileName())
190  FuncName = UserData;
191  // Create a tracepoint object that has a lifetime of this class
192  MTP = new TracePoint(TData.fileName(), FuncName, TData.lineNumber(),
193  TData.columnNumber(), CodePtr);
194  if (TraceType == (uint16_t)xpti::trace_point_type_t::graph_create ||
195  TraceType == (uint16_t)xpti::trace_point_type_t::node_create ||
196  TraceType == (uint16_t)xpti::trace_point_type_t::edge_create ||
197  TraceType == (uint16_t)xpti::trace_point_type_t::queue_create)
198  MTP->parent_event(GSYCLGraphEvent);
199  // Now if tracing is enabled, create trace events and notify
200  if (xptiTraceEnabled() && MTP) {
201  MTP->stream(StreamName).trace_type((xpti::trace_point_type_t)TraceType);
202  MTraceEvent = const_cast<xpti::trace_event_data_t *>(MTP->trace_event());
203  MStreamID = MTP->stream_id();
204  // This constructor uses a manual override for the instance ID as some
205  // objects such as queues keep track of instance IDs
206  MTP->override_instance_id(MInstanceID);
207  }
208  }
209 
217  XPTIScope(void *CodePtr, uint16_t TraceType, const char *StreamName,
218  const char *UserData)
219  : MUserData(UserData), MStreamID(0), MInstanceID(0), MScopedNotify(false),
220  MTraceType(0) {
221  detail::tls_code_loc_t Tls;
222  auto TData = Tls.query();
223  // If TLS is not set, we can still genertate universal IDs with user data
224  // and CodePtr information
225  const char *FuncName = TData.functionName();
226  if (!TData.functionName() && !TData.fileName())
227  FuncName = UserData;
228  // Create a tracepoint object that has a lifetime of this class
229  MTP = new TracePoint(TData.fileName(), FuncName, TData.lineNumber(),
230  TData.columnNumber(), CodePtr);
231  if (TraceType == (uint16_t)xpti::trace_point_type_t::graph_create ||
232  TraceType == (uint16_t)xpti::trace_point_type_t::node_create ||
233  TraceType == (uint16_t)xpti::trace_point_type_t::edge_create ||
234  TraceType == (uint16_t)xpti::trace_point_type_t::queue_create)
235  MTP->parent_event(GSYCLGraphEvent);
236  // Now if tracing is enabled, create trace events and notify
237  if (xptiTraceEnabled() && MTP) {
238  MTP->stream(StreamName).trace_type((xpti::trace_point_type_t)TraceType);
239  MTraceEvent = const_cast<xpti::trace_event_data_t *>(MTP->trace_event());
240  MStreamID = MTP->stream_id();
241  MInstanceID = MTP->instance_id();
242  }
243  }
244 
245  XPTIScope(const XPTIScope &rhs) = delete;
246 
247  XPTIScope &operator=(const XPTIScope &rhs) = delete;
248 
249  xpti::trace_event_data_t *traceEvent() { return MTraceEvent; }
250 
251  uint8_t streamID() { return MStreamID; }
252 
253  uint64_t instanceID() { return MTP ? MTP->instance_id() : 0; }
254 
255  XPTIScope &
256  addMetadata(const std::function<void(xpti::trace_event_data_t *)> &Callback) {
257  if (xptiTraceEnabled() && MTP) {
258  auto TEvent = const_cast<xpti::trace_event_data_t *>(MTP->trace_event());
259  Callback(TEvent);
260  }
261  return *this;
262  }
263 
264  XPTIScope &notify() {
265  MTP->notify(static_cast<const void *>(MUserData));
266  return *this;
267  }
268 
271  XPTIScope &scopedNotify(uint16_t TraceType) {
272  // Keep this data even if no subscribers are for this TraceType (begin).
273  // Someone could still use (end) emitted from destructor.
274  MTraceType = TraceType & 0xfffe;
275  MScopedNotify = true;
276  if (xptiCheckTraceEnabled(MStreamID, TraceType) && MTP) {
277  xptiNotifySubscribers(MStreamID, MTraceType, nullptr, MTraceEvent,
278  MInstanceID, static_cast<const void *>(MUserData));
279  }
280  return *this;
281  }
282  ~XPTIScope() {
283  MTraceType = MTraceType | 1;
284  if (xptiCheckTraceEnabled(MStreamID, MTraceType) && MTP && MScopedNotify) {
285  if (MTraceType == (uint16_t)xpti::trace_point_type_t::signal ||
286  MTraceType == (uint16_t)xpti::trace_point_type_t::graph_create ||
287  MTraceType == (uint16_t)xpti::trace_point_type_t::node_create ||
288  MTraceType == (uint16_t)xpti::trace_point_type_t::edge_create ||
289  MTraceType == (uint16_t)xpti::trace_point_type_t::queue_create ||
290  MTraceType == (uint16_t)xpti::trace_point_type_t::queue_destroy ||
291  MTraceType == (uint16_t)xpti::trace_point_type_t::diagnostics)
292  return;
293 
294  // Only notify for a trace type that has a begin/end
295  xptiNotifySubscribers(MStreamID, MTraceType, nullptr, MTraceEvent,
296  MInstanceID, static_cast<const void *>(MUserData));
297  }
298  // Delete the tracepoint object which will clear TLS if it is the top of
299  // the scope
300  delete MTP;
301  }
302 
303 private:
304  // Tracepoint_t object who's lifetime is that of the class
305  TracePoint *MTP = nullptr;
306  // Trace event created from the TLS data, if it exists
307  xpti::trace_event_data_t *MTraceEvent = nullptr;
308  // The const string that indicates the operation
309  const char *MUserData = nullptr;
310  // The stream on which the notifications occur
311  uint8_t MStreamID;
312  // The instance ID for the trace event; if it is called in a loop, then the
313  // trace event ID will remain the same, but the instance ID will increment
314  uint64_t MInstanceID;
315  // If scoped notifcation is requested, this tracks the request
316  bool MScopedNotify;
317  // The trace type information for scoped notifications
318  uint16_t MTraceType;
319 }; // class XPTIScope
320 #endif
321 
322 class queue_impl;
323 std::string queueDeviceToString(const detail::queue_impl *const &Queue);
324 
325 } // namespace detail
326 } // namespace _V1
327 } // namespace sycl
static void sampledImageHostAccessorNotification(const void *, const void *, const void *, uint32_t, const detail::code_location &)
static void bufferAccessorNotification(const void *, const void *, uint32_t, uint32_t, const detail::code_location &)
static void bufferAssociateNotification(const void *, const void *)
static void unsampledImageAccessorNotification(const void *, const void *, uint32_t, uint32_t, const void *, uint32_t, const detail::code_location &)
static void bufferConstructorNotification(const void *, const detail::code_location &, const void *, const void *, uint32_t, uint32_t, size_t[3])
static void unsampledImageHostAccessorNotification(const void *, const void *, uint32_t, const void *, uint32_t, const detail::code_location &)
static void sampledImageDestructorNotification(const void *)
static void unsampledImageDestructorNotification(const void *)
static void bufferDestructorNotification(const void *)
static void sampledImageAccessorNotification(const void *, const void *, uint32_t, const void *, uint32_t, const detail::code_location &)
static void bufferReleaseNotification(const void *, const void *)
static void unsampledImageConstructorNotification(const void *, const detail::code_location &, const void *, uint32_t, size_t[3], uint32_t)
void initializeStream(const std::string &StreamName, uint32_t MajVer, uint32_t MinVer, const std::string &VerStr)
Notifies XPTI subscribers about new stream.
static void sampledImageConstructorNotification(const void *, const detail::code_location &, const void *, uint32_t, size_t[3], uint32_t, uint32_t, uint32_t, uint32_t)
Data type that manages the code_location information in TLS.
Definition: common.hpp:129
const detail::code_location & query()
Query the information in the TLS slot.
Definition: common.cpp:54
constexpr const char * SYCL_IMAGE_STREAM_NAME
constexpr const char * SYCL_PIDEBUGCALL_STREAM_NAME
constexpr const char * SYCL_STREAM_NAME
constexpr auto SYCL_MEM_ALLOC_STREAM_NAME
constexpr const char * SYCL_BUFFER_STREAM_NAME
std::string queueDeviceToString(const queue_impl *const &Queue)
constexpr const char * SYCL_PICALL_STREAM_NAME
PropertyListT int access::address_space multi_ptr & operator=(multi_ptr &&)=default
Definition: access.hpp:18
constexpr const char * functionName() const noexcept
Definition: common.hpp:90
constexpr int GMajVer
Definition: tracing.cpp:27
constexpr int GMinVer
Definition: tracing.cpp:28
constexpr auto GVerStr
Definition: tracing.cpp:26