Skip to content

Commit b6454e4

Browse files
committed
[L0 v2] Add raii wrapper for L0 handles
that encapsulate lifetime management logic (including support for ownZeHandle).
1 parent 84f5e70 commit b6454e4

File tree

5 files changed

+108
-27
lines changed

5 files changed

+108
-27
lines changed
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
//===--------- common.hpp - Level Zero Adapter ---------------------------===//
2+
//
3+
// Copyright (C) 2024 Intel Corporation
4+
//
5+
// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM
6+
// Exceptions. See LICENSE.TXT
7+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8+
//
9+
//===----------------------------------------------------------------------===//
10+
11+
#pragma once
12+
13+
#include <exception>
14+
#include <ze_api.h>
15+
16+
#include "../common.hpp"
17+
18+
namespace v2 {
19+
20+
namespace raii {
21+
22+
template <typename ZeHandleT, ze_result_t (*destroy)(ZeHandleT)>
23+
struct ze_handle_wrapper {
24+
ze_handle_wrapper(bool ownZeHandle = true)
25+
: handle(nullptr), ownZeHandle(ownZeHandle) {}
26+
27+
ze_handle_wrapper(ZeHandleT handle, bool ownZeHandle = true)
28+
: handle(handle), ownZeHandle(ownZeHandle) {}
29+
30+
ze_handle_wrapper(const ze_handle_wrapper &) = delete;
31+
ze_handle_wrapper &operator=(const ze_handle_wrapper &) = delete;
32+
33+
ze_handle_wrapper(ze_handle_wrapper &&other)
34+
: handle(other.handle), ownZeHandle(other.ownZeHandle) {
35+
other.handle = nullptr;
36+
}
37+
38+
ze_handle_wrapper &operator=(ze_handle_wrapper &&other) {
39+
if (this == &other) {
40+
return *this;
41+
}
42+
43+
if (handle) {
44+
reset();
45+
}
46+
handle = other.handle;
47+
ownZeHandle = other.ownZeHandle;
48+
other.handle = nullptr;
49+
return *this;
50+
}
51+
52+
~ze_handle_wrapper() {
53+
try {
54+
reset();
55+
} catch (...) {
56+
}
57+
}
58+
59+
void reset() {
60+
if (!handle) {
61+
return;
62+
}
63+
64+
auto zeResult = ZE_CALL_NOCHECK(destroy, (handle));
65+
// Gracefully handle the case that L0 was already unloaded.
66+
if (zeResult && zeResult != ZE_RESULT_ERROR_UNINITIALIZED)
67+
throw ze2urResult(zeResult);
68+
69+
handle = nullptr;
70+
}
71+
72+
ZeHandleT release() {
73+
auto handle = this->handle;
74+
this->handle = nullptr;
75+
return handle;
76+
}
77+
78+
ZeHandleT get() const { return handle; }
79+
80+
ZeHandleT *ptr() { return &handle; }
81+
82+
private:
83+
ZeHandleT handle;
84+
bool ownZeHandle;
85+
};
86+
87+
using ze_kernel_handle_t =
88+
ze_handle_wrapper<::ze_kernel_handle_t, zeKernelDestroy>;
89+
90+
using ze_event_handle_t =
91+
ze_handle_wrapper<::ze_event_handle_t, zeEventDestroy>;
92+
93+
using ze_event_pool_handle_t =
94+
ze_handle_wrapper<::ze_event_pool_handle_t, zeEventPoolDestroy>;
95+
96+
} // namespace raii
97+
} // namespace v2

source/adapters/level_zero/v2/event_provider_counter.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,6 @@ provider_counter::provider_counter(ur_platform_handle_t platform,
3333
(ZEL_HANDLE_DEVICE, device->ZeDevice, (void **)&translatedDevice));
3434
}
3535

