-
Notifications
You must be signed in to change notification settings - Fork 789
[SYCL] Device code generation for "free functions", a new way to define kernels #13207
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
b8835d1
e5864bb
776caa4
1bcbc38
dae3832
4c9a1ef
ec6f4f4
40fb9e7
1c98d08
96b7666
30e13a4
aebaec9
7f9a825
fff52dc
28ce5fb
8c8cd01
8e6906b
78d884b
fd3bc83
3e61a19
f97a99d
c7acb89
369ea3a
4188d64
b783416
7ce6411
721ca8e
d058180
4a119dd
d0fe5a3
046d28a
440871c
e8350a5
8ec09f1
bca0d25
5b74294
73a4392
f0ba17e
c35ec7f
6e87103
703b7cb
7b0ae97
d20fa73
e0f8470
10d27ee
9c93370
9c0ee62
cc44aaf
e186994
c355219
5679870
8044a18
fbf72b0
5ecceea
5e62a60
81b529d
be4b4b2
a3cc690
c38c74e
53e1cc9
a4762de
56ad051
19e58d7
ecda3d8
10000f3
5992d47
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
// RUN: %clang_cc1 -fsycl-is-device -internal-isystem %S/Inputs -triple spir64-unknown-unknown -sycl-std=2020 -fsycl-int-header=%t.h %s | ||
// RUN: FileCheck -input-file=%t.h %s | ||
// | ||
// This test checks integration header contents for free functions with scalar | ||
// and pointer parameters. | ||
|
||
#include "mock_properties.hpp" | ||
#include "sycl.hpp" | ||
|
||
// First overload of function ff_2. | ||
__attribute__((sycl_device)) | ||
[[__sycl_detail__::add_ir_attributes_function("sycl-single-task-kernel", | ||
2)]] void | ||
ff_2(int *ptr, int start, int end) { | ||
for (int i = start; i <= end; i++) | ||
ptr[i] = start + 66; | ||
} | ||
|
||
// Second overload of function ff_2. | ||
__attribute__((sycl_device)) | ||
[[__sycl_detail__::add_ir_attributes_function("sycl-single-task-kernel", | ||
2)]] void | ||
ff_2(int* ptr, int start, int end, int value) { | ||
for (int i = start; i <= end; i++) | ||
ptr[i] = start + value; | ||
} | ||
|
||
// Templated definition of function ff_3. | ||
template <typename T> | ||
__attribute__((sycl_device)) | ||
[[__sycl_detail__::add_ir_attributes_function("sycl-nd-range-kernel", 2)]] void | ||
ff_3(T *ptr, T start, T end) { | ||
for (int i = start; i <= end; i++) | ||
ptr[i] = start; | ||
} | ||
|
||
// Explicit instantiation of ff_3 with int type. | ||
template void ff_3(int *ptr, int start, int end); | ||
|
||
// Explicit instantiation of ff_3 with float type. | ||
template void ff_3(float* ptr, float start, float end); | ||
|
||
// Specialization of ff_3 with double type. | ||
template <> void ff_3<double>(double *ptr, double start, double end) { | ||
for (int i = start; i <= end; i++) | ||
ptr[i] = end; | ||
} | ||
|
||
// CHECK: const char* const kernel_names[] = { | ||
// CHECK-NEXT: {{.*}}__sycl_kernel_ff_2Piii | ||
// CHECK-NEXT: {{.*}}__sycl_kernel_ff_2Piiii | ||
// CHECK-NEXT: {{.*}}__sycl_kernel_ff_3IiEvPT_S0_S0_ | ||
// CHECK-NEXT: {{.*}}__sycl_kernel_ff_3IfEvPT_S0_S0_ | ||
// CHECK-NEXT: {{.*}}__sycl_kernel_ff_3IdEvPT_S0_S0_ | ||
// CHECK-NEXT: }; | ||
|
||
// CHECK: const kernel_param_desc_t kernel_signatures[] = { | ||
// CHECK-NEXT: {{.*}}__sycl_kernel_ff_2Piii | ||
// CHECK-NEXT: { kernel_param_kind_t::kind_pointer, 8, 0 }, | ||
// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 8 }, | ||
// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 12 }, | ||
|
||
// CHECK: {{.*}}__sycl_kernel_ff_2Piiii | ||
// CHECK-NEXT: { kernel_param_kind_t::kind_pointer, 8, 0 }, | ||
// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 8 }, | ||
// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 12 }, | ||
// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 16 }, | ||
|
||
// CHECK: {{.*}}__sycl_kernel_ff_3IiEvPT_S0_S0_ | ||
// CHECK-NEXT: { kernel_param_kind_t::kind_pointer, 8, 0 }, | ||
// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 8 }, | ||
// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 12 }, | ||
|
||
// CHECK: {{.*}}__sycl_kernel_ff_3IfEvPT_S0_S0_ | ||
// CHECK-NEXT: { kernel_param_kind_t::kind_pointer, 8, 0 }, | ||
// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 8 }, | ||
// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 12 }, | ||
|
||
// CHECK: {{.*}}__sycl_kernel_ff_3IdEvPT_S0_S0_ | ||
// CHECK-NEXT: { kernel_param_kind_t::kind_pointer, 8, 0 }, | ||
// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 8, 8 }, | ||
// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 8, 16 }, | ||
|
||
// CHECK: { kernel_param_kind_t::kind_invalid, -987654321, -987654321 }, | ||
// CHECK-NEXT: }; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
// RUN: %clang_cc1 -internal-isystem %S/Inputs -fsycl-is-device -ast-dump \ | ||
// RUN: %s -o - | FileCheck %s | ||
// This test checks parameter rewriting for free functions with parameters | ||
// of type scalar and pointer. | ||
|
||
#include "sycl.hpp" | ||
|
||
__attribute__((sycl_device)) | ||
[[__sycl_detail__::add_ir_attributes_function("sycl-single-task-kernel", 0)]] | ||
void ff_2(int *ptr, int start, int end) { | ||
for (int i = start; i <= end; i++) | ||
ptr[i] = start; | ||
} | ||
// CHECK: FunctionDecl {{.*}}__sycl_kernel_{{.*}} 'void (__global int *, int, int)' | ||
// CHECK-NEXT: ParmVarDecl {{.*}} __arg_ptr '__global int *' | ||
// CHECK-NEXT: ParmVarDecl {{.*}} __arg_start 'int' | ||
// CHECK-NEXT: ParmVarDecl {{.*}} __arg_end 'int' | ||
// CHECK-NEXT: CompoundStmt | ||
// CHECK-NEXT: CallExpr {{.*}} 'void' | ||
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(int *, int, int)' <FunctionToPointerDecay> | ||
// CHECK-NEXT: DeclRefExpr {{.*}} 'void (int *, int, int)' lvalue Function {{.*}} 'ff_2' 'void (int *, int, int)' | ||
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int *' <AddressSpaceConversion> | ||
elizabethandrews marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// CHECK-NEXT: ImplicitCastExpr {{.*}} '__global int *' <LValueToRValue> | ||
// CHECK-NEXT: DeclRefExpr {{.*}} '__global int *' lvalue ParmVar {{.*}} '__arg_ptr' '__global int *' | ||
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' <LValueToRValue> | ||
// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} '__arg_start' 'int' | ||
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' <LValueToRValue> | ||
// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} '__arg_end' 'int' | ||
|
||
|
||
// Templated free function definition. | ||
template <typename T> | ||
__attribute__((sycl_device)) | ||
[[__sycl_detail__::add_ir_attributes_function("sycl-single-task-kernel", 0)]] | ||
void ff_3(T* ptr, T start, int end) { | ||
for (int i = start; i <= end; i++) | ||
ptr[i] = start; | ||
} | ||
|
||
// Explicit instantiation with "int*" | ||
template void ff_3(int* ptr, int start, int end); | ||
|
||
// CHECK: FunctionDecl {{.*}}__sycl_kernel_{{.*}} 'void (__global int *, int, int)' | ||
// CHECK-NEXT: ParmVarDecl {{.*}} __arg_ptr '__global int *' | ||
// CHECK-NEXT: ParmVarDecl {{.*}} __arg_start 'int' | ||
// CHECK-NEXT: ParmVarDecl {{.*}} __arg_end 'int' | ||
// CHECK-NEXT: CompoundStmt | ||
// CHECK-NEXT: CallExpr {{.*}} 'void' | ||
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(int *, int, int)' <FunctionToPointerDecay> | ||
// CHECK-NEXT: DeclRefExpr {{.*}} 'void (int *, int, int)' lvalue Function {{.*}} 'ff_3' 'void (int *, int, int)' | ||
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int *' <AddressSpaceConversion> | ||
// CHECK-NEXT: ImplicitCastExpr {{.*}} '__global int *' <LValueToRValue> | ||
// CHECK-NEXT: DeclRefExpr {{.*}} '__global int *' lvalue ParmVar {{.*}} '__arg_ptr' '__global int *' | ||
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' <LValueToRValue> | ||
// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} '__arg_start' 'int' | ||
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' <LValueToRValue> | ||
// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} '__arg_end' 'int' |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -61,6 +61,16 @@ struct device_has_key | |
std::integral_constant<aspect, Aspects>...>; | ||
}; | ||
|
||
struct nd_range_kernel_key { | ||
template <int Dims> | ||
using value_t = | ||
property_value<nd_range_kernel_key, std::integral_constant<int, Dims>>; | ||
}; | ||
|
||
struct single_task_kernel_key { | ||
using value_t = property_value<single_task_kernel_key>; | ||
}; | ||
|
||
template <size_t Dim0, size_t... Dims> | ||
struct property_value<work_group_size_key, std::integral_constant<size_t, Dim0>, | ||
std::integral_constant<size_t, Dims>...> { | ||
|
@@ -113,6 +123,21 @@ struct property_value<device_has_key, | |
static constexpr std::array<aspect, sizeof...(Aspects)> value{Aspects...}; | ||
}; | ||
|
||
template <int Dims> | ||
struct property_value<nd_range_kernel_key, std::integral_constant<int, Dims>> { | ||
static_assert( | ||
Dims >= 1 && Dims <= 3, | ||
"nd_range_kernel_key property must use dimension of 1, 2 or 3."); | ||
|
||
using key_t = nd_range_kernel_key; | ||
using value_t = int; | ||
static constexpr int dimensions = Dims; | ||
}; | ||
|
||
template <> struct property_value<single_task_kernel_key> { | ||
using key_t = single_task_kernel_key; | ||
}; | ||
|
||
template <size_t Dim0, size_t... Dims> | ||
inline constexpr work_group_size_key::value_t<Dim0, Dims...> work_group_size; | ||
|
||
|
@@ -126,6 +151,11 @@ inline constexpr sub_group_size_key::value_t<Size> sub_group_size; | |
template <aspect... Aspects> | ||
inline constexpr device_has_key::value_t<Aspects...> device_has; | ||
|
||
template <int Dims> | ||
inline constexpr nd_range_kernel_key::value_t<Dims> nd_range_kernel; | ||
|
||
inline constexpr single_task_kernel_key::value_t single_task_kernel; | ||
|
||
struct work_group_progress_key | ||
: detail::compile_time_property_key<detail::PropKind::WorkGroupProgress> { | ||
template <forward_progress_guarantee Guarantee, | ||
|
@@ -209,6 +239,7 @@ template <> struct is_property_key<sub_group_progress_key> : std::true_type {}; | |
template <> struct is_property_key<work_item_progress_key> : std::true_type {}; | ||
|
||
namespace detail { | ||
|
||
template <size_t Dim0, size_t... Dims> | ||
struct PropertyMetaInfo<work_group_size_key::value_t<Dim0, Dims...>> { | ||
static constexpr const char *name = "sycl-work-group-size"; | ||
|
@@ -230,6 +261,15 @@ struct PropertyMetaInfo<device_has_key::value_t<Aspects...>> { | |
static constexpr const char *value = | ||
SizeListToStr<static_cast<size_t>(Aspects)...>::value; | ||
}; | ||
template <int Dims> | ||
struct PropertyMetaInfo<nd_range_kernel_key::value_t<Dims>> { | ||
static constexpr const char *name = "sycl-nd-range-kernel"; | ||
static constexpr int value = Dims; | ||
}; | ||
template <> struct PropertyMetaInfo<single_task_kernel_key::value_t> { | ||
static constexpr const char *name = "sycl-single-task-kernel"; | ||
static constexpr int value = 0; | ||
}; | ||
|
||
template <typename T, typename = void> | ||
struct HasKernelPropertiesGetMethod : std::false_type {}; | ||
|
@@ -251,7 +291,6 @@ struct HasKernelPropertiesGetMethod<T, | |
#ifdef __SYCL_DEVICE_ONLY__ | ||
#define SYCL_EXT_ONEAPI_FUNCTION_PROPERTY(PROP) \ | ||
[[__sycl_detail__::add_ir_attributes_function( \ | ||
{"sycl-device-has"}, \ | ||
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. Is this intended? 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. Yes, multiple function attributes can now be specified and this string is not needed. |
||
sycl::ext::oneapi::experimental::detail::PropertyMetaInfo< \ | ||
std::remove_cv_t<std::remove_reference_t<decltype(PROP)>>>::name, \ | ||
sycl::ext::oneapi::experimental::detail::PropertyMetaInfo< \ | ||
|
Uh oh!
There was an error while loading. Please reload this page.