Skip to content

Commit b7a34be

Browse files
authored
[SYCL] Add handling for wrapped sampler (#1942)
This adds proper initialization for sampler object that is wrapped by a struct. This is temporary change because it contradicts the OpenCL and SPIR-V spec, since the struct with sampler opaque type field appears as kernel argument. We need it now to fix crashes in OpenCL backends.
1 parent 67fdb04 commit b7a34be

File tree

3 files changed

+42
-3
lines changed

3 files changed

+42
-3
lines changed

clang/lib/Sema/SemaSYCL.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -784,12 +784,14 @@ static void VisitField(CXXRecordDecl *Owner, RangeTy &&Item, QualType ItemTy,
784784
Handlers &... handlers) {
785785
if (Util::isSyclAccessorType(ItemTy))
786786
KF_FOR_EACH(handleSyclAccessorType, Item, ItemTy);
787-
if (Util::isSyclStreamType(ItemTy))
787+
else if (Util::isSyclStreamType(ItemTy))
788788
KF_FOR_EACH(handleSyclStreamType, Item, ItemTy);
789-
if (ItemTy->isStructureOrClassType())
789+
else if (Util::isSyclSamplerType(ItemTy))
790+
KF_FOR_EACH(handleSyclSamplerType, Item, ItemTy);
791+
else if (ItemTy->isStructureOrClassType())
790792
VisitAccessorWrapper(Owner, Item, ItemTy->getAsCXXRecordDecl(),
791793
handlers...);
792-
if (ItemTy->isArrayType())
794+
else if (ItemTy->isArrayType())
793795
VisitArrayElements(Item, ItemTy, handlers...);
794796
}
795797

@@ -892,6 +894,9 @@ template <typename Derived> class SyclKernelFieldHandler {
892894
return true;
893895
}
894896
virtual bool handleSyclAccessorType(FieldDecl *, QualType) { return true; }
897+
virtual bool handleSyclSamplerType(const CXXBaseSpecifier &, QualType) {
898+
return true;
899+
}
895900
virtual bool handleSyclSamplerType(FieldDecl *, QualType) { return true; }
896901
virtual bool handleSyclSpecConstantType(FieldDecl *, QualType) {
897902
return true;
@@ -1204,6 +1209,7 @@ class SyclKernelDeclCreator
12041209
return ArrayRef<ParmVarDecl *>(std::begin(Params) + LastParamIndex,
12051210
std::end(Params));
12061211
}
1212+
using SyclKernelFieldHandler::handleSyclSamplerType;
12071213
};
12081214

12091215
class SyclKernelBodyCreator
@@ -1458,6 +1464,7 @@ class SyclKernelBodyCreator
14581464
}
14591465

14601466
using SyclKernelFieldHandler::enterStruct;
1467+
using SyclKernelFieldHandler::handleSyclSamplerType;
14611468
using SyclKernelFieldHandler::leaveStruct;
14621469
};
14631470

@@ -1607,6 +1614,7 @@ class SyclKernelIntHeaderCreator
16071614
CurOffset -= Layout.getBaseClassOffset(BS.getType()->getAsCXXRecordDecl())
16081615
.getQuantity();
16091616
}
1617+
using SyclKernelFieldHandler::handleSyclSamplerType;
16101618
};
16111619
} // namespace
16121620

clang/test/CodeGenSYCL/sampler.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,20 @@
1111
// CHECK-NEXT: [[GEPCAST:%[0-9]+]] = addrspacecast %"class{{.*}}.cl::sycl::sampler"* [[GEP]] to %"class{{.*}}.cl::sycl::sampler" addrspace(4)*
1212
// CHECK-NEXT: call spir_func void @{{[a-zA-Z0-9_]+}}(%"class.{{.*}}.cl::sycl::sampler" addrspace(4)* [[GEPCAST]], %opencl.sampler_t addrspace(2)* [[LOAD_SAMPLER_ARG]])
1313
//
14+
15+
// CHECK: define spir_kernel void @{{[a-zA-Z0-9_]+}}(%struct{{.*}}sampler_wrapper{{.*}} %opencl.sampler_t addrspace(2)* [[SAMPLER_ARG_WRAPPED:%[a-zA-Z0-9_]+]])
16+
// CHECK: [[SAMPLER_ARG_WRAPPED]].addr = alloca %opencl.sampler_t addrspace(2)*, align 8
17+
// CHECK: store %opencl.sampler_t addrspace(2)* [[SAMPLER_ARG_WRAPPED]], %opencl.sampler_t addrspace(2)** [[SAMPLER_ARG_WRAPPED]].addr, align 8
18+
// CHECK: [[LOAD_SAMPLER_ARG_WRAPPED:%[0-9]+]] = load %opencl.sampler_t addrspace(2)*, %opencl.sampler_t addrspace(2)** [[SAMPLER_ARG_WRAPPED]].addr, align 8
19+
// CHECK: call spir_func void @{{[a-zA-Z0-9_]+}}(%"class.{{.*}}.cl::sycl::sampler" addrspace(4)* {{.*}}, %opencl.sampler_t addrspace(2)* [[LOAD_SAMPLER_ARG_WRAPPED]])
20+
//
1421
#include "sycl.hpp"
1522

23+
struct sampler_wrapper {
24+
cl::sycl::sampler smpl;
25+
int a;
26+
};
27+
1628
template <typename KernelName, typename KernelType>
1729
__attribute__((sycl_kernel)) void kernel_single_task(KernelType kernelFunc) {
1830
kernelFunc();
@@ -24,5 +36,10 @@ int main() {
2436
smplr.use();
2537
});
2638

39+
sampler_wrapper wrappedSampler = {smplr, 1};
40+
kernel_single_task<class second_kernel>([=]() {
41+
wrappedSampler.smpl.use();
42+
});
43+
2744
return 0;
2845
}

sycl/test/basic_tests/sampler/sampler.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,15 @@ namespace sycl {
2222
using namespace cl::sycl;
2323
}
2424

25+
struct SamplerWrapper {
26+
SamplerWrapper(sycl::coordinate_normalization_mode Norm,
27+
sycl::addressing_mode Addr, sycl::filtering_mode Filter)
28+
: Smpl(Norm, Addr, Filter), A(0) {}
29+
30+
sycl::sampler Smpl;
31+
int A;
32+
};
33+
2534
int main() {
2635
// Check constructor from enums
2736
sycl::sampler A(sycl::coordinate_normalization_mode::unnormalized,
@@ -88,13 +97,18 @@ int main() {
8897
assert(C == A);
8998
assert(Hasher(C) != Hasher(B));
9099

100+
SamplerWrapper WrappedSmplr(
101+
sycl::coordinate_normalization_mode::normalized,
102+
sycl::addressing_mode::repeat, sycl::filtering_mode::linear);
103+
91104
// Device sampler.
92105
{
93106
sycl::queue Queue;
94107
Queue.submit([&](sycl::handler &cgh) {
95108
cgh.single_task<class kernel>([=]() {
96109
sycl::sampler C = A;
97110
sycl::sampler D(C);
111+
sycl::sampler E(WrappedSmplr.Smpl);
98112
});
99113
});
100114
}

0 commit comments

Comments
 (0)