36-
provider_counter::~provider_counter() {
37-
for (auto &e : freelist) {
38-
ZE_CALL_NOCHECK(zeEventDestroy, (e));
39-
}
40-
}
41-
4236
event_allocation provider_counter::allocate() {
4337
if (freelist.empty()) {
4438
ZeStruct<ze_event_desc_t> desc;
@@ -54,11 +48,11 @@ event_allocation provider_counter::allocate() {
5448
freelist.emplace_back(handle);
5549
}
5650

57-
auto event = freelist.back();
51+
auto event = std::move(freelist.back());
5852
freelist.pop_back();
5953

6054
return {event_type::EVENT_COUNTER,
61-
event_borrowed(event, [this](ze_event_handle_t handle) {
55+
event_borrowed(event.release(), [this](ze_event_handle_t handle) {
6256
freelist.push_back(handle);
6357
})};
6458
}

source/adapters/level_zero/v2/event_provider_counter.hpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ class provider_counter : public event_provider {
3535
public:
3636
provider_counter(ur_platform_handle_t platform, ur_context_handle_t,
3737
ur_device_handle_t);
38-
~provider_counter() override;
3938

4039
event_allocation allocate() override;
4140
ur_device_handle_t device() override;
@@ -48,7 +47,7 @@ class provider_counter : public event_provider {
4847

4948
zexCounterBasedEventCreate eventCreateFunc;
5049

51-
std::vector<ze_event_handle_t> freelist;
50+
std::vector<raii::ze_event_handle_t> freelist;
5251
};
5352

5453
} // namespace v2

source/adapters/level_zero/v2/event_provider_normal.cpp

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,33 +38,27 @@ provider_pool::provider_pool(ur_context_handle_t context,
3838
ZE2UR_CALL_THROWS(zeEventPoolCreate,
3939
(context->ZeContext, &desc, 1,
4040
const_cast<ze_device_handle_t *>(&device->ZeDevice),
41-
&pool));
41+
pool.ptr()));
4242

4343
freelist.resize(EVENTS_BURST);
4444
for (int i = 0; i < EVENTS_BURST; ++i) {
4545
ZeStruct<ze_event_desc_t> desc;
4646
desc.index = i;
4747
desc.signal = 0;
4848
desc.wait = 0;
49-
ZE2UR_CALL_THROWS(zeEventCreate, (pool, &desc, &freelist[i]));
49+
ZE2UR_CALL_THROWS(zeEventCreate, (pool.get(), &desc, freelist[i].ptr()));
5050
}
5151
}
5252

53-
provider_pool::~provider_pool() {
54-
for (auto e : freelist) {
55-
ZE_CALL_NOCHECK(zeEventDestroy, (e));
56-
}
57-
ZE_CALL_NOCHECK(zeEventPoolDestroy, (pool));
58-
}
59-
6053
event_borrowed provider_pool::allocate() {
6154
if (freelist.empty()) {
6255
return nullptr;
6356
}
64-
ze_event_handle_t e = freelist.back();
57+
auto e = std::move(freelist.back());
6558
freelist.pop_back();
66-
return event_borrowed(
67-
e, [this](ze_event_handle_t handle) { freelist.push_back(handle); });
59+
return event_borrowed(e.release(), [this](ze_event_handle_t handle) {
60+
freelist.push_back(handle);
61+
});
6862
}
6963

7064
size_t provider_pool::nfree() const { return freelist.size(); }

source/adapters/level_zero/v2/event_provider_normal.hpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,13 @@ class provider_pool {
3434
public:
3535
provider_pool(ur_context_handle_t, ur_device_handle_t, event_type,
3636
queue_type);
37-
~provider_pool();
3837

3938
event_borrowed allocate();
4039
size_t nfree() const;
4140

4241
private:
43-
// TODO: use a RAII wrapper for the pool handle
44-
ze_event_pool_handle_t pool;
45-
46-
std::vector<ze_event_handle_t> freelist;
42+
raii::ze_event_pool_handle_t pool;
43+
std::vector<raii::ze_event_handle_t> freelist;
4744
};
4845

4946
class provider_normal : public event_provider {

0 commit comments

Comments
 (0)