Skip to content

Commit 2816c14

Browse files
authored
[SYCL] Implement atomic_memory_scope_capabilities device query for OpenCL and Level Zero (#8595)
Adds support to query devices for `atomic_memory_scope_capabilities`. The backends supported are OpenCL and Level Zero. For the rest of backends, it has been left unsupported. --------- Signed-off-by: Maronas, Marcos <[email protected]>
1 parent 8c9691a commit 2816c14

File tree

7 files changed

+151
-6
lines changed

7 files changed

+151
-6
lines changed

opencl/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ FetchContent_GetProperties(ocl-headers)
4444
set(OpenCL_INCLUDE_DIR
4545
${ocl-headers_SOURCE_DIR} CACHE PATH "Path to OpenCL Headers")
4646

47-
target_compile_definitions(Headers INTERFACE -DCL_TARGET_OPENCL_VERSION=220)
47+
target_compile_definitions(Headers INTERFACE -DCL_TARGET_OPENCL_VERSION=300)
4848
add_library(OpenCL-Headers ALIAS Headers)
4949

5050
# OpenCL Library (ICD Loader)

sycl/include/sycl/detail/cl.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
#pragma once
1010

1111
// Suppress a compiler message about undefined CL_TARGET_OPENCL_VERSION
12-
// and define all symbols up to OpenCL 2.2
12+
// and define all symbols up to OpenCL 3.0
1313
#ifndef CL_TARGET_OPENCL_VERSION
14-
#define CL_TARGET_OPENCL_VERSION 220
14+
#define CL_TARGET_OPENCL_VERSION 300
1515
#endif
1616

1717
#include <CL/cl.h>

sycl/plugins/esimd_emulator/pi_esimd_emulator.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -805,6 +805,7 @@ pi_result piDeviceGetInfo(pi_device Device, pi_device_info ParamName,
805805
CASE_PI_UNSUPPORTED(PI_DEVICE_INFO_IMAGE_SRGB)
806806
CASE_PI_UNSUPPORTED(PI_DEVICE_INFO_ATOMIC_64)
807807
CASE_PI_UNSUPPORTED(PI_DEVICE_INFO_ATOMIC_MEMORY_ORDER_CAPABILITIES)
808+
CASE_PI_UNSUPPORTED(PI_DEVICE_INFO_ATOMIC_MEMORY_SCOPE_CAPABILITIES)
808809
CASE_PI_UNSUPPORTED(PI_EXT_ONEAPI_DEVICE_INFO_MAX_GLOBAL_WORK_GROUPS)
809810
CASE_PI_UNSUPPORTED(PI_EXT_ONEAPI_DEVICE_INFO_MAX_WORK_GROUPS_1D)
810811
CASE_PI_UNSUPPORTED(PI_EXT_ONEAPI_DEVICE_INFO_MAX_WORK_GROUPS_2D)

sycl/plugins/opencl/pi_opencl.cpp

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,8 +283,68 @@ pi_result piDeviceGetInfo(pi_device device, pi_device_info paramName,
283283
// sycl/doc/extensions/supported/sycl_ext_intel_device_info.md
284284
case PI_DEVICE_INFO_UUID:
285285
case PI_DEVICE_INFO_ATOMIC_MEMORY_ORDER_CAPABILITIES:
286-
case PI_DEVICE_INFO_ATOMIC_MEMORY_SCOPE_CAPABILITIES:
287286
return PI_ERROR_INVALID_VALUE;
287+
case PI_DEVICE_INFO_ATOMIC_MEMORY_SCOPE_CAPABILITIES: {
288+
// Initialize result to minimum mandated capabilities according to
289+
// SYCL2020 4.6.3.2
290+
// Because scopes are hierarchical, wider scopes support all narrower
291+
// scopes. At a minimum, each device must support WORK_ITEM, SUB_GROUP and
292+
// WORK_GROUP. (https://github.com/KhronosGroup/SYCL-Docs/pull/382)
293+
pi_memory_scope_capabilities result = PI_MEMORY_SCOPE_WORK_ITEM |
294+
PI_MEMORY_SCOPE_SUB_GROUP |
295+
PI_MEMORY_SCOPE_WORK_GROUP;
296+
297+
OCLV::OpenCLVersion devVer;
298+
299+
cl_device_id deviceID = cast<cl_device_id>(device);
300+
cl_int ret_err = getDeviceVersion(deviceID, devVer);
301+
if (ret_err != CL_SUCCESS)
302+
return static_cast<pi_result>(ret_err);
303+
304+
cl_device_atomic_capabilities devCapabilities = 0;
305+
if (devVer >= OCLV::V3_0) {
306+
ret_err = clGetDeviceInfo(deviceID, CL_DEVICE_ATOMIC_MEMORY_CAPABILITIES,
307+
sizeof(cl_device_atomic_capabilities),
308+
&devCapabilities, nullptr);
309+
if (ret_err != CL_SUCCESS)
310+
return static_cast<pi_result>(ret_err);
311+
assert((devCapabilities & CL_DEVICE_ATOMIC_SCOPE_WORK_GROUP) &&
312+
"Violates minimum mandated guarantee");
313+
314+
// Because scopes are hierarchical, wider scopes support all narrower
315+
// scopes. At a minimum, each device must support WORK_ITEM, SUB_GROUP and
316+
// WORK_GROUP. (https://github.com/KhronosGroup/SYCL-Docs/pull/382)
317+
// We already initialized to these minimum mandated capabilities. Just
318+
// check wider scopes.
319+
if (devCapabilities & CL_DEVICE_ATOMIC_SCOPE_DEVICE) {
320+
result |= PI_MEMORY_SCOPE_DEVICE;
321+
}
322+
323+
if (devCapabilities & CL_DEVICE_ATOMIC_SCOPE_ALL_DEVICES) {
324+
result |= PI_MEMORY_SCOPE_SYSTEM;
325+
}
326+
327+
} else {
328+
// This info is only available in OpenCL version >= 3.0
329+
// Just return minimum mandated capabilities for older versions.
330+
// OpenCL 1.x minimum mandated capabilities are WORK_GROUP, we
331+
// already initialized using it.
332+
if (devVer >= OCLV::V2_0) {
333+
// OpenCL 2.x minimum mandated capabilities are WORK_GROUP | DEVICE |
334+
// ALL_DEVICES
335+
result |= PI_MEMORY_SCOPE_DEVICE | PI_MEMORY_SCOPE_SYSTEM;
336+
}
337+
}
338+
if (paramValue) {
339+
if (paramValueSize < sizeof(cl_device_atomic_capabilities))
340+
return PI_ERROR_INVALID_VALUE;
341+
342+
std::memcpy(paramValue, &result, sizeof(result));
343+
}
344+
if (paramValueSizeRet)
345+
*paramValueSizeRet = sizeof(result);
346+
return PI_SUCCESS;
347+
}
288348
case PI_DEVICE_INFO_ATOMIC_64: {
289349
cl_int ret_err = CL_SUCCESS;
290350
cl_bool result = CL_FALSE;

sycl/plugins/unified_runtime/ur/adapters/level_zero/ur_level_zero.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,9 +1173,19 @@ UR_APIEXPORT ur_result_t UR_APICALL urDeviceGetInfo(
11731173
// bfloat16 math functions are not yet supported on Intel GPUs.
11741174
return ReturnValue(bool{false});
11751175
}
1176+
case UR_DEVICE_INFO_ATOMIC_MEMORY_SCOPE_CAPABILITIES: {
1177+
// There are no explicit restrictions in L0 programming guide, so assume all
1178+
// are supported
1179+
ur_memory_scope_capability_flags_t result =
1180+
UR_MEMORY_SCOPE_CAPABILITY_FLAG_WORK_ITEM |
1181+
UR_MEMORY_SCOPE_CAPABILITY_FLAG_SUB_GROUP |
1182+
UR_MEMORY_SCOPE_CAPABILITY_FLAG_WORK_GROUP |
1183+
UR_MEMORY_SCOPE_CAPABILITY_FLAG_DEVICE |
1184+
UR_MEMORY_SCOPE_CAPABILITY_FLAG_SYSTEM;
1185+
1186+
return ReturnValue(result);
1187+
}
11761188

1177-
// TODO: Implement.
1178-
case UR_DEVICE_INFO_ATOMIC_MEMORY_SCOPE_CAPABILITIES:
11791189
default:
11801190
zePrint("Unsupported ParamName in piGetDeviceInfo\n");
11811191
zePrint("ParamName=%d(0x%x)\n", ParamName, ParamName);
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
//==-------- AtomicMemoryScopeCapabilities.cpp --- queue unit tests --------==//
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 <CL/sycl.hpp>
10+
#include <gtest/gtest.h>
11+
#include <helpers/PiMock.hpp>
12+
13+
using namespace sycl;
14+
15+
namespace {
16+
17+
thread_local bool deviceGetInfoCalled;
18+
19+
pi_platform PiPlatform = nullptr;
20+
21+
pi_result redefinedDeviceGetInfoAfter(pi_device device,
22+
pi_device_info param_name,
23+
size_t param_value_size,
24+
void *param_value,
25+
size_t *param_value_size_ret) {
26+
if (param_name == PI_DEVICE_INFO_ATOMIC_MEMORY_SCOPE_CAPABILITIES) {
27+
deviceGetInfoCalled = true;
28+
if (param_value) {
29+
auto *Result =
30+
reinterpret_cast<pi_memory_scope_capabilities *>(param_value);
31+
*Result = PI_MEMORY_SCOPE_WORK_ITEM | PI_MEMORY_SCOPE_SUB_GROUP |
32+
PI_MEMORY_SCOPE_WORK_GROUP | PI_MEMORY_SCOPE_DEVICE |
33+
PI_MEMORY_SCOPE_SYSTEM;
34+
}
35+
}
36+
return PI_SUCCESS;
37+
}
38+
39+
TEST(AtomicMemoryScopeCapabilitiesCheck, CheckAtomicMemoryScopeCapabilities) {
40+
sycl::unittest::PiMock Mock;
41+
sycl::platform Plt = Mock.getPlatform();
42+
43+
PiPlatform = detail::getSyclObjImpl(Plt)->getHandleRef();
44+
context DefaultCtx = Plt.ext_oneapi_get_default_context();
45+
device Dev = DefaultCtx.get_devices()[0];
46+
47+
deviceGetInfoCalled = false;
48+
49+
Mock.redefineAfter<detail::PiApiKind::piDeviceGetInfo>(
50+
redefinedDeviceGetInfoAfter);
51+
auto scope_capabilities =
52+
Dev.get_info<sycl::info::device::atomic_memory_scope_capabilities>();
53+
EXPECT_TRUE(deviceGetInfoCalled);
54+
size_t expectedSize = 5;
55+
EXPECT_EQ(scope_capabilities.size(), expectedSize);
56+
57+
auto res = std::find(scope_capabilities.begin(), scope_capabilities.end(),
58+
sycl::memory_scope::work_item);
59+
EXPECT_FALSE(res == scope_capabilities.end());
60+
res = std::find(scope_capabilities.begin(), scope_capabilities.end(),
61+
sycl::memory_scope::sub_group);
62+
EXPECT_FALSE(res == scope_capabilities.end());
63+
res = std::find(scope_capabilities.begin(), scope_capabilities.end(),
64+
sycl::memory_scope::work_group);
65+
EXPECT_FALSE(res == scope_capabilities.end());
66+
res = std::find(scope_capabilities.begin(), scope_capabilities.end(),
67+
sycl::memory_scope::device);
68+
EXPECT_FALSE(res == scope_capabilities.end());
69+
res = std::find(scope_capabilities.begin(), scope_capabilities.end(),
70+
sycl::memory_scope::system);
71+
EXPECT_FALSE(res == scope_capabilities.end());
72+
}
73+
} // anonymous namespace

sycl/unittests/SYCL2020/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@ add_sycl_unittest(SYCL2020Tests OBJECT
1010
IsCompatible.cpp
1111
DeviceGetInfoAspects.cpp
1212
DeviceAspectTraits.cpp
13+
AtomicMemoryScopeCapabilities.cpp
1314
)
1415

0 commit comments

Comments
 (0)