Skip to content

Commit 64f0db7

Browse files
[SYCL] SYCL 2020 callable device selectors (#6486)
Signed-off-by: Chris Perkins <[email protected]>
1 parent b3cbda5 commit 64f0db7

File tree

9 files changed

+228
-50
lines changed

9 files changed

+228
-50
lines changed

sycl/include/sycl/device.hpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@ class device_impl;
3333
auto getDeviceComparisonLambda();
3434
} // namespace detail
3535

36+
namespace ext {
37+
namespace oneapi {
38+
// Forward declaration
39+
class filter_selector;
40+
} // namespace oneapi
41+
} // namespace ext
42+
3643
/// The SYCL device class encapsulates a single SYCL device on which kernels
3744
/// may be executed.
3845
///
@@ -53,9 +60,20 @@ class __SYCL_EXPORT device {
5360
/// Constructs a SYCL device instance using the device selected
5461
/// by the DeviceSelector provided.
5562
///
56-
/// \param DeviceSelector SYCL device selector to be used (see 4.6.1.1).
63+
/// \param DeviceSelector SYCL 1.2.1 device_selector to be used (see 4.6.1.1).
5764
explicit device(const device_selector &DeviceSelector);
5865

66+
#if __cplusplus >= 201703L
67+
/// Constructs a SYCL device instance using the device
68+
/// identified by the device selector provided.
69+
/// \param DeviceSelector is SYCL 2020 Device Selector, a simple callable that
70+
/// takes a device and returns an int
71+
template <typename DeviceSelector,
72+
typename = detail::EnableIfDeviceSelectorInvocable<DeviceSelector>>
73+
explicit device(const DeviceSelector &deviceSelector)
74+
: device(detail::select_device(deviceSelector)) {}
75+
#endif
76+
5977
bool operator==(const device &rhs) const { return impl == rhs.impl; }
6078

6179
bool operator!=(const device &rhs) const { return !(*this == rhs); }

sycl/include/sycl/device_selector.hpp

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,19 @@ namespace sycl {
1919
// Forward declarations
2020
class device;
2121

22-
/// The device_selector class provides ability to choose the best SYCL device
23-
/// based on heuristics specified by the user.
22+
namespace ext {
23+
namespace oneapi {
24+
class filter_selector;
25+
}
26+
} // namespace ext
27+
28+
/// The SYCL 1.2.1 device_selector class provides ability to choose the
29+
/// best SYCL device based on heuristics specified by the user.
2430
///
2531
/// \sa device
2632
///
2733
/// \ingroup sycl_api_dev_sel
2834
class __SYCL_EXPORT device_selector {
29-
protected:
30-
// SYCL 1.2.1 defines a negative score to reject a device from selection
31-
static constexpr int REJECT_DEVICE_SCORE = -1;
3235

3336
public:
3437
virtual ~device_selector() = default;
@@ -87,5 +90,33 @@ class __SYCL_EXPORT host_selector : public device_selector {
8790
public:
8891
int operator()(const device &dev) const override;
8992
};
93+
94+
namespace detail {
95+
96+
// SYCL 2020 section 4.6.1.1 defines a negative score to reject a device from
97+
// selection
98+
static constexpr int REJECT_DEVICE_SCORE = -1;
99+
100+
using DSelectorInvocableType = std::function<int(const sycl::device &)>;
101+
102+
#if __cplusplus >= 201703L
103+
104+
// Enable if DeviceSelector callable has matching signature, but
105+
// exclude if descended from filter_selector which is not purely callable.
106+
// See [FilterSelector not Callable] in device_selector.cpp
107+
template <typename DeviceSelector>
108+
using EnableIfDeviceSelectorInvocable = std::enable_if_t<
109+
std::is_invocable_r_v<int, DeviceSelector &, const device &> &&
110+
!std::is_base_of_v<ext::oneapi::filter_selector, DeviceSelector>>;
111+
#endif
112+
113+
__SYCL_EXPORT device
114+
select_device(const DSelectorInvocableType &DeviceSelectorInvocable);
115+
116+
__SYCL_EXPORT device
117+
select_device(const DSelectorInvocableType &DeviceSelectorInvocable,
118+
const context &SyclContext);
119+
120+
} // namespace detail
90121
} // namespace sycl
91122
} // __SYCL_INLINE_NAMESPACE(cl)

sycl/include/sycl/platform.hpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <sycl/detail/common.hpp>
1515
#include <sycl/detail/export.hpp>
1616
#include <sycl/detail/info_desc_helpers.hpp>
17+
#include <sycl/device_selector.hpp>
1718
#include <sycl/stl.hpp>
1819

1920
// 4.6.2 Platform class
@@ -31,6 +32,12 @@ auto get_native(const SyclObjectT &Obj)
3132
namespace detail {
3233
class platform_impl;
3334
}
35+
namespace ext {
36+
namespace oneapi {
37+
// Forward declaration
38+
class filter_selector;
39+
} // namespace oneapi
40+
} // namespace ext
3441

3542
/// Encapsulates a SYCL platform on which kernels may be executed.
3643
///
@@ -50,15 +57,26 @@ class __SYCL_EXPORT platform {
5057
explicit platform(cl_platform_id PlatformId);
5158
#endif
5259

53-
/// Constructs a SYCL platform instance using device selector.
60+
/// Constructs a SYCL platform instance using a device_selector.
5461
///
5562
/// One of the SYCL devices that is associated with the constructed SYCL
5663
/// platform instance must be the SYCL device that is produced from the
5764
/// provided device selector.
5865
///
59-
/// \param DeviceSelector is an instance of SYCL device_selector.
66+
/// \param DeviceSelector is an instance of a SYCL 1.2.1 device_selector
6067
explicit platform(const device_selector &DeviceSelector);
6168

69+
#if __cplusplus >= 201703L
70+
/// Constructs a SYCL platform instance using the platform of the device
71+
/// identified by the device selector provided.
72+
/// \param DeviceSelector is SYCL 2020 Device Selector, a simple callable that
73+
/// takes a device and returns an int
74+
template <typename DeviceSelector,
75+
typename = detail::EnableIfDeviceSelectorInvocable<DeviceSelector>>
76+
explicit platform(const DeviceSelector &deviceSelector)
77+
: platform(detail::select_device(deviceSelector)) {}
78+
#endif
79+
6280
platform(const platform &rhs) = default;
6381

6482
platform(platform &&rhs) = default;
@@ -141,6 +159,8 @@ class __SYCL_EXPORT platform {
141159
std::shared_ptr<detail::platform_impl> impl;
142160
platform(std::shared_ptr<detail::platform_impl> impl) : impl(impl) {}
143161

162+
platform(const device &Device);
163+
144164
template <class T>
145165
friend T detail::createSyclObjFromImpl(decltype(T::impl) ImplObj);
146166
template <class Obj>

sycl/include/sycl/queue.hpp

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#define __STDC_FORMAT_MACROS 1
2929
#endif
3030
#include <cinttypes>
31+
#include <type_traits>
3132
#include <utility>
3233

3334
// having _TWO_ mid-param #ifdefs makes the functions very difficult to read.
@@ -123,10 +124,68 @@ class __SYCL_EXPORT queue {
123124
queue(const async_handler &AsyncHandler, const property_list &PropList = {})
124125
: queue(default_selector(), AsyncHandler, PropList) {}
125126

127+
#if __cplusplus >= 201703L
128+
/// Constructs a SYCL queue instance using the device identified by the
129+
/// device selector provided.
130+
/// \param DeviceSelector is SYCL 2020 Device Selector, a simple callable that
131+
/// takes a device and returns an int
132+
/// \param AsyncHandler is a SYCL asynchronous exception handler.
133+
/// \param PropList is a list of properties for queue construction.
134+
template <typename DeviceSelector,
135+
typename = detail::EnableIfDeviceSelectorInvocable<DeviceSelector>>
136+
explicit queue(const DeviceSelector &deviceSelector,
137+
const async_handler &AsyncHandler,
138+
const property_list &PropList = {})
139+
: queue(detail::select_device(deviceSelector), AsyncHandler, PropList) {}
140+
141+
/// Constructs a SYCL queue instance using the device identified by the
142+
/// device selector provided.
143+
/// \param DeviceSelector is SYCL 2020 Device Selector, a simple callable that
144+
/// takes a device and returns an int
145+
/// \param PropList is a list of properties for queue construction.
146+
template <typename DeviceSelector,
147+
typename = detail::EnableIfDeviceSelectorInvocable<DeviceSelector>>
148+
explicit queue(const DeviceSelector &deviceSelector,
149+
const property_list &PropList = {})
150+
: queue(detail::select_device(deviceSelector), async_handler{},
151+
PropList) {}
152+
153+
/// Constructs a SYCL queue instance using the device identified by the
154+
/// device selector provided.
155+
/// \param SyclContext is an instance of SYCL context.
156+
/// \param DeviceSelector is SYCL 2020 Device Selector, a simple callable that
157+
/// takes a device and returns an int
158+
/// \param PropList is a list of properties for queue construction.
159+
template <typename DeviceSelector,
160+
typename = detail::EnableIfDeviceSelectorInvocable<DeviceSelector>>
161+
explicit queue(const context &syclContext,
162+
const DeviceSelector &deviceSelector,
163+
const property_list &propList = {})
164+
: queue(syclContext, detail::select_device(deviceSelector, syclContext),
165+
propList) {}
166+
167+
/// Constructs a SYCL queue instance using the device identified by the
168+
/// device selector provided.
169+
/// \param SyclContext is an instance of SYCL context.
170+
/// \param DeviceSelector is SYCL 2020 Device Selector, a simple callable that
171+
/// takes a device and returns an int
172+
/// \param AsyncHandler is a SYCL asynchronous exception handler.
173+
/// \param PropList is a list of properties for queue construction.
174+
template <typename DeviceSelector,
175+
typename = detail::EnableIfDeviceSelectorInvocable<DeviceSelector>>
176+
explicit queue(const context &syclContext,
177+
const DeviceSelector &deviceSelector,
178+
const async_handler &AsyncHandler,
179+
const property_list &propList = {})
180+
: queue(syclContext, detail::select_device(deviceSelector, syclContext),
181+
AsyncHandler, propList) {}
182+
183+
#endif
184+
126185
/// Constructs a SYCL queue instance using the device returned by the
127186
/// DeviceSelector provided.
128187
///
129-
/// \param DeviceSelector is an instance of SYCL device selector.
188+
/// \param DeviceSelector is an instance of a SYCL 1.2.1 device_selector.
130189
/// \param PropList is a list of properties for queue construction.
131190
queue(const device_selector &DeviceSelector,
132191
const property_list &PropList = {})
@@ -135,7 +194,7 @@ class __SYCL_EXPORT queue {
135194
/// Constructs a SYCL queue instance with an async_handler using the device
136195
/// returned by the DeviceSelector provided.
137196
///
138-
/// \param DeviceSelector is an instance of SYCL device selector.
197+
/// \param DeviceSelector is an instance of SYCL 1.2.1 device_selector.
139198
/// \param AsyncHandler is a SYCL asynchronous exception handler.
140199
/// \param PropList is a list of properties for queue construction.
141200
queue(const device_selector &DeviceSelector,

0 commit comments

Comments
 (0)