21 #ifdef XPTI_ENABLE_INSTRUMENTATION
22 #include "xpti/xpti_trace_framework.hpp"
29 inline namespace _V1 {
31 #ifdef XPTI_ENABLE_INSTRUMENTATION
32 extern xpti::trace_event_data_t *GSYCLGraphEvent;
49 }
catch (std::exception &e) {
61 if (Success !=
nullptr &&
62 (Err == UR_RESULT_ERROR_UNKNOWN ||
63 Err == UR_RESULT_ERROR_IN_EVENT_LIST_EXEC_STATUS))
67 if (Success !=
nullptr)
74 "waitInternal method cannot be used for a discarded event.");
77 std::unique_lock<std::mutex> lock(
MMutex);
89 std::unique_lock<std::mutex> lock(
MMutex);
94 bool Succeeded =
MState.compare_exchange_strong(Expected, Desired);
96 assert(Succeeded &&
"Unexpected state of event");
105 assert(
false &&
"setComplete is not supported for non-host event");
109 auto Timestamp = std::chrono::high_resolution_clock::now().time_since_epoch();
110 return std::chrono::duration_cast<std::chrono::nanoseconds>(Timestamp)
136 MIsFlushed(true), MState(HES_Complete) {
138 ur_context_handle_t TempContext;
140 sizeof(ur_context_handle_t), &TempContext,
nullptr);
142 if (
MContext->getHandleRef() != TempContext) {
144 "The syclContext must match the OpenCL context "
145 "associated with the clEvent. " +
151 : MQueue{Queue}, MIsProfilingEnabled{!Queue || Queue->MIsProfilingEnabled},
152 MFallbackProfiling{MIsProfilingEnabled && Queue &&
153 Queue->isProfilingFallback()} {
162 "Out of host memory " +
170 uint64_t &IId)
const {
171 void *TraceEvent =
nullptr;
172 #ifdef XPTI_ENABLE_INSTRUMENTATION
173 constexpr uint16_t NotificationTraceType = xpti::trace_wait_begin;
174 if (!xptiCheckTraceEnabled(StreamID, NotificationTraceType))
178 static std::atomic<uint64_t> InstanceID = {1};
179 xpti::trace_event_data_t *WaitEvent =
nullptr;
183 xpti::utils::StringHelper SH;
184 Name = SH.nameWithAddress<ur_event_handle_t>(
"event.wait",
MEvent);
194 WaitEvent = GSYCLGraphEvent;
198 xptiNotifySubscribers(StreamID, NotificationTraceType,
nullptr, WaitEvent,
199 IId,
static_cast<const void *
>(Name.c_str()));
200 TraceEvent = (
void *)WaitEvent;
206 const std::string &Name,
207 int32_t StreamID, uint64_t IId)
const {
208 #ifdef XPTI_ENABLE_INSTRUMENTATION
209 constexpr uint16_t NotificationTraceType = xpti::trace_wait_end;
210 if (!(xptiCheckTraceEnabled(StreamID, NotificationTraceType) &&
214 xpti::trace_event_data_t *TraceEvent =
215 (xpti::trace_event_data_t *)TelemetryEvent;
216 xptiNotifySubscribers(StreamID, NotificationTraceType,
nullptr, TraceEvent,
217 IId,
static_cast<const void *
>(Name.c_str()));
225 "wait method cannot be used for a discarded event.");
229 "wait method cannot be used for an event associated "
230 "with a command graph.");
233 #ifdef XPTI_ENABLE_INSTRUMENTATION
234 void *TelemetryEvent =
nullptr;
248 #ifdef XPTI_ENABLE_INSTRUMENTATION
254 std::shared_ptr<sycl::detail::event_impl> Self) {
258 SubmittedQueue->throw_asynchronous();
262 std::weak_ptr<queue_impl> EmptyPtr;
265 !
MQueue.owner_before(EmptyPtr)) {
267 "Profiling information is unavailable as the event "
268 "has no associated queue.");
273 "Profiling information is unavailable as the queue associated with "
274 "the event does not have the 'enable_profiling' property.");
280 event_impl::get_profiling_info<info::event_profiling::command_submit>() {
281 checkProfilingPreconditions();
282 if (isProfilingTagEvent()) {
285 return get_event_profiling_info<info::event_profiling::command_submit>(
286 this->getHandleRef(), this->
getPlugin());
303 if (MEventFromSubmittedExecCommandBuffer && !MIsHostEvent && MEvent) {
305 get_event_profiling_info<info::event_profiling::command_start>(
306 this->getHandleRef(), this->
getPlugin());
307 if (StartTime < MSubmitTime)
308 MSubmitTime = StartTime;
315 event_impl::get_profiling_info<info::event_profiling::command_start>() {
316 checkProfilingPreconditions();
320 get_event_profiling_info<info::event_profiling::command_start>(
321 this->getHandleRef(), this->
getPlugin());
322 if (!MFallbackProfiling) {
325 auto DeviceBaseTime =
326 get_event_profiling_info<info::event_profiling::command_submit>(
327 this->getHandleRef(), this->
getPlugin());
328 return MHostBaseTime - DeviceBaseTime + StartTime;
333 if (!MHostProfilingInfo)
336 "Profiling info is not available. " +
337 codeToString(UR_RESULT_ERROR_PROFILING_INFO_NOT_AVAILABLE));
338 return MHostProfilingInfo->getStartTime();
342 uint64_t event_impl::get_profiling_info<info::event_profiling::command_end>() {
343 checkProfilingPreconditions();
347 get_event_profiling_info<info::event_profiling::command_end>(
348 this->getHandleRef(), this->
getPlugin());
349 if (!MFallbackProfiling) {
352 auto DeviceBaseTime =
353 get_event_profiling_info<info::event_profiling::command_submit>(
354 this->getHandleRef(), this->
getPlugin());
355 return MHostBaseTime - DeviceBaseTime + EndTime;
360 if (!MHostProfilingInfo)
363 "Profiling info is not available. " +
364 codeToString(UR_RESULT_ERROR_PROFILING_INFO_NOT_AVAILABLE));
365 return MHostProfilingInfo->getEndTime();
368 template <> uint32_t event_impl::get_info<info::event::reference_count>() {
369 if (!MIsHostEvent && MEvent) {
370 return get_event_info<info::event::reference_count>(this->getHandleRef(),
378 event_impl::get_info<info::event::command_execution_status>() {
379 if (MState == HES_Discarded)
385 return get_event_info<info::event::command_execution_status>(
386 this->getHandleRef(), this->
getPlugin());
389 return sycl::info::event_command_status::submitted;
392 return MIsHostEvent && MState.load() != HES_Complete
393 ? sycl::info::event_command_status::submitted
398 typename info::platform::version::return_type
399 event_impl::get_backend_info<info::platform::version>()
const {
401 return "Context not initialized, no backend info available";
405 "the info::platform::version info descriptor can "
406 "only be queried with an OpenCL backend");
409 return Queue->getDeviceImplPtr()
411 .get_info<info::platform::version>();
419 typename info::device::version::return_type
420 event_impl::get_backend_info<info::device::version>()
const {
422 return "Context not initialized, no backend info available";
426 "the info::device::version info descriptor can only "
427 "be queried with an OpenCL backend");
430 return Queue->getDeviceImplPtr()->get_info<info::device::version>();
437 typename info::device::backend_version::return_type
438 event_impl::get_backend_info<info::device::backend_version>()
const {
440 return "Context not initialized, no backend info available";
444 "the info::device::backend_version info descriptor "
445 "can only be queried with a Level Zero backend");
464 auto TempContext =
MContext.get()->getHandleRef();
465 ur_event_native_properties_t NativeProperties{};
466 Plugin->call(urEventCreateWithNativeHandle, 0, TempContext,
467 &NativeProperties, &
MEvent);
471 ur_native_handle_t Handle;
472 Plugin->call(urEventGetNativeHandle,
getHandleRef(), &Handle);
480 "get_wait_list() cannot be used for a discarded event.");
482 std::lock_guard<std::mutex> Lock(
MMutex);
484 std::vector<EventImplPtr> Result;
507 if (Queue == UserQueue)
511 ur_event_status_t Status = UR_EVENT_STATUS_QUEUED;
513 UR_EVENT_INFO_COMMAND_EXECUTION_STATUS,
514 sizeof(ur_event_status_t), &Status,
nullptr);
515 if (Status == UR_EVENT_STATUS_QUEUED) {
516 getPlugin()->call(urQueueFlush, Queue->getHandleRef());
522 std::lock_guard<std::mutex> Lock(
MMutex);
528 std::lock_guard<std::mutex> Lock(
MMutex);
530 Event->cleanupDependencyEvents();
533 Event->cleanupDependencyEvents();
543 MSubmitTime = Queue->getDeviceImplPtr()->getCurrentDeviceTime();
545 if (e.
code() == sycl::errc::feature_not_supported)
548 std::string(
"Unable to get command group submission time: ") +
550 std::rethrow_exception(std::current_exception());
554 using namespace std::chrono;
556 duration_cast<nanoseconds>(steady_clock::now().time_since_epoch())
577 return get_info<info::event::command_execution_status>() ==
583 auto TypedCommand =
static_cast<Command *
>(Cmd);
585 MIsHostEvent = TypedCommand->getWorkerContext() ==
nullptr;
The context class represents a SYCL context on which kernel functions may be executed.
The Command class represents some action that needs to be performed on one or more memory objects.
void * MTraceEvent
The event for node_create and task_begin.
Profiling info for the host execution.
void end()
Measures event's end time.
void start()
Measures event's start time.
void waitForEvent(const EventImplPtr &Event, bool *Success=nullptr)
Waits for the event.
static Scheduler & getInstance()
void checkProfilingPreconditions() const
std::vector< EventImplPtr > getWaitList()
Returns vector of event_impl that this event_impl depends on.
void * instrumentationProlog(std::string &Name, int32_t StreamID, uint64_t &instance_id) const
uint64_t getSubmissionTime()
void initContextIfNeeded()
std::vector< EventImplPtr > MPostCompleteEvents
void cleanDepEventsThroughOneLevel()
Cleans dependencies of this event's dependencies.
void waitInternal(bool *Success=nullptr)
Waits for the event with respect to device type.
void setComplete()
Marks this event as completed.
std::unique_ptr< HostProfilingInfo > MHostProfilingInfo
void setContextImpl(const ContextImplPtr &Context)
Associate event with the context.
void setHostEnqueueTime()
Calling this function to capture the host timestamp to use profiling base time.
std::weak_ptr< ext::oneapi::experimental::detail::graph_impl > MGraph
Store the command graph associated with this event, if any.
const ContextImplPtr & getContextImpl()
Returns context that is associated with this event.
void flushIfNeeded(const QueueImplPtr &UserQueue)
Performs a flush on the queue associated with this event if the user queue is different and the task ...
std::weak_ptr< queue_impl > MSubmittedQueue
std::atomic< int > MState
void instrumentationEpilog(void *TelementryEvent, const std::string &Name, int32_t StreamID, uint64_t IId) const
event_impl(std::optional< HostEventState > State=HES_Complete)
Constructs a ready SYCL event.
bool isCompleted()
Checks if this event is complete.
ur_native_handle_t getNative()
Gets the native handle of the SYCL event.
ur_event_handle_t & getHandleRef()
Returns raw interoperability event handle.
bool MIsDefaultConstructed
std::vector< EventImplPtr > MPreparedHostDepsEvents
void wait(std::shared_ptr< sycl::detail::event_impl > Self, bool *Success=nullptr)
Waits for the event.
void setStateIncomplete()
Clear the event state.
std::condition_variable cv
std::vector< EventImplPtr > MPreparedDepsEvents
Dependency events prepared for waiting by backend.
void setSubmissionTime()
Calling this function queries the current device timestamp and sets it as submission time for the com...
void cleanupDependencyEvents()
Cleans dependencies of this event_impl.
void wait_and_throw(std::shared_ptr< sycl::detail::event_impl > Self)
Waits for the event.
void setCommand(void *Command)
Associates this event with the command.
const PluginPtr & getPlugin()
std::atomic< bool > MIsFlushed
Indicates that the task associated with this event has been submitted by the queue to the device.
std::weak_ptr< queue_impl > MQueue
static ContextImplPtr getDefaultOrNew(const DeviceImplPtr &Device)
The SYCL device class encapsulates a single SYCL device on which kernels may be executed.
const char * what() const noexcept final
const std::error_code & code() const noexcept
#define __SYCL_REPORT_EXCEPTION_TO_STREAM(str, e)
decltype(Obj::impl) const & getSyclObjImpl(const Obj &SyclObject)
std::string codeToString(int32_t code)
constexpr const char * SYCL_STREAM_NAME
static uint64_t getTimestamp()
std::shared_ptr< sycl::detail::context_impl > ContextImplPtr
static const PluginPtr & getPlugin(backend Backend)
std::shared_ptr< event_impl > EventImplPtr
std::shared_ptr< plugin > PluginPtr
std::shared_ptr< sycl::detail::queue_impl > QueueImplPtr
std::error_code make_error_code(sycl::errc E) noexcept
Constructs an error code using e and sycl_category()