Skip to content

Commit 2b77ca6

Browse files
authored
Merge pull request #1801 from igchor/context_v2
[L0 v2] Implement command list initialization
2 parents 38a575b + 3dd675c commit 2b77ca6

20 files changed

+307
-744
lines changed

source/adapters/level_zero/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ add_ur_adapter(${TARGET_NAME}
115115
${CMAKE_CURRENT_SOURCE_DIR}/sampler.hpp
116116
${CMAKE_CURRENT_SOURCE_DIR}/v2/queue_immediate_in_order.hpp
117117
${CMAKE_CURRENT_SOURCE_DIR}/v2/queue_factory.hpp
118+
${CMAKE_CURRENT_SOURCE_DIR}/v2/context.hpp
119+
${CMAKE_CURRENT_SOURCE_DIR}/v2/command_list_cache.hpp
118120
${CMAKE_CURRENT_SOURCE_DIR}/ur_level_zero.cpp
119121
${CMAKE_CURRENT_SOURCE_DIR}/common.cpp
120122
${CMAKE_CURRENT_SOURCE_DIR}/context.cpp
@@ -135,6 +137,8 @@ add_ur_adapter(${TARGET_NAME}
135137
${CMAKE_CURRENT_SOURCE_DIR}/image.cpp
136138
${CMAKE_CURRENT_SOURCE_DIR}/../../ur/ur.cpp
137139
${CMAKE_CURRENT_SOURCE_DIR}/v2/queue_immediate_in_order.cpp
140+
${CMAKE_CURRENT_SOURCE_DIR}/v2/context.cpp
141+
${CMAKE_CURRENT_SOURCE_DIR}/v2/command_list_cache.cpp
138142
)
139143

140144
if(NOT WIN32)

source/adapters/level_zero/context.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#include "queue.hpp"
1919
#include "ur_level_zero.hpp"
2020

21+
#include "v2/context.hpp"
22+
2123
UR_APIEXPORT ur_result_t UR_APICALL urContextCreate(
2224
uint32_t DeviceCount, ///< [in] the number of devices given in phDevices
2325
const ur_device_handle_t
@@ -36,7 +38,7 @@ UR_APIEXPORT ur_result_t UR_APICALL urContextCreate(
3638
ZE2UR_CALL(zeContextCreate, (Platform->ZeDriver, &ContextDesc, &ZeContext));
3739
try {
3840
ur_context_handle_t_ *Context =
39-
new ur_context_handle_t_(ZeContext, DeviceCount, Devices, true);
41+
new v2::ur_context_handle_t_(ZeContext, DeviceCount, Devices, true);
4042

4143
Context->initialize();
4244
*RetContext = reinterpret_cast<ur_context_handle_t>(Context);

source/adapters/level_zero/queue.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,7 @@ UR_APIEXPORT ur_result_t UR_APICALL urQueueCreate(
503503

504504
// optimized path for immediate, in-order command lists
505505
if (v2::shouldUseQueueV2(Device, Flags)) {
506-
*Queue = v2::createQueue(Context, Device, Flags);
506+
*Queue = v2::createQueue(Context, Device, Props);
507507
return UR_RESULT_SUCCESS;
508508
}
509509

source/adapters/level_zero/v2/command_list_cache.cpp

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010

1111
#include "command_list_cache.hpp"
1212

13-
#include "context.hpp"
14-
#include "device.hpp"
13+
#include "../context.hpp"
14+
#include "../device.hpp"
1515

1616
bool v2::immediate_command_list_descriptor_t::operator==(
1717
const immediate_command_list_descriptor_t &rhs) const {
@@ -76,7 +76,8 @@ command_list_cache_t::createCommandList(const command_list_descriptor_t &desc) {
7676
}
7777
}
7878

79-
raii::ze_command_list_t command_list_cache_t::getImmediateCommandList(
79+
raii::cache_borrowed_command_list_t
80+
command_list_cache_t::getImmediateCommandList(
8081
ze_device_handle_t ZeDevice, bool IsInOrder, uint32_t Ordinal,
8182
ze_command_queue_mode_t Mode, ze_command_queue_priority_t Priority,
8283
std::optional<uint32_t> Index) {
@@ -87,41 +88,29 @@ raii::ze_command_list_t command_list_cache_t::getImmediateCommandList(
8788
Desc.Mode = Mode;
8889
Desc.Priority = Priority;
8990
Desc.Index = Index;
90-
return getCommandList(Desc);
91+
92+
auto CommandList = getCommandList(Desc).release();
93+
return raii::cache_borrowed_command_list_t(
94+
CommandList, [Cache = this, Desc](ze_command_list_handle_t CmdList) {
95+
Cache->addCommandList(
96+
Desc, raii::ze_command_list_t(CmdList, &zeCommandListDestroy));
97+
});
9198
}
9299

93-
raii::ze_command_list_t
100+
raii::cache_borrowed_command_list_t
94101
command_list_cache_t::getRegularCommandList(ze_device_handle_t ZeDevice,
95102
bool IsInOrder, uint32_t Ordinal) {
96103
regular_command_list_descriptor_t Desc;
97104
Desc.ZeDevice = ZeDevice;
98105
Desc.IsInOrder = IsInOrder;
99106
Desc.Ordinal = Ordinal;
100-
return getCommandList(Desc);
101-
}
102107

103-
void command_list_cache_t::addImmediateCommandList(
104-
raii::ze_command_list_t cmdList, ze_device_handle_t ZeDevice,
105-
bool IsInOrder, uint32_t Ordinal, ze_command_queue_mode_t Mode,
106-
ze_command_queue_priority_t Priority, std::optional<uint32_t> Index) {
107-
immediate_command_list_descriptor_t Desc;
108-
Desc.ZeDevice = ZeDevice;
109-
Desc.Ordinal = Ordinal;
110-
Desc.IsInOrder = IsInOrder;
111-
Desc.Mode = Mode;
112-
Desc.Priority = Priority;
113-
Desc.Index = Index;
114-
addCommandList(Desc, std::move(cmdList));
115-
}
116-
117-
void command_list_cache_t::addRegularCommandList(
118-
raii::ze_command_list_t cmdList, ze_device_handle_t ZeDevice,
119-
bool IsInOrder, uint32_t Ordinal) {
120-
regular_command_list_descriptor_t Desc;
121-
Desc.ZeDevice = ZeDevice;
122-
Desc.IsInOrder = IsInOrder;
123-
Desc.Ordinal = Ordinal;
124-
addCommandList(Desc, std::move(cmdList));
108+
auto CommandList = getCommandList(Desc).release();
109+
return raii::cache_borrowed_command_list_t(
110+
CommandList, [Cache = this, Desc](ze_command_list_handle_t CmdList) {
111+
Cache->addCommandList(
112+
Desc, raii::ze_command_list_t(CmdList, &zeCommandListDestroy));
113+
});
125114
}
126115

127116
raii::ze_command_list_t
@@ -151,4 +140,25 @@ void command_list_cache_t::addCommandList(const command_list_descriptor_t &desc,
151140
auto [it, _] = ZeCommandListCache.try_emplace(desc);
152141
it->second.emplace(std::move(cmdList));
153142
}
143+
144+
size_t command_list_cache_t::getNumImmediateCommandLists() {
145+
std::unique_lock<ur_mutex> Lock(ZeCommandListCacheMutex);
146+
size_t NumLists = 0;
147+
for (auto &Pair : ZeCommandListCache) {
148+
if (std::holds_alternative<immediate_command_list_descriptor_t>(Pair.first))
149+
NumLists += Pair.second.size();
150+
}
151+
return NumLists;
152+
}
153+
154+
size_t command_list_cache_t::getNumRegularCommandLists() {
155+
std::unique_lock<ur_mutex> Lock(ZeCommandListCacheMutex);
156+
size_t NumLists = 0;
157+
for (auto &Pair : ZeCommandListCache) {
158+
if (std::holds_alternative<regular_command_list_descriptor_t>(Pair.first))
159+
NumLists += Pair.second.size();
160+
}
161+
return NumLists;
162+
}
163+
154164
} // namespace v2

source/adapters/level_zero/v2/command_list_cache.hpp

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,23 @@
99
//===----------------------------------------------------------------------===//
1010
#pragma once
1111

12+
#include <functional>
1213
#include <stack>
1314

1415
#include <ur/ur.hpp>
1516
#include <ur_api.h>
1617
#include <ze_api.h>
1718

18-
#include "common.hpp"
19+
#include "../common.hpp"
1920

2021
namespace v2 {
2122
namespace raii {
2223
using ze_command_list_t = std::unique_ptr<::_ze_command_list_handle_t,
2324
decltype(&zeCommandListDestroy)>;
24-
}
25+
using cache_borrowed_command_list_t =
26+
std::unique_ptr<::_ze_command_list_handle_t,
27+
std::function<void(ze_command_list_handle_t)>>;
28+
} // namespace raii
2529

2630
struct immediate_command_list_descriptor_t {
2731
ze_device_handle_t ZeDevice;
@@ -51,23 +55,18 @@ struct command_list_descriptor_hash_t {
5155
struct command_list_cache_t {
5256
command_list_cache_t(ze_context_handle_t ZeContext);
5357

54-
raii::ze_command_list_t
58+
raii::cache_borrowed_command_list_t
5559
getImmediateCommandList(ze_device_handle_t ZeDevice, bool IsInOrder,
5660
uint32_t Ordinal, ze_command_queue_mode_t Mode,
5761
ze_command_queue_priority_t Priority,
5862
std::optional<uint32_t> Index = std::nullopt);
59-
raii::ze_command_list_t getRegularCommandList(ze_device_handle_t ZeDevice,
60-
bool IsInOrder,
61-
uint32_t Ordinal);
63+
raii::cache_borrowed_command_list_t
64+
getRegularCommandList(ze_device_handle_t ZeDevice, bool IsInOrder,
65+
uint32_t Ordinal);
6266

63-
void addImmediateCommandList(raii::ze_command_list_t cmdList,
64-
ze_device_handle_t ZeDevice, bool IsInOrder,
65-
uint32_t Ordinal, ze_command_queue_mode_t Mode,
66-
ze_command_queue_priority_t Priority,
67-
std::optional<uint32_t> Index = std::nullopt);
68-
void addRegularCommandList(raii::ze_command_list_t cmdList,
69-
ze_device_handle_t ZeDevice, bool IsInOrder,
70-
uint32_t Ordinal);
67+
// For testing purposes
68+
size_t getNumImmediateCommandLists();
69+
size_t getNumRegularCommandLists();
7170

7271
private:
7372
ze_context_handle_t ZeContext;
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//===--------- context.cpp - 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+
#include "context.hpp"
12+
13+
namespace v2 {
14+
15+
ur_context_handle_t_::ur_context_handle_t_(ze_context_handle_t hContext,
16+
uint32_t numDevices,
17+
const ur_device_handle_t *phDevices,
18+
bool ownZeContext)
19+
: ::ur_context_handle_t_(hContext, numDevices, phDevices, ownZeContext),
20+
commandListCache(hContext) {}
21+
22+
} // namespace v2
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//===--------- context.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 "command_list_cache.hpp"
14+
15+
#include "../context.hpp"
16+
17+
namespace v2 {
18+
19+
struct ur_context_handle_t_;
20+
using ur_context_handle_t = ur_context_handle_t_ *;
21+
22+
struct ur_context_handle_t_ : public ::ur_context_handle_t_ {
23+
ur_context_handle_t_(ze_context_handle_t hContext, uint32_t numDevices,
24+
const ur_device_handle_t *phDevices, bool ownZeContext);
25+
26+
command_list_cache_t commandListCache;
27+
};
28+
29+
} // namespace v2

source/adapters/level_zero/v2/queue_factory.hpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,29 +11,30 @@
1111
#pragma once
1212

1313
#include "../queue.hpp"
14+
#include "context.hpp"
1415

1516
#include "queue_immediate_in_order.hpp"
1617

1718
namespace v2 {
1819

19-
inline bool shouldUseQueueV2(ur_device_handle_t Device,
20-
ur_queue_flags_t Flags) {
21-
std::ignore = Device;
22-
std::ignore = Flags;
20+
inline bool shouldUseQueueV2(ur_device_handle_t hDevice,
21+
ur_queue_flags_t flags) {
22+
std::ignore = hDevice;
23+
std::ignore = flags;
2324

2425
const char *UrRet = std::getenv("UR_L0_USE_QUEUE_V2");
2526
return UrRet && std::stoi(UrRet);
2627
}
2728

28-
inline ur_queue_handle_t createQueue(ur_context_handle_t Context,
29-
ur_device_handle_t Device,
30-
ur_queue_flags_t Flags) {
31-
if (!shouldUseQueueV2(Device, Flags)) {
29+
inline ur_queue_handle_t createQueue(::ur_context_handle_t hContext,
30+
ur_device_handle_t hDevice,
31+
const ur_queue_properties_t *pProps) {
32+
if (!shouldUseQueueV2(hDevice, pProps ? pProps->flags : ur_queue_flags_t{})) {
3233
throw UR_RESULT_ERROR_INVALID_ARGUMENT;
3334
}
34-
3535
// TODO: For now, always use immediate, in-order
36-
return new ur_queue_immediate_in_order_t(Context, Device, Flags);
36+
return new ur_queue_immediate_in_order_t(
37+
static_cast<v2::ur_context_handle_t>(hContext), hDevice, pProps);
3738
}
3839

3940
} // namespace v2

source/adapters/level_zero/v2/queue_immediate_in_order.cpp

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,49 @@
1111
#include "queue_immediate_in_order.hpp"
1212

1313
namespace v2 {
14+
15+
static int32_t getZeOrdinal(ur_device_handle_t hDevice, queue_group_type type) {
16+
if (type == queue_group_type::MainCopy && hDevice->hasMainCopyEngine()) {
17+
return hDevice->QueueGroup[queue_group_type::MainCopy].ZeOrdinal;
18+
}
19+
return hDevice->QueueGroup[queue_group_type::Compute].ZeOrdinal;
20+
}
21+
22+
static std::optional<int32_t> getZeIndex(const ur_queue_properties_t *pProps) {
23+
if (pProps && pProps->pNext) {
24+
const ur_base_properties_t *extendedDesc =
25+
reinterpret_cast<const ur_base_properties_t *>(pProps->pNext);
26+
if (extendedDesc->stype == UR_STRUCTURE_TYPE_QUEUE_INDEX_PROPERTIES) {
27+
const ur_queue_index_properties_t *indexProperties =
28+
reinterpret_cast<const ur_queue_index_properties_t *>(extendedDesc);
29+
return indexProperties->computeIndex;
30+
}
31+
}
32+
return std::nullopt;
33+
}
34+
35+
static ze_command_queue_priority_t getZePriority(ur_queue_flags_t flags) {
36+
if ((flags & UR_QUEUE_FLAG_PRIORITY_LOW) != 0)
37+
return ZE_COMMAND_QUEUE_PRIORITY_PRIORITY_LOW;
38+
if ((flags & UR_QUEUE_FLAG_PRIORITY_HIGH) != 0)
39+
return ZE_COMMAND_QUEUE_PRIORITY_PRIORITY_HIGH;
40+
return ZE_COMMAND_QUEUE_PRIORITY_NORMAL;
41+
}
42+
43+
ur_command_list_handler_t::ur_command_list_handler_t(
44+
v2::ur_context_handle_t hContext, ur_device_handle_t hDevice,
45+
const ur_queue_properties_t *pProps, queue_group_type type)
46+
: commandList(hContext->commandListCache.getImmediateCommandList(
47+
hDevice->ZeDevice, true, getZeOrdinal(hDevice, type),
48+
ZE_COMMAND_QUEUE_MODE_ASYNCHRONOUS,
49+
getZePriority(pProps ? pProps->flags : ur_queue_flags_t{}),
50+
getZeIndex(pProps))) {}
51+
1452
ur_queue_immediate_in_order_t::ur_queue_immediate_in_order_t(
15-
ur_context_handle_t, ur_device_handle_t, ur_queue_flags_t) {}
53+
v2::ur_context_handle_t hContext, ur_device_handle_t hDevice,
54+
const ur_queue_properties_t *pProps)
55+
: copyHandler(hContext, hDevice, pProps, queue_group_type::MainCopy),
56+
computeHandler(hContext, hDevice, pProps, queue_group_type::Compute) {}
1657

1758
ur_result_t
1859
ur_queue_immediate_in_order_t::queueGetInfo(ur_queue_info_t propName,
@@ -26,11 +67,16 @@ ur_queue_immediate_in_order_t::queueGetInfo(ur_queue_info_t propName,
2667
}
2768

2869
ur_result_t ur_queue_immediate_in_order_t::queueRetain() {
29-
return UR_RESULT_ERROR_UNSUPPORTED_FEATURE;
70+
RefCount.increment();
71+
return UR_RESULT_SUCCESS;
3072
}
3173

3274
ur_result_t ur_queue_immediate_in_order_t::queueRelease() {
33-
return UR_RESULT_ERROR_UNSUPPORTED_FEATURE;
75+
if (!RefCount.decrementAndTest())
76+
return UR_RESULT_SUCCESS;
77+
78+
delete this;
79+
return UR_RESULT_SUCCESS;
3480
}
3581

3682
ur_result_t ur_queue_immediate_in_order_t::queueGetNativeHandle(

0 commit comments

Comments
 (0)