Skip to content

Commit 4c0c295

Browse files
authored
[Offload] OL_EVENT_INFO_IS_COMPLETE (#153194)
A simple info query for events that returns whether the event is complete or not.
1 parent 2a79ef6 commit 4c0c295

File tree

11 files changed

+95
-4
lines changed

11 files changed

+95
-4
lines changed

offload/liboffload/API/Event.td

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ def ol_event_info_t : Enum {
4444
let desc = "Supported event info.";
4545
let is_typed = 1;
4646
let etors = [
47-
TaggedEtor<"QUEUE", "ol_queue_handle_t", "The handle of the queue associated with the device.">
47+
TaggedEtor<"QUEUE", "ol_queue_handle_t", "The handle of the queue associated with the device.">,
48+
TaggedEtor<"IS_COMPLETE", "bool", "True if and only if the event is complete.">,
4849
];
4950
}
5051

offload/liboffload/src/OffloadImpl.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -645,8 +645,8 @@ Error olGetQueueInfoSize_impl(ol_queue_handle_t Queue, ol_queue_info_t PropName,
645645
}
646646

647647
Error olSyncEvent_impl(ol_event_handle_t Event) {
648+
// No event info means that this event was complete on creation
648649
if (!Event->EventInfo)
649-
// Event always complete
650650
return Plugin::success();
651651

652652
if (auto Res = Event->Queue->Device->Device->syncEvent(Event->EventInfo))
@@ -667,10 +667,22 @@ Error olGetEventInfoImplDetail(ol_event_handle_t Event,
667667
ol_event_info_t PropName, size_t PropSize,
668668
void *PropValue, size_t *PropSizeRet) {
669669
InfoWriter Info(PropSize, PropValue, PropSizeRet);
670+
auto Queue = Event->Queue;
670671

671672
switch (PropName) {
672673
case OL_EVENT_INFO_QUEUE:
673-
return Info.write<ol_queue_handle_t>(Event->Queue);
674+
return Info.write<ol_queue_handle_t>(Queue);
675+
case OL_EVENT_INFO_IS_COMPLETE: {
676+
// No event info means that this event was complete on creation
677+
if (!Event->EventInfo)
678+
return Info.write<bool>(true);
679+
680+
auto Res = Queue->Device->Device->isEventComplete(Event->EventInfo,
681+
Queue->AsyncInfo);
682+
if (auto Err = Res.takeError())
683+
return Err;
684+
return Info.write<bool>(*Res);
685+
}
674686
default:
675687
return createOffloadError(ErrorCode::INVALID_ENUMERATION,
676688
"olGetEventInfo enum '%i' is invalid", PropName);

offload/plugins-nextgen/amdgpu/src/rtl.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1568,6 +1568,9 @@ struct AMDGPUStreamTy {
15681568
/// actions for that and prior events.
15691569
Error synchronizeOn(AMDGPUEventTy &Event);
15701570

1571+
/// Return true if the event from this queue is complete
1572+
Expected<bool> isEventComplete(const AMDGPUEventTy &Event);
1573+
15711574
/// Query the stream and complete pending post actions if operations finished.
15721575
/// Return whether all the operations completed. This operation does not block
15731576
/// the calling thread.
@@ -1732,6 +1735,18 @@ Error AMDGPUStreamTy::synchronizeOn(AMDGPUEventTy &Event) {
17321735
return completeUntil(Event.RecordedSlot);
17331736
}
17341737

1738+
Expected<bool> AMDGPUStreamTy::isEventComplete(const AMDGPUEventTy &Event) {
1739+
std::lock_guard<std::mutex> Lock(Mutex);
1740+
assert(Event.RecordedStream == this && "event is for a different stream");
1741+
1742+
if (Event.RecordedSyncCycle < SyncCycle) {
1743+
return true;
1744+
}
1745+
assert(Event.RecordedSyncCycle == SyncCycle && "event is from the future?");
1746+
1747+
return !Slots[Event.RecordedSlot].Signal->load();
1748+
}
1749+
17351750
struct AMDGPUStreamManagerTy final
17361751
: GenericDeviceResourceManagerTy<AMDGPUResourceRef<AMDGPUStreamTy>> {
17371752
using ResourceRef = AMDGPUResourceRef<AMDGPUStreamTy>;
@@ -2666,6 +2681,13 @@ struct AMDGPUDeviceTy : public GenericDeviceTy, AMDGenericDeviceTy {
26662681
return Query.takeError();
26672682
}
26682683

2684+
Expected<bool> isEventCompleteImpl(void *EventPtr,
2685+
AsyncInfoWrapperTy &AsyncInfo) override {
2686+
AMDGPUEventTy *Event = reinterpret_cast<AMDGPUEventTy *>(EventPtr);
2687+
auto Stream = AsyncInfo.getQueueAs<AMDGPUStreamTy *>();
2688+
return Stream && Stream->isEventComplete(*Event);
2689+
}
2690+
26692691
/// Synchronize the current thread with the event.
26702692
Error syncEventImpl(void *EventPtr) override {
26712693
AMDGPUEventTy *Event = reinterpret_cast<AMDGPUEventTy *>(EventPtr);

offload/plugins-nextgen/common/include/PluginInterface.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -997,6 +997,11 @@ struct GenericDeviceTy : public DeviceAllocatorTy {
997997
virtual Error waitEventImpl(void *EventPtr,
998998
AsyncInfoWrapperTy &AsyncInfoWrapper) = 0;
999999

1000+
/// Check if the event enqueued to AsyncInfo is complete
1001+
Expected<bool> isEventComplete(void *Event, __tgt_async_info *AsyncInfo);
1002+
virtual Expected<bool>
1003+
isEventCompleteImpl(void *EventPtr, AsyncInfoWrapperTy &AsyncInfoWrapper) = 0;
1004+
10001005
/// Synchronize the current thread with the event.
10011006
Error syncEvent(void *EventPtr);
10021007
virtual Error syncEventImpl(void *EventPtr) = 0;

offload/plugins-nextgen/common/src/PluginInterface.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1657,6 +1657,22 @@ Expected<bool> GenericDeviceTy::hasPendingWork(__tgt_async_info *AsyncInfo) {
16571657
return Res;
16581658
}
16591659

1660+
Expected<bool> GenericDeviceTy::isEventComplete(void *Event,
1661+
__tgt_async_info *AsyncInfo) {
1662+
AsyncInfoWrapperTy AsyncInfoWrapper(*this, AsyncInfo);
1663+
auto Res = isEventCompleteImpl(Event, AsyncInfoWrapper);
1664+
if (auto Err = Res.takeError()) {
1665+
AsyncInfoWrapper.finalize(Err);
1666+
return Err;
1667+
}
1668+
1669+
auto Err = Plugin::success();
1670+
AsyncInfoWrapper.finalize(Err);
1671+
if (Err)
1672+
return Err;
1673+
return Res;
1674+
}
1675+
16601676
Error GenericDeviceTy::syncEvent(void *EventPtr) {
16611677
return syncEventImpl(EventPtr);
16621678
}

offload/plugins-nextgen/cuda/dynamic_cuda/cuda.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ DLWRAP(cuCtxSetLimit, 2)
8383

8484
DLWRAP(cuEventCreate, 2)
8585
DLWRAP(cuEventRecord, 2)
86+
DLWRAP(cuEventQuery, 1)
8687
DLWRAP(cuStreamWaitEvent, 3)
8788
DLWRAP(cuEventSynchronize, 1)
8889
DLWRAP(cuEventDestroy, 1)

offload/plugins-nextgen/cuda/dynamic_cuda/cuda.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ CUresult cuCtxSetLimit(CUlimit, size_t);
353353

354354
CUresult cuEventCreate(CUevent *, unsigned int);
355355
CUresult cuEventRecord(CUevent, CUstream);
356+
CUresult cuEventQuery(CUevent);
356357
CUresult cuStreamWaitEvent(CUstream, CUevent, unsigned int);
357358
CUresult cuEventSynchronize(CUevent);
358359
CUresult cuEventDestroy(CUevent);

offload/plugins-nextgen/cuda/src/rtl.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -963,6 +963,20 @@ struct CUDADeviceTy : public GenericDeviceTy {
963963
return Plugin::check(Ret, "error in cuStreamQuery: %s");
964964
}
965965

966+
Expected<bool> isEventCompleteImpl(void *EventPtr,
967+
AsyncInfoWrapperTy &) override {
968+
CUevent Event = reinterpret_cast<CUevent>(EventPtr);
969+
970+
CUresult Ret = cuEventQuery(Event);
971+
if (Ret == CUDA_SUCCESS)
972+
return true;
973+
974+
if (Ret == CUDA_ERROR_NOT_READY)
975+
return false;
976+
977+
return Plugin::check(Ret, "error in cuEventQuery: %s");
978+
}
979+
966980
/// Synchronize the current thread with the event.
967981
Error syncEventImpl(void *EventPtr) override {
968982
CUevent Event = reinterpret_cast<CUevent>(EventPtr);

offload/plugins-nextgen/host/src/rtl.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,10 @@ struct GenELF64DeviceTy : public GenericDeviceTy {
358358
Expected<bool> hasPendingWorkImpl(AsyncInfoWrapperTy &AsyncInfo) override {
359359
return true;
360360
}
361+
Expected<bool> isEventCompleteImpl(void *Event,
362+
AsyncInfoWrapperTy &AsyncInfo) override {
363+
return true;
364+
}
361365
Error syncEventImpl(void *EventPtr) override { return Plugin::success(); }
362366

363367
/// Print information about the device.

offload/unittests/OffloadAPI/event/olGetEventInfo.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,22 @@
1313
using olGetEventInfoTest = OffloadEventTest;
1414
OFFLOAD_TESTS_INSTANTIATE_DEVICE_FIXTURE(olGetEventInfoTest);
1515

16-
TEST_P(olGetEventInfoTest, SuccessDevice) {
16+
TEST_P(olGetEventInfoTest, SuccessQueue) {
1717
ol_queue_handle_t RetrievedQueue;
1818
ASSERT_SUCCESS(olGetEventInfo(Event, OL_EVENT_INFO_QUEUE,
1919
sizeof(ol_queue_handle_t), &RetrievedQueue));
2020
ASSERT_EQ(Queue, RetrievedQueue);
2121
}
2222

23+
TEST_P(olGetEventInfoTest, SuccessIsComplete) {
24+
bool Complete = false;
25+
while (!Complete) {
26+
ASSERT_SUCCESS(olGetEventInfo(Event, OL_EVENT_INFO_IS_COMPLETE,
27+
sizeof(Complete), &Complete));
28+
}
29+
ASSERT_EQ(Complete, true);
30+
}
31+
2332
TEST_P(olGetEventInfoTest, InvalidNullHandle) {
2433
ol_queue_handle_t RetrievedQueue;
2534
ASSERT_ERROR(OL_ERRC_INVALID_NULL_HANDLE,

0 commit comments

Comments
 (0)