Skip to content

Commit 89804af

Browse files
authored
[SYCL] Added support for aspects and the has() function. (#2237)
* [SYCL] Added support for aspects and the has() function. The SYCL 2020 Provisional Spec adds a new concept called device "aspects", which provide a way for an application to query whether a device supports certain features which are not available on all devices. The device::has() function returns true if a device supports the aspect, and false otherwise. The platform::has() function returns true if all devices on the platform support the given aspect, and false otherwise. Signed-off-by: Gail Lyons <gail.lyons@intel.com>
1 parent 4d5b34d commit 89804af

File tree

12 files changed

+202
-8
lines changed

12 files changed

+202
-8
lines changed

sycl/include/CL/sycl.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#pragma once
1010

1111
#include <CL/sycl/accessor.hpp>
12+
#include <CL/sycl/aspects.hpp>
1213
#include <CL/sycl/atomic.hpp>
1314
#include <CL/sycl/backend.hpp>
1415
#include <CL/sycl/buffer.hpp>

sycl/include/CL/sycl/aspects.hpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//==-------------- aspects.hpp - SYCL Aspect Enums ------------*- C++ -*---==//
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+
#pragma once
9+
10+
#include <CL/sycl/detail/defines.hpp>
11+
12+
__SYCL_INLINE_NAMESPACE(cl) {
13+
namespace sycl {
14+
15+
enum class aspect {
16+
host,
17+
cpu,
18+
gpu,
19+
accelerator,
20+
custom,
21+
fp16,
22+
fp64,
23+
int64_base_atomics,
24+
int64_extended_atomics,
25+
image,
26+
online_compiler,
27+
online_linker,
28+
queue_profiling,
29+
usm_device_allocations,
30+
usm_host_allocations,
31+
usm_shared_allocations,
32+
usm_restricted_shared_allocations,
33+
usm_system_allocator
34+
};
35+
36+
} // namespace sycl
37+
} // __SYCL_INLINE_NAMESPACE(cl)

sycl/include/CL/sycl/device.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#pragma once
1010

11+
#include <CL/sycl/aspects.hpp>
1112
#include <CL/sycl/backend_types.hpp>
1213
#include <CL/sycl/detail/common.hpp>
1314
#include <CL/sycl/detail/export.hpp>
@@ -179,6 +180,14 @@ class __SYCL_EXPORT device {
179180
return (typename interop<BackendName, device>::type)getNative();
180181
}
181182

183+
/// Indicates if the SYCL device has the given feature.
184+
///
185+
/// \param Aspect is one of the values in Table 4.20 of the SYCL 2020
186+
/// Provisional Spec.
187+
///
188+
/// \return true if the SYCL device has the given feature.
189+
bool has(aspect Aspect) const;
190+
182191
private:
183192
shared_ptr_class<detail::device_impl> impl;
184193
device(shared_ptr_class<detail::device_impl> impl) : impl(impl) {}

sycl/include/CL/sycl/platform.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,16 @@ class __SYCL_EXPORT platform {
116116
getNative());
117117
}
118118

119+
/// Indicates if all of the SYCL devices on this platform have the
120+
/// given feature.
121+
///
122+
/// \param Aspect is one of the values in Table 4.20 of the SYCL 2020
123+
/// Provisional Spec.
124+
///
125+
/// \return true if all of the SYCL devices on this platform have the
126+
/// given feature.
127+
bool has(aspect Aspect) const;
128+
119129
private:
120130
pi_native_handle getNative() const;
121131

