Skip to content

Commit 8ba1d4e

Browse files
committed
Begin moving ordered_queue to be a property on the queue. Can deprecate ordered_queue in the future.
Signed-off-by: James Brodman <[email protected]>
1 parent 00baa4b commit 8ba1d4e

File tree

3 files changed

+142
-2
lines changed

3 files changed

+142
-2
lines changed

sycl/include/CL/sycl/property_list.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ class context_bound;
3939

4040
namespace queue {
4141
class enable_profiling;
42+
class in_order;
43+
class out_of_order;
4244
} // namespace queue
4345

4446
namespace detail {
@@ -57,6 +59,8 @@ enum PropKind {
5759

5860
// Queue properties
5961
QueueEnableProfiling,
62+
InOrder,
63+
OutOfOrder,
6064

6165
PropKindSize
6266
};
@@ -110,6 +114,8 @@ RegisterProp(PropKind::BufferContextBound, buffer::context_bound);
110114

111115
// Queue
112116
RegisterProp(PropKind::QueueEnableProfiling, queue::enable_profiling);
117+
RegisterProp(PropKind::InOrder, queue::in_order);
118+
RegisterProp(PropKind::OutOfOrder, queue::out_of_order);
113119

114120
// Sentinel, needed for automatic build of tuple in property_list.
115121
RegisterProp(PropKind::PropKindSize, PropBase);
@@ -172,6 +178,10 @@ class context_bound
172178
namespace queue {
173179
class enable_profiling
174180
: public detail::Prop<detail::PropKind::QueueEnableProfiling> {};
181+
182+
class in_order : public detail::Prop<detail::PropKind::InOrder> {};
183+
184+
class out_of_order : public detail::Prop<detail::PropKind::OutOfOrder> {};
175185
} // namespace queue
176186

177187
} // namespace property

sycl/source/queue.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,19 @@
1313

1414
__SYCL_INLINE namespace cl {
1515
namespace sycl {
16+
17+
namespace detail {
18+
19+
QueueOrder getQueueOrder(const property_list &propList) {
20+
if (propList.has_property<property::queue::in_order>()) {
21+
return QueueOrder::Ordered;
22+
} else {
23+
return QueueOrder::OOO;
24+
}
25+
}
26+
27+
} // namespace detail
28+
1629
queue::queue(const context &syclContext, const device_selector &deviceSelector,
1730
const async_handler &asyncHandler, const property_list &propList) {
1831

@@ -23,16 +36,17 @@ queue::queue(const context &syclContext, const device_selector &deviceSelector,
2336
};
2437

2538
const device &syclDevice = *std::max_element(Devs.begin(), Devs.end(), Comp);
39+
2640
impl = std::make_shared<detail::queue_impl>(
2741
detail::getSyclObjImpl(syclDevice), detail::getSyclObjImpl(syclContext),
28-
asyncHandler, cl::sycl::detail::QueueOrder::OOO, propList);
42+
asyncHandler, detail::getQueueOrder(propList), propList);
2943
}
3044

3145
queue::queue(const device &syclDevice, const async_handler &asyncHandler,
3246
const property_list &propList) {
3347
impl = std::make_shared<detail::queue_impl>(
3448
detail::getSyclObjImpl(syclDevice), asyncHandler,
35-
cl::sycl::detail::QueueOrder::OOO, propList);
49+
detail::getQueueOrder(propList), propList);
3650
}
3751

3852
queue::queue(cl_command_queue clQueue, const context &syclContext,
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
// RUN: %clangxx -fsycl %s -o %t1.out -lOpenCL
2+
// RUN: %CPU_RUN_PLACEHOLDER %t1.out
3+
// RUN: %GPU_RUN_PLACEHOLDER %t1.out
4+
5+
//==----------- ordered_dmemll.cpp - Device Memory Linked List test --------==//
6+
// It uses an ordered queue where explicit waiting is not necessary between
7+
// kernels
8+
//
9+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
10+
// See https://llvm.org/LICENSE.txt for license information.
11+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
#include <CL/sycl.hpp>
16+
17+
using namespace cl::sycl;
18+
19+
constexpr int numNodes = 4;
20+
21+
bool getQueueOrder(cl_command_queue cq) {
22+
cl_command_queue_properties reportedProps;
23+
cl_int iRet = clGetCommandQueueInfo(
24+
cq, CL_QUEUE_PROPERTIES, sizeof(reportedProps), &reportedProps, nullptr);
25+
assert(CL_SUCCESS == iRet && "Failed to obtain queue info from ocl device");
26+
return (reportedProps & CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE) ? false
27+
: true;
28+
}
29+
30+
struct Node {
31+
Node() : pNext(nullptr), Num(0xDEADBEEF) {}
32+
33+
Node *pNext;
34+
uint32_t Num;
35+
};
36+
37+
class foo;
38+
int main() {
39+
queue q{property::queue::in_order()};
40+
auto dev = q.get_device();
41+
auto ctxt = q.get_context();
42+
Node *d_head = nullptr;
43+
Node *d_cur = nullptr;
44+
Node h_cur;
45+
46+
d_head = (Node *)malloc_device(sizeof(Node), dev, ctxt);
47+
if (d_head == nullptr) {
48+
return -1;
49+
}
50+
d_cur = d_head;
51+
52+
for (int i = 0; i < numNodes; i++) {
53+
h_cur.Num = i * 2;
54+
55+
if (i != (numNodes - 1)) {
56+
h_cur.pNext = (Node *)malloc_device(sizeof(Node), dev, ctxt);
57+
if (h_cur.pNext == nullptr) {
58+
return -1;
59+
}
60+
} else {
61+
h_cur.pNext = nullptr;
62+
}
63+
64+
event e0 = q.memcpy(d_cur, &h_cur, sizeof(Node));
65+
e0.wait();
66+
67+
d_cur = h_cur.pNext;
68+
}
69+
70+
q.submit([=](handler &cgh) {
71+
cgh.single_task<class foo>([=]() {
72+
Node *pHead = d_head;
73+
while (pHead) {
74+
pHead->Num = pHead->Num * 2 + 1;
75+
pHead = pHead->pNext;
76+
}
77+
});
78+
});
79+
80+
q.submit([=](handler &cgh) {
81+
cgh.single_task<class bar>([=]() {
82+
Node *pHead = d_head;
83+
while (pHead) {
84+
pHead->Num = pHead->Num + 42;
85+
pHead = pHead->pNext;
86+
}
87+
});
88+
});
89+
90+
d_cur = d_head;
91+
for (int i = 0; i < numNodes; i++) {
92+
event c = q.memcpy(&h_cur, d_cur, sizeof(Node));
93+
c.wait();
94+
free(d_cur, ctxt);
95+
96+
const int want = i * 4 + 43;
97+
if (h_cur.Num != want) {
98+
std::cout << "Result mismatches " << h_cur.Num << " vs expected "
99+
<< i * 4 + 43 << " for index " << i << std::endl;
100+
return -1;
101+
}
102+
d_cur = h_cur.pNext;
103+
}
104+
105+
bool result = true;
106+
cl_command_queue cq = q.get();
107+
bool expected_result = dev.is_host() ? true : getQueueOrder(cq);
108+
if (expected_result != result) {
109+
std::cout << "Resulting queue order is OOO but expected order is inorder"
110+
<< std::endl;
111+
112+
return -1;
113+
}
114+
115+
return 0;
116+
}

0 commit comments

Comments
 (0)