Skip to content

Commit 03c13fd

Browse files
authored
[SYCL][InvokeSimd] Add error for callee with struct return or argument (#10121)
It doesn't work at runtime even if we make it through the compiler because of an IGC issue. Once the IGC issue is fixed, we will need make some changes to the compiler and then lift this restriction. --------- Signed-off-by: Sarnie, Nick <[email protected]>
1 parent 76976a2 commit 03c13fd

File tree

3 files changed

+83
-0
lines changed

3 files changed

+83
-0
lines changed

sycl/include/sycl/ext/oneapi/experimental/invoke_simd.hpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,16 @@ constexpr bool has_ref_ret(Ret (*)(Args...)) {
364364
return std::is_reference_v<Ret>;
365365
}
366366

367+
template <typename Ret, typename... Args>
368+
constexpr bool has_struct_arg(Ret (*)(Args...)) {
369+
return (... || (std::is_class_v<Args> && !is_simd_or_mask_type<Args>::value));
370+
}
371+
372+
template <typename Ret, typename... Args>
373+
constexpr bool has_struct_ret(Ret (*)(Args...)) {
374+
return std::is_class_v<Ret> && !is_simd_or_mask_type<Ret>::value;
375+
}
376+
367377
template <typename Ret, typename... Args>
368378
constexpr bool has_non_trivially_copyable_uniform_ret(Ret (*)(Args...)) {
369379
return is_non_trivially_copyable_uniform_v<Ret>;
@@ -386,6 +396,16 @@ template <class Callable> constexpr void verify_callable() {
386396
static_assert(
387397
!callable_has_ref_arg,
388398
"invoke_simd does not support callables with reference arguments");
399+
#ifndef __INVOKE_SIMD_ENABLE_STRUCTS
400+
constexpr bool callable_has_struct_ret = has_struct_ret(obj);
401+
static_assert(
402+
!callable_has_struct_ret,
403+
"invoke_simd does not support callables returning structures");
404+
constexpr bool callable_has_struct_arg = has_struct_arg(obj);
405+
static_assert(
406+
!callable_has_struct_arg,
407+
"invoke_simd does not support callables with structure arguments");
408+
#endif
389409
#ifdef __SYCL_DEVICE_ONLY__
390410
constexpr bool callable_has_uniform_non_trivially_copyable_ret =
391411
has_non_trivially_copyable_uniform_ret(obj);
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// RUN: not %clangxx -fsycl -fsycl-device-only -S %s -o /dev/null 2>&1 | FileCheck %s
2+
#include <sycl/ext/oneapi/experimental/invoke_simd.hpp>
3+
#include <sycl/sycl.hpp>
4+
5+
using namespace sycl::ext::oneapi::experimental;
6+
using namespace sycl;
7+
namespace esimd = sycl::ext::intel::esimd;
8+
9+
[[intel::device_indirectly_callable]] std::tuple<simd<int, 4>, simd<int, 4>>
10+
callee(simd<int, 8>) {
11+
return std::make_tuple(simd<int, 4>(), simd<int, 4>());
12+
}
13+
14+
void foo() {
15+
constexpr unsigned Size = 1024;
16+
constexpr unsigned GroupSize = 64;
17+
sycl::range<1> GlobalRange{Size};
18+
sycl::range<1> LocalRange{GroupSize};
19+
sycl::nd_range<1> Range(GlobalRange, LocalRange);
20+
queue q;
21+
auto e = q.submit([&](handler &cgh) {
22+
cgh.parallel_for(Range, [=](nd_item<1> ndi) {
23+
auto x = invoke_simd(ndi.get_sub_group(), callee, 0);
24+
});
25+
});
26+
}
27+
28+
int main() {
29+
foo();
30+
// CHECK: {{.*}}error:{{.*}}static assertion failed due to requirement '!callable_has_struct_ret': invoke_simd does not support callables returning structures{{.*}}
31+
}

sycl/test/invoke_simd/struct-arg.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// RUN: not %clangxx -fsycl -fsycl-device-only -S %s -o /dev/null 2>&1 | FileCheck %s
2+
#include <sycl/ext/oneapi/experimental/invoke_simd.hpp>
3+
#include <sycl/sycl.hpp>
4+
5+
using namespace sycl::ext::oneapi::experimental;
6+
using namespace sycl;
7+
namespace esimd = sycl::ext::intel::esimd;
8+
9+
[[intel::device_indirectly_callable]] void
10+
callee(simd<int, 8>, std::tuple<simd<int, 4>, simd<int, 4>>) {
11+
return std::make_tuple(simd<int, 4>(), simd<int, 4>());
12+
}
13+
14+
void foo() {
15+
constexpr unsigned Size = 1024;
16+
constexpr unsigned GroupSize = 64;
17+
sycl::range<1> GlobalRange{Size};
18+
sycl::range<1> LocalRange{GroupSize};
19+
sycl::nd_range<1> Range(GlobalRange, LocalRange);
20+
queue q;
21+
auto e = q.submit([&](handler &cgh) {
22+
cgh.parallel_for(Range, [=](nd_item<1> ndi) {
23+
std::tuple<simd<int, 4>, simd<int, 4>> arg;
24+
invoke_simd(ndi.get_sub_group(), callee, 0, arg);
25+
});
26+
});
27+
}
28+
29+
int main() {
30+
foo();
31+
// CHECK: {{.*}}error:{{.*}}static assertion failed due to requirement '!callable_has_struct_arg': invoke_simd does not support callables with structure arguments{{.*}}
32+
}

0 commit comments

Comments
 (0)