Skip to content

Commit c20712f

Browse files
authored
[SYCL][Graph] Implement dynamic local accessors (#18437)
- Implements the dynamic_local_accessor class with compiler support. - Refactor the recently added dynamic_work_group_memory class to only use one `impl` member variable. This brings it closer to the design of other sycl classes and avoids future ABI break issues. - There are 2 ABI breaking changes. However, they are both related to the `dynamic_work_group_memory` class whose [specification](#16712) has not been merged yet and is not yet officially supported.
1 parent 8500738 commit c20712f

File tree

22 files changed

+1083
-227
lines changed

22 files changed

+1083
-227
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1637,12 +1637,14 @@ def SYCLType: InheritableAttr {
16371637
let Subjects = SubjectList<[CXXRecord, Enum], ErrorDiag>;
16381638
let LangOpts = [SYCLIsDevice, SilentlyIgnoreSYCLIsHost];
16391639
let Args = [EnumArgument<"Type", "SYCLType", /*is_string=*/true,
1640-
["accessor", "local_accessor", "work_group_memory", "dynamic_work_group_memory",
1640+
["accessor", "local_accessor", "dynamic_local_accessor",
1641+
"work_group_memory", "dynamic_work_group_memory",
16411642
"specialization_id", "kernel_handler", "buffer_location",
16421643
"no_alias", "accessor_property_list", "group",
16431644
"private_memory", "aspect", "annotated_ptr", "annotated_arg",
16441645
"stream", "sampler", "host_pipe", "multi_ptr"],
1645-
["accessor", "local_accessor", "work_group_memory", "dynamic_work_group_memory",
1646+
["accessor", "local_accessor", "dynamic_local_accessor",
1647+
"work_group_memory", "dynamic_work_group_memory",
16461648
"specialization_id", "kernel_handler", "buffer_location",
16471649
"no_alias", "accessor_property_list", "group",
16481650
"private_memory", "aspect", "annotated_ptr", "annotated_arg",

clang/include/clang/Sema/SemaSYCL.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ class SYCLIntegrationHeader {
6464
kind_stream,
6565
kind_work_group_memory,
6666
kind_dynamic_work_group_memory,
67-
kind_last = kind_dynamic_work_group_memory
67+
kind_dynamic_accessor,
68+
kind_last = kind_dynamic_accessor
6869
};
6970

7071
public:

clang/lib/Sema/SemaSYCL.cpp

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,8 @@ bool SemaSYCL::isSyclType(QualType Ty, SYCLTypeAttr::SYCLType TypeName) {
9494

9595
static bool isSyclAccessorType(QualType Ty) {
9696
return SemaSYCL::isSyclType(Ty, SYCLTypeAttr::accessor) ||
97-
SemaSYCL::isSyclType(Ty, SYCLTypeAttr::local_accessor);
97+
SemaSYCL::isSyclType(Ty, SYCLTypeAttr::local_accessor) ||
98+
SemaSYCL::isSyclType(Ty, SYCLTypeAttr::dynamic_local_accessor);
9899
}
99100

100101
// FIXME: Accessor property lists should be modified to use compile-time
@@ -1151,7 +1152,8 @@ static QualType GetSYCLKernelObjectType(const FunctionDecl *KernelCaller) {
11511152
/// \return the target of given SYCL accessor type
11521153
static target getAccessTarget(QualType FieldTy,
11531154
const ClassTemplateSpecializationDecl *AccTy) {
1154-
if (SemaSYCL::isSyclType(FieldTy, SYCLTypeAttr::local_accessor))
1155+
if (SemaSYCL::isSyclType(FieldTy, SYCLTypeAttr::local_accessor) ||
1156+
SemaSYCL::isSyclType(FieldTy, SYCLTypeAttr::dynamic_local_accessor))
11551157
return local;
11561158

11571159
return static_cast<target>(
@@ -4815,7 +4817,13 @@ class SyclKernelIntHeaderCreator : public SyclKernelFieldHandler {
48154817
int Dims = static_cast<int>(
48164818
AccTy->getTemplateArgs()[1].getAsIntegral().getExtValue());
48174819
int Info = getAccessTarget(FieldTy, AccTy) | (Dims << 11);
4818-
Header.addParamDesc(SYCLIntegrationHeader::kind_accessor, Info,
4820+
4821+
SYCLIntegrationHeader::kernel_param_kind_t ParamKind =
4822+
SemaSYCL::isSyclType(FieldTy, SYCLTypeAttr::dynamic_local_accessor)
4823+
? SYCLIntegrationHeader::kind_dynamic_accessor
4824+
: SYCLIntegrationHeader::kind_accessor;
4825+
4826+
Header.addParamDesc(ParamKind, Info,
48194827
CurOffset +
48204828
offsetOf(RD, BC.getType()->getAsCXXRecordDecl()));
48214829
} else if (SemaSYCL::isSyclType(FieldTy, SYCLTypeAttr::work_group_memory)) {
@@ -4841,8 +4849,12 @@ class SyclKernelIntHeaderCreator : public SyclKernelFieldHandler {
48414849
AccTy->getTemplateArgs()[1].getAsIntegral().getExtValue());
48424850
int Info = getAccessTarget(FieldTy, AccTy) | (Dims << 11);
48434851

4844-
Header.addParamDesc(SYCLIntegrationHeader::kind_accessor, Info,
4845-
CurOffset + offsetOf(FD, FieldTy));
4852+
SYCLIntegrationHeader::kernel_param_kind_t ParamKind =
4853+
SemaSYCL::isSyclType(FieldTy, SYCLTypeAttr::dynamic_local_accessor)
4854+
? SYCLIntegrationHeader::kind_dynamic_accessor
4855+
: SYCLIntegrationHeader::kind_accessor;
4856+
4857+
Header.addParamDesc(ParamKind, Info, CurOffset + offsetOf(FD, FieldTy));
48464858
} else if (SemaSYCL::isSyclType(FieldTy, SYCLTypeAttr::stream)) {
48474859
addParam(FD, FieldTy, SYCLIntegrationHeader::kind_stream);
48484860
} else if (SemaSYCL::isSyclType(FieldTy, SYCLTypeAttr::work_group_memory)) {
@@ -6056,6 +6068,7 @@ static const char *paramKind2Str(KernelParamKind K) {
60566068
CASE(pointer);
60576069
CASE(work_group_memory);
60586070
CASE(dynamic_work_group_memory);
6071+
CASE(dynamic_accessor);
60596072
}
60606073
return "<ERROR>";
60616074

clang/test/CodeGenSYCL/Inputs/sycl.hpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,9 @@ local_accessor: public accessor<dataT,
440440
#ifdef __SYCL_DEVICE_ONLY__
441441
void __init(__attribute__((opencl_local)) dataT *Ptr, range<dimensions> AccessRange,
442442
range<dimensions> MemRange, id<dimensions> Offset) {}
443+
444+
template <typename, int>
445+
friend class dynamic_local_accessor;
443446
#endif
444447
};
445448

@@ -693,6 +696,23 @@ __SYCL_TYPE(dynamic_work_group_memory) dynamic_work_group_memory {
693696
work_group_memory<DataT> LocalMem;
694697
};
695698

699+
template <typename DataT, int Dimensions>
700+
class __attribute__((sycl_special_class))
701+
__SYCL_TYPE(dynamic_local_accessor) dynamic_local_accessor {
702+
public:
703+
dynamic_local_accessor() = default;
704+
705+
void __init(__attribute__((opencl_local)) DataT *Ptr,
706+
range<Dimensions> AccessRange, range<Dimensions> range,
707+
id<Dimensions> id) {
708+
this->LocalMem.__init(Ptr, AccessRange, range, id);
709+
}
710+
local_accessor<DataT, Dimensions> get() const { return LocalMem; }
711+
712+
private:
713+
local_accessor<DataT, Dimensions> LocalMem;
714+
};
715+
696716
template <typename T, int dimensions = 1,
697717
typename AllocatorT = int /*fake type as AllocatorT is not used*/>
698718
class buffer {
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// RUN: %clang_cc1 -fsycl-is-device -triple spir64-unknown-unknown -disable-llvm-passes -emit-llvm %s -o %t.ll
2+
// RUN: FileCheck < %t.ll %s --check-prefix CHECK-IR
3+
// RUN: %clang_cc1 -fsycl-is-device -triple spir64-unknown-unknown -fsycl-int-header=%t.h %s
4+
// RUN: FileCheck < %t.h %s --check-prefix CHECK-INT-HEADER
5+
//
6+
// Tests for dynamic_local_accessor kernel parameter using the dummy implementation in Inputs/sycl.hpp.
7+
// The first two RUN commands verify that the init call is generated with the correct arguments in LLVM IR
8+
// and the second two RUN commands verify the contents of the integration header produced by the frontend.
9+
//
10+
// CHECK-IR: define dso_local spir_kernel void @
11+
// CHECK-IR-SAME: ptr addrspace(3) noundef align 4 [[PTR:%[a-zA-Z0-9_]+]]
12+
//
13+
// CHECK-IR: [[PTR]].addr = alloca ptr addrspace(3), align 8
14+
// CHECK-IR: [[PTR]].addr.ascast = addrspacecast ptr [[PTR]].addr to ptr addrspace(4)
15+
// CHECK-IR: store ptr addrspace(3) [[PTR]], ptr addrspace(4) [[PTR]].addr.ascast, align 8
16+
// CHECK-IR: [[PTR_LOAD:%[a-zA-Z0-9_]+]] = load ptr addrspace(3), ptr addrspace(4) [[PTR]].addr.ascast, align 8
17+
//
18+
// CHECK-IR: call spir_func void @{{.*}}__init{{.*}}(ptr addrspace(4) noundef align 4 dereferenceable_or_null(24) %{{[a-zA-Z0-9_]+}}, ptr addrspace(3) noundef %{{[a-zA-Z0-9_]+}}, ptr noundef byval(%"struct.sycl::_V1::range") align 4 %agg.{{[a-zA-Z0-9_]+}}.ascast.ascast, ptr noundef byval(%"struct.sycl::_V1::range") align 4 %agg.{{[a-zA-Z0-9_]+}}.ascast.ascast, ptr noundef byval(%"struct.sycl::_V1::id") align 4 %agg.{{[a-zA-Z0-9_]+}}.ascast.ascast) #{{[0-9_]+}}
19+
//
20+
// CHECK-INT-HEADER: const kernel_param_desc_t kernel_signatures[] = {
21+
// CHECK-INT-HEADER-NEXT: //--- _ZTSZZ4mainENKUlRN4sycl3_V17handlerEE_clES2_EUlNS0_4itemILi1EEEE_
22+
// CHECK-INT-HEADER-NEXT: { kernel_param_kind_t::kind_dynamic_accessor, 4064, 0 },
23+
// CHECK-INT-HEADER-EMPTY:
24+
// CHECK-INT-HEADER-NEXT: { kernel_param_kind_t::kind_invalid, -987654321, -987654321 },
25+
// CHECK-INT-HEADER-NEXT: };
26+
27+
#include "Inputs/sycl.hpp"
28+
29+
int main() {
30+
sycl::queue Q;
31+
sycl::dynamic_local_accessor<int, 1> DynLocalAcc;
32+
Q.submit([&](sycl::handler &CGH) {
33+
sycl::range<1> ndr;
34+
CGH.parallel_for(ndr, [=](sycl::item<1> it) {
35+
auto LocalAcc = DynLocalAcc.get();
36+
auto* Ptr = &LocalAcc;
37+
});
38+
});
39+
return 0;
40+
}

sycl/include/sycl/accessor.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,10 @@ template <typename DataT, int Dimensions = 1,
227227
typename PropertyListT = ext::oneapi::accessor_property_list<>>
228228
class accessor;
229229

230+
namespace ext::oneapi::experimental {
231+
template <typename, int> class dynamic_local_accessor;
232+
}
233+
230234
namespace detail {
231235

232236
template <typename... Ts>
@@ -2638,6 +2642,8 @@ class __SYCL_EBO __SYCL_SPECIAL_CLASS __SYCL_TYPE(local_accessor) local_accessor
26382642

26392643
private:
26402644
friend class sycl::ext::intel::esimd::detail::AccessorPrivateProxy;
2645+
template <typename, int>
2646+
friend class ext::oneapi::experimental::dynamic_local_accessor;
26412647
};
26422648

26432649
template <typename DataT, int Dimensions = 1,

sycl/include/sycl/detail/kernel_desc.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ enum class kernel_param_kind_t {
6060
kind_stream = 5,
6161
kind_work_group_memory = 6,
6262
kind_dynamic_work_group_memory = 7,
63+
kind_dynamic_accessor = 8,
6364
kind_invalid = 0xf, // not a valid kernel kind
6465
};
6566

0 commit comments

Comments
 (0)