sycl/source/detail/device_impl.cpp

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,9 @@ device_impl::device_impl(pi_native_handle InteropDeviceHandle,
5353

5454
RT::PiDevice parent = nullptr;
5555
// TODO catch an exception and put it to list of asynchronous exceptions
56-
Plugin.call<PiApiKind::piDeviceGetInfo>(
57-
MDevice, PI_DEVICE_INFO_PARENT_DEVICE, sizeof(RT::PiDevice), &parent, nullptr);
56+
Plugin.call<PiApiKind::piDeviceGetInfo>(MDevice, PI_DEVICE_INFO_PARENT_DEVICE,
57+
sizeof(RT::PiDevice), &parent,
58+
nullptr);
5859

5960
MIsRootDevice = (nullptr == parent);
6061
if (!MIsRootDevice && !InteroperabilityConstructor) {
@@ -181,13 +182,11 @@ device_impl::create_sub_devices(const vector_class<size_t> &Counts) const {
181182
"Partitioning to subdevices of the host device is not implemented yet",
182183
PI_INVALID_DEVICE);
183184

184-
if (!is_partition_supported(
185-
info::partition_property::partition_by_counts)) {
185+
if (!is_partition_supported(info::partition_property::partition_by_counts)) {
186186
throw cl::sycl::feature_not_supported();
187187
}
188188
static const cl_device_partition_property P[] = {
189-
CL_DEVICE_PARTITION_BY_COUNTS, CL_DEVICE_PARTITION_BY_COUNTS_LIST_END,
190-
0};
189+
CL_DEVICE_PARTITION_BY_COUNTS, CL_DEVICE_PARTITION_BY_COUNTS_LIST_END, 0};
191190
vector_class<cl_device_partition_property> Properties(P, P + 3);
192191
Properties.insert(Properties.begin() + 1, Counts.begin(), Counts.end());
193192
return create_sub_devices(Properties.data(), Counts.size());
@@ -210,8 +209,7 @@ vector_class<device> device_impl::create_sub_devices(
210209
const cl_device_partition_property Properties[3] = {
211210
CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN,
212211
(cl_device_partition_property)AffinityDomain, 0};
213-
size_t SubDevicesCount =
214-
get_info<info::device::partition_max_sub_devices>();
212+
size_t SubDevicesCount = get_info<info::device::partition_max_sub_devices>();
215213
return create_sub_devices(Properties, SubDevicesCount);
216214
}
217215

@@ -222,6 +220,38 @@ pi_native_handle device_impl::getNative() const {
222220
return Handle;
223221
}
224222

223+
bool device_impl::has(aspect Aspect) const {
224+
switch (Aspect) {
225+
case aspect::host:
226+
return is_host();
227+
case aspect::cpu:
228+
return is_cpu();
229+
case aspect::gpu:
230+
return is_gpu();
231+
case aspect::accelerator:
232+
return is_accelerator();
233+
case aspect::fp16:
234+
return has_extension("cl_khr_fp16");
235+
case aspect::fp64:
236+
return has_extension("cl_khr_fp64");
237+
case aspect::int64_base_atomics:
238+
return has_extension("cl_khr_int64_base_atomics");
239+
case aspect::int64_extended_atomics:
240+
return has_extension("cl_khr_int64_extended_atomics");
241+
case aspect::image:
242+
return get_info<info::device::image_support>();
243+
case aspect::online_compiler:
244+
return get_info<info::device::is_compiler_available>();
245+
case aspect::online_linker:
246+
return get_info<info::device::is_linker_available>();
247+
case aspect::queue_profiling:
248+
return get_info<info::device::queue_profiling>();
249+
default:
250+
throw runtime_error("This device aspect has not been implemented yet.",
251+
PI_INVALID_DEVICE);
252+
}
253+
}
254+
225255
} // namespace detail
226256
} // namespace sycl
227257
} // __SYCL_INLINE_NAMESPACE(cl)

sycl/source/detail/device_impl.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#pragma once
1010

