Skip to content

[SYCL] Refactor stream class handing implementation #3646

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 34 commits into from
Jun 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
ade97f5
Stream handing implementation - PR2268
zahiraam Apr 28, 2021
9a60e02
Stream handing implementation - PR2268
zahiraam Apr 28, 2021
eb0b35d
Stream handing implementation - code from draft PR2268
zahiraam Apr 29, 2021
d9f7e79
Stream handing implementation - code from draft PR2268
zahiraam Apr 29, 2021
ac64f6f
Merge remote-tracking branch 'remote/sycl' into stream-class
zahiraam Apr 29, 2021
d504662
Adding finalize function
zahiraam Apr 29, 2021
cf327e5
Adding finalize function
zahiraam Apr 29, 2021
75d0e57
Review comments fixes
zahiraam May 3, 2021
a54e368
Merge remote-tracking branch 'remote/sycl' into stream-class
zahiraam May 3, 2021
afdc281
Review comments fixes
zahiraam May 4, 2021
63efc9d
Merge remote-tracking branch 'remote/sycl' into stream-class
zahiraam May 4, 2021
64544b9
Merge remote-tracking branch 'remote/sycl' into stream-class
zahiraam May 5, 2021
2bd73f4
Merge remote-tracking branch 'remote/sycl' into stream-class
zahiraam May 6, 2021
872f494
Review comments fixes
zahiraam May 6, 2021
e979fe1
Review comments fixes
zahiraam May 6, 2021
c3e0dcc
Review comments fixes
zahiraam May 6, 2021
45cd12f
Review comments fixes
zahiraam May 6, 2021
d2e42e5
Merge remote-tracking branch 'remote/sycl' into stream-class
zahiraam May 7, 2021
8dad222
Completed resolving conflict
zahiraam May 7, 2021
ea58203
Completed resolving conflict
zahiraam May 7, 2021
41f9f12
Fixed resolution conflict
zahiraam May 7, 2021
fe5935d
Merge remote-tracking branch 'remote/sycl' into stream-class
zahiraam May 17, 2021
98220c3
Fixed LIT test
zahiraam May 18, 2021
5a1355c
Merge remote-tracking branch 'remote/sycl' into stream-class
zahiraam May 18, 2021
4b7c9d9
Merge remote-tracking branch 'remote/sycl' into stream-class
zahiraam May 19, 2021
0fd8564
Merge remote-tracking branch 'remote/sycl' into stream-class
zahiraam May 25, 2021
1dbf04c
Fixing ESIMD test failures
zahiraam May 25, 2021
02e5c06
Merge remote-tracking branch 'remote/sycl' into stream-class
zahiraam May 25, 2021
d5f0fea
Fixing LIT failure
zahiraam May 25, 2021
ab02a86
Merge remote-tracking branch 'remote/sycl' into stream-class
zahiraam May 26, 2021
84dc696
Fix after review
zahiraam May 26, 2021
772cb8a
Merge remote-tracking branch 'remote/sycl' into stream-class
zahiraam May 27, 2021
59047b7
Fix after review and renamed SemaSYCL/streams.cpp to SemaSYCL/stream.cpp
zahiraam May 27, 2021
71d1c57
Merge remote-tracking branch 'remote/sycl' into stream-class
zahiraam May 27, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -11412,6 +11412,8 @@ def err_sycl_mismatch_group_size
"have a sub group size that matches the size specified for the "
"kernel">;
def note_sycl_kernel_declared_here : Note<"kernel declared here">;
def err_sycl_expected_finalize_method : Error<
"expected a 'finalize' method for the 'stream' class">;
def ext_sycl_2020_attr_spelling : ExtWarn<
"use of attribute %0 is a SYCL 2020 extension">,
InGroup<Sycl2017Compat>;
Expand Down
3 changes: 2 additions & 1 deletion clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,8 @@ class SYCLIntegrationHeader {
kind_sampler,
kind_pointer,
kind_specialization_constants_buffer,
kind_last = kind_specialization_constants_buffer
kind_stream,
kind_last = kind_stream
};

public:
Expand Down
113 changes: 13 additions & 100 deletions clang/lib/Sema/SemaSYCL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1034,23 +1034,6 @@ class KernelObjVisitor {
VisitRecordFields(Owner, Handlers...);
}

