DPC++ Runtime
Runtime libraries for oneAPI DPC++
event_impl.hpp
Go to the documentation of this file.
1 //==---------------- event_impl.hpp - SYCL event ---------------------------==//
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 <detail/plugin.hpp>
12 #include <sycl/detail/cl.h>
13 #include <sycl/detail/common.hpp>
15 #include <sycl/detail/pi.hpp>
16 #include <sycl/info/info_desc.hpp>
17 
18 #include <atomic>
19 #include <cassert>
20 #include <condition_variable>
21 #include <optional>
22 
23 namespace sycl {
24 inline namespace _V1 {
25 namespace ext::oneapi::experimental::detail {
26 class graph_impl;
27 }
28 class context;
29 namespace detail {
30 class plugin;
31 class context_impl;
32 using ContextImplPtr = std::shared_ptr<sycl::detail::context_impl>;
33 class queue_impl;
34 using QueueImplPtr = std::shared_ptr<sycl::detail::queue_impl>;
35 class event_impl;
36 using EventImplPtr = std::shared_ptr<sycl::detail::event_impl>;
37 
38 class event_impl {
39 public:
40  enum HostEventState : int {
44  };
45 
51  event_impl(std::optional<HostEventState> State = HES_Complete)
52  : MIsFlushed(true), MState(State.value_or(HES_Complete)),
53  MIsDefaultConstructed(!State), MIsHostEvent(State) {
54  // Need to fail in event() constructor if there are problems with the
55  // ONEAPI_DEVICE_SELECTOR. Deferring may lead to conficts with noexcept
56  // event methods. This ::get() call uses static vars to read and parse the
57  // ODS env var exactly once.
59  }
60 
68  event_impl(sycl::detail::pi::PiEvent Event, const context &SyclContext);
69  event_impl(const QueueImplPtr &Queue);
70 
80  void wait(std::shared_ptr<sycl::detail::event_impl> Self,
81  bool *Success = nullptr);
82 
91  void wait_and_throw(std::shared_ptr<sycl::detail::event_impl> Self);
92 
104  template <typename Param> typename Param::return_type get_profiling_info();
105 
109  template <typename Param> typename Param::return_type get_info();
110 
114  template <typename Param>
115  typename Param::return_type get_backend_info() const;
116 
117  ~event_impl();
118 
124  void waitInternal(bool *Success = nullptr);
125 
127  void setComplete();
128 
139 
144 
147  const PluginPtr &getPlugin();
148 
155  void setContextImpl(const ContextImplPtr &Context);
156 
158  void setStateIncomplete();
159 
165  void *getCommand() { return MCommand; }
166 
172  void setCommand(void *Command);
173 
178 
183 
187  std::vector<std::shared_ptr<event_impl>> &getPreparedDepsEvents() {
188  return MPreparedDepsEvents;
189  }
190 
194  std::vector<std::shared_ptr<event_impl>> &getPreparedHostDepsEvents() {
196  }
197 
201  std::vector<EventImplPtr> getWaitList();
202 
206  void flushIfNeeded(const QueueImplPtr &UserQueue);
207 
210 
213 
217  bool isDiscarded() const { return MState == HES_Discarded; }
218 
224 
228  void setWorkerQueue(const QueueImplPtr &WorkerQueue) {
229  MWorkerQueue = WorkerQueue;
230  };
231 
235  void setSubmittedQueue(const QueueImplPtr &SubmittedQueue) {
236  MSubmittedQueue = SubmittedQueue;
237  };
238 
243  bool isNOP() { return !MCommand && !getHandleRef(); }
244 
247  void setSubmissionTime();
248 
251  void setHostEnqueueTime();
252 
254  uint64_t getSubmissionTime();
255 
256  QueueImplPtr getSubmittedQueue() const { return MSubmittedQueue.lock(); };
257 
261  bool isCompleted();
262 
266  bool isEnqueued() const noexcept { return MIsEnqueued; };
267 
268  void attachEventToComplete(const EventImplPtr &Event) {
269  std::lock_guard<std::mutex> Lock(MMutex);
270  MPostCompleteEvents.push_back(Event);
271  }
272 
274 
278  return MContext;
279  }
280 
281  // Sets a sync point which is used when this event represents an enqueue to a
282  // Command Buffer.
284  MSyncPoint = SyncPoint;
285  }
286 
287  // Get the sync point associated with this event.
289 
291  std::shared_ptr<ext::oneapi::experimental::detail::graph_impl> Graph) {
292  MGraph = Graph;
293  }
294 
295  std::shared_ptr<ext::oneapi::experimental::detail::graph_impl>
296  getCommandGraph() const {
297  return MGraph.lock();
298  }
299 
302  }
303 
306  }
307 
308  void setProfilingEnabled(bool Value) { MIsProfilingEnabled = Value; }
309 
310  // Sets a command-buffer command when this event represents an enqueue to a
311  // Command Buffer.
312  void
315  }
316 
318  return MCommandBufferCommand;
319  }
320 
321  const std::vector<EventImplPtr> &getPostCompleteEvents() const {
322  return MPostCompleteEvents;
323  }
324 
325  void setEnqueued() { MIsEnqueued = true; }
326 
327  bool isHost() { return MIsHostEvent; }
328 
330 
332 
333 protected:
334  // When instrumentation is enabled emits trace event for event wait begin and
335  // returns the telemetry event generated for the wait
336  void *instrumentationProlog(std::string &Name, int32_t StreamID,
337  uint64_t &instance_id) const;
338  // Uses events generated by the Prolog and emits event wait done event
339  void instrumentationEpilog(void *TelementryEvent, const std::string &Name,
340  int32_t StreamID, uint64_t IId) const;
341  void checkProfilingPreconditions() const;
342 
344  // Stores submission time of command associated with event
345  uint64_t MSubmitTime = 0;
346  uint64_t MHostBaseTime = 0;
348  std::unique_ptr<HostProfilingInfo> MHostProfilingInfo;
349  void *MCommand = nullptr;
350  std::weak_ptr<queue_impl> MQueue;
351  bool MIsProfilingEnabled = false;
352  bool MFallbackProfiling = false;
353 
354  std::weak_ptr<queue_impl> MWorkerQueue;
355  std::weak_ptr<queue_impl> MSubmittedQueue;
356 
358  std::vector<EventImplPtr> MPreparedDepsEvents;
359  std::vector<EventImplPtr> MPreparedHostDepsEvents;
360 
361  std::vector<EventImplPtr> MPostCompleteEvents;
362 
365  std::atomic<bool> MIsFlushed = false;
366 
367  // State of host event. Employed only for host events and event with no
368  // backend's representation (e.g. alloca). Used values are listed in
369  // HostEventState enum.
370  std::atomic<int> MState;
371 
372  std::mutex MMutex;
373  std::condition_variable cv;
374 
377  std::weak_ptr<ext::oneapi::experimental::detail::graph_impl> MGraph;
380 
381  // If this event represents a submission to a
382  // sycl::detail::pi::PiExtCommandBuffer the sync point for that submission is
383  // stored here.
385 
386  // If this event represents a submission to a
387  // sycl::detail::pi::PiExtCommandBuffer the command-buffer command
388  // (if any) associated with that submission is stored here.
390 
391  // Signifies whether this event is the result of a profiling tag command. This
392  // allows for profiling, even if the queue does not have profiling enabled.
393  bool MProfilingTagEvent = false;
394 
395  std::atomic_bool MIsEnqueued{false};
396 
397  // Events constructed without a context will lazily use the default context
398  // when needed.
399  void initContextIfNeeded();
400  // Event class represents 3 different kinds of operations:
401  // | type | has PI event | MContext | MIsHostTask | MIsDefaultConstructed |
402  // | dev | true | !nullptr | false | false |
403  // | host | false | nullptr | true | false |
404  // |default| * | * | false | true |
405  // Default constructed event is created with empty ctor in host code, MContext
406  // is lazily initialized with default device context on first context query.
407  // MEvent is lazily created in first pi handle query.
408  bool MIsDefaultConstructed = false;
409  bool MIsHostEvent = false;
410 };
411 
412 } // namespace detail
413 } // namespace _V1
414 } // namespace sycl
The context class represents a SYCL context on which kernel functions may be executed.
Definition: context.hpp:50
The Command class represents some action that needs to be performed on one or more memory objects.
Definition: commands.hpp:106
Profiling info for the host execution.
static const char * get()
Definition: config.hpp:115
Param::return_type get_backend_info() const
Queries this SYCL event for SYCL backend-specific information.
void setCommandGraph(std::shared_ptr< ext::oneapi::experimental::detail::graph_impl > Graph)
Definition: event_impl.hpp:290
void attachEventToComplete(const EventImplPtr &Event)
Definition: event_impl.hpp:268
void setSubmittedQueue(const QueueImplPtr &SubmittedQueue)
Sets original queue used for submission.
Definition: event_impl.hpp:235
Param::return_type get_info()
Queries this SYCL event for information.
std::vector< std::shared_ptr< event_impl > > & getPreparedDepsEvents()
Returns vector of event dependencies.
Definition: event_impl.hpp:187
void checkProfilingPreconditions() const
Definition: event_impl.cpp:264
Param::return_type get_profiling_info()
Queries this event for profiling information.
std::vector< EventImplPtr > getWaitList()
Returns vector of event_impl that this event_impl depends on.
Definition: event_impl.cpp:477
void * instrumentationProlog(std::string &Name, int32_t StreamID, uint64_t &instance_id) const
Definition: event_impl.cpp:172
std::vector< EventImplPtr > MPostCompleteEvents
Definition: event_impl.hpp:361
void cleanDepEventsThroughOneLevel()
Cleans dependencies of this event's dependencies.
Definition: event_impl.cpp:528
void waitInternal(bool *Success=nullptr)
Waits for the event with respect to device type.
Definition: event_impl.cpp:54
void setComplete()
Marks this event as completed.
Definition: event_impl.cpp:87
bool isEnqueued() const noexcept
Checks if associated command is enqueued.
Definition: event_impl.hpp:266
pi_native_handle getNative()
Gets the native handle of the SYCL event.
Definition: event_impl.cpp:460
bool MEventFromSubmittedExecCommandBuffer
Indicates that the event results from a command graph submission.
Definition: event_impl.hpp:379
void * getCommand()
Returns command that is associated with the event.
Definition: event_impl.hpp:165
std::unique_ptr< HostProfilingInfo > MHostProfilingInfo
Definition: event_impl.hpp:348
std::vector< std::shared_ptr< event_impl > > & getPreparedHostDepsEvents()
Returns vector of host event dependencies.
Definition: event_impl.hpp:194
bool isDefaultConstructed() const noexcept
Definition: event_impl.hpp:273
void setCommandBufferCommand(sycl::detail::pi::PiExtCommandBufferCommand Command)
Definition: event_impl.hpp:313
void setEventFromSubmittedExecCommandBuffer(bool value)
Definition: event_impl.hpp:300
void setContextImpl(const ContextImplPtr &Context)
Associate event with the context.
Definition: event_impl.cpp:132
void setHostEnqueueTime()
Calling this function to capture the host timestamp to use profiling base time.
Definition: event_impl.cpp:567
std::weak_ptr< ext::oneapi::experimental::detail::graph_impl > MGraph
Store the command graph associated with this event, if any.
Definition: event_impl.hpp:377
bool isDiscarded() const
Checks if this event is discarded by SYCL implementation.
Definition: event_impl.hpp:217
const ContextImplPtr & getContextImpl()
Returns context that is associated with this event.
Definition: event_impl.cpp:120
void flushIfNeeded(const QueueImplPtr &UserQueue)
Performs a flush on the queue associated with this event if the user queue is different and the task ...
Definition: event_impl.cpp:495
std::weak_ptr< queue_impl > MSubmittedQueue
Definition: event_impl.hpp:355
void setSyncPoint(sycl::detail::pi::PiExtSyncPoint SyncPoint)
Definition: event_impl.hpp:283
std::atomic< int > MState
Definition: event_impl.hpp:370
sycl::detail::pi::PiEvent MEvent
Definition: event_impl.hpp:343
void instrumentationEpilog(void *TelementryEvent, const std::string &Name, int32_t StreamID, uint64_t IId) const
Definition: event_impl.cpp:208
event_impl(std::optional< HostEventState > State=HES_Complete)
Constructs a ready SYCL event.
Definition: event_impl.hpp:51
bool isEventFromSubmittedExecCommandBuffer() const
Definition: event_impl.hpp:304
sycl::detail::pi::PiExtSyncPoint MSyncPoint
Definition: event_impl.hpp:384
bool isCompleted()
Checks if this event is complete.
Definition: event_impl.cpp:577
void setProfilingEnabled(bool Value)
Definition: event_impl.hpp:308
sycl::detail::pi::PiExtSyncPoint getSyncPoint() const
Definition: event_impl.hpp:288
QueueImplPtr getWorkerQueue()
Returns worker queue for command.
Definition: event_impl.hpp:223
std::vector< EventImplPtr > MPreparedHostDepsEvents
Definition: event_impl.hpp:359
void wait(std::shared_ptr< sycl::detail::event_impl > Self, bool *Success=nullptr)
Waits for the event.
Definition: event_impl.cpp:224
QueueImplPtr getSubmittedQueue() const
Definition: event_impl.hpp:256
void setStateIncomplete()
Clear the event state.
Definition: event_impl.cpp:130
std::condition_variable cv
Definition: event_impl.hpp:373
sycl::detail::pi::PiExtCommandBufferCommand getCommandBufferCommand() const
Definition: event_impl.hpp:317
std::vector< EventImplPtr > MPreparedDepsEvents
Dependency events prepared for waiting by backend.
Definition: event_impl.hpp:358
void setSubmissionTime()
Calling this function queries the current device timestamp and sets it as submission time for the com...
Definition: event_impl.cpp:538
void cleanupDependencyEvents()
Cleans dependencies of this event_impl.
Definition: event_impl.cpp:522
const std::vector< EventImplPtr > & getPostCompleteEvents() const
Definition: event_impl.hpp:321
void wait_and_throw(std::shared_ptr< sycl::detail::event_impl > Self)
Waits for the event.
Definition: event_impl.cpp:256
void setWorkerQueue(const QueueImplPtr &WorkerQueue)
Sets worker queue for command.
Definition: event_impl.hpp:228
void setCommand(void *Command)
Associates this event with the command.
Definition: event_impl.cpp:582
const PluginPtr & getPlugin()
Definition: event_impl.cpp:125
bool isNOP()
Indicates if this event is not associated with any command and doesn't have native handle.
Definition: event_impl.hpp:243
sycl::detail::pi::PiEvent & getHandleRef()
Returns raw interoperability event handle.
Definition: event_impl.cpp:118
bool isProfilingTagEvent() const noexcept
Definition: event_impl.hpp:331
HostProfilingInfo * getHostProfilingInfo()
Returns host profiling information.
Definition: event_impl.hpp:177
std::atomic< bool > MIsFlushed
Indicates that the task associated with this event has been submitted by the queue to the device.
Definition: event_impl.hpp:365
std::weak_ptr< queue_impl > MWorkerQueue
Definition: event_impl.hpp:354
sycl::detail::pi::PiExtCommandBufferCommand MCommandBufferCommand
Definition: event_impl.hpp:389
std::atomic_bool MIsEnqueued
Definition: event_impl.hpp:395
std::weak_ptr< queue_impl > MQueue
Definition: event_impl.hpp:350
std::shared_ptr< ext::oneapi::experimental::detail::graph_impl > getCommandGraph() const
Definition: event_impl.hpp:296
ContextImplPtr getContextImplPtr()
Definition: event_impl.hpp:275
::pi_ext_sync_point PiExtSyncPoint
Definition: pi.hpp:130
::pi_ext_command_buffer_command PiExtCommandBufferCommand
Definition: pi.hpp:133
std::shared_ptr< sycl::detail::context_impl > ContextImplPtr
Definition: event_impl.hpp:32
std::shared_ptr< event_impl > EventImplPtr
Definition: handler.hpp:184
std::shared_ptr< plugin > PluginPtr
Definition: pi.hpp:47
std::shared_ptr< sycl::detail::queue_impl > QueueImplPtr
Definition: event_impl.hpp:34
Definition: access.hpp:18
uintptr_t pi_native_handle
Definition: pi.h:258
C++ wrapper of extern "C" PI interfaces.
_Abi const simd< _Tp, _Abi > & noexcept
Definition: simd.hpp:1324