Skip to content

Commit 6490076

Browse files
[SYCL-MLIR] Fix cast to sycl::detail::image_accessor (#8137)
There was segfault when handling: ``` ImplicitCastExpr 0x7ff1e72ca528 'class sycl::detail::image_accessor<class sycl::vec<float, 4>, 1, sycl::access::mode::read, sycl::access::target::image, sycl::access::placeholder::false_t> *' <UncheckedDerivedToBase (image_accessor)> `-CXXThisExpr 0x7ff1e72ca4a0 'class sycl::accessor<class sycl::vec<float, 4>, 1, sycl::access::mode::read, sycl::access::target::image, sycl::access::placeholder::false_t> *' this ``` There is no SYCL MLIR type for `sycl::detail::image_accessor`, so it is represented as a LLVM structure, and so the pointer of it is a LLVM pointer, instead of a memref. The code in `VisitCastExpr` incorrectly expects it to be a memref. `Plugin/enqueue-arg-order-image.cpp` passes on GPU after this PR. Signed-off-by: Tsang, Whitney <[email protected]>
1 parent a6c92a8 commit 6490076

File tree

2 files changed

+75
-25
lines changed

2 files changed

+75
-25
lines changed

polygeist/tools/cgeist/Lib/CGExpr.cc

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1498,31 +1498,32 @@ ValueCategory MLIRScanner::VisitCastExpr(CastExpr *E) {
14981498
}
14991499

15001500
if (auto UT = SE.val.getType().dyn_cast<mlir::MemRefType>()) {
1501-
auto MT = Glob.getTypes()
1502-
.getMLIRType(
1503-
(E->isLValue() || E->isXValue())
1504-
? Glob.getCGM().getContext().getLValueReferenceType(
1505-
E->getType())
1506-
: E->getType())
1507-
.dyn_cast<mlir::MemRefType>();
1508-
1509-
if (UT.getShape().size() != MT.getShape().size()) {
1510-
E->dump();
1511-
llvm::errs() << " se.val: " << SE.val << " ut: " << UT << " mt: " << MT
1512-
<< "\n";
1513-
}
1514-
assert(UT.getShape().size() == MT.getShape().size());
1515-
auto Ty = mlir::MemRefType::get(MT.getShape(), MT.getElementType(),
1516-
MemRefLayoutAttrInterface(),
1517-
UT.getMemorySpace());
1518-
if (Ty.getElementType().getDialect().getNamespace() ==
1519-
mlir::sycl::SYCLDialect::getDialectNamespace() &&
1520-
UT.getElementType().getDialect().getNamespace() ==
1521-
mlir::sycl::SYCLDialect::getDialectNamespace() &&
1522-
Ty.getElementType() != UT.getElementType()) {
1523-
return ValueCategory(
1524-
Builder.create<mlir::sycl::SYCLCastOp>(Loc, Ty, SE.val),
1525-
/*isReference*/ SE.isReference);
1501+
if (auto MT =
1502+
Glob.getTypes()
1503+
.getMLIRType(
1504+
(E->isLValue() || E->isXValue())
1505+
? Glob.getCGM().getContext().getLValueReferenceType(
1506+
E->getType())
1507+
: E->getType())
1508+
.dyn_cast<mlir::MemRefType>()) {
1509+
if (UT.getShape().size() != MT.getShape().size()) {
1510+
E->dump();
1511+
llvm::errs() << " se.val: " << SE.val << " ut: " << UT
1512+
<< " mt: " << MT << "\n";
1513+
}
1514+
assert(UT.getShape().size() == MT.getShape().size());
1515+
auto Ty = mlir::MemRefType::get(MT.getShape(), MT.getElementType(),
1516+
MemRefLayoutAttrInterface(),
1517+
UT.getMemorySpace());
1518+
if (Ty.getElementType().getDialect().getNamespace() ==
1519+
mlir::sycl::SYCLDialect::getDialectNamespace() &&
1520+
UT.getElementType().getDialect().getNamespace() ==
1521+
mlir::sycl::SYCLDialect::getDialectNamespace() &&
1522+
Ty.getElementType() != UT.getElementType()) {
1523+
return ValueCategory(
1524+
Builder.create<mlir::sycl::SYCLCastOp>(Loc, Ty, SE.val),
1525+
/*isReference*/ SE.isReference);
1526+
}
15261527
}
15271528
}
15281529

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// RUN: clang++ -fsycl -fsycl-device-only -O0 -w -emit-mlir -o - %s | FileCheck %s
2+
3+
#include <sycl/accessor.hpp>
4+
#include <sycl/sycl.hpp>
5+
6+
using namespace sycl;
7+
static constexpr unsigned N = 8;
8+
9+
// CHECK-LABEL: func.func @_ZN4sycl3_V18accessorINS0_3vecIfLi4EEELi1ELNS0_6access4modeE1024ELNS4_6targetE2017ELNS4_11placeholderE0ENS0_3ext6oneapi22accessor_property_listIJEEEE6__initE14ocl_image1d_ro(%arg0: memref<?x!sycl_accessor_1_21sycl2Evec3C5Bf322C_45D2C_28vector3C4xf323E293E_r_i, 4> {llvm.align = 8 : i64, llvm.dereferenceable_or_null = 32 : i64, llvm.noundef}, %arg1: !llvm.ptr<struct<"opencl.image1d_ro_t", opaque>, 1>)
10+
// CHECK-NEXT: %0 = "polygeist.memref2pointer"(%arg0) : (memref<?x!sycl_accessor_1_21sycl2Evec3C5Bf322C_45D2C_28vector3C4xf323E293E_r_i, 4>) -> !llvm.ptr<struct<(ptr<struct<"opencl.image1d_ro_t", opaque>, 1>, array<24 x i8>)>, 4>
11+
// CHECK-NEXT: sycl.call(%0, %arg1) {FunctionName = @imageAccessorInit, MangledFunctionName = @_ZN4sycl3_V16detail14image_accessorINS0_3vecIfLi4EEELi1ELNS0_6access4modeE1024ELNS5_6targetE2017ELNS5_11placeholderE0EE17imageAccessorInitE14ocl_image1d_ro, TypeName = @image_accessor} : (!llvm.ptr<struct<(ptr<struct<"opencl.image1d_ro_t", opaque>, 1>, array<24 x i8>)>, 4>, !llvm.ptr<struct<"opencl.image1d_ro_t", opaque>, 1>) -> ()
12+
// CHECK-NEXT: return
13+
// CHECK-NEXT: }
14+
15+
// CHECK-LABEL: func.func private @_ZZZ9testImagevENKUlRN4sycl3_V17handlerEE_clES2_ENKUlNS0_4itemILi1ELb1EEEE_clES5_(%arg0: memref<?x!llvm.struct<(!sycl_accessor_1_21sycl2Evec3C5Bf322C_45D2C_28vector3C4xf323E293E_r_i)>, 4> {llvm.align = 8 : i64, llvm.dereferenceable_or_null = 32 : i64, llvm.noundef}, %arg1: memref<?x!sycl_item_1_> {llvm.align = 8 : i64, llvm.byval = !sycl_item_1_, llvm.noundef})
16+
// CHECK-DAG: %c0_i32 = arith.constant 0 : i32
17+
// CHECK-DAG: %alloca = memref.alloca() : memref<1xi32>
18+
// CHECK-DAG: %0 = llvm.mlir.undef : i32
19+
// CHECK-NEXT: affine.store %0, %alloca[0] : memref<1xi32>
20+
// CHECK-NEXT: %1 = "polygeist.memref2pointer"(%arg0) : (memref<?x!llvm.struct<(!sycl_accessor_1_21sycl2Evec3C5Bf322C_45D2C_28vector3C4xf323E293E_r_i)>, 4>) -> !llvm.ptr<struct<(ptr<struct<"opencl.image1d_ro_t", opaque>, 1>, array<24 x i8>)>, 4>
21+
// CHECK-NEXT: %2 = affine.load %arg1[0] : memref<?x!sycl_item_1_>
22+
// CHECK-NEXT: %3 = "sycl.item.get_id"(%2, %c0_i32) {ArgumentTypes = [memref<?x!sycl_item_1_, 4>, i32], FunctionName = @"operator[]", MangledFunctionName = @_ZNK4sycl3_V14itemILi1ELb1EEixEi, TypeName = @item} : (!sycl_item_1_, i32) -> i64
23+
// CHECK-NEXT: %4 = arith.trunci %3 : i64 to i32
24+
// CHECK-NEXT: %5 = "polygeist.memref2pointer"(%alloca) : (memref<1xi32>) -> !llvm.ptr<i32>
25+
// CHECK-NEXT: %6 = llvm.addrspacecast %5 : !llvm.ptr<i32> to !llvm.ptr<i32, 4>
26+
// CHECK-NEXT: %7 = "polygeist.pointer2memref"(%6) : (!llvm.ptr<i32, 4>) -> memref<?xi32, 4>
27+
// CHECK-NEXT: llvm.store %4, %6 : !llvm.ptr<i32, 4>
28+
// CHECK-NEXT: %8 = sycl.call(%1, %7) {FunctionName = @read, MangledFunctionName = @_ZNK4sycl3_V16detail14image_accessorINS0_3vecIfLi4EEELi1ELNS0_6access4modeE1024ELNS5_6targetE2017ELNS5_11placeholderE0EE4readIiLi1EvEES4_RKT_, TypeName = @image_accessor} : (!llvm.ptr<struct<(ptr<struct<"opencl.image1d_ro_t", opaque>, 1>, array<24 x i8>)>, 4>, memref<?xi32, 4>) -> !sycl_vec_f32_4_
29+
// CHECK-NEXT: return
30+
// CHECK-NEXT: }
31+
32+
void testImage() {
33+
const image_channel_order ChanOrder = image_channel_order::rgba;
34+
const image_channel_type ChanType = image_channel_type::fp32;
35+
const range<1> ImgSize_1D(N);
36+
std::vector<float4> data_from_1D(ImgSize_1D.size(), {1, 2, 3, 4});
37+
38+
{
39+
image<1> image_from_1D(data_from_1D.data(), ChanOrder, ChanType, ImgSize_1D);
40+
queue Q;
41+
Q.submit([&](handler &CGH) {
42+
auto readAcc = image_from_1D.get_access<float4, access::mode::read>(CGH);
43+
CGH.parallel_for<class ReadImg>(
44+
ImgSize_1D, [=](item<1> Item) {
45+
float4 Data = readAcc.read(int(Item[0]));
46+
});
47+
});
48+
}
49+
}

0 commit comments

Comments
 (0)