Skip to content

Commit 7f1a6ef

Browse files
author
Andrew Lamzed-Short
authored
[SYCL] Add support for has_extension free functions (#7059)
Implemented `has_extension` free functions defined in SYCL 2020 spec in `sycl::opencl` namespace: https://registry.khronos.org/SYCL/specs/sycl-2020/html/sycl-2020.html#_extension_query
1 parent fceaf94 commit 7f1a6ef

File tree

6 files changed

+116
-0
lines changed

6 files changed

+116
-0
lines changed

sycl/include/sycl/backend/opencl.hpp

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

1212
#include <sycl/backend.hpp>
1313

14+
#include <string>
15+
1416
namespace sycl {
1517
__SYCL_INLINE_VER_NAMESPACE(_V1) {
1618
namespace opencl {
@@ -25,6 +27,11 @@ __SYCL_EXPORT context make_context(pi_native_handle NativeHandle);
2527
__SYCL_EXPORT queue make_queue(const context &Context,
2628
pi_native_handle InteropHandle);
2729

30+
__SYCL_EXPORT bool has_extension(const sycl::platform &SyclPlatform,
31+
const std::string &Extension);
32+
__SYCL_EXPORT bool has_extension(const sycl::device &SyclDevice,
33+
const std::string &Extension);
34+
2835
// Construction of SYCL platform.
2936
template <typename T, typename detail::enable_if_t<
3037
std::is_same<T, platform>::value> * = nullptr>

sycl/source/backend/opencl.cpp

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
#include <detail/queue_impl.hpp>
1414
#include <sycl/sycl.hpp>
1515

16+
#include <memory>
17+
#include <string_view>
18+
1619
namespace sycl {
1720
__SYCL_INLINE_VER_NAMESPACE(_V1) {
1821
namespace opencl {
@@ -44,6 +47,70 @@ __SYCL_EXPORT queue make_queue(const context &Context,
4447
return detail::make_queue(NativeHandle, Context, nullptr, false,
4548
ContextImpl->get_async_handler(), backend::opencl);
4649
}
50+
51+
//----------------------------------------------------------------------------
52+
// Free functions to query OpenCL backend extensions
53+
__SYCL_EXPORT bool has_extension(const sycl::platform &SyclPlatform,
54+
const std::string &Extension) {
55+
if (SyclPlatform.get_backend() != sycl::backend::opencl) {
56+
throw sycl::exception(
57+
errc::backend_mismatch,
58+
"has_extension can only be used with an OpenCL backend");
59+
}
60+
61+
std::shared_ptr<sycl::detail::platform_impl> PlatformImpl =
62+
getSyclObjImpl(SyclPlatform);
63+
detail::RT::PiPlatform PluginPlatform = PlatformImpl->getHandleRef();
64+
const plugin &Plugin = PlatformImpl->getPlugin();
65+
66+
// Manual invocation of plugin API to avoid using deprecated
67+
// info::platform::extensions call.
68+
size_t ResultSize = 0;
69+
Plugin.call<PiApiKind::piPlatformGetInfo>(
70+
PluginPlatform, PI_PLATFORM_INFO_EXTENSIONS, /*param_value_size=*/0,
71+
/*param_value_size=*/nullptr, &ResultSize);
72+
if (ResultSize == 0)
73+
return false;
74+
75+
std::unique_ptr<char[]> Result(new char[ResultSize]);
76+
Plugin.call<PiApiKind::piPlatformGetInfo>(PluginPlatform,
77+
PI_PLATFORM_INFO_EXTENSIONS,
78+
ResultSize, Result.get(), nullptr);
79+
80+
std::string_view ExtensionsString(Result.get());
81+
return ExtensionsString.find(Extension) != std::string::npos;
82+
}
83+
84+
__SYCL_EXPORT bool has_extension(const sycl::device &SyclDevice,
85+
const std::string &Extension) {
86+
if (SyclDevice.get_backend() != sycl::backend::opencl) {
87+
throw sycl::exception(
88+
errc::backend_mismatch,
89+
"has_extension can only be used with an OpenCL backend");
90+
}
91+
92+
std::shared_ptr<sycl::detail::device_impl> DeviceImpl =
93+
getSyclObjImpl(SyclDevice);
94+
detail::RT::PiDevice PluginDevice = DeviceImpl->getHandleRef();
95+
const plugin &Plugin = DeviceImpl->getPlugin();
96+
97+
// Manual invocation of plugin API to avoid using deprecated
98+
// info::device::extensions call.
99+
size_t ResultSize = 0;
100+
Plugin.call<PiApiKind::piDeviceGetInfo>(
101+
PluginDevice, PI_DEVICE_INFO_EXTENSIONS, /*param_value_size=*/0,
102+
/*param_value_size=*/nullptr, &ResultSize);
103+
if (ResultSize == 0)
104+
return false;
105+
106+
std::unique_ptr<char[]> Result(new char[ResultSize]);
107+
Plugin.call<PiApiKind::piDeviceGetInfo>(PluginDevice,
108+
PI_DEVICE_INFO_EXTENSIONS, ResultSize,
109+
Result.get(), nullptr);
110+
111+
std::string_view ExtensionsString(Result.get());
112+
return ExtensionsString.find(Extension) != std::string::npos;
113+
}
47114
} // namespace opencl
48115
} // __SYCL_INLINE_VER_NAMESPACE(_V1)
49116
} // namespace sycl

sycl/test/abi/sycl_symbols_linux.dump

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3897,6 +3897,8 @@ _ZN4sycl3_V16mallocEmRKNS0_6deviceERKNS0_7contextENS0_3usm5allocERKNS0_6detail13
38973897
_ZN4sycl3_V16opencl10make_queueERKNS0_7contextEm
38983898
_ZN4sycl3_V16opencl11make_deviceEm
38993899
_ZN4sycl3_V16opencl12make_contextEm
3900+
_ZN4sycl3_V16opencl13has_extensionERKNS0_6deviceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
3901+
_ZN4sycl3_V16opencl13has_extensionERKNS0_8platformERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
39003902
_ZN4sycl3_V16opencl13make_platformEm
39013903
_ZN4sycl3_V16streamC1EmmRNS0_7handlerE
39023904
_ZN4sycl3_V16streamC1EmmRNS0_7handlerERKNS0_13property_listE

sycl/test/abi/sycl_symbols_windows.dump

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -914,6 +914,8 @@
914914
?hasUserDataPtr@SYCLMemObjT@detail@_V1@sycl@@QEBA_NXZ
915915
?has_context@exception@_V1@sycl@@QEBA_NXZ
916916
?has_extension@device@_V1@sycl@@QEBA_NAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z
917+
?has_extension@opencl@_V1@sycl@@YA_NAEBVdevice@23@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z
918+
?has_extension@opencl@_V1@sycl@@YA_NAEBVplatform@23@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z
917919
?has_extension@platform@_V1@sycl@@QEBA_NAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z
918920
?has_kernel@device_image_plain@detail@_V1@sycl@@QEBA_NAEBVkernel_id@34@@Z
919921
?has_kernel@device_image_plain@detail@_V1@sycl@@QEBA_NAEBVkernel_id@34@AEBVdevice@34@@Z

sycl/unittests/SYCL2020/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ add_sycl_unittest(SYCL2020Tests OBJECT
55
SpecializationConstant.cpp
66
KernelBundle.cpp
77
KernelID.cpp
8+
HasExtension.cpp
89
)
910

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//==---- HasExtension.cpp --- Spec constants default values unit test ------==//
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 <sycl/backend/opencl.hpp>
10+
#include <sycl/sycl.hpp>
11+
12+
#include <helpers/PiMock.hpp>
13+
14+
#include <gtest/gtest.h>
15+
16+
using namespace sycl;
17+
18+
TEST(HasExtensionID, HasExtensionCallsCorrectPluginMethods) {
19+
sycl::unittest::PiMock Mock;
20+
21+
sycl::platform Plt = Mock.getPlatform();
22+
sycl::device Dev = Plt.get_devices()[0];
23+
24+
bool PlatformHasSubgroups = opencl::has_extension(Plt, "cl_khr_subgroups");
25+
EXPECT_TRUE(PlatformHasSubgroups);
26+
27+
bool DeviceHasFP64 = opencl::has_extension(Dev, "cl_khr_fp64");
28+
EXPECT_TRUE(DeviceHasFP64);
29+
30+
bool PlatformNotHasErroneousExtension =
31+
opencl::has_extension(Plt, "test_for_unknown_platform_extension");
32+
EXPECT_FALSE(PlatformNotHasErroneousExtension);
33+
34+
bool DeviceNotHasErroneousExtension =
35+
opencl::has_extension(Dev, "test_for_unknown_device_extension");
36+
EXPECT_FALSE(DeviceNotHasErroneousExtension);
37+
}

0 commit comments

Comments
 (0)