Skip to content

Commit 333ec8b

Browse files
dkhaldibader
authored andcommitted
[SYCL][USM] Add ordered queue extension
Signed-off-by: Dounia <[email protected]>
1 parent 5e06976 commit 333ec8b

File tree

12 files changed

+538
-23
lines changed

12 files changed

+538
-23
lines changed

sycl/include/CL/sycl.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include <CL/sycl/pointers.hpp>
3333
#include <CL/sycl/program.hpp>
3434
#include <CL/sycl/queue.hpp>
35+
#include <CL/sycl/ordered_queue.hpp>
3536
#include <CL/sycl/range.hpp>
3637
#include <CL/sycl/sampler.hpp>
3738
#include <CL/sycl/stream.hpp>

sycl/include/CL/sycl/detail/queue_impl.hpp

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,23 @@ namespace detail {
2424
// Set max number of queues supported by FPGA RT.
2525
const size_t MaxNumQueues = 256;
2626

27+
enum QueueOrder { Ordered, OOO };
28+
2729
class queue_impl {
2830
public:
2931
queue_impl(const device &SyclDevice, async_handler AsyncHandler,
30-
const property_list &PropList)
31-
: queue_impl(SyclDevice, context(SyclDevice), AsyncHandler, PropList) {};
32+
QueueOrder Order, const property_list &PropList)
33+
: queue_impl(SyclDevice, context(SyclDevice), AsyncHandler, Order,
34+
PropList){};
3235

3336
queue_impl(const device &SyclDevice, const context &Context,
34-
async_handler AsyncHandler, const property_list &PropList)
37+
async_handler AsyncHandler, QueueOrder Order,
38+
const property_list &PropList)
3539
: m_Device(SyclDevice), m_Context(Context), m_AsyncHandler(AsyncHandler),
3640
m_PropList(PropList), m_HostQueue(m_Device.is_host()) {
3741
m_OpenCLInterop = !m_HostQueue;
3842
if (!m_HostQueue) {
39-
m_CommandQueue = createQueue();
43+
m_CommandQueue = createQueue(Order);
4044
}
4145
}
4246