// FIXME: Can this be refactored/handled some other way?
template <typename ParentTy, typename... HandlerTys>
void visitStreamRecord(const CXXRecordDecl *Owner, ParentTy &Parent,
CXXRecordDecl *Wrapper, QualType RecordTy,
HandlerTys &... Handlers) {
(void)std::initializer_list<int>{
(Handlers.enterStream(Owner, Parent, RecordTy), 0)...};
for (const auto &Field : Wrapper->fields()) {
QualType FieldTy = Field->getType();
// Required to initialize accessors inside streams.
if (Util::isSyclAccessorType(FieldTy))
KF_FOR_EACH(handleSyclAccessorType, Field, FieldTy);
}
(void)std::initializer_list<int>{
(Handlers.leaveStream(Owner, Parent, RecordTy), 0)...};
}

template <typename... HandlerTys>
void visitArrayElementImpl(const CXXRecordDecl *Owner, FieldDecl *ArrayField,
QualType ElementTy, uint64_t Index,
Expand Down Expand Up @@ -1125,12 +1108,9 @@ class KernelObjVisitor {
KF_FOR_EACH(handleSyclHalfType, Field, FieldTy);
else if (Util::isSyclSpecConstantType(FieldTy))
KF_FOR_EACH(handleSyclSpecConstantType, Field, FieldTy);
else if (Util::isSyclStreamType(FieldTy)) {
CXXRecordDecl *RD = FieldTy->getAsCXXRecordDecl();
// Handle accessors in stream class.
else if (Util::isSyclStreamType(FieldTy))
KF_FOR_EACH(handleSyclStreamType, Field, FieldTy);
visitStreamRecord(Owner, Field, RD, FieldTy, Handlers...);
} else if (FieldTy->isStructureOrClassType()) {
else if (FieldTy->isStructureOrClassType()) {
if (KF_FOR_EACH(handleStructType, Field, FieldTy)) {
CXXRecordDecl *RD = FieldTy->getAsCXXRecordDecl();
visitRecord(Owner, Field, RD, FieldTy, Handlers...);
Expand Down Expand Up @@ -1244,12 +1224,6 @@ class SyclKernelFieldHandlerBase {
virtual bool leaveStruct(const CXXRecordDecl *, FieldDecl *, QualType) {
return true;
}
virtual bool enterStream(const CXXRecordDecl *, FieldDecl *, QualType) {
return true;
}
virtual bool leaveStream(const CXXRecordDecl *, FieldDecl *, QualType) {
return true;
}
virtual bool enterStruct(const CXXRecordDecl *, const CXXBaseSpecifier &,
QualType) {
return true;
Expand Down Expand Up @@ -1697,18 +1671,6 @@ class SyclKernelDecompMarker : public SyclKernelFieldHandler {
return true;
}

// Stream is always decomposed (and whether it gets decomposed is handled in
// handleSyclStreamType), but we need a CollectionStack entry to capture the
// accessors that get handled.
bool enterStream(const CXXRecordDecl *, FieldDecl *, QualType) final {
CollectionStack.push_back(false);
return true;
}
bool leaveStream(const CXXRecordDecl *, FieldDecl *, QualType Ty) final {
CollectionStack.pop_back();
return true;
}

bool enterStruct(const CXXRecordDecl *, FieldDecl *, QualType) final {
CollectionStack.push_back(false);
return true;
Expand Down Expand Up @@ -1956,14 +1918,6 @@ class SyclKernelDeclCreator : public SyclKernelFieldHandler {
SemaRef.addSyclDeviceDecl(KernelDecl);
}

bool enterStream(const CXXRecordDecl *RD, FieldDecl *FD, QualType Ty) final {
return enterStruct(RD, FD, Ty);
}

bool leaveStream(const CXXRecordDecl *RD, FieldDecl *FD, QualType Ty) final {
return leaveStruct(RD, FD, Ty);
}

bool enterStruct(const CXXRecordDecl *, FieldDecl *, QualType) final {
++StructDepth;
return true;
Expand Down Expand Up @@ -2099,8 +2053,7 @@ class SyclKernelDeclCreator : public SyclKernelFieldHandler {
}

bool handleSyclStreamType(FieldDecl *FD, QualType FieldTy) final {
addParam(FD, FieldTy);
return true;
return handleSpecialType(FD, FieldTy);
}

bool handleSyclStreamType(const CXXRecordDecl *, const CXXBaseSpecifier &,
Expand Down Expand Up @@ -2419,15 +2372,6 @@ class SyclOptReportCreator : public SyclKernelFieldHandler {
}

bool handleSyclStreamType(FieldDecl *FD, QualType FieldTy) final {
// For the current implementation of stream class, the Visitor 'handles'
// stream argument and then visits each accessor field in stream. Therefore
// handleSpecialType in this case only adds a single argument for stream.
// The arguments corresponding to accessors in stream are handled in
// handleSyclAccessorType. The opt-report therefore does not diffrentiate
// between the accessors in streams and accessors captured by SYCL kernel.
// Once stream API is modified to use __init(), the visitor will no longer
// visit the stream object and opt-report output for stream class will be
// similar to that of other special types.
return handleSpecialType(
FD, FieldTy, KernelArgDescription(KernelArgDescription::Stream));
}
Expand Down Expand Up @@ -2805,6 +2749,13 @@ class SyclKernelBodyCreator : public SyclKernelFieldHandler {

const auto *RecordDecl = Ty->getAsCXXRecordDecl();
createSpecialMethodCall(RecordDecl, getInitMethodName(), BodyStmts);
CXXMethodDecl *FinalizeMethod =
getMethodByName(RecordDecl, FinalizeMethodName);
// A finalize-method is expected for stream class.
if (!FinalizeMethod && Util::isSyclStreamType(Ty))
SemaRef.Diag(FD->getLocation(), diag::err_sycl_expected_finalize_method);
else
createSpecialMethodCall(RecordDecl, FinalizeMethodName, FinalizeStmts);

removeFieldMemberExpr(FD, Ty);

Expand Down Expand Up @@ -2898,9 +2849,7 @@ class SyclKernelBodyCreator : public SyclKernelFieldHandler {
}

bool handleSyclStreamType(FieldDecl *FD, QualType Ty) final {
// Streams just get copied as a new init.
addSimpleFieldInit(FD, Ty);
return true;
return handleSpecialType(FD, Ty);
}

bool handleSyclStreamType(const CXXRecordDecl *, const CXXBaseSpecifier &BS,
Expand Down Expand Up @@ -2977,31 +2926,6 @@ class SyclKernelBodyCreator : public SyclKernelFieldHandler {
handleSpecialType(KernelHandlerArg->getType());
}

bool enterStream(const CXXRecordDecl *RD, FieldDecl *FD, QualType Ty) final {
++StructDepth;
// Add a dummy init expression to catch the accessor initializers.
const auto *StreamDecl = Ty->getAsCXXRecordDecl();
CollectionInitExprs.push_back(createInitListExpr(StreamDecl));

addFieldMemberExpr(FD, Ty);
return true;
}

bool leaveStream(const CXXRecordDecl *RD, FieldDecl *FD, QualType Ty) final {
--StructDepth;
// Stream requires that its 'init' calls happen after its accessors init
// calls, so add them here instead.
const auto *StreamDecl = Ty->getAsCXXRecordDecl();

createSpecialMethodCall(StreamDecl, getInitMethodName(), BodyStmts);
createSpecialMethodCall(StreamDecl, FinalizeMethodName, FinalizeStmts);

removeFieldMemberExpr(FD, Ty);

CollectionInitExprs.pop_back();
return true;
}

bool enterStruct(const CXXRecordDecl *RD, FieldDecl *FD, QualType Ty) final {
++StructDepth;
addCollectionInitListExpr(Ty->getAsCXXRecordDecl());
Expand Down Expand Up @@ -3315,7 +3239,7 @@ class SyclKernelIntHeaderCreator : public SyclKernelFieldHandler {
}

bool handleSyclStreamType(FieldDecl *FD, QualType FieldTy) final {
addParam(FD, FieldTy, SYCLIntegrationHeader::kind_std_layout);
addParam(FD, FieldTy, SYCLIntegrationHeader::kind_stream);
return true;
}

Expand Down Expand Up @@ -3347,18 +3271,6 @@ class SyclKernelIntHeaderCreator : public SyclKernelFieldHandler {
SYCLIntegrationHeader::kind_specialization_constants_buffer, 0);
}

bool enterStream(const CXXRecordDecl *, FieldDecl *FD, QualType Ty) final {
++StructDepth;
CurOffset += offsetOf(FD, Ty);
return true;
}

bool leaveStream(const CXXRecordDecl *, FieldDecl *FD, QualType Ty) final {
--StructDepth;
CurOffset -= offsetOf(FD, Ty);
return true;
}

bool enterStruct(const CXXRecordDecl *, FieldDecl *FD, QualType Ty) final {
++StructDepth;
CurOffset += offsetOf(FD, Ty);
Expand Down Expand Up @@ -4160,6 +4072,7 @@ static const char *paramKind2Str(KernelParamKind K) {
CASE(accessor);
CASE(std_layout);
CASE(sampler);
CASE(stream);
CASE(specialization_constants_buffer);
CASE(pointer);
}
Expand Down
15 changes: 14 additions & 1 deletion clang/test/CodeGenSYCL/Inputs/sycl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ class accessor {
void __init(__attribute__((opencl_global)) dataT *Ptr, range<dimensions> AccessRange,
range<dimensions> MemRange, id<dimensions> Offset) {}
void __init_esimd(__attribute__((opencl_global)) dataT *Ptr) {}
friend class stream;
};

template <int dimensions, access::mode accessmode, access::target accesstarget>
Expand Down Expand Up @@ -411,10 +412,22 @@ class stream {
public:
stream(unsigned long BufferSize, unsigned long MaxStatementSize,
handler &CGH) {}
#ifdef __SYCL_DEVICE_ONLY__
// Default constructor for objects later initialized with __init member.
stream() = default;
#endif

void __init() {}
void __init(__attribute((opencl_global)) char *Ptr, range<1> AccessRange,
range<1> MemRange, id<1> Offset, int _FlushBufferSize) {
Acc.__init(Ptr, AccessRange, MemRange, Offset);
FlushBufferSize = _FlushBufferSize;
}

void __finalize() {}

private:
cl::sycl::accessor<char, 1, cl::sycl::access::mode::read_write> Acc;
int FlushBufferSize;
};

template <typename T>
Expand Down
22 changes: 18 additions & 4 deletions clang/test/CodeGenSYCL/stream.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
// RUN: %clang_cc1 -fsycl-is-device -triple spir64-unknown-unknown-sycldevice -disable-llvm-passes -emit-llvm %s -o %t.ll
// RUN: FileCheck < %t.ll --enable-var-scope %s
//
// CHECK: define {{.*}}spir_kernel void @"{{.*}}StreamTester"(%"{{.*}}cl::sycl::stream"* byval(%"{{.*}}cl::sycl::stream") {{.*}}){{.*}}
// CHECK: call spir_func void @{{.*}}__init{{.*}}(%{{.*}}cl::sycl::stream{{.*}} addrspace(4)* {{[^,]*}} %{{[0-9]+}})
// CHECK: call spir_func void @{{.*}}__finalize{{.*}}(%{{.*}}cl::sycl::stream{{.*}} addrspace(4)* {{[^,]*}} %{{[0-9]+}})
//
// CHECK: %[[RANGE_TYPE:"struct.*cl::sycl::range"]]
// CHECK: %[[ID_TYPE:"struct.*cl::sycl::id"]]

// CHECK: define dso_local spir_kernel void @{{.*}}StreamTester
// CHECK-SAME: i8 addrspace(1)* [[ACC_DATA:%[a-zA-Z0-9_]+]],
// CHECK-SAME: %[[RANGE_TYPE]]* byval(%[[RANGE_TYPE]]) align 4 [[ACC_RANGE1:%[a-zA-Z0-9_]+]],
// CHECK-SAME: %[[RANGE_TYPE]]* byval(%[[RANGE_TYPE]]) align 4 [[ACC_RANGE2:%[a-zA-Z0-9_]+]],
// CHECK-SAME: %[[ID_TYPE]]* byval(%[[ID_TYPE]]) align 4 [[ACC_ID:%[a-zA-Z0-9_]+]],
// CHECK-SAME: i32 [[ACC_INT:%[a-zA-Z0-9_]+]])

// Alloca and addrspace casts for kernel parameters
// CHECK: [[ARG:%[a-zA-Z0-9_]+]].addr = alloca i8 addrspace(1)*, align 8
// CHECK: [[ARG:%[a-zA-Z0-9_]+]].addr.ascast = addrspacecast i8 addrspace(1)** [[ARG]].addr to i8 addrspace(1)* addrspace(4)*
// CHECK: [[ARG_LOAD:%[a-zA-Z0-9_]+]] = load i8 addrspace(1)*, i8 addrspace(1)* addrspace(4)* [[ARG]].addr.ascast, align 8,

// Check __init and __finalize method calls
// CHECK: call spir_func void @{{.*}}__init{{.*}}(%{{.*}}cl::sycl::stream" addrspace(4)* align 4 dereferenceable_or_null(16) %4, i8 addrspace(1)* [[ARG_LOAD]], %[[RANGE_TYPE]]* byval(%[[RANGE_TYPE]]) {{.*}}%{{.*}}
// CHECK: call spir_func void @_ZN2cl4sycl6stream10__finalizeEv(%{{.*}}cl::sycl::stream" addrspace(4)* align 4 dereferenceable_or_null(16) %{{[0-9]+}})

#include "Inputs/sycl.hpp"

Expand Down
16 changes: 15 additions & 1 deletion clang/test/SemaSYCL/Inputs/sycl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ class accessor {
using PtrType = typename DeviceValueType<dataT, accessTarget>::type *;
void __init(PtrType Ptr, range<dimensions> AccessRange,
range<dimensions> MemRange, id<dimensions> Offset) {}
friend class stream;
};

template <int dimensions, access::mode accessmode, access::target accesstarget>
Expand Down Expand Up @@ -291,11 +292,24 @@ class stream {
public:
stream(unsigned long BufferSize, unsigned long MaxStatementSize,
handler &CGH) {}
#ifdef __SYCL_DEVICE_ONLY__
// Default constructor for objects later initialized with __init member.
stream() = default;
#endif

void __init(__attribute((opencl_global)) char *Ptr, range<1> AccessRange,
range<1> MemRange, id<1> Offset, int _FlushBufferSize) {
Acc.__init(Ptr, AccessRange, MemRange, Offset);
FlushBufferSize = _FlushBufferSize;
}

void __init() {}
void use() const {}

void __finalize() {}

private:
cl::sycl::accessor<char, 1, cl::sycl::access::mode::read_write> Acc;
int FlushBufferSize;
};

namespace ONEAPI {
Expand Down
5 changes: 2 additions & 3 deletions clang/test/SemaSYCL/decomposition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,13 +131,12 @@ int main() {
myQueue.submit([&](sycl::handler &h) {
h.single_task<class Stream1>([=]() { return t1.i; });
});
// CHECK: FunctionDecl {{.*}}Stream1{{.*}} 'void (sycl::stream, __global int *, sycl::range<1>, sycl::range<1>, sycl::id<1>, sycl::stream, __global int *, sycl::range<1>, sycl::range<1>, sycl::id<1>, sycl::stream, __global int *, sycl::range<1>, sycl::range<1>, sycl::id<1>, StructNonDecomposed, int)'

// CHECK: FunctionDecl {{.*}}Stream1{{.*}} 'void (__global char *, sycl::range<1>, sycl::range<1>, sycl::id<1>, int, __global char *, sycl::range<1>, sycl::range<1>, sycl::id<1>, int, __global char *, sycl::range<1>, sycl::range<1>, sycl::id<1>, int, StructNonDecomposed, int)'
DerivedStruct<StructWithStream> t2;
myQueue.submit([&](sycl::handler &h) {
h.single_task<class Stream2>([=]() { return t2.i; });
});
// CHECK: FunctionDecl {{.*}}Stream2{{.*}} 'void (sycl::stream, __global int *, sycl::range<1>, sycl::range<1>, sycl::id<1>, StructNonDecomposed, int)'
// CHECK: FunctionDecl {{.*}}Stream2{{.*}} 'void (__global char *, sycl::range<1>, sycl::range<1>, sycl::id<1>, int, StructNonDecomposed, int)'
}

{
Expand Down
Loading