From 0829524cbeb4a3ef1de3b991e53c8dd312129ed3 Mon Sep 17 00:00:00 2001 From: Krzysztof Swiecicki Date: Tue, 30 Sep 2025 10:35:35 +0000 Subject: [PATCH] [UR][L0][L0v2] Explicitly mark timestamped events This is a workaround for a case where L0 driver fails to retrieve a timestamp but doesn't return an error. In such case, when event profiling info is queried we check the timestamp value and assume the event was not timestamped even though it was. This scenario can happen on newer platform with not yet full driver support. --- .../source/adapters/level_zero/event.cpp | 17 ++++++----------- .../source/adapters/level_zero/event.hpp | 7 +++---- .../source/adapters/level_zero/v2/event.cpp | 8 +++----- .../source/adapters/level_zero/v2/event.hpp | 3 ++- 4 files changed, 14 insertions(+), 21 deletions(-) diff --git a/unified-runtime/source/adapters/level_zero/event.cpp b/unified-runtime/source/adapters/level_zero/event.cpp index 7e71058dda7d3..2b6af79f292c0 100644 --- a/unified-runtime/source/adapters/level_zero/event.cpp +++ b/unified-runtime/source/adapters/level_zero/event.cpp @@ -531,7 +531,7 @@ ur_result_t urEventGetProfilingInfo( std::shared_lock EventLock(Event->Mutex); // The event must either have profiling enabled or be recording timestamps. - bool isTimestampedEvent = Event->isTimestamped(); + bool isTimestampedEvent = Event->IsTimestamped; if (!Event->isProfilingEnabled() && !isTimestampedEvent) { return UR_RESULT_ERROR_PROFILING_INFO_NOT_AVAILABLE; } @@ -764,6 +764,9 @@ ur_result_t urEnqueueTimestampRecordingExp( Device, &DeviceStartTimestamp, nullptr)); (*OutEvent)->RecordEventStartTimestamp = DeviceStartTimestamp; + // Mark this event as timestamped + (*OutEvent)->IsTimestamped = true; + // Create a new entry in the queue's recordings. Queue->EndTimeRecordings[*OutEvent] = 0; @@ -1141,7 +1144,7 @@ ur_result_t urEventReleaseInternal(ur_event_handle_t Event, // If the event was a timestamp recording, we try to evict its entry in the // queue. - if (Event->isTimestamped()) { + if (Event->IsTimestamped) { auto Entry = Queue->EndTimeRecordings.find(Event); if (Entry != Queue->EndTimeRecordings.end()) { auto &EndTimeRecording = Entry->second; @@ -1435,6 +1438,7 @@ ur_result_t ur_event_handle_t_::reset() { CommandList = std::nullopt; completionBatch = std::nullopt; OriginAllocEvent = nullptr; + IsTimestamped = false; if (!isHostVisible()) HostVisibleEvent = nullptr; @@ -1767,12 +1771,3 @@ bool ur_event_handle_t_::isProfilingEnabled() const { return !UrQueue || // tentatively assume user events are profiling enabled (UrQueue->Properties & UR_QUEUE_FLAG_PROFILING_ENABLE) != 0; } - -// Tells if this event was created as a timestamp event, allowing profiling -// info even if profiling is not enabled. -bool ur_event_handle_t_::isTimestamped() const { - // If we are recording, the start time of the event will be non-zero. The - // end time might still be missing, depending on whether the corresponding - // enqueue is still running. - return RecordEventStartTimestamp != 0; -} diff --git a/unified-runtime/source/adapters/level_zero/event.hpp b/unified-runtime/source/adapters/level_zero/event.hpp index 7e5efa87bb6f2..77c3aa8fb24a8 100644 --- a/unified-runtime/source/adapters/level_zero/event.hpp +++ b/unified-runtime/source/adapters/level_zero/event.hpp @@ -200,6 +200,9 @@ struct ur_event_handle_t_ : ur_object { // plugin. bool IsDiscarded = {false}; + // Indicates that this is a timestamped event. + bool IsTimestamped = {false}; + // Indicates that this event is needed to be visible by multiple devices. // When possible, allocate Event from single device pool for optimal // performance @@ -246,10 +249,6 @@ struct ur_event_handle_t_ : ur_object { // Tells if this event is with profiling capabilities. bool isProfilingEnabled() const; - // Tells if this event was created as a timestamp event, allowing profiling - // info even if profiling is not enabled. - bool isTimestamped() const; - // Get the host-visible event or create one and enqueue its signal. ur_result_t getOrCreateHostVisibleEvent(ze_event_handle_t &HostVisibleEvent); diff --git a/unified-runtime/source/adapters/level_zero/v2/event.cpp b/unified-runtime/source/adapters/level_zero/v2/event.cpp index 2c3c4b9a8685c..7151e10a4be8a 100644 --- a/unified-runtime/source/adapters/level_zero/v2/event.cpp +++ b/unified-runtime/source/adapters/level_zero/v2/event.cpp @@ -73,6 +73,7 @@ void event_profiling_data_t::reset() { // possible. adjustedEventStartTimestamp = 0; adjustedEventEndTimestamp = 0; + timestampRecorded = false; } void event_profiling_data_t::recordStartTimestamp(ur_device_handle_t hDevice) { @@ -85,18 +86,15 @@ void event_profiling_data_t::recordStartTimestamp(ur_device_handle_t hDevice) { assert(adjustedEventStartTimestamp == 0); adjustedEventStartTimestamp = deviceStartTimestamp; + timestampRecorded = true; } uint64_t event_profiling_data_t::getEventStartTimestmap() const { return adjustedEventStartTimestamp; } -bool event_profiling_data_t::recordingEnded() const { - return adjustedEventEndTimestamp != 0; -} - bool event_profiling_data_t::recordingStarted() const { - return adjustedEventStartTimestamp != 0; + return timestampRecorded; } uint64_t *event_profiling_data_t::eventEndTimestampAddr() { diff --git a/unified-runtime/source/adapters/level_zero/v2/event.hpp b/unified-runtime/source/adapters/level_zero/v2/event.hpp index 9a31c47358947..98b3b98c3ce1f 100644 --- a/unified-runtime/source/adapters/level_zero/v2/event.hpp +++ b/unified-runtime/source/adapters/level_zero/v2/event.hpp @@ -34,7 +34,6 @@ struct event_profiling_data_t { uint64_t *eventEndTimestampAddr(); bool recordingStarted() const; - bool recordingEnded() const; // clear the profiling data, allowing the event to be reused // for a new command @@ -49,6 +48,8 @@ struct event_profiling_data_t { uint64_t zeTimerResolution = 0; uint64_t timestampMaxValue = 0; + + bool timestampRecorded = false; }; struct ur_event_handle_t_ : ur_object {