Skip to content

Commit 4644e63

Browse files
[SYCL] Align get_info<info::device::version>() with the SYCL spec (#2507)
According to the SYCL spec, cl::sycl::info::device::version should be returned in a form: `<major_version>.<minor_version>` This patch trims the string returned from the piDeviceGetInfo call. For example, for the string "OpenCL 2.1 (Build 0)", it will return "2.1".
1 parent ba4e567 commit 4644e63

File tree

5 files changed

+85
-14
lines changed

5 files changed

+85
-14
lines changed

sycl/source/detail/device_info.hpp

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,9 @@ template <info::device param> struct get_device_info<platform, param> {
122122
}
123123
};
124124

125-
// Specialization for string return type, variable return size
126-
template <info::device param> struct get_device_info<string_class, param> {
125+
// Helper struct to allow using the specialization of get_device_info
126+
// for string return type in other specializations.
127+
template <info::device param> struct get_device_info_string {
127128
static string_class get(RT::PiDevice dev, const plugin &Plugin) {
128129
size_t resultSize;
129130
Plugin.call<PiApiKind::piDeviceGetInfo>(
@@ -140,6 +141,13 @@ template <info::device param> struct get_device_info<string_class, param> {
140141
}
141142
};
142143

144+
// Specialization for string return type, variable return size
145+
template <info::device param> struct get_device_info<string_class, param> {
146+
static string_class get(RT::PiDevice dev, const plugin &Plugin) {
147+
return get_device_info_string<param>::get(dev, Plugin);
148+
}
149+
};
150+
143151
// Specialization for parent device
144152
template <typename T> struct get_device_info<T, info::device::parent_device> {
145153
static T get(RT::PiDevice dev, const plugin &Plugin);
@@ -176,6 +184,30 @@ struct get_device_info<vector_class<info::fp_config>, param> {
176184
}
177185
};
178186

187+
// Specialization for OpenCL version, splits the string returned by OpenCL
188+
template <> struct get_device_info<string_class, info::device::version> {
189+
static string_class get(RT::PiDevice dev, const plugin &Plugin) {
190+
string_class result =
191+
get_device_info_string<info::device::version>::get(dev, Plugin);
192+
193+
// Extract OpenCL version from the returned string.
194+
// For example, for the string "OpenCL 2.1 (Build 0)"
195+
// return '2.1'.
196+
auto dotPos = result.find('.');
197+
if (dotPos == std::string::npos)
198+
return result;
199+
200+
auto leftPos = result.rfind(' ', dotPos);
201+
if (leftPos == std::string::npos)
202+
leftPos = 0;
203+
else
204+
leftPos++;
205+
206+
auto rightPos = result.find(' ', dotPos);
207+
return result.substr(leftPos, rightPos - leftPos);
208+
}
209+
};
210+
179211
// Specialization for single_fp_config, no type support check required
180212
template <>
181213
struct get_device_info<vector_class<info::fp_config>,

sycl/source/detail/error_handling/enqueue_kernel.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ bool handleInvalidWorkGroupSize(const device_impl &DeviceImpl, pi_kernel Kernel,
5757
if (Platform.get_backend() == cl::sycl::backend::opencl) {
5858
string_class VersionString = DeviceImpl.get_info<info::device::version>();
5959
IsOpenCL = true;
60-
IsOpenCLV1x = (VersionString.find("OpenCL 1.") == 0);
61-
IsOpenCLV20 = (VersionString.find("OpenCL 2.0") == 0);
60+
IsOpenCLV1x = (VersionString.find("1.") == 0);
61+
IsOpenCLV20 = (VersionString.find("2.0") == 0);
6262
}
6363

6464
size_t CompileWGSize[3] = {0};
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out
2+
// RUN: env SYCL_DEVICE_TYPE=HOST %t.out
3+
// RUN: env %CPU_RUN_PLACEHOLDER %t.out
4+
// RUN: env %GPU_RUN_PLACEHOLDER %t.out
5+
// RUN: env %ACC_RUN_PLACEHOLDER %t.out
6+
7+
//==--------info_ocl_version.cpp - SYCL objects get_info() test ------------==//
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+
#include <iostream>
17+
#include <regex>
18+
#include <string>
19+
20+
using namespace cl::sycl;
21+
22+
// This test checks that cl::sycl::info::device::version
23+
// is returned in a form: <major_version>.<minor_version>
24+
25+
int main() {
26+
default_selector selector;
27+
device dev(selector.select_device());
28+
auto ocl_version = dev.get_info<info::device::version>();
29+
std::cout << ocl_version << std::endl;
30+
const std::regex oclVersionRegex("[0-9]\\.[0-9]");
31+
if (!std::regex_match(ocl_version, oclVersionRegex)) {
32+
std::cout << "Failed" << std::endl;
33+
return 1;
34+
}
35+
std::cout << "Passed" << std::endl;
36+
return 0;
37+
}

sycl/test/basic_tests/parallel_for_range.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,18 @@ int main() {
3030
string_class DeviceVendorName = D.get_info<info::device::vendor>();
3131
auto DeviceType = D.get_info<info::device::device_type>();
3232

33+
const bool OCLBackend = D.get_platform().get_backend() == backend::opencl;
3334
string_class OCLVersionStr = D.get_info<info::device::version>();
34-
const bool OCLBackend = (OCLVersionStr.find("OpenCL") != string_class::npos);
35-
assert((!OCLBackend || (OCLVersionStr.size() >= 10)) &&
36-
"Unexpected device version string"); // strlen("OpenCL X.Y")
37-
const char *OCLVersion = &OCLVersionStr[7]; // strlen("OpenCL ")
35+
assert((OCLVersionStr.size() == 3) && "Unexpected device version string");
36+
assert(OCLVersionStr.find(".") != string_class::npos &&
37+
"Unexpected device version string");
38+
const char OCLVersionMajor = OCLVersionStr[0];
39+
const char OCLVersionMinor = OCLVersionStr[2];
3840

3941
// reqd_work_group_size is OpenCL specific.
4042
if (OCLBackend) {
41-
if (OCLVersion[0] == '1' ||
42-
(OCLVersion[0] == '2' && OCLVersion[2] == '0')) {
43+
if (OCLVersionMajor == '1' ||
44+
(OCLVersionMajor == '2' && OCLVersionMinor == '0')) {
4345
// parallel_for, (16, 16, 16) global, (8, 8, 8) local, reqd_wg_size(4, 4,
4446
// 4)
4547
// -> fail
@@ -143,7 +145,7 @@ int main() {
143145
}
144146
} // if (OCLBackend)
145147

146-
if (!OCLBackend || (OCLVersion[0] == '1')) {
148+
if (!OCLBackend || (OCLVersionMajor == '1')) {
147149
// OpenCL 1.x or non-OpenCL backends which behave like OpenCl 1.2 in SYCL.
148150

149151
// CL_INVALID_WORK_GROUP_SIZE if local_work_size is specified and
@@ -346,7 +348,7 @@ int main() {
346348
<< std::endl;
347349
return 1;
348350
}
349-
} else if (OCLBackend && (OCLVersion[0] == '2')) {
351+
} else if (OCLBackend && (OCLVersionMajor == '2')) {
350352
// OpenCL 2.x
351353

352354
// OpenCL 2.x:

sycl/test/plugins/sycl-ls-gpu-opencl.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
// RUN: env SYCL_BE=PI_OPENCL sycl-ls --verbose >%t.opencl.out
44
// RUN: FileCheck %s --check-prefixes=CHECK-GPU-BUILTIN,CHECK-GPU-CUSTOM --input-file %t.opencl.out
55

6-
// CHECK-GPU-BUILTIN: gpu_selector(){{.*}}GPU : OpenCL
7-
// CHECK-GPU-CUSTOM: custom_selector(gpu){{.*}}GPU : OpenCL
6+
// CHECK-GPU-BUILTIN: gpu_selector(){{.*}}GPU : {{[0-9]\.[0-9]}}
7+
// CHECK-GPU-CUSTOM: custom_selector(gpu){{.*}}GPU : {{[0-9]\.[0-9]}}
88

99
//==-- sycl-ls-gpu-opencl.cpp - SYCL test for discovered/selected devices -===//
1010
//

0 commit comments

Comments
 (0)