11+
#include <CL/sycl/aspects.hpp>
1112
#include <CL/sycl/detail/pi.hpp>
1213
#include <CL/sycl/stl.hpp>
1314
#include <detail/device_info.hpp>
@@ -203,6 +204,14 @@ class device_impl {
203204
/// \return a native handle.
204205
pi_native_handle getNative() const;
205206

207+
/// Indicates if the SYCL device has the given feature.
208+
///
209+
/// \param Aspect is one of the values in Table 4.20 of the SYCL 2020
210+
/// Provisional Spec.
211+
//
212+
/// \return true if the SYCL device has the given feature.
213+
bool has(aspect Aspect) const;
214+
206215
private:
207216
explicit device_impl(pi_native_handle InteropDevice, RT::PiDevice Device,
208217
PlatformImplPtr Platform, const plugin &Plugin);

sycl/source/detail/platform_impl.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,16 @@ platform_impl::get_info() const {
298298
param>::get(this->getHandleRef(), getPlugin());
299299
}
300300

301+
// All devices on the platform must have the given aspect.
302+
bool platform_impl::has(aspect Aspect) const {
303+
for (const auto &dev : get_devices()) {
304+
if (dev.has(Aspect) == false) {
305+
return false;
306+
}
307+
}
308+
return true;
309+
}
310+
301311
#define PARAM_TRAITS_SPEC(param_type, param, ret_type) \
302312
template ret_type platform_impl::get_info<info::param_type::param>() const;
303313

sycl/source/detail/platform_impl.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,16 @@ class platform_impl {
127127
/// \return a native handle.
128128
pi_native_handle getNative() const;
129129

130+
/// Indicates if all of the SYCL devices on this platform have the
131+
/// given feature.
132+
///
133+
/// \param Aspect is one of the values in Table 4.20 of the SYCL 2020
134+
/// Provisional Spec.
135+
///
136+
/// \return true all of the SYCL devices on this platform have the
137+
/// given feature.
138+
bool has(aspect Aspect) const;
139+
130140
private:
131141
bool MHostPlatform = false;
132142
RT::PiPlatform MPlatform = 0;

sycl/source/device.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,5 +137,7 @@ device::get_info() const {
137137

138138
pi_native_handle device::getNative() const { return impl->getNative(); }
139139

140+
bool device::has(aspect Aspect) const { return impl->has(Aspect); }
141+
140142
} // namespace sycl
141143
} // __SYCL_INLINE_NAMESPACE(cl)

sycl/source/platform.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ platform::get_info() const {
5353

5454
pi_native_handle platform::getNative() const { return impl->getNative(); }
5555

56+
bool platform::has(aspect Aspect) const { return impl->has(Aspect); }
57+
5658
#define PARAM_TRAITS_SPEC(param_type, param, ret_type) \
5759
template __SYCL_EXPORT ret_type \
5860
platform::get_info<info::param_type::param>() const;

sycl/test/abi/sycl_symbols_linux.dump

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3927,6 +3927,7 @@ _ZNK2cl4sycl6device18create_sub_devicesILNS0_4info18partition_propertyE4230EEESt
39273927
_ZNK2cl4sycl6device18create_sub_devicesILNS0_4info18partition_propertyE4231EEESt6vectorIS1_SaIS1_EERKS5_ImSaImEE
39283928
_ZNK2cl4sycl6device18create_sub_devicesILNS0_4info18partition_propertyE4232EEESt6vectorIS1_SaIS1_EENS3_25partition_affinity_domainE
39293929
_ZNK2cl4sycl6device3getEv
3930+
_ZNK2cl4sycl6device3hasENS0_6aspectE
39303931
_ZNK2cl4sycl6device6is_cpuEv
39313932
_ZNK2cl4sycl6device6is_gpuEv
39323933
_ZNK2cl4sycl6device7is_hostEv
@@ -4071,6 +4072,7 @@ _ZNK2cl4sycl8platform11get_backendEv
40714072
_ZNK2cl4sycl8platform11get_devicesENS0_4info11device_typeE
40724073
_ZNK2cl4sycl8platform13has_extensionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
40734074
_ZNK2cl4sycl8platform3getEv
4075+
_ZNK2cl4sycl8platform3hasENS0_6aspectE
40744076
_ZNK2cl4sycl8platform7is_hostEv
40754077
_ZNK2cl4sycl8platform8get_infoILNS0_4info8platformE2304EEENS3_12param_traitsIS4_XT_EE11return_typeEv
40764078
_ZNK2cl4sycl8platform8get_infoILNS0_4info8platformE2305EEENS3_12param_traitsIS4_XT_EE11return_typeEv

sycl/test/basic_tests/aspects.cpp

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// RUN: %clangxx %s -o %t.out -I %sycl_include -lsycl
2+
// RUN: %t.out
3+
4+
//==--------------- aspects.cpp - SYCL device test ------------------------==//
5+
//
6+
// Returns the various aspects of a device and platform.
7+
//
8+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
9+
// See https://llvm.org/LICENSE.txt for license information.
10+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#include <CL/sycl.hpp>
15+
#include <iostream>
16+
17+
using namespace cl::sycl;
18+
19+
// platform::has() calls device::has() for each device on the platform.
20+
21+
int main() {
22+
bool failed = false;
23+
int pltIdx = 0;
24+
for (const auto &plt : platform::get_platforms()) {
25+
pltIdx++;
26+
if (plt.has(aspect::host)) {
27+
std::cout << "Platform #" << pltIdx
28+
<< " type: host supports:" << std::endl;
29+
} else if (plt.has(aspect::cpu)) {
30+
std::cout << "Platform #" << pltIdx
31+
<< " type: cpu supports:" << std::endl;
32+
} else if (plt.has(aspect::gpu)) {
33+
std::cout << "Platform #" << pltIdx
34+
<< " type: gpu supports:" << std::endl;
35+
} else if (plt.has(aspect::accelerator)) {
36+
std::cout << "Platform #" << pltIdx
37+
<< " type: accelerator supports:" << std::endl;
38+
} else {
39+
failed = true;
40+
std::cout << "Failed: platform #" << pltIdx << " type: unknown"
41+
<< std::endl;
42+
return 1;
43+
}
44+
45+
if (plt.has(aspect::fp16)) {
46+
std::cout << " fp16" << std::endl;
47+
}
48+
if (plt.has(aspect::fp64)) {
49+
std::cout << " fp64" << std::endl;
50+
}
51+
if (plt.has(aspect::int64_base_atomics)) {
52+
std::cout << " base atomic operations" << std::endl;
53+
}
54+
if (plt.has(aspect::int64_extended_atomics)) {
55+
std::cout << " extended atomic operations" << std::endl;
56+
}
57+
if (plt.has(aspect::image)) {
58+
std::cout << " images" << std::endl;
59+
}
60+
if (plt.has(aspect::online_compiler)) {
61+
std::cout << " online compiler" << std::endl;
62+
}
63+
if (plt.has(aspect::online_linker)) {
64+
std::cout << " online linker" << std::endl;
65+
}
66+
if (plt.has(aspect::queue_profiling)) {
67+
std::cout << " queue profiling" << std::endl;
68+
}
69+
}
70+
std::cout << "Passed." << std::endl;
71+
return 0;
72+
}

0 commit comments

Comments
 (0)