21 #ifdef XPTI_ENABLE_INSTRUMENTATION
22 #include "xpti/xpti_trace_framework.hpp"
31 #ifdef XPTI_ENABLE_INSTRUMENTATION
32 extern xpti::trace_event_data_t *GSYCLGraphEvent;
36 void event_impl::ensureContextInitialized() {
37 if (MIsContextInitialized)
41 QueueImplPtr HostQueue = Scheduler::getInstance().getDefaultHostQueue();
44 const device &SyclDevice = default_selector().select_device();
45 this->setContextImpl(detail::queue_impl::getDefaultOrNew(
50 bool event_impl::is_host() {
56 event_impl::~event_impl() {
61 void event_impl::waitInternal() {
62 if (!MHostEvent && MEvent) {
65 }
else if (MState == HES_Discarded) {
67 throw sycl::exception(
69 "waitInternal method cannot be used for a discarded event.");
70 }
else if (MState != HES_Complete) {
72 std::unique_lock<std::mutex> lock(MMutex);
73 cv.wait(lock, [
this] {
return MState == HES_Complete; });
81 void event_impl::setComplete() {
82 if (MHostEvent || !MEvent) {
84 std::unique_lock<std::mutex> lock(MMutex);
86 int Expected = HES_NotComplete;
87 int Desired = HES_Complete;
89 bool Succeeded = MState.compare_exchange_strong(Expected, Desired);
91 assert(Succeeded &&
"Unexpected state of event");
93 MState.store(
static_cast<int>(HES_Complete));
100 assert(
false &&
"setComplete is not supported for non-host event");
103 const RT::PiEvent &event_impl::getHandleRef()
const {
return MEvent; }
104 RT::PiEvent &event_impl::getHandleRef() {
return MEvent; }
107 ensureContextInitialized();
112 ensureContextInitialized();
113 return MContext->getPlugin();
116 void event_impl::setStateIncomplete() { MState = HES_NotComplete; }
119 MHostEvent = Context->is_host();
121 MIsContextInitialized =
true;
125 : MIsContextInitialized(true), MEvent(Event),
127 MIsFlushed(true), MState(HES_Complete) {
130 throw sycl::invalid_parameter_error(
131 "The syclContext must match the OpenCL context associated with the "
133 PI_ERROR_INVALID_CONTEXT);
139 &TempContext,
nullptr);
140 if (
MContext->getHandleRef() != TempContext) {
141 throw sycl::invalid_parameter_error(
142 "The syclContext must match the OpenCL context associated with the "
144 PI_ERROR_INVALID_CONTEXT);
150 MIsProfilingEnabled{Queue->is_host() || Queue->MIsProfilingEnabled} {
151 this->setContextImpl(Queue->getContextImplPtr());
153 if (Queue->is_host()) {
154 MState.store(HES_NotComplete);
156 if (Queue->has_property<property::queue::enable_profiling>()) {
157 MHostProfilingInfo.reset(
new HostProfilingInfo());
158 if (!MHostProfilingInfo)
159 throw runtime_error(
"Out of host memory", PI_ERROR_OUT_OF_HOST_MEMORY);
163 MState.store(HES_Complete);
167 uint64_t &IId)
const {
168 void *TraceEvent =
nullptr;
169 #ifdef XPTI_ENABLE_INSTRUMENTATION
170 if (!xptiTraceEnabled())
174 static std::atomic<uint64_t> InstanceID = {1};
175 xpti::trace_event_data_t *WaitEvent =
nullptr;
179 xpti::utils::StringHelper SH;
190 WaitEvent = GSYCLGraphEvent;
194 xptiNotifySubscribers(StreamID, xpti::trace_wait_begin,
nullptr, WaitEvent,
195 IId,
static_cast<const void *
>(Name.c_str()));
196 TraceEvent = (
void *)WaitEvent;
202 const std::string &Name,
203 int32_t StreamID, uint64_t IId)
const {
204 #ifdef XPTI_ENABLE_INSTRUMENTATION
205 if (!(xptiTraceEnabled() && TelemetryEvent))
208 xpti::trace_event_data_t *TraceEvent =
209 (xpti::trace_event_data_t *)TelemetryEvent;
210 xptiNotifySubscribers(StreamID, xpti::trace_wait_end,
nullptr, TraceEvent,
211 IId,
static_cast<const void *
>(Name.c_str()));
218 "wait method cannot be used for a discarded event.");
220 #ifdef XPTI_ENABLE_INSTRUMENTATION
221 void *TelemetryEvent =
nullptr;
235 #ifdef XPTI_ENABLE_INSTRUMENTATION
241 std::shared_ptr<sycl::detail::event_impl> Self) {
245 SubmittedQueue->throw_asynchronous();
249 std::weak_ptr<queue_impl> EmptyPtr;
251 if (!EmptyPtr.owner_before(
MQueue) && !
MQueue.owner_before(EmptyPtr)) {
253 "Profiling information is unavailable as the event "
254 "has no associated queue.");
257 throw sycl::exception(
259 "Profiling information is unavailable as the queue associated with "
260 "the event does not have the 'enable_profiling' property.");
266 event_impl::get_profiling_info<info::event_profiling::command_submit>() {
267 checkProfilingPreconditions();
273 event_impl::get_profiling_info<info::event_profiling::command_start>() {
274 checkProfilingPreconditions();
277 return get_event_profiling_info<info::event_profiling::command_start>(
278 this->getHandleRef(), this->
getPlugin());
281 if (!MHostProfilingInfo)
282 throw invalid_object_error(
"Profiling info is not available.",
283 PI_ERROR_PROFILING_INFO_NOT_AVAILABLE);
284 return MHostProfilingInfo->getStartTime();
288 uint64_t event_impl::get_profiling_info<info::event_profiling::command_end>() {
289 checkProfilingPreconditions();
292 return get_event_profiling_info<info::event_profiling::command_end>(
293 this->getHandleRef(), this->
getPlugin());
296 if (!MHostProfilingInfo)
297 throw invalid_object_error(
"Profiling info is not available.",
298 PI_ERROR_PROFILING_INFO_NOT_AVAILABLE);
299 return MHostProfilingInfo->getEndTime();
302 template <> uint32_t event_impl::get_info<info::event::reference_count>() {
303 if (!MHostEvent && MEvent) {
304 return get_event_info<info::event::reference_count>(this->getHandleRef(),
312 event_impl::get_info<info::event::command_execution_status>() {
313 if (MState == HES_Discarded)
319 return get_event_info<info::event::command_execution_status>(
320 this->getHandleRef(), this->
getPlugin());
323 return sycl::info::event_command_status::submitted;
326 return MHostEvent && MState.load() != HES_Complete
327 ? sycl::info::event_command_status::submitted
332 auto TimeStamp = std::chrono::high_resolution_clock::now().time_since_epoch();
333 return std::chrono::duration_cast<std::chrono::nanoseconds>(TimeStamp)
347 auto TempContext =
MContext.get()->getHandleRef();
359 throw sycl::exception(
361 "get_wait_list() cannot be used for a discarded event.");
363 std::lock_guard<std::mutex> Lock(
MMutex);
365 std::vector<EventImplPtr> Result;
388 if (Queue == UserQueue)
403 std::lock_guard<std::mutex> Lock(
MMutex);
409 std::lock_guard<std::mutex> Lock(
MMutex);
411 Event->cleanupDependencyEvents();
414 Event->cleanupDependencyEvents();
423 MSubmitTime = Queue->getDeviceImplPtr()->getCurrentDeviceTime();
426 std::string(
"Unable to get command group submission time: ") +
435 return get_info<info::event::command_execution_status>() ==