-
Notifications
You must be signed in to change notification settings - Fork 802
[ESIMD] SYCL device function cannot be called from ESIMD context #3511
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
Changes from all commits
904b81a
16a1d38
0253b80
ba430ce
47e5030
9372dc5
29c367b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,87 @@ | ||
| // RUN: %clang_cc1 -fsycl-is-device -fsyntax-only -verify %s | ||
|
|
||
| // This test checks that SYCL device functions cannot be called from ESIMD context. | ||
|
|
||
| __attribute__((sycl_device)) void sycl_func() {} | ||
| __attribute__((sycl_device)) void __spirv_reserved_func() {} | ||
| __attribute__((sycl_device)) void __sycl_reserved_func() {} | ||
| __attribute__((sycl_device)) void __other_reserved_func() {} | ||
|
|
||
| // -- Immediate diagnostic | ||
| __attribute__((sycl_device)) __attribute__((sycl_explicit_simd)) void esimd_func1() { | ||
| // expected-error@+1{{SYCL device function cannot be called from an ESIMD context}} | ||
| sycl_func(); | ||
| // Reserved SPIRV and SYCL functions are allowed | ||
| __spirv_reserved_func(); | ||
| __sycl_reserved_func(); | ||
| // expected-error@+1{{SYCL device function cannot be called from an ESIMD context}} | ||
| __other_reserved_func(); | ||
| } | ||
|
|
||
| // -- Deferred diagnostic | ||
| void foo() { | ||
| // expected-error@+1{{SYCL device function cannot be called from an ESIMD context}} | ||
| sycl_func(); | ||
| } | ||
|
|
||
| __attribute__((sycl_device)) __attribute__((sycl_explicit_simd)) void esimd_func2() { | ||
| // expected-note@+1{{called by}} | ||
| foo(); | ||
| } | ||
|
|
||
| // -- Class method | ||
| struct S { | ||
| __attribute__((sycl_device)) void sycl_func() {} | ||
| }; | ||
|
|
||
| __attribute__((sycl_device)) __attribute__((sycl_explicit_simd)) void esimd_func3() { | ||
| S s; | ||
| // expected-error@+1{{SYCL device function cannot be called from an ESIMD context}} | ||
| s.sycl_func(); | ||
| } | ||
|
|
||
| // -- Template function | ||
| template <typename Ty> | ||
| __attribute__((sycl_device)) void sycl_func() {} | ||
|
|
||
| __attribute__((sycl_device)) __attribute__((sycl_explicit_simd)) void esimd_func4() { | ||
| // expected-error@+1{{SYCL device function cannot be called from an ESIMD context}} | ||
| sycl_func<int>(); | ||
| } | ||
|
|
||
| // -- std::function | ||
| namespace std { | ||
| template <typename _Tp> | ||
| _Tp declval(); | ||
|
|
||
| template <typename _Functor, typename... _ArgTypes> | ||
| struct __res { | ||
| template <typename... _Args> | ||
| static decltype(declval<_Functor>()(_Args()...)) _S_test(int); | ||
|
|
||
| template <typename...> | ||
| static void _S_test(...); | ||
|
|
||
| typedef decltype(_S_test<_ArgTypes...>(0)) type; | ||
| }; | ||
|
|
||
| template <typename> | ||
| struct function; | ||
|
|
||
| template <typename _R, typename... _ArgTypes> | ||
| struct function<_R(_ArgTypes...)> { | ||
| template <typename _Functor, | ||
| typename = typename __res<_Functor, _ArgTypes...>::type> | ||
| __attribute__((sycl_device, sycl_explicit_simd)) function(_Functor) {} | ||
| __attribute__((sycl_device, sycl_explicit_simd)) _R operator()(_ArgTypes...) const; | ||
| }; | ||
| } // namespace std | ||
|
|
||
| __attribute__((sycl_device)) void sycl_func1() {} | ||
|
|
||
| __attribute__((sycl_device, sycl_explicit_simd)) void passthrough(std::function<void(void)> &&C) { C(); } | ||
|
|
||
| __attribute__((sycl_device)) __attribute__((sycl_explicit_simd)) void esimd_func5() { | ||
| // expected-error@+1{{SYCL device function cannot be called from an ESIMD context}} | ||
| passthrough(sycl_func1); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,17 +10,17 @@ | |
|
|
||
| #pragma once | ||
|
|
||
| /// \defgroup sycl_esimd DPC++ Explicit SIMD API | ||
|
|
||
| #include <CL/sycl/INTEL/esimd/esimd.hpp> | ||
| #include <CL/sycl/INTEL/esimd/esimd_math.hpp> | ||
| #include <CL/sycl/INTEL/esimd/esimd_memory.hpp> | ||
| #include <CL/sycl/INTEL/esimd/esimd_view.hpp> | ||
|
|
||
| #ifdef __SYCL_DEVICE_ONLY__ | ||
| #define SYCL_ESIMD_KERNEL __attribute__((sycl_explicit_simd)) | ||
| #define SYCL_ESIMD_FUNCTION __attribute__((sycl_explicit_simd)) | ||
| #else | ||
| #define SYCL_ESIMD_KERNEL | ||
| #define SYCL_ESIMD_FUNCTION | ||
| #endif | ||
|
|
||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This change is needed because |
||
| /// \defgroup sycl_esimd DPC++ Explicit SIMD API | ||
|
|
||
| #include <CL/sycl/INTEL/esimd/esimd.hpp> | ||
| #include <CL/sycl/INTEL/esimd/esimd_math.hpp> | ||
| #include <CL/sycl/INTEL/esimd/esimd_memory.hpp> | ||
| #include <CL/sycl/INTEL/esimd/esimd_view.hpp> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -64,11 +64,11 @@ | |
| // | ||
| template <typename T, int N, int M, int VStride, int Width, int Stride, | ||
| int ParentWidth = 0> | ||
| SYCL_EXTERNAL __SIGD::vector_type_t<T, M> | ||
| SYCL_EXTERNAL SYCL_ESIMD_FUNCTION __SIGD::vector_type_t<T, M> | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the suggested way to add function attributes is after the last ')' - @erichkeane, is it correct?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, that adds the attribute to the function type and not the function declaration.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What Aaron said! For an attribute to apply to the function declaration it needs to go on the left. See SYCL_EXTERNAL, which is a function declaration attribute.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see, thanks. We'll need to refactor examples and tests.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In a lambda, the only place you can currently put an attribute is in the type position (this was resolved for C++23 but SYCL can't require use of that yet, for obvious reasons). So: is the only place for it to go on a lambda for the moment. |
||
| __esimd_rdregion(__SIGD::vector_type_t<T, N> Input, uint16_t Offset); | ||
|
|
||
| template <typename T, int N, int M, int ParentWidth = 0> | ||
| SYCL_EXTERNAL __SIGD::vector_type_t<T, M> | ||
| SYCL_EXTERNAL SYCL_ESIMD_FUNCTION __SIGD::vector_type_t<T, M> | ||
| __esimd_rdindirect(__SIGD::vector_type_t<T, N> Input, | ||
| __SIGD::vector_type_t<uint16_t, M> Offset); | ||
|
|
||
|
|
@@ -121,13 +121,13 @@ __esimd_rdindirect(__SIGD::vector_type_t<T, N> Input, | |
| // | ||
| template <typename T, int N, int M, int VStride, int Width, int Stride, | ||
| int ParentWidth = 0> | ||
| SYCL_EXTERNAL __SIGD::vector_type_t<T, N> | ||
| SYCL_EXTERNAL SYCL_ESIMD_FUNCTION __SIGD::vector_type_t<T, N> | ||
| __esimd_wrregion(__SIGD::vector_type_t<T, N> OldVal, | ||
| __SIGD::vector_type_t<T, M> NewVal, uint16_t Offset, | ||
| sycl::INTEL::gpu::mask_type_t<M> Mask = 1); | ||
|
|
||
| template <typename T, int N, int M, int ParentWidth = 0> | ||
| SYCL_EXTERNAL __SIGD::vector_type_t<T, N> | ||
| SYCL_EXTERNAL SYCL_ESIMD_FUNCTION __SIGD::vector_type_t<T, N> | ||
| __esimd_wrindirect(__SIGD::vector_type_t<T, N> OldVal, | ||
| __SIGD::vector_type_t<T, M> NewVal, | ||
| __SIGD::vector_type_t<uint16_t, M> Offset, | ||
|
|
@@ -217,29 +217,32 @@ readRegion(const __SIGD::vector_type_t<BT, BN> &Base, std::pair<T, U> Region) { | |
| // optimization on simd object | ||
| // | ||
| template <typename T, int N> | ||
| SYCL_EXTERNAL __SIGD::vector_type_t<T, N> | ||
| SYCL_EXTERNAL SYCL_ESIMD_FUNCTION __SIGD::vector_type_t<T, N> | ||
| __esimd_vload(const __SIGD::vector_type_t<T, N> *ptr); | ||
|
|
||
| // vstore | ||
| // | ||
| // map to the backend vstore intrinsic, used by compiler to control | ||
| // optimization on simd object | ||
| template <typename T, int N> | ||
| SYCL_EXTERNAL void __esimd_vstore(__SIGD::vector_type_t<T, N> *ptr, | ||
| __SIGD::vector_type_t<T, N> vals); | ||
| SYCL_EXTERNAL SYCL_ESIMD_FUNCTION void | ||
| __esimd_vstore(__SIGD::vector_type_t<T, N> *ptr, | ||
| __SIGD::vector_type_t<T, N> vals); | ||
|
|
||
| template <typename T, int N> | ||
| SYCL_EXTERNAL uint16_t __esimd_any(__SIGD::vector_type_t<T, N> src); | ||
| SYCL_EXTERNAL SYCL_ESIMD_FUNCTION uint16_t | ||
| __esimd_any(__SIGD::vector_type_t<T, N> src); | ||
|
|
||
| template <typename T, int N> | ||
| SYCL_EXTERNAL uint16_t __esimd_all(__SIGD::vector_type_t<T, N> src); | ||
| SYCL_EXTERNAL SYCL_ESIMD_FUNCTION uint16_t | ||
| __esimd_all(__SIGD::vector_type_t<T, N> src); | ||
|
|
||
| #ifndef __SYCL_DEVICE_ONLY__ | ||
|
|
||
| // Implementations of ESIMD intrinsics for the SYCL host device | ||
| template <typename T, int N, int M, int VStride, int Width, int Stride, | ||
| int ParentWidth> | ||
| SYCL_EXTERNAL __SIGD::vector_type_t<T, M> | ||
| SYCL_EXTERNAL SYCL_ESIMD_FUNCTION __SIGD::vector_type_t<T, M> | ||
| __esimd_rdregion(__SIGD::vector_type_t<T, N> Input, uint16_t Offset) { | ||
| uint16_t EltOffset = Offset / sizeof(T); | ||
| assert(Offset % sizeof(T) == 0); | ||
|
|
@@ -258,7 +261,7 @@ __esimd_rdregion(__SIGD::vector_type_t<T, N> Input, uint16_t Offset) { | |
| } | ||
|
|
||
| template <typename T, int N, int M, int ParentWidth> | ||
| SYCL_EXTERNAL __SIGD::vector_type_t<T, M> | ||
| SYCL_EXTERNAL SYCL_ESIMD_FUNCTION __SIGD::vector_type_t<T, M> | ||
| __esimd_rdindirect(__SIGD::vector_type_t<T, N> Input, | ||
| __SIGD::vector_type_t<uint16_t, M> Offset) { | ||
| __SIGD::vector_type_t<T, M> Result; | ||
|
|
@@ -273,7 +276,7 @@ __esimd_rdindirect(__SIGD::vector_type_t<T, N> Input, | |
|
|
||
| template <typename T, int N, int M, int VStride, int Width, int Stride, | ||
| int ParentWidth> | ||
| SYCL_EXTERNAL __SIGD::vector_type_t<T, N> | ||
| SYCL_EXTERNAL SYCL_ESIMD_FUNCTION __SIGD::vector_type_t<T, N> | ||
| __esimd_wrregion(__SIGD::vector_type_t<T, N> OldVal, | ||
| __SIGD::vector_type_t<T, M> NewVal, uint16_t Offset, | ||
| sycl::INTEL::gpu::mask_type_t<M> Mask) { | ||
|
|
@@ -296,7 +299,7 @@ __esimd_wrregion(__SIGD::vector_type_t<T, N> OldVal, | |
| } | ||
|
|
||
| template <typename T, int N, int M, int ParentWidth> | ||
| SYCL_EXTERNAL __SIGD::vector_type_t<T, N> | ||
| SYCL_EXTERNAL SYCL_ESIMD_FUNCTION __SIGD::vector_type_t<T, N> | ||
| __esimd_wrindirect(__SIGD::vector_type_t<T, N> OldVal, | ||
| __SIGD::vector_type_t<T, M> NewVal, | ||
| __SIGD::vector_type_t<uint16_t, M> Offset, | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.