Skip to content

Commit d0d8a56

Browse files
NaghasansommerlukasAD2605maarquitos14callumfare
authored
Implement work_group_static / work_group_scratch_memory (#15061)
The patch partially implements `work_group_static` and update proposal. Implemented: - `work_group_static` to handle static allocation in kernel. - `get_dynamic_work_group_memory` to handle runtime allocation, but only on CUDA `work_group_static` is implemented by exposing `SYCLScope(WorkGroup)`, allowing the class to be decorated by the attribute and uses the same mechanism during lowering to place the variable in local memory. `get_dynamic_work_group_memory` uses a new builtin function, `__sycl_dynamicLocalMemoryPlaceholder `, which is lowered into referencing a 0 sized array GV when targeting NVPTX. The approach for SPIR will need to differ from this lowering. UR change oneapi-src/unified-runtime#1968, oneapi-src/unified-runtime#2403 --------- Signed-off-by: Lukas Sommer <[email protected]> Signed-off-by: Victor Lomuller <[email protected]> Co-authored-by: Lukas Sommer <[email protected]> Co-authored-by: Atharva Dubey <[email protected]> Co-authored-by: Marcos Maronas <[email protected]> Co-authored-by: Callum Fare <[email protected]> Co-authored-by: Martin Morrison-Grant <[email protected]>
1 parent 8a17167 commit d0d8a56

File tree

66 files changed

+1816
-388
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+1816
-388
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1682,12 +1682,12 @@ def SYCLIntelESimdVectorize : InheritableAttr {
16821682
}
16831683

16841684
def SYCLScope : Attr {
1685-
// No spelling, as this attribute can't be created in the source code.
1686-
let Spellings = [];
1685+
let Spellings = [CXX11<"__sycl_detail__", "wg_scope">];
16871686
let Args = [EnumArgument<"level", "Level", /*is_string=*/false,
16881687
["work_group", "work_item"],
1689-
["WorkGroup", "WorkItem"]>];
1690-
let Subjects = SubjectList<[Function, Var]>;
1688+
["WorkGroup", "WorkItem"],
1689+
/*optional=*/true>];
1690+
let Subjects = SubjectList<[Function, Var, CXXRecord]>;
16911691
let LangOpts = [SYCLIsDevice];
16921692

16931693
let AdditionalMembers = [{
@@ -1700,7 +1700,7 @@ def SYCLScope : Attr {
17001700
}
17011701
}];
17021702

1703-
let Documentation = [InternalOnly];
1703+
let Documentation = [SYCLWGScopeDocs];
17041704
}
17051705

17061706
def SYCLDeviceIndirectlyCallable : InheritableAttr {

clang/include/clang/Basic/AttrDocs.td

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4271,6 +4271,18 @@ function pointer for the specified function.
42714271
}];
42724272
}
42734273

