Skip to content

Commit 1fffb1d

Browse files
committed
[UR] Improve event native handle handling
Some changes to make the get/create native handles logic for more ergonomic and match existing behaviour: * Added a new command type specifically for commands generated from native handles (rather than just using WAIT). * Allowed UR_EVENT_INFO_QUEUE to return NULL if the adapter can't generate a UR handle. * Fixed a properties parsing bug in level zero. * Implemented it for liboffload
1 parent 5f2dfe6 commit 1fffb1d

File tree

11 files changed

+81
-49
lines changed

11 files changed

+81
-49
lines changed

unified-runtime/include/ur_api.h

Lines changed: 6 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

unified-runtime/include/ur_print.hpp

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

unified-runtime/scripts/core/event.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ etors:
7777
desc: Event created by $xEnqueueReadHostPipe
7878
- name: WRITE_HOST_PIPE
7979
desc: Event created by $xEnqueueWriteHostPipe
80+
- name: FROM_NATIVE
81+
desc: Command type used by events created by $xEventCreateWithNativeHandle
8082
--- #--------------------------------------------------------------------------
8183
type: enum
8284
desc: "Event Status"
@@ -101,7 +103,7 @@ name: $x_event_info_t
101103
typed_etors: True
102104
etors:
103105
- name: COMMAND_QUEUE
104-
desc: "[$x_queue_handle_t] Command queue information of an event object"
106+
desc: "[$x_queue_handle_t] Command queue information of an event object. This may be NULL if the event was created via $xEventCreateWithNativeHandle and the adapter has no associated UR queue"
105107
- name: CONTEXT
106108
desc: "[$x_context_handle_t] Context information of an event object"
107109
- name: COMMAND_TYPE

