Skip to content

Commit f08d42c

Browse files
[L0] Interrupt-based event implementation
To expose this functionality in UR, we want two ways of enabling low-power events: Queue-wide enabling so all events created on the queue are low-powered. As a property passed to urEnqueueEventsWaitWithBarrier making the resulting event a low-power event. This will require the existing interface to be extended with properties, potentially through a new experimental function. Signed-off-by: Zhang, Winston <winston.zhang@intel.com>
1 parent e7ee297 commit f08d42c

File tree

8 files changed

+72
-22
lines changed

8 files changed

+72
-22
lines changed

source/adapters/level_zero/command_buffer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ ur_result_t createSyncPointAndGetZeEvents(
215215
UR_CALL(EventCreate(CommandBuffer->Context, nullptr /*Queue*/,
216216
false /*IsMultiDevice*/, HostVisible, &LaunchEvent,
217217
false /*CounterBasedEventEnabled*/,
218-
!CommandBuffer->IsProfilingEnabled));
218+
!CommandBuffer->IsProfilingEnabled, false));
219219
LaunchEvent->CommandType = CommandType;
220220
ZeLaunchEvent = LaunchEvent->ZeEvent;
221221

source/adapters/level_zero/context.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,8 @@ static const uint32_t MaxNumEventsPerPool = [] {
478478
ur_result_t ur_context_handle_t_::getFreeSlotInExistingOrNewPool(
479479
ze_event_pool_handle_t &Pool, size_t &Index, bool HostVisible,
480480
bool ProfilingEnabled, ur_device_handle_t Device,
481-
bool CounterBasedEventEnabled, bool UsingImmCmdList) {
481+
bool CounterBasedEventEnabled, bool UsingImmCmdList,
482+
bool InterruptBasedEventEnabled) {
482483
// Lock while updating event pool machinery.
483484
std::scoped_lock<ur_mutex> Lock(ZeEventPoolCacheMutex);
484485

@@ -537,6 +538,14 @@ ur_result_t ur_context_handle_t_::getFreeSlotInExistingOrNewPool(
537538
counterBasedExt.flags);
538539
ZeEventPoolDesc.pNext = &counterBasedExt;
539540
}
541+
if (InterruptBasedEventEnabled) {
542+
ze_intel_event_sync_mode_exp_desc_t eventSyncMode = {
543+
ZE_INTEL_STRUCTURE_TYPE_EVENT_SYNC_MODE_EXP_DESC, nullptr, 0};
544+
eventSyncMode.syncModeFlags =
545+
ZE_INTEL_EVENT_SYNC_MODE_EXP_FLAG_LOW_POWER_WAIT |
546+
ZE_INTEL_EVENT_SYNC_MODE_EXP_FLAG_SIGNAL_INTERRUPT;
547+
ZeEventPoolDesc.pNext = &eventSyncMode;
548+
}
540549

541550
std::vector<ze_device_handle_t> ZeDevices;
542551
if (ZeDevice) {

source/adapters/level_zero/context.hpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,24 @@ struct l0_command_list_cache_info {
3333
bool IsImmediate = false;
3434
};
3535

36+
typedef uint32_t ze_intel_event_sync_mode_exp_flags_t;
37+
typedef enum _ze_intel_event_sync_mode_exp_flag_t {
38+
ZE_INTEL_EVENT_SYNC_MODE_EXP_FLAG_LOW_POWER_WAIT = ZE_BIT(0),
39+
ZE_INTEL_EVENT_SYNC_MODE_EXP_FLAG_SIGNAL_INTERRUPT = ZE_BIT(1),
40+
ZE_INTEL_EVENT_SYNC_MODE_EXP_EXP_FLAG_FORCE_UINT32 = 0x7fffffff
41+
42+
} ze_intel_event_sync_mode_exp_flag_t;
43+
44+
#define ZE_INTEL_STRUCTURE_TYPE_EVENT_SYNC_MODE_EXP_DESC \
45+
(ze_structure_type_t)0x00030016
46+
47+
typedef struct _ze_intel_event_sync_mode_exp_desc_t {
48+
ze_structure_type_t stype;
49+
const void *pNext;
50+
51+
ze_intel_event_sync_mode_exp_flags_t syncModeFlags;
52+
} ze_intel_event_sync_mode_exp_desc_t;
53+
3654
struct ur_context_handle_t_ : _ur_object {
3755
ur_context_handle_t_(ze_context_handle_t ZeContext, uint32_t NumDevices,
3856
const ur_device_handle_t *Devs, bool OwnZeContext)
@@ -199,7 +217,8 @@ struct ur_context_handle_t_ : _ur_object {
199217
bool ProfilingEnabled,
200218
ur_device_handle_t Device,
201219
bool CounterBasedEventEnabled,
202-
bool UsingImmCmdList);
220+
bool UsingImmCmdList,
221+
bool InterruptBasedEventEnabled);
203222

204223
// Get ur_event_handle_t from cache.
205224
ur_event_handle_t getEventFromContextCache(bool HostVisible,

source/adapters/level_zero/device.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,8 @@ ur_result_t urDeviceGetInfo(
485485
case UR_DEVICE_INFO_BUILT_IN_KERNELS:
486486
// TODO: To find out correct value
487487
return ReturnValue("");
488+
case UR_DEVICE_INFO_LOW_POWER_EVENTS_EXP:
489+
return ReturnValue(UR_DEVICE_INFO_LOW_POWER_EVENTS_EXP);
488490
case UR_DEVICE_INFO_QUEUE_PROPERTIES:
489491
return ReturnValue(
490492
ur_queue_flag_t(UR_QUEUE_FLAG_OUT_OF_ORDER_EXEC_MODE_ENABLE |

source/adapters/level_zero/event.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,8 @@ ur_result_t urEnqueueEventsWaitWithBarrier(
422422
ur_result_t urEnqueueEventsWaitWithBarrierExt(
423423
ur_queue_handle_t Queue, ///< [in] handle of the queue object
424424
const ur_exp_enqueue_ext_properties_t
425-
*, ///< [in][optional] pointer to the extended enqueue properties
425+
*EnqueueExtProp, ///< [in][optional] pointer to the extended enqueue
426+
///< properties
426427
uint32_t NumEventsInWaitList, ///< [in] size of the event wait list
427428
const ur_event_handle_t
428429
*EventWaitList, ///< [in][optional][range(0, numEventsInWaitList)]
@@ -913,7 +914,7 @@ ur_result_t urExtEventCreate(
913914
UR_CALL(EventCreate(Context, nullptr /*Queue*/, false /*IsMultiDevice*/,
914915
true /*HostVisible*/, Event,
915916
false /*CounterBasedEventEnabled*/,
916-
false /*ForceDisableProfiling*/));
917+
false /*ForceDisableProfiling*/, false));
917918

918919
(*Event)->RefCountExternal++;
919920
if (!(*Event)->CounterBasedEventsEnabled)
@@ -935,7 +936,7 @@ ur_result_t urEventCreateWithNativeHandle(
935936
UR_CALL(EventCreate(Context, nullptr /*Queue*/, false /*IsMultiDevice*/,
936937
true /*HostVisible*/, Event,
937938
false /*CounterBasedEventEnabled*/,
938-
false /*ForceDisableProfiling*/));
939+
false /*ForceDisableProfiling*/, false));
939940

940941
(*Event)->RefCountExternal++;
941942
if (!(*Event)->CounterBasedEventsEnabled)
@@ -1293,7 +1294,8 @@ ur_result_t EventCreate(ur_context_handle_t Context, ur_queue_handle_t Queue,
12931294
bool IsMultiDevice, bool HostVisible,
12941295
ur_event_handle_t *RetEvent,
12951296
bool CounterBasedEventEnabled,
1296-
bool ForceDisableProfiling) {
1297+
bool ForceDisableProfiling,
1298+
bool InterruptBasedEventEnabled) {
12971299
bool ProfilingEnabled =
12981300
ForceDisableProfiling ? false : (!Queue || Queue->isProfilingEnabled());
12991301
bool UsingImmediateCommandlists = !Queue || Queue->UsingImmCmdLists;
@@ -1317,14 +1319,15 @@ ur_result_t EventCreate(ur_context_handle_t Context, ur_queue_handle_t Queue,
13171319

13181320
if (auto Res = Context->getFreeSlotInExistingOrNewPool(
13191321
ZeEventPool, Index, HostVisible, ProfilingEnabled, Device,
1320-
CounterBasedEventEnabled, UsingImmediateCommandlists))
1322+
CounterBasedEventEnabled, UsingImmediateCommandlists,
1323+
Queue->interruptBasedEventsEnabled()))
13211324
return Res;
13221325

13231326
ZeStruct<ze_event_desc_t> ZeEventDesc;
13241327
ZeEventDesc.index = Index;
13251328
ZeEventDesc.wait = 0;
13261329

1327-
if (HostVisible || CounterBasedEventEnabled) {
1330+
if (HostVisible || CounterBasedEventEnabled || InterruptBasedEventEnabled) {
13281331
ZeEventDesc.signal = ZE_EVENT_SCOPE_FLAG_HOST;
13291332
} else {
13301333
//
@@ -1350,6 +1353,7 @@ ur_result_t EventCreate(ur_context_handle_t Context, ur_queue_handle_t Queue,
13501353
return UR_RESULT_ERROR_UNKNOWN;
13511354
}
13521355
(*RetEvent)->CounterBasedEventsEnabled = CounterBasedEventEnabled;
1356+
(*RetEvent)->InterruptBasedEventsEnabled = InterruptBasedEventEnabled;
13531357
if (HostVisible)
13541358
(*RetEvent)->HostVisibleEvent =
13551359
reinterpret_cast<ur_event_handle_t>(*RetEvent);

source/adapters/level_zero/event.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ ur_result_t EventCreate(ur_context_handle_t Context, ur_queue_handle_t Queue,
3333
bool IsMultiDevice, bool HostVisible,
3434
ur_event_handle_t *RetEvent,
3535
bool CounterBasedEventEnabled,
36-
bool ForceDisableProfiling);
36+
bool ForceDisableProfiling,
37+
bool InterruptBasedEventEnabled);
3738
} // extern "C"
3839

3940
// This is an experimental option that allows to disable caching of events in
@@ -251,6 +252,8 @@ struct ur_event_handle_t_ : _ur_object {
251252
std::optional<ur_completion_batch_it> completionBatch;
252253
// Keeps track of whether we are using Counter-based Events.
253254
bool CounterBasedEventsEnabled = false;
255+
// Keeps track of whether we are using Interrupt-based Events.
256+
bool InterruptBasedEventsEnabled = false;
254257
};
255258

256259
// Helper function to implement zeHostSynchronize.

source/adapters/level_zero/queue.cpp

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,10 @@ ur_result_t ur_completion_batch::seal(ur_queue_handle_t queue,
104104
assert(st == ACCUMULATING);
105105

106106
if (!barrierEvent) {
107-
UR_CALL(EventCreate(queue->Context, queue, false /*IsMultiDevice*/,
108-
true /*HostVisible*/, &barrierEvent,
109-
false /*CounterBasedEventEnabled*/,
110-
false /*ForceDisableProfiling*/));
107+
UR_CALL(EventCreate(
108+
queue->Context, queue, false /*IsMultiDevice*/, true /*HostVisible*/,
109+
&barrierEvent, false /*CounterBasedEventEnabled*/,
110+
false /*ForceDisableProfiling*/, false /*InterruptBasedEventEnabled*/));
111111
}
112112

113113
// Instead of collecting all the batched events, we simply issue a global
@@ -1494,6 +1494,11 @@ bool ur_queue_handle_t_::doReuseDiscardedEvents() {
14941494
return ReuseDiscardedEvents && isInOrderQueue() && isDiscardEvents();
14951495
}
14961496

1497+
bool ur_queue_handle_t_::interruptBasedEventsEnabled() {
1498+
return isInOrderQueue() && Device->useDriverInOrderLists() &&
1499+
isLowPowerEvents();
1500+
}
1501+
14971502
ur_result_t
14981503
ur_queue_handle_t_::resetDiscardedEvent(ur_command_list_ptr_t CommandList) {
14991504
if (LastCommandEvent && LastCommandEvent->IsDiscarded) {
@@ -1654,6 +1659,10 @@ bool ur_queue_handle_t_::isInOrderQueue() const {
16541659
0);
16551660
}
16561661

1662+
bool ur_queue_handle_t_::isLowPowerEvents() const {
1663+
return ((this->Properties & UR_QUEUE_FLAG_LOW_POWER_EVENTS_EXP) != 0);
1664+
}
1665+
16571666
// Helper function to perform the necessary cleanup of the events from reset cmd
16581667
// list.
16591668
ur_result_t CleanupEventListFromResetCmdList(
@@ -1868,12 +1877,10 @@ ur_result_t setSignalEvent(ur_queue_handle_t Queue, bool UseCopyEngine,
18681877
// visible pool.
18691878
// \param HostVisible tells if the event must be created in the
18701879
// host-visible pool. If not set then this function will decide.
1871-
ur_result_t createEventAndAssociateQueue(ur_queue_handle_t Queue,
1872-
ur_event_handle_t *Event,
1873-
ur_command_t CommandType,
1874-
ur_command_list_ptr_t CommandList,
1875-
bool IsInternal, bool IsMultiDevice,
1876-
std::optional<bool> HostVisible) {
1880+
ur_result_t createEventAndAssociateQueue(
1881+
ur_queue_handle_t Queue, ur_event_handle_t *Event, ur_command_t CommandType,
1882+
ur_command_list_ptr_t CommandList, bool IsInternal, bool IsMultiDevice,
1883+
std::optional<bool> HostVisible, std::optional<bool> InterruptBasedEvents) {
18771884

18781885
if (!HostVisible.has_value()) {
18791886
// Internal/discarded events do not need host-scope visibility.
@@ -1888,7 +1895,8 @@ ur_result_t createEventAndAssociateQueue(ur_queue_handle_t Queue,
18881895
if (*Event == nullptr)
18891896
UR_CALL(EventCreate(
18901897
Queue->Context, Queue, IsMultiDevice, HostVisible.value(), Event,
1891-
Queue->CounterBasedEventsEnabled, false /*ForceDisableProfiling*/));
1898+
Queue->CounterBasedEventsEnabled, false /*ForceDisableProfiling*/,
1899+
HostVisible.has_value() ? true : Queue->interruptBasedEventsEnabled()));
18921900

18931901
(*Event)->UrQueue = Queue;
18941902
(*Event)->CommandType = CommandType;

source/adapters/level_zero/queue.hpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,8 @@ struct ur_queue_handle_t_ : _ur_object {
533533
// queue.
534534
bool doReuseDiscardedEvents();
535535

536+
bool interruptBasedEventsEnabled();
537+
536538
// Append command to provided command list to wait and reset the last event if
537539
// it is discarded and create new ur_event_handle_t wrapper using the same
538540
// native event and put it to the cache. We call this method after each
@@ -557,6 +559,9 @@ struct ur_queue_handle_t_ : _ur_object {
557559
// Returns true if the queue has discard events property.
558560
bool isDiscardEvents() const;
559561

562+
// Returns true if the queue has low power events property.
563+
bool isLowPowerEvents() const;
564+
560565
// Returns true if the queue has explicit priority set by user.
561566
bool isPriorityLow() const;
562567
bool isPriorityHigh() const;
@@ -708,7 +713,7 @@ struct ur_queue_handle_t_ : _ur_object {
708713
ur_result_t createEventAndAssociateQueue(
709714
ur_queue_handle_t Queue, ur_event_handle_t *Event, ur_command_t CommandType,
710715
ur_command_list_ptr_t CommandList, bool IsInternal, bool IsMultiDevice,
711-
std::optional<bool> HostVisible = std::nullopt);
716+
std::optional<bool> HostVisible = std::nullopt, std::optional<bool> InterruptBasedEvents = std::nullopt);
712717

713718
// This helper function checks to see if an event for a command can be included
714719
// at the end of a command list batch. This will only be true if the event does

0 commit comments

Comments
 (0)