4274+
def SYCLWGScopeDocs : Documentation {
4275+
let Category = DocCatFunction;
4276+
let Heading = "__sycl_detail__::wg_scope";
4277+
let Content = [{
4278+
This attribute can only be applied to records with a trivial default constructor and destructor.
4279+
Types with this attribute cannot be used for non-static data members.
4280+
It indicates that any block and namespace scope variable of a type holding this attribute
4281+
will be allocated in local memory. For variables allocated in block scope, they behave
4282+
as implicitly declared as static.
4283+
}];
4284+
}
4285+
42744286
def SYCLDeviceDocs : Documentation {
42754287
let Category = DocCatFunction;
42764288
let Heading = "sycl_device";

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12556,6 +12556,11 @@ def err_sycl_external_global : Error<
1255612556
def warn_sycl_kernel_too_big_args : Warning<
1255712557
"size of kernel arguments (%0 bytes) may exceed the supported maximum "
1255812558
"of %1 bytes on some devices">, InGroup<SyclStrict>, ShowInSystemHeader;
12559+
def err_sycl_wg_scope : Error<
12560+
"SYCL work group scope only applies to class with a trivial "
12561+
"%select{default constructor|destructor}0">;
12562+
def err_sycl_field_with_wg_scope : Error<
12563+
"non-static data member is of a type with a SYCL work group scope attribute applied to it">;
1255912564
def err_sycl_virtual_types : Error<
1256012565
"no class with a vtable can be used in a SYCL kernel or any code included in the kernel">;
1256112566
def note_sycl_recursive_function_declared_here: Note<"function implemented using recursion declared here">;

clang/include/clang/Sema/SemaSYCL.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ class SemaSYCL : public SemaBase {
267267

268268
void CheckSYCLKernelCall(FunctionDecl *CallerFunc,
269269
ArrayRef<const Expr *> Args);
270+
void CheckSYCLScopeAttr(CXXRecordDecl *Decl);
270271

271272
/// Creates a SemaDiagnosticBuilder that emits the diagnostic if the current
272273
/// context is "used as device code".
@@ -478,6 +479,7 @@ class SemaSYCL : public SemaBase {
478479
const ParsedAttr &AL);
479480
void handleSYCLIntelMaxWorkGroupsPerMultiprocessor(Decl *D,
480481
const ParsedAttr &AL);
482+
void handleSYCLScopeAttr(Decl *D, const ParsedAttr &AL);
481483

482484
void checkSYCLAddIRAttributesFunctionAttrConflicts(Decl *D);
483485

clang/lib/CodeGen/CGDecl.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,11 @@ void CodeGenFunction::EmitVarDecl(const VarDecl &D) {
217217
if (D.getType().getAddressSpace() == LangAS::opencl_local)
218218
return CGM.getOpenCLRuntime().EmitWorkGroupLocalVarDecl(*this, D);
219219

220-
if (D.getAttr<SYCLScopeAttr>() && D.getAttr<SYCLScopeAttr>()->isWorkGroup())
220+
SYCLScopeAttr *ScopeAttr = D.getAttr<SYCLScopeAttr>();
221+
if (!ScopeAttr)
222+
if (auto *RD = D.getType()->getAsCXXRecordDecl())
223+
ScopeAttr = RD->getAttr<SYCLScopeAttr>();
224+
if (ScopeAttr && ScopeAttr->isWorkGroup())
221225
return CGM.getSYCLRuntime().emitWorkGroupLocalVarDecl(*this, D);
222226

223227
assert(D.hasLocalStorage());

clang/lib/CodeGen/CGSYCLRuntime.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,10 @@ void CGSYCLRuntime::emitWorkGroupLocalVarDecl(CodeGenFunction &CGF,
9696
const VarDecl &D) {
9797
#ifndef NDEBUG
9898
SYCLScopeAttr *Scope = D.getAttr<SYCLScopeAttr>();
99-
assert(Scope && Scope->isWorkGroup() && "work group scope expected");
99+
if (!Scope)
100+
if (auto *RD = D.getType()->getAsCXXRecordDecl())
101+
Scope = RD->getAttr<SYCLScopeAttr>();
102+
assert((Scope && Scope->isWorkGroup()) && "work group scope expected");
100103
#endif // NDEBUG
101104
// generate global variable in the address space selected by the clang CodeGen
102105
// (should be local)

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5789,6 +5789,9 @@ LangAS CodeGenModule::GetGlobalVarAddressSpace(const VarDecl *D) {
57895789

57905790
if (LangOpts.SYCLIsDevice && D) {
57915791
auto *Scope = D->getAttr<SYCLScopeAttr>();
5792+
if (!Scope)
5793+
if (auto *RD = D->getType()->getAsCXXRecordDecl())
5794+
Scope = RD->getAttr<SYCLScopeAttr>();
57925795
if (Scope && Scope->isWorkGroup())
57935796
return LangAS::sycl_local;
57945797
}

clang/lib/Sema/Sema.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1849,7 +1849,9 @@ class DeferredDiagnosticsEmitter
18491849
if (!S.SYCL().checkAllowedSYCLInitializer(VD) &&
18501850
!S.SYCL()
18511851
.isTypeDecoratedWithDeclAttribute<
1852-
SYCLGlobalVariableAllowedAttr>(VD->getType())) {
1852+
SYCLGlobalVariableAllowedAttr>(VD->getType()) &&
1853+
!S.SYCL().isTypeDecoratedWithDeclAttribute<SYCLScopeAttr>(
1854+
VD->getType())) {
18531855
S.Diag(Loc, diag::err_sycl_restrict)
18541856
<< SemaSYCL::KernelConstStaticVariable;
18551857
return;

clang/lib/Sema/SemaDecl.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7876,6 +7876,8 @@ NamedDecl *Sema::ActOnVariableDeclarator(
78767876
// attribute.
78777877
if (SCSpec == DeclSpec::SCS_static && !R.isConstant(Context) &&
78787878
!SYCL().isTypeDecoratedWithDeclAttribute<SYCLGlobalVariableAllowedAttr>(
7879+
NewVD->getType()) &&
7880+
!SYCL().isTypeDecoratedWithDeclAttribute<SYCLScopeAttr>(
78797881
NewVD->getType()))
78807882
SYCL().DiagIfDeviceCode(D.getIdentifierLoc(), diag::err_sycl_restrict)
78817883
<< SemaSYCL::KernelNonConstStaticDataVariable;
@@ -18578,6 +18580,14 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
1857818580
InvalidDecl = true;
1857918581
}
1858018582

18583+
if (LangOpts.SYCLIsDevice) {
18584+
const CXXRecordDecl *RD = T->getAsCXXRecordDecl();
18585+
if (RD && RD->hasAttr<SYCLScopeAttr>()) {
18586+
Diag(Loc, diag::err_sycl_field_with_wg_scope);
18587+
InvalidDecl = true;
18588+
}
18589+
}
18590+
1858118591
if (LangOpts.OpenCL) {
1858218592
// OpenCL v1.2 s6.9b,r & OpenCL v2.0 s6.12.5 - The following types cannot be
1858318593
// used as structure or union field: image, sampler, event or block types.

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6717,6 +6717,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
67176717
case ParsedAttr::AT_SYCLDevice:
67186718
S.SYCL().handleSYCLDeviceAttr(D, AL);
67196719
break;
6720+
case ParsedAttr::AT_SYCLScope:
6721+
S.SYCL().handleSYCLScopeAttr(D, AL);
6722+
break;
67206723
case ParsedAttr::AT_SYCLDeviceIndirectlyCallable:
67216724
S.SYCL().handleSYCLDeviceIndirectlyCallableAttr(D, AL);
67226725
break;

0 commit comments

Comments
 (0)