unified-runtime/source/adapters/cuda/event.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ ur_event_handle_t_::ur_event_handle_t_(ur_command_t Type,
4242

4343
ur_event_handle_t_::ur_event_handle_t_(ur_context_handle_t Context,
4444
CUevent EventNative)
45-
: handle_base(), CommandType{UR_COMMAND_EVENTS_WAIT}, HasOwnership{false},
45+
: handle_base(), CommandType{UR_COMMAND_FROM_NATIVE}, HasOwnership{false},
4646
IsInterop{true}, StreamToken{std::numeric_limits<uint32_t>::max()},
4747
EvEnd{EventNative}, EvStart{nullptr}, EvQueued{nullptr}, Queue{nullptr},
4848
Stream{nullptr}, Context{Context} {
@@ -168,11 +168,7 @@ UR_APIEXPORT ur_result_t UR_APICALL urEventGetInfo(ur_event_handle_t hEvent,
168168
// If the runtime owns the native handle, we have reference to the queue.
169169
// Otherwise, the event handle comes from an interop API with no RT refs.
170170
if (!hEvent->getQueue()) {
171-
setErrorMessage("Command queue info cannot be queried for the event. The "
172-
"event object was created from a native event and has no "
173-
"valid reference to a command queue.",
174-
UR_RESULT_ERROR_INVALID_VALUE);
175-
return UR_RESULT_ERROR_ADAPTER_SPECIFIC;
171+
return ReturnValue(nullptr);
176172
}
177173
return ReturnValue(hEvent->getQueue());
178174
}

unified-runtime/source/adapters/hip/event.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ ur_event_handle_t_::ur_event_handle_t_(ur_command_t Type,
3535

3636
ur_event_handle_t_::ur_event_handle_t_(ur_context_handle_t Context,
3737
hipEvent_t EventNative)
38-
: handle_base(), CommandType{UR_COMMAND_EVENTS_WAIT}, HasOwnership{false},
38+
: handle_base(), CommandType{UR_COMMAND_FROM_NATIVE}, HasOwnership{false},
3939
IsInterop{true}, StreamToken{std::numeric_limits<uint32_t>::max()},
4040
EvEnd{EventNative}, EvStart{nullptr}, EvQueued{nullptr}, Queue{nullptr},
4141
Stream{nullptr}, Context{Context} {
@@ -178,11 +178,7 @@ UR_APIEXPORT ur_result_t UR_APICALL urEventGetInfo(ur_event_handle_t hEvent,
178178
// If the runtime owns the native handle, we have reference to the queue.
179179
// Otherwise, the event handle comes from an interop API with no RT refs.
180180
if (!hEvent->getQueue()) {
181-
setErrorMessage("Command queue info cannot be queried for the event. The "
182-
"event object was created from a native event and has no "
183-
"valid reference to a command queue.",
184-
UR_RESULT_ERROR_INVALID_VALUE);
185-
return UR_RESULT_ERROR_ADAPTER_SPECIFIC;
181+
return ReturnValue(nullptr);
186182
}
187183
return ReturnValue(hEvent->getQueue());
188184
}

unified-runtime/source/adapters/level_zero/event.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -975,9 +975,9 @@ ur_result_t urEventCreateWithNativeHandle(
975975
auto ZeEvent = ur_cast<ze_event_handle_t>(NativeEvent);
976976
ur_event_handle_t_ *UREvent{};
977977
try {
978-
UREvent = new ur_event_handle_t_(ZeEvent, nullptr /* ZeEventPool */,
979-
Context, UR_EXT_COMMAND_TYPE_USER,
980-
Properties->isNativeHandleOwned);
978+
UREvent = new ur_event_handle_t_(
979+
ZeEvent, nullptr /* ZeEventPool */, Context, UR_COMMAND_FROM_NATIVE,
980+
Properties ? Properties->isNativeHandleOwned : false);
981981
UREvent->RefCountExternal++;
982982

983983
} catch (const std::bad_alloc &) {

unified-runtime/source/adapters/offload/event.cpp

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ UR_APIEXPORT ur_result_t UR_APICALL urEventGetInfo(ur_event_handle_t hEvent,
2424

2525
switch (propName) {
2626
case UR_EVENT_INFO_CONTEXT:
27-
return ReturnValue(hEvent->UrQueue->UrContext);
27+
return ReturnValue(hEvent->UrContext);
2828
case UR_EVENT_INFO_COMMAND_QUEUE:
2929
return ReturnValue(hEvent->UrQueue);
3030
case UR_EVENT_INFO_COMMAND_TYPE:
@@ -107,7 +107,7 @@ UR_APIEXPORT ur_result_t UR_APICALL urEventRetain(ur_event_handle_t hEvent) {
107107

108108
UR_APIEXPORT ur_result_t UR_APICALL urEventRelease(ur_event_handle_t hEvent) {
109109
if (--hEvent->RefCount == 0) {
110-
if (hEvent->OffloadEvent) {
110+
if (hEvent->OffloadEvent && hEvent->isNativeHandleOwned) {
111111
auto Res = olDestroyEvent(hEvent->OffloadEvent);
112112
if (Res) {
113113
return offloadResultToUR(Res);
@@ -119,13 +119,32 @@ UR_APIEXPORT ur_result_t UR_APICALL urEventRelease(ur_event_handle_t hEvent) {
119119
return UR_RESULT_SUCCESS;
120120
}
121121

122-
UR_APIEXPORT ur_result_t UR_APICALL
123-
urEventGetNativeHandle(ur_event_handle_t, ur_native_handle_t *) {
124-
return UR_RESULT_ERROR_UNSUPPORTED_FEATURE;
122+
UR_APIEXPORT ur_result_t UR_APICALL urEventGetNativeHandle(
123+
ur_event_handle_t hEvent, ur_native_handle_t *phNativeEvent) {
124+
if (!hEvent->OffloadEvent) {
125+
// There is no associated event - rather than returning nullptr, create an
126+
// empty one
127+
ol_queue_handle_t TmpQueue;
128+
OL_RETURN_ON_ERR(olCreateQueue(hEvent->UrQueue->OffloadDevice, &TmpQueue));
129+
OL_RETURN_ON_ERR(olCreateEvent(
130+
TmpQueue, reinterpret_cast<ol_event_handle_t *>(phNativeEvent)));
131+
OL_RETURN_ON_ERR(olDestroyQueue(TmpQueue));
132+
} else {
133+
*phNativeEvent = reinterpret_cast<ur_native_handle_t>(hEvent->OffloadEvent);
134+
}
135+
136+
return UR_RESULT_SUCCESS;
125137
}
126138

127139
UR_APIEXPORT ur_result_t UR_APICALL urEventCreateWithNativeHandle(
128-
ur_native_handle_t, ur_context_handle_t,
129-
const ur_event_native_properties_t *, ur_event_handle_t *) {
130-
return UR_RESULT_ERROR_UNSUPPORTED_FEATURE;
140+
ur_native_handle_t hNativeEvent, ur_context_handle_t hContext,
141+
const ur_event_native_properties_t *pProperties,
142+
ur_event_handle_t *hEvent) {
143+
bool IsNativeHandleOwned =
144+
pProperties ? pProperties->isNativeHandleOwned : false;
145+
146+
*hEvent =
147+
new ur_event_handle_t_(reinterpret_cast<ol_event_handle_t>(hNativeEvent),
148+
hContext, IsNativeHandleOwned);
149+
return UR_RESULT_SUCCESS;
131150
}

unified-runtime/source/adapters/offload/event.hpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,23 @@
1414
#include <ur_api.h>
1515

1616
#include "common.hpp"
17+
#include "queue.hpp"
1718

1819
struct ur_event_handle_t_ : RefCounted {
1920
ol_event_handle_t OffloadEvent;
2021
ur_command_t Type;
2122
ur_queue_handle_t UrQueue;
23+
ur_context_handle_t UrContext;
24+
bool isNativeHandleOwned;
2225

2326
ur_event_handle_t_(ur_command_t Type, ur_queue_handle_t Queue)
24-
: Type(Type), UrQueue(Queue) {}
27+
: Type(Type), UrQueue(Queue), UrContext(Queue->UrContext),
28+
isNativeHandleOwned(true) {}
29+
ur_event_handle_t_(ol_event_handle_t NativeHandle,
30+
ur_context_handle_t Context, bool isNativeHandleOwned)
31+
: OffloadEvent(NativeHandle), Type(UR_COMMAND_FROM_NATIVE),
32+
UrQueue(nullptr), UrContext(Context),
33+
isNativeHandleOwned(isNativeHandleOwned) {}
2534

2635
static ur_event_handle_t createEmptyEvent(ur_command_t Type,
2736
ur_queue_handle_t Queue) {

unified-runtime/source/adapters/offload/queue.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,29 @@
1414

1515
#include "context.hpp"
1616
#include "device.hpp"
17+
#include "event.hpp"
1718
#include "queue.hpp"
1819
#include "ur2offload.hpp"
1920

21+
ol_result_t ur_queue_handle_t_::nextQueueNoLock(ol_queue_handle_t &Handle) {
22+
auto &Slot = OffloadQueues[(QueueOffset++) % OffloadQueues.size()];
23+
24+
if (!Slot) {
25+
if (auto Res = olCreateQueue(OffloadDevice, &Slot)) {
26+
return Res;
27+
}
28+
29+
if (auto Event = Barrier) {
30+
if (auto Res = olWaitEvents(Slot, &Event->OffloadEvent, 1)) {
31+
return Res;
32+
}
33+
}
34+
}
35+
36+
Handle = Slot;
37+
return nullptr;
38+
}
39+
2040
UR_APIEXPORT ur_result_t UR_APICALL urQueueCreate(
2141
[[maybe_unused]] ur_context_handle_t hContext, ur_device_handle_t hDevice,
2242
const ur_queue_properties_t *pProps, ur_queue_handle_t *phQueue) {

unified-runtime/source/adapters/offload/queue.hpp

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
#include <ur_api.h>
1515

1616
#include "common.hpp"
17-
#include "event.hpp"
1817

1918
constexpr size_t OOO_QUEUE_POOL_SIZE = 32;
2019

@@ -66,24 +65,7 @@ struct ur_queue_handle_t_ : RefCounted {
6665
return OL_SUCCESS;
6766
}
6867

69-
ol_result_t nextQueueNoLock(ol_queue_handle_t &Handle) {
70-
auto &Slot = OffloadQueues[(QueueOffset++) % OffloadQueues.size()];
71-
72-
if (!Slot) {
73-
if (auto Res = olCreateQueue(OffloadDevice, &Slot)) {
74-
return Res;
75-
}
76-
77-
if (auto Event = Barrier) {
78-
if (auto Res = olWaitEvents(Slot, &Event->OffloadEvent, 1)) {
79-
return Res;
80-
}
81-
}
82-
}
83-
84-
Handle = Slot;
85-
return nullptr;
86-
}
68+
ol_result_t nextQueueNoLock(ol_queue_handle_t &Handle);
8769

8870
ol_result_t nextQueue(ol_queue_handle_t &Handle) {
8971
std::lock_guard<std::mutex> Lock(OooMutex);

0 commit comments

Comments
 (0)