Skip to content

Commit cdb09dc

Browse files
[SYCL] Add support for sycl::ext::oneapi::property::queue::use_priority (#7523)
Adds a new queue property (hint) for setting its priority in backends that support it. Currently supported in Level Zero backend only and ignored for others. Test: intel/llvm-test-suite#1414 Signed-off-by: Sergey V Maslov <sergey.v.maslov@intel.com>
1 parent 142d9f5 commit cdb09dc

File tree

10 files changed

+239
-15
lines changed

10 files changed

+239
-15
lines changed
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
= sycl_ext_oneapi_queue_priority
2+
3+
:source-highlighter: coderay
4+
:coderay-linenums-mode: table
5+
6+
// This section needs to be after the document title.
7+
:doctype: book
8+
:toc2:
9+
:toc: left
10+
:encoding: utf-8
11+
:lang: en
12+
:dpcpp: pass:[DPC++]
13+
14+
// Set the default source code type in this document to C++,
15+
// for syntax highlighting purposes. This is needed because
16+
// docbook uses c++ and html5 uses cpp.
17+
:language: {basebackend@docbook:c++:cpp}
18+
19+
20+
== Notice
21+
22+
[%hardbreaks]
23+
Copyright (C) 2022-2022 Intel Corporation. All rights reserved.
24+
25+
Khronos(R) is a registered trademark and SYCL(TM) and SPIR(TM) are trademarks
26+
of The Khronos Group Inc. OpenCL(TM) is a trademark of Apple Inc. used by
27+
permission by Khronos.
28+
29+
== Contact
30+
31+
To report problems with this extension, please open a new issue at:
32+
33+
https://github.com/intel/llvm/issues
34+
35+
36+
== Dependencies
37+
38+
This extension is written against the SYCL 2020 revision 6 specification. All
39+
references below to the "core SYCL specification" or to section numbers in the
40+
SYCL specification refer to that revision.
41+
42+
== Status
43+
44+
This extension is implemented and fully supported by {dpcpp}.
45+
[NOTE]
46+
====
47+
Although {dpcpp} supports this extension on all backends, it is currently used
48+
only on Level Zero. Other backends ignore the properties defined in this specification.
49+
====
50+
51+
== Overview
52+
53+
Introduce SYCL queue properties specifying the desired priority of a queue.
54+
These priorities are a hint and may be ignored if not supported by
55+
underlying backends.
56+
57+
== Specification
58+
59+
=== Feature test macro
60+
61+
This extension provides a feature-test macro as described in the core SYCL
62+
specification. An implementation supporting this extension must predefine
63+
the macro `SYCL_EXT_ONEAPI_QUEUE_PRIORITY` to one of the values defined
64+
in the table below. Applications can test for the existence of this macro
65+
to determine if the implementation supports this feature, or applications
66+
can test the macro's value to determine which of the extension's features
67+
the implementation supports.
68+
69+
[%header,cols="1,5"]
70+
|===
71+
|Value
72+
|Description
73+
74+
|1
75+
|Initial version of this extension.
76+
|===
77+
78+
=== API of the extension
79+
80+
This extension adds support for new properties for SYCL queue constructors
81+
taking properties list:
82+
83+
```c++
84+
namespace sycl::ext::oneapi::property::queue {
85+
86+
class priority_normal {
87+
public:
88+
priority_normal() = default;
89+
};
90+
class priority_low {
91+
public:
92+
priority_low() = default;
93+
};
94+
class priority_high {
95+
public:
96+
priority_high() = default;
97+
};
98+
99+
} // namespace
100+
```
101+
The new properties hint the SYCL runtime that the queue gets the specified
102+
priority for execution if supported by underlying target runtimes. These
103+
properties are hints and may safely be ignored by an implementation.
104+
105+
It is illegal to specify multiple differrent priority hints for the same queue.
106+
Doing so causes the `queue` constructor to throw a synchronous `exception` with
107+
the `errc::invalid` error code.

sycl/include/sycl/detail/pi.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@
5656
// 11.16 Add PI_EXT_INTEL_DEVICE_INFO_MEMORY_CLOCK_RATE and
5757
// PI_EXT_INTEL_DEVICE_INFO_MEMORY_BUS_WIDTH as an extension for
5858
// piDeviceGetInfo.
59+
// 11.17 Added new PI_EXT_ONEAPI_QUEUE_PRIORITY_LOW and
60+
// PI_EXT_ONEAPI_QUEUE_PRIORITY_HIGH queue properties.
5961

6062
#define _PI_H_VERSION_MAJOR 11
6163
#define _PI_H_VERSION_MINOR 16
@@ -580,6 +582,8 @@ constexpr pi_queue_properties PI_QUEUE_PROFILING_ENABLE = (1 << 1);
580582
constexpr pi_queue_properties PI_QUEUE_ON_DEVICE = (1 << 2);
581583
constexpr pi_queue_properties PI_QUEUE_ON_DEVICE_DEFAULT = (1 << 3);
582584
constexpr pi_queue_properties PI_EXT_ONEAPI_QUEUE_DISCARD_EVENTS = (1 << 4);
585+
constexpr pi_queue_properties PI_EXT_ONEAPI_QUEUE_PRIORITY_LOW = (1 << 5);
586+
constexpr pi_queue_properties PI_EXT_ONEAPI_QUEUE_PRIORITY_HIGH = (1 << 6);
583587

584588
using pi_result = _pi_result;
585589
using pi_platform_info = _pi_platform_info;

sycl/include/sycl/detail/properties_traits.def

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,16 @@ __SYCL_PARAM_TRAITS_SPEC(sycl::property::buffer::context_bound)
44
__SYCL_PARAM_TRAITS_SPEC(sycl::property::image::use_host_ptr)
55
__SYCL_PARAM_TRAITS_SPEC(sycl::property::image::use_mutex)
66
__SYCL_PARAM_TRAITS_SPEC(sycl::property::image::context_bound)
7-
__SYCL_PARAM_TRAITS_SPEC(sycl::ext::oneapi::property::buffer::use_pinned_host_memory)
7+
__SYCL_PARAM_TRAITS_SPEC(
8+
sycl::ext::oneapi::property::buffer::use_pinned_host_memory)
89
__SYCL_PARAM_TRAITS_SPEC(sycl::property::noinit)
910
__SYCL_PARAM_TRAITS_SPEC(sycl::property::no_init)
10-
__SYCL_PARAM_TRAITS_SPEC(sycl::property::context::cuda::use_primary_context) // Deprecated
11-
__SYCL_PARAM_TRAITS_SPEC(sycl::ext::oneapi::cuda::property::context::use_primary_context)
11+
__SYCL_PARAM_TRAITS_SPEC(
12+
sycl::property::context::cuda::use_primary_context) // Deprecated
13+
__SYCL_PARAM_TRAITS_SPEC(
14+
sycl::ext::oneapi::cuda::property::context::use_primary_context)
1215
__SYCL_PARAM_TRAITS_SPEC(sycl::property::queue::in_order)
1316
__SYCL_PARAM_TRAITS_SPEC(sycl::property::reduction::initialize_to_identity)
17+
__SYCL_PARAM_TRAITS_SPEC(sycl::ext::oneapi::property::queue::priority_low)
18+
__SYCL_PARAM_TRAITS_SPEC(sycl::ext::oneapi::property::queue::priority_high)
19+
__SYCL_PARAM_TRAITS_SPEC(sycl::ext::oneapi::property::queue::priority_normal)

sycl/include/sycl/detail/property_helper.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,11 @@ enum DataLessPropKind {
4040
FusionNoBarrier = 13,
4141
FusionEnable = 14,
4242
FusionForce = 15,
43+
QueuePriorityNormal = 16,
44+
QueuePriorityLow = 17,
45+
QueuePriorityHigh = 18,
4346
// Indicates the last known dataless property.
44-
LastKnownDataLessPropKind = 15,
47+
LastKnownDataLessPropKind = 18,
4548
// Exceeding 32 may cause ABI breaking change on some of OSes.
4649
DataLessPropKindSize = 32
4750
};

sycl/include/sycl/feature_test.hpp.in

100644100755
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ __SYCL_INLINE_VER_NAMESPACE(_V1) {
3737
#define SYCL_EXT_ONEAPI_ASSERT 1
3838
#define SYCL_EXT_ONEAPI_COMPLEX_ALGORITHMS 1
3939
#define SYCL_EXT_ONEAPI_DISCARD_QUEUE_EVENTS 1
40+
#define SYCL_EXT_ONEAPI_QUEUE_PRIORITY 1
4041
#define SYCL_EXT_ONEAPI_ENQUEUE_BARRIER 1
4142
#define SYCL_EXT_ONEAPI_FREE_FUNCTION_QUERIES 1
4243
#define SYCL_EXT_ONEAPI_GROUP_ALGORITHMS 1

sycl/include/sycl/properties/queue_properties.hpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,15 @@ namespace property {
2828
namespace queue {
2929
class discard_events
3030
: public ::sycl::detail::DataLessProperty<::sycl::detail::DiscardEvents> {};
31+
32+
class priority_normal
33+
: public sycl::detail::DataLessProperty<sycl::detail::QueuePriorityNormal> {
34+
};
35+
class priority_low
36+
: public sycl::detail::DataLessProperty<sycl::detail::QueuePriorityLow> {};
37+
class priority_high
38+
: public sycl::detail::DataLessProperty<sycl::detail::QueuePriorityHigh> {};
39+
3140
} // namespace queue
3241
} // namespace property
3342

@@ -67,6 +76,15 @@ template <>
6776
struct is_property_of<ext::oneapi::property::queue::discard_events, queue>
6877
: std::true_type {};
6978
template <>
79+
struct is_property_of<ext::oneapi::property::queue::priority_normal, queue>
80+
: std::true_type {};
81+
template <>
82+
struct is_property_of<ext::oneapi::property::queue::priority_low, queue>
83+
: std::true_type {};
84+
template <>
85+
struct is_property_of<ext::oneapi::property::queue::priority_high, queue>
86+
: std::true_type {};
87+
template <>
7088
struct is_property_of<property::queue::cuda::use_default_stream, queue>
7189
: std::true_type {};
7290
template <>

sycl/plugins/level_zero/pi_level_zero.cpp

100755100644
Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,6 +1002,14 @@ bool _pi_queue::isDiscardEvents() const {
10021002
return ((this->Properties & PI_EXT_ONEAPI_QUEUE_DISCARD_EVENTS) != 0);
10031003
}
10041004

1005+
bool _pi_queue::isPriorityLow() const {
1006+
return ((this->Properties & PI_EXT_ONEAPI_QUEUE_PRIORITY_LOW) != 0);
1007+
}
1008+
1009+
bool _pi_queue::isPriorityHigh() const {
1010+
return ((this->Properties & PI_EXT_ONEAPI_QUEUE_PRIORITY_HIGH) != 0);
1011+
}
1012+
10051013
pi_result
10061014
_pi_queue::resetCommandList(pi_command_list_ptr_t CommandList,
10071015
bool MakeAvailable,
@@ -1829,16 +1837,24 @@ _pi_queue::pi_queue_group_t::getZeQueue(uint32_t *QueueGroupOrdinal) {
18291837
ZeCommandQueueDesc.ordinal = *QueueGroupOrdinal;
18301838
ZeCommandQueueDesc.index = QueueIndex;
18311839
ZeCommandQueueDesc.mode = ZE_COMMAND_QUEUE_MODE_ASYNCHRONOUS;
1840+
const char *Priority = "Normal";
1841+
if (Queue->isPriorityLow()) {
1842+
ZeCommandQueueDesc.priority = ZE_COMMAND_QUEUE_PRIORITY_PRIORITY_LOW;
1843+
Priority = "Low";
1844+
} else if (Queue->isPriorityHigh()) {
1845+
ZeCommandQueueDesc.priority = ZE_COMMAND_QUEUE_PRIORITY_PRIORITY_HIGH;
1846+
Priority = "High";
1847+
}
18321848

18331849
// Evaluate performance of explicit usage for "0" index.
18341850
if (QueueIndex != 0) {
18351851
ZeCommandQueueDesc.flags = ZE_COMMAND_QUEUE_FLAG_EXPLICIT_ONLY;
18361852
}
18371853

18381854
zePrint("[getZeQueue]: create queue ordinal = %d, index = %d "
1839-
"(round robin in [%d, %d])\n",
1855+
"(round robin in [%d, %d]) priority = %s\n",
18401856
ZeCommandQueueDesc.ordinal, ZeCommandQueueDesc.index, LowerIndex,
1841-
UpperIndex);
1857+
UpperIndex, Priority);
18421858

18431859
auto ZeResult = ZE_CALL_NOCHECK(
18441860
zeCommandQueueCreate, (Queue->Context->ZeContext, Queue->Device->ZeDevice,
@@ -1864,16 +1880,24 @@ pi_command_list_ptr_t &_pi_queue::pi_queue_group_t::getImmCmdList() {
18641880
ZeCommandQueueDesc.ordinal = QueueOrdinal;
18651881
ZeCommandQueueDesc.index = QueueIndex;
18661882
ZeCommandQueueDesc.mode = ZE_COMMAND_QUEUE_MODE_ASYNCHRONOUS;
1883+
const char *Priority = "Normal";
1884+
if (Queue->isPriorityLow()) {
1885+
ZeCommandQueueDesc.priority = ZE_COMMAND_QUEUE_PRIORITY_PRIORITY_LOW;
1886+
Priority = "Low";
1887+
} else if (Queue->isPriorityHigh()) {
1888+
ZeCommandQueueDesc.priority = ZE_COMMAND_QUEUE_PRIORITY_PRIORITY_HIGH;
1889+
Priority = "High";
1890+
}
18671891

18681892
// Evaluate performance of explicit usage for "0" index.
18691893
if (QueueIndex != 0) {
18701894
ZeCommandQueueDesc.flags = ZE_COMMAND_QUEUE_FLAG_EXPLICIT_ONLY;
18711895
}
18721896

18731897
zePrint("[getZeQueue]: create queue ordinal = %d, index = %d "
1874-
"(round robin in [%d, %d])\n",
1898+
"(round robin in [%d, %d]) priority = %s\n",
18751899
ZeCommandQueueDesc.ordinal, ZeCommandQueueDesc.index, LowerIndex,
1876-
UpperIndex);
1900+
UpperIndex, Priority);
18771901

18781902
ze_command_list_handle_t ZeCommandList;
18791903
ZE_CALL_NOCHECK(zeCommandListCreateImmediate,
@@ -3532,7 +3556,9 @@ pi_result piQueueCreate(pi_context Context, pi_device Device,
35323556
PI_ASSERT(!(Properties & ~(PI_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE |
35333557
PI_QUEUE_PROFILING_ENABLE | PI_QUEUE_ON_DEVICE |
35343558
PI_QUEUE_ON_DEVICE_DEFAULT |
3535-
PI_EXT_ONEAPI_QUEUE_DISCARD_EVENTS)),
3559+
PI_EXT_ONEAPI_QUEUE_DISCARD_EVENTS |
3560+
PI_EXT_ONEAPI_QUEUE_PRIORITY_LOW |
3561+
PI_EXT_ONEAPI_QUEUE_PRIORITY_HIGH)),
35363562
PI_ERROR_INVALID_VALUE);
35373563

35383564
PI_ASSERT(Context, PI_ERROR_INVALID_CONTEXT);

sycl/plugins/level_zero/pi_level_zero.hpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -432,9 +432,9 @@ using pi_command_list_ptr_t = pi_command_list_map_t::iterator;
432432
struct _pi_context : _pi_object {
433433
_pi_context(ze_context_handle_t ZeContext, pi_uint32 NumDevices,
434434
const pi_device *Devs, bool OwnZeContext)
435-
: ZeContext{ZeContext},
436-
OwnZeContext{OwnZeContext}, Devices{Devs, Devs + NumDevices},
437-
SingleRootDevice(getRootDevice()), ZeCommandListInit{nullptr} {
435+
: ZeContext{ZeContext}, OwnZeContext{OwnZeContext},
436+
Devices{Devs, Devs + NumDevices}, SingleRootDevice(getRootDevice()),
437+
ZeCommandListInit{nullptr} {
438438
// NOTE: one must additionally call initialize() to complete
439439
// PI context creation.
440440
}
@@ -788,6 +788,10 @@ struct _pi_queue : _pi_object {
788788
// Returns true if the queue has discard events property.
789789
bool isDiscardEvents() const;
790790

791+
// Returns true if the queue has explicit priority set by user.
792+
bool isPriorityLow() const;
793+
bool isPriorityHigh() const;
794+
791795
// adjust the queue's batch size, knowing that the current command list
792796
// is being closed with a full batch.
793797
// For copy commands, IsCopy is set to 'true'.
@@ -1366,9 +1370,9 @@ struct _pi_program : _pi_object {
13661370

13671371
// Construct a program in IL or Native state.
13681372
_pi_program(state St, pi_context Context, const void *Input, size_t Length)
1369-
: Context{Context},
1370-
OwnZeModule{true}, State{St}, Code{new uint8_t[Length]},
1371-
CodeLength{Length}, ZeModule{nullptr}, ZeBuildLog{nullptr} {
1373+
: Context{Context}, OwnZeModule{true}, State{St},
1374+
Code{new uint8_t[Length]}, CodeLength{Length}, ZeModule{nullptr},
1375+
ZeBuildLog{nullptr} {
13721376
std::memcpy(Code.get(), Input, Length);
13731377
}
13741378

sycl/source/detail/queue_impl.hpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,31 @@ class queue_impl {
312312
// queue property.
313313
CreationFlags |= PI_EXT_ONEAPI_QUEUE_DISCARD_EVENTS;
314314
}
315+
// Track that priority settings are not ambiguous.
316+
bool PrioritySeen = false;
317+
if (MPropList
318+
.has_property<ext::oneapi::property::queue::priority_normal>()) {
319+
// Normal is the default priority, don't pass anything.
320+
PrioritySeen = true;
321+
}
322+
if (MPropList.has_property<ext::oneapi::property::queue::priority_low>()) {
323+
if (PrioritySeen) {
324+
throw sycl::exception(
325+
make_error_code(errc::invalid),
326+
"Queue cannot be constructed with different priorities.");
327+
}
328+
CreationFlags |= PI_EXT_ONEAPI_QUEUE_PRIORITY_LOW;
329+
PrioritySeen = true;
330+
}
331+
if (MPropList.has_property<ext::oneapi::property::queue::priority_high>()) {
332+
if (PrioritySeen) {
333+
throw sycl::exception(
334+
make_error_code(errc::invalid),
335+
"Queue cannot be constructed with different priorities.");
336+
}
337+
CreationFlags |= PI_EXT_ONEAPI_QUEUE_PRIORITY_HIGH;
338+
PrioritySeen = true;
339+
}
315340
RT::PiQueue Queue{};
316341
RT::PiContext Context = MContext->getHandleRef();
317342
RT::PiDevice Device = MDevice->getHandleRef();

0 commit comments

Comments
 (0)