Skip to content

[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

Merged
merged 66 commits into from
May 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
b8835d1
Prototype for free functions.
rdeodhar Mar 1, 2024
e5864bb
Merge branch 'sycl' of https://github.com/intel/llvm into freefunc
rdeodhar Mar 1, 2024
776caa4
Reenabled an assert.
rdeodhar Mar 7, 2024
1bcbc38
Various enhancements.
rdeodhar Mar 26, 2024
dae3832
Merge branch 'sycl' of https://github.com/intel/llvm into freefunc
rdeodhar Mar 27, 2024
4c9a1ef
Merge branch 'sycl' of https://github.com/intel/llvm into freefunc
rdeodhar Mar 27, 2024
ec6f4f4
Fix for reordered attributes.
rdeodhar Mar 28, 2024
40fb9e7
Merge branch 'sycl' of https://github.com/intel/llvm into freefunc
rdeodhar Mar 28, 2024
1c98d08
Fixed merge error.
rdeodhar Mar 28, 2024
96b7666
Test fiex.
rdeodhar Mar 29, 2024
30e13a4
Remove unused code.
rdeodhar Mar 29, 2024
aebaec9
Formatting changes.
rdeodhar Mar 29, 2024
7f9a825
Formatting change.
rdeodhar Mar 29, 2024
fff52dc
Updated formatting, removed unneeded range_kernel property and update…
rdeodhar Apr 1, 2024
28ce5fb
Formatting change.
rdeodhar Apr 1, 2024
8c8cd01
Corrected test and added feature test macro.
rdeodhar Apr 2, 2024
8e6906b
Added a frontend test, updated end-to-end test.
rdeodhar Apr 4, 2024
78d884b
Merge branch 'sycl' of https://github.com/intel/llvm into freefunc
rdeodhar Apr 4, 2024
fd3bc83
Replaced a CodeGen test with an AST test.
rdeodhar Apr 4, 2024
3e61a19
Added CodeGen test.
rdeodhar Apr 4, 2024
f97a99d
Separated free function kernel BodyCreator from SYCL kernel BodyCreat…
rdeodhar Apr 9, 2024
c7acb89
Merge branch 'sycl' of https://github.com/intel/llvm into freefunc
rdeodhar Apr 9, 2024
369ea3a
Updated test and removed unused code.
rdeodhar Apr 9, 2024
4188d64
Formatting change.
rdeodhar Apr 9, 2024
b783416
Added some checking for unsupported types.
rdeodhar Apr 10, 2024
7ce6411
Removed some code realted to arrays.
rdeodhar Apr 10, 2024
721ca8e
Formatting change.
rdeodhar Apr 10, 2024
d058180
Fixed a problem dealing with casts in the tree transformer.
rdeodhar Apr 10, 2024
4a119dd
Changes based on reviewer comments.
rdeodhar Apr 15, 2024
d0fe5a3
Formatting change.
rdeodhar Apr 15, 2024
046d28a
Update test to temporarily test only on Linux.
rdeodhar Apr 16, 2024
440871c
Modified device code generation.
rdeodhar Apr 22, 2024
e8350a5
Merge branch 'sycl' of https://github.com/intel/llvm into freefunc
rdeodhar Apr 22, 2024
8ec09f1
Added error message for unsupported parameter types and minor cleanup.
rdeodhar Apr 22, 2024
bca0d25
Corrected diagnosing of unsupported parameter types.
rdeodhar Apr 23, 2024
5b74294
Removed support for simple structs because checking that a struct is …
rdeodhar Apr 24, 2024
73a4392
Fixed unintended format corrections.
rdeodhar Apr 24, 2024
f0ba17e
Merge branch 'sycl' of https://github.com/intel/llvm into freefunc
rdeodhar Apr 24, 2024
c35ec7f
Formatting changes.
rdeodhar Apr 24, 2024
6e87103
Removed some more unneeded code, now that structs will be supported l…
rdeodhar Apr 24, 2024
703b7cb
Added lvalue to rvalue casts.
rdeodhar Apr 25, 2024
7b0ae97
Formatting change.
rdeodhar Apr 25, 2024
d20fa73
Formatting change.
rdeodhar Apr 25, 2024
e0f8470
Reverted an argument name change that is not a part of this PR.
rdeodhar Apr 25, 2024
10d27ee
Changed name of free function kernel.
rdeodhar Apr 30, 2024
9c93370
Merge branch 'sycl' of https://github.com/intel/llvm into freefunc
rdeodhar May 1, 2024
9c0ee62
Correction to how function-address is taken.
rdeodhar May 1, 2024
cc44aaf
Changed kernel naming to account for non-templated but overloaded fun…
rdeodhar May 1, 2024
e186994
Restored a line that had been accidentally deleted.
rdeodhar May 1, 2024
c355219
Merge branch 'sycl' of https://github.com/intel/llvm into freefunc
rdeodhar May 3, 2024
5679870
Removed some more unneeded code.
rdeodhar May 3, 2024
8044a18
Minor changes.
rdeodhar May 5, 2024
fbf72b0
Added dependency in a test on USM shared allocations.
rdeodhar May 5, 2024
5ecceea
Now using a string manipulation scheme to generate the free function …
rdeodhar May 6, 2024
5e62a60
Correction to test for windows.
rdeodhar May 7, 2024
81b529d
Removed unneeded #include.
rdeodhar May 7, 2024
be4b4b2
Merge branch 'sycl' of https://github.com/intel/llvm into freefunc
rdeodhar May 8, 2024
a3cc690
Minor changes.
rdeodhar May 10, 2024
c38c74e
Changed kernel naming scheme.
rdeodhar May 11, 2024
53e1cc9
Merge branch 'sycl' of https://github.com/intel/llvm into freefunc
rdeodhar May 11, 2024
a4762de
Changed naming scheme and disabled testing on CUDA.
rdeodhar May 13, 2024
56ad051
Merge branch 'sycl' of https://github.com/intel/llvm into freefunc
rdeodhar May 13, 2024
19e58d7
Added a diagnostic for non-void free function.
rdeodhar May 14, 2024
ecda3d8
Added a comment.
rdeodhar May 14, 2024
10000f3
Removed some duplicate code, enhanced a comment.
rdeodhar May 14, 2024
5992d47
Merge branch 'sycl' of https://github.com/intel/llvm into freefunc
rdeodhar May 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions clang/include/clang/Sema/SemaSYCL.h
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@ class SemaSYCL : public SemaBase {
void ConstructOpenCLKernel(FunctionDecl *KernelCallerFunc, MangleContext &MC);
void SetSYCLKernelNames();
void MarkDevices();
void ProcessFreeFunction(FunctionDecl *FD);

/// Get the number of fields or captures within the parsed type.
ExprResult ActOnSYCLBuiltinNumFieldsExpr(ParsedType PT);
Expand Down
7 changes: 7 additions & 0 deletions clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16651,6 +16651,13 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
if (FD && !FD->isDeleted())
checkTypeSupport(FD->getType(), FD->getLocation(), FD);

// Handle free functions.
if (LangOpts.SYCLIsDevice && FD->hasAttr<SYCLDeviceAttr>() && Body &&
(FD->getTemplatedKind() == FunctionDecl::TK_NonTemplate ||
FD->getTemplatedKind() ==
FunctionDecl::TK_FunctionTemplateSpecialization))
SYCL().ProcessFreeFunction(FD);

return dcl;
}

Expand Down
813 changes: 783 additions & 30 deletions clang/lib/Sema/SemaSYCL.cpp

Large diffs are not rendered by default.

85 changes: 85 additions & 0 deletions clang/test/CodeGenSYCL/free_function_int_header.cpp
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: };
57 changes: 57 additions & 0 deletions clang/test/SemaSYCL/free_function_kernel_params.cpp
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>
// 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'
41 changes: 40 additions & 1 deletion sycl/include/sycl/ext/oneapi/kernel_properties/properties.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>...> {
Expand Down Expand Up @@ -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;

Expand All @@ -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,
Expand Down Expand Up @@ -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";
Expand All @@ -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 {};
Expand All @@ -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"}, \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this intended?

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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< \
Expand Down
4 changes: 3 additions & 1 deletion sycl/include/sycl/ext/oneapi/properties/property.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,10 @@ enum PropKind : uint32_t {
WorkGroupProgress = 62,
SubGroupProgress = 63,
WorkItemProgress = 64,
NDRangeKernel = 65,
SingleTaskKernel = 66,
// PropKindSize must always be the last value.
PropKindSize = 65,
PropKindSize = 67,
};

struct property_key_base_tag {};
Expand Down
1 change: 1 addition & 0 deletions sycl/source/feature_test.hpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ inline namespace _V1 {
#define SYCL_EXT_INTEL_FPGA_TASK_SEQUENCE 1
#define SYCL_EXT_ONEAPI_PRIVATE_ALLOCA 1
#define SYCL_EXT_ONEAPI_FORWARD_PROGRESS 1
#define SYCL_EXT_ONEAPI_FREE_FUNCTION_KERNELS 1

#ifndef __has_include
#define __has_include(x) 0
Expand Down
Loading