@@ -51,8 +55,8 @@ class queue_impl {
5155
// TODO catch an exception and put it to list of asynchronous exceptions
5256
PI_CALL(RT::piQueueGetInfo(m_CommandQueue, PI_QUEUE_INFO_DEVICE,
5357
sizeof(Device), &Device, nullptr));
54-
m_Device = createSyclObjFromImpl<device>(
55-
std::make_shared<device_impl_pi>(Device));
58+
m_Device =
59+
createSyclObjFromImpl<device>(std::make_shared<device_impl_pi>(Device));
5660

5761
// TODO catch an exception and put it to list of asynchronous exceptions
5862
PI_CALL(RT::piQueueRetain(m_CommandQueue));
@@ -127,32 +131,31 @@ class queue_impl {
127131
m_Exceptions.Clear();
128132
}
129133

130-
RT::PiQueue createQueue() {
134+
RT::PiQueue createQueue(QueueOrder Order) {
131135
RT::PiQueueProperties CreationFlags = 0;
132136

133-
if (m_SupportOOO) {
137+
if (Order == QueueOrder::OOO) {
134138
CreationFlags = PI_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE;
135139
}
136-
137140
if (m_PropList.has_property<property::queue::enable_profiling>()) {
138141
CreationFlags |= PI_QUEUE_PROFILING_ENABLE;
139142
}
140-
141143
RT::PiQueue Queue;
142144
RT::PiContext Context = detail::getSyclObjImpl(m_Context)->getHandleRef();
143145
RT::PiDevice Device = detail::getSyclObjImpl(m_Device)->getHandleRef();
144-
RT::PiResult Error = PI_CALL_RESULT(RT::piQueueCreate(Context, Device,
145-
CreationFlags, &Queue));
146+
RT::PiResult Error = PI_CALL_RESULT(
147+
RT::piQueueCreate(Context, Device, CreationFlags, &Queue));
146148

147149
// If creating out-of-order queue failed and this property is not
148150
// supported (for example, on FPGA), it will return
149151
// CL_INVALID_QUEUE_PROPERTIES and will try to create in-order queue.
150152
if (m_SupportOOO && Error == PI_INVALID_QUEUE_PROPERTIES) {
151153
m_SupportOOO = false;
152-
Queue = createQueue();
154+
Queue = createQueue(QueueOrder::Ordered);
153155
} else {
154156
PI_CHECK(Error);
155157
}
158+
156159
return Queue;
157160
}
158161

@@ -162,7 +165,7 @@ class queue_impl {
162165
// possibility of two kernels to share data with each other we shall
163166
// create a queue for every kernel enqueued.
164167
if (m_Queues.size() < MaxNumQueues) {
165-
m_Queues.push_back(createQueue());
168+
m_Queues.push_back(createQueue(QueueOrder::Ordered));
166169
return m_Queues.back();
167170
}
168171

@@ -196,8 +199,8 @@ class queue_impl {
196199
return m_PropList.get_property<propertyT>();
197200
}
198201

199-
event memset(void* Ptr, int Value, size_t Count);
200-
event memcpy(void* Dest, const void* Src, size_t Count);
202+
event memset(void *Ptr, int Value, size_t Count);
203+
event memcpy(void *Dest, const void *Src, size_t Count);
201204
event mem_advise(const void *Ptr, size_t Length, int Advice);
202205

203206
private:

sycl/include/CL/sycl/detail/stream_impl.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <CL/sycl/detail/array.hpp>
1414
#include <CL/sycl/device_selector.hpp>
1515
#include <CL/sycl/queue.hpp>
16+
#include <CL/sycl/ordered_queue.hpp>
1617

1718
namespace cl {
1819
namespace sycl {

sycl/include/CL/sycl/info/info_desc.hpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,12 +172,17 @@ enum class execution_capability : unsigned int {
172172
exec_native_kernel
173173
};
174174

175-
// A.4 Queue information desctiptors
175+
// A.4 Queue information descriptors
176176
enum class queue : cl_command_queue_info {
177177
context = CL_QUEUE_CONTEXT,
178178
device = CL_QUEUE_DEVICE,
179179
reference_count = CL_QUEUE_REFERENCE_COUNT
180180
};
181+
enum class ordered_queue : cl_command_queue_info {
182+
context = CL_QUEUE_CONTEXT,
183+
device = CL_QUEUE_DEVICE,
184+
reference_count = CL_QUEUE_REFERENCE_COUNT
185+
};
181186

182187
// A.5 Kernel information desctiptors
183188
enum class kernel : cl_kernel_info {
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
//==----------------- ordered queue.hpp - SYCL queue -----------------------==//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#pragma once
10+
11+
#include <CL/sycl/detail/common.hpp>
12+
#include <CL/sycl/detail/queue_impl.hpp>
13+
#include <CL/sycl/device_selector.hpp>
14+
#include <CL/sycl/exception_list.hpp>
15+
#include <CL/sycl/info/info_desc.hpp>
16+
#include <CL/sycl/property_list.hpp>
17+
18+
#include <memory>
19+
#include <utility>
20+
21+
namespace cl {
22+
namespace sycl {
23+
24+
// Forward declaration
25+
class context;
26+
class device;
27+
class ordered_queue {
28+
public:
29+
explicit ordered_queue(const property_list &propList = {})
30+
: ordered_queue(default_selector(), async_handler{}, propList) {}
31+
32+
ordered_queue(const async_handler &asyncHandler, const property_list &propList = {})
33+
: ordered_queue(default_selector(), asyncHandler, propList) {}
34+
35+
ordered_queue(const device_selector &deviceSelector,
36+
const property_list &propList = {})
37+
: ordered_queue(deviceSelector.select_device(), async_handler{}, propList) {}
38+
39+
ordered_queue(const device_selector &deviceSelector,
40+
const async_handler &asyncHandler, const property_list &propList = {})
41+
: ordered_queue(deviceSelector.select_device(), asyncHandler, propList) {}
42+
43+
ordered_queue(const device &syclDevice, const property_list &propList = {})
44+
: ordered_queue(syclDevice, async_handler{}, propList) {}
45+
46+
ordered_queue(const device &syclDevice, const async_handler &asyncHandler,
47+
const property_list &propList = {});
48+
49+
ordered_queue(const context &syclContext, const device_selector &deviceSelector,
50+
const property_list &propList = {})
51+
: ordered_queue(syclContext, deviceSelector,
52+
detail::getSyclObjImpl(syclContext)->get_async_handler(),
53+
propList) {}
54+
55+
ordered_queue(const context &syclContext, const device_selector &deviceSelector,
56+
const async_handler &asyncHandler, const property_list &propList = {});
57+
58+
ordered_queue(cl_command_queue cl_Queue, const context &syclContext,
59+
const async_handler &asyncHandler = {});
60+
61+
ordered_queue(const ordered_queue &rhs) = default;
62+
63+
ordered_queue(ordered_queue &&rhs) = default;
64+
65+
ordered_queue &operator=(const ordered_queue &rhs) = default;
66+
67+
ordered_queue &operator=(ordered_queue &&rhs) = default;
68+
69+
bool operator==(const ordered_queue &rhs) const { return impl == rhs.impl; }
70+
71+
bool operator!=(const ordered_queue &rhs) const { return !(*this == rhs); }
72+
73+
cl_command_queue get() const { return impl->get(); }
74+
75+
context get_context() const { return impl->get_context(); }
76+
77+
device get_device() const { return impl->get_device(); }
78+
79+
bool is_host() const { return impl->is_host(); }
80+
81+
template <info::ordered_queue param>
82+
typename info::param_traits<info::ordered_queue, param>::return_type
83+
get_info() const {
84+
return impl->get_info<param>();
85+
}
86+
87+
template <typename T> event submit(T cgf) { return impl->submit(cgf, impl); }
88+
89+
template <typename T> event submit(T cgf, ordered_queue &secondaryQueue) {
90+
return impl->submit(cgf, impl, secondaryQueue.impl);
91+
}
92+
93+
void wait() { impl->wait(); }
94+
95+
void wait_and_throw() { impl->wait_and_throw(); }
96+
97+
void throw_asynchronous() { impl->throw_asynchronous(); }
98+
99+
template <typename propertyT> bool has_property() const {
100+
return impl->has_property<propertyT>();
101+
}
102+
103+
template <typename propertyT> propertyT get_property() const {
104+
return impl->get_property<propertyT>();
105+
}
106+
107+
event memset(void* ptr, int value, size_t count) {
108+
return impl->memset(ptr, value, count);
109+
}
110+
111+
event memcpy(void* dest, const void* src, size_t count) {
112+
return impl->memcpy(dest, src, count);
113+
}
114+
115+
private:
116+
std::shared_ptr<detail::queue_impl> impl;
117+
template <class Obj>
118+
friend decltype(Obj::impl) detail::getSyclObjImpl(const Obj &SyclObject);
119+
};
120+
121+
} // namespace sycl
122+
} // namespace cl
123+
124+
namespace std {
125+
template <> struct hash<cl::sycl::ordered_queue> {
126+
size_t operator()(const cl::sycl::ordered_queue &q) const {
127+
return std::hash<std::shared_ptr<cl::sycl::detail::queue_impl>>()(
128+
cl::sycl::detail::getSyclObjImpl(q));
129+
}
130+
};
131+
} // namespace std

sycl/source/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ add_library(sycl SHARED
5252
"kernel.cpp"
5353
"platform.cpp"
5454
"queue.cpp"
55+
"ordered_queue.cpp"
5556
"sampler.cpp"
5657
"stream.cpp"
5758
"spirv_ops.cpp"

sycl/source/detail/scheduler/scheduler.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,8 @@ EventImplPtr Scheduler::addHostAccessor(Requirement *Req) {
145145

146146
Scheduler::Scheduler() {
147147
sycl::device HostDevice;
148-
DefaultHostQueue = QueueImplPtr(
149-
new queue_impl(HostDevice, /*AsyncHandler=*/{}, /*PropList=*/{}));
148+
DefaultHostQueue = QueueImplPtr(new queue_impl(
149+
HostDevice, /*AsyncHandler=*/{}, QueueOrder::Ordered, /*PropList=*/{}));
150150
}
151151

152152
} // namespace detail

sycl/source/ordered_queue.cpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
//==-------------- ordered_queue.cpp ---------------------------------------==//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include <CL/sycl/exception_list.hpp>
10+
#include <CL/sycl/ordered_queue.hpp>
11+
12+
#include <algorithm>
13+
14+
namespace cl {
15+
namespace sycl {
16+
ordered_queue::ordered_queue(const context &syclContext,
17+
const device_selector &deviceSelector,
18+
const async_handler &asyncHandler,
19+
const property_list &propList) {
20+
21+
const vector_class<device> Devs = syclContext.get_devices();
22+
23+
auto Comp = [&deviceSelector](const device &d1, const device &d2) {
24+
return deviceSelector(d1) < deviceSelector(d2);
25+
};
26+
27+
const device &syclDevice = *std::max_element(Devs.begin(), Devs.end(), Comp);
28+
impl = std::make_shared<detail::queue_impl>(
29+
syclDevice, syclContext, asyncHandler,
30+
cl::sycl::detail::QueueOrder::Ordered, propList);
31+
}
32+
33+
ordered_queue::ordered_queue(const device &syclDevice,
34+
const async_handler &asyncHandler,
35+
const property_list &propList) {
36+
impl = std::make_shared<detail::queue_impl>(
37+
syclDevice, asyncHandler, cl::sycl::detail::QueueOrder::Ordered,
38+
propList);
39+
}
40+
41+
ordered_queue::ordered_queue(cl_command_queue clQueue,
42+
const context &syclContext,
43+
const async_handler &asyncHandler) {
44+
cl_command_queue_properties reportedProps;
45+
RT::PiQueue m_CommandQueue = detail::pi::cast<detail::RT::PiQueue>(clQueue);
46+
PI_CALL(RT::piQueueGetInfo(m_CommandQueue, PI_QUEUE_INFO_DEVICE,
47+
sizeof(reportedProps), &reportedProps, nullptr));
48+
if (reportedProps & CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE)
49+
throw runtime_error(
50+
"Failed to build a sycl ordered queue from a cl OOO queue.");
51+
52+
impl =
53+
std::make_shared<detail::queue_impl>(clQueue, syclContext, asyncHandler);
54+
}
55+
56+
} // namespace sycl
57+
} // namespace cl

sycl/source/queue.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,15 @@ queue::queue(const context &syclContext, const device_selector &deviceSelector,
2323
};
2424

2525
const device &syclDevice = *std::max_element(Devs.begin(), Devs.end(), Comp);
26-
impl = std::make_shared<detail::queue_impl>(syclDevice, syclContext,
27-
asyncHandler, propList);
26+
impl = std::make_shared<detail::queue_impl>(
27+
syclDevice, syclContext, asyncHandler, cl::sycl::detail::QueueOrder::OOO,
28+
propList);
2829
}
2930

3031
queue::queue(const device &syclDevice, const async_handler &asyncHandler,
3132
const property_list &propList) {
32-
impl =
33-
std::make_shared<detail::queue_impl>(syclDevice, asyncHandler, propList);
33+
impl = std::make_shared<detail::queue_impl>(
34+
syclDevice, asyncHandler, cl::sycl::detail::QueueOrder::OOO, propList);
3435
}
3536

3637
queue::queue(cl_command_queue clQueue, const context &syclContext,

0 commit comments

Comments
 (0)