Skip to content

[SYCL] Provide separate compilation support for free function kernels #18955

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 47 commits into from
Jul 1, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
34a11ca
Provide supports for decomposable structs
lbushi25 May 28, 2025
edec2b4
Merge branch 'sycl' of https://github.com/lbushi25/llvm into sycl
lbushi25 May 28, 2025
c9680a2
Revert "Provide supports for decomposable structs"
lbushi25 Jun 3, 2025
b932fe6
Merge branch 'sycl' of https://github.com/lbushi25/llvm into sycl
lbushi25 Jun 3, 2025
6b6da56
Merge branch 'sycl' of https://github.com/lbushi25/llvm into sycl
lbushi25 Jun 10, 2025
a90c277
Provide separate compilation for free function kernels
lbushi25 Jun 12, 2025
f1e77e9
Update SemaSYCL.cpp
lbushi25 Jun 12, 2025
99d9786
Update SemaSYCL.cpp
lbushi25 Jun 12, 2025
fa27639
Update SemaSYCL.cpp
lbushi25 Jun 12, 2025
7d91bdf
Update SemaSYCL.cpp
lbushi25 Jun 12, 2025
fd73179
Update SemaSYCL.cpp
lbushi25 Jun 12, 2025
c4b3eda
Update SemaSYCL.cpp
lbushi25 Jun 12, 2025
fb99d5e
Provide support for separate compilation for free function kernels
lbushi25 Jun 13, 2025
b66ef5c
Merge branch 'intel:sycl' into free_functions_separate_compilation
lbushi25 Jun 13, 2025
d35ecd2
Add helper files ofr testing
lbushi25 Jun 13, 2025
0c855ba
Merge branch 'free_functions_separate_compilation' of https://github.…
lbushi25 Jun 13, 2025
2d6af89
Formatting changes
lbushi25 Jun 13, 2025
19eed5d
Formatting changes
lbushi25 Jun 13, 2025
7927adf
More formatting
lbushi25 Jun 13, 2025
2b343cd
Fix edge case in the case where there is no forward declaration
lbushi25 Jun 13, 2025
b737915
Fix pre-commit failures
lbushi25 Jun 19, 2025
3136c0e
Formatting
lbushi25 Jun 19, 2025
61429ea
More Formatting
lbushi25 Jun 19, 2025
e4c7946
Yet More formatting
lbushi25 Jun 19, 2025
1b6567d
Fix a formatter error
lbushi25 Jun 19, 2025
feca690
Fix some pre-commit failures and rename tests
lbushi25 Jun 19, 2025
134a24e
Remove rogue changes
lbushi25 Jun 19, 2025
e3bbc5b
Fix pre-commit failures
lbushi25 Jun 23, 2025
928e6c4
Update SemaSYCL.cpp
lbushi25 Jun 23, 2025
b0055ce
Update SemaSYCL.cpp
lbushi25 Jun 23, 2025
8e5786d
Update SeparateCompilation.cpp
lbushi25 Jun 23, 2025
cf25552
Update SeparateCompilation.cpp
lbushi25 Jun 23, 2025
43c7893
Update SemaSYCL.cpp
lbushi25 Jun 24, 2025
51203c1
Add more integration header tests
lbushi25 Jun 24, 2025
9816ac0
Formatting
lbushi25 Jun 24, 2025
21ec543
Formatting
lbushi25 Jun 24, 2025
36ac956
Merge branch 'sycl' into free_functions_separate_compilation
lbushi25 Jun 24, 2025
568abf8
Update free_function_int_header.cpp
lbushi25 Jun 24, 2025
f42146a
Fix formatting
lbushi25 Jun 25, 2025
26c87a5
Apply suggestions
lbushi25 Jun 27, 2025
8402046
Use DenseMap instead of SmallMap
lbushi25 Jun 27, 2025
0cf00ec
Formatting
lbushi25 Jun 27, 2025
8e8868e
Apply more suggestions
lbushi25 Jun 27, 2025
22a4427
Fix CI failures
lbushi25 Jun 27, 2025
f23b5a7
Apply suggestions
lbushi25 Jun 30, 2025
924a3d7
Fix formatting
lbushi25 Jun 30, 2025
2ab3d6e
Fix pre-commit failures
lbushi25 Jun 30, 2025
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
4 changes: 4 additions & 0 deletions clang/include/clang/Sema/SemaSYCL.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,8 @@ class SemaSYCL : public SemaBase {

llvm::DenseSet<const FunctionDecl *> SYCLKernelFunctions;

llvm::DenseSet<const FunctionDecl *> FreeFunctionDeclarations;

public:
SemaSYCL(Sema &S);

Expand Down Expand Up @@ -357,7 +359,9 @@ class SemaSYCL : public SemaBase {
void ConstructOpenCLKernel(FunctionDecl *KernelCallerFunc, MangleContext &MC);
void SetSYCLKernelNames();
void MarkDevices();
void processFreeFunctionDeclaration(const FunctionDecl *FD);
void ProcessFreeFunction(FunctionDecl *FD);
void finalizeFreeFunctionKernels();

/// Get the number of fields or captures within the parsed type.
ExprResult ActOnSYCLBuiltinNumFieldsExpr(ParsedType PT);
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Sema/Sema.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1250,6 +1250,7 @@ void Sema::ActOnEndOfTranslationUnitFragment(TUFragmentKind Kind) {
}

if (getLangOpts().SYCLIsDevice) {
SYCL().finalizeFreeFunctionKernels();
// Set the names of the kernels, now that the names have settled down. This
// needs to happen before we generate the integration headers.
SYCL().SetSYCLKernelNames();
Expand Down
6 changes: 6 additions & 0 deletions clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11170,6 +11170,12 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
if (getLangOpts().OpenACC)
OpenACC().ActOnFunctionDeclarator(NewFD);

// Handle free functions.
if (LangOpts.SYCLIsDevice && !NewFD->isDependentContext() &&
!D.isRedeclaration() &&
D.getFunctionDefinitionKind() == FunctionDefinitionKind::Declaration)
SYCL().processFreeFunctionDeclaration(NewFD);

return NewFD;
}

Expand Down
45 changes: 41 additions & 4 deletions clang/lib/Sema/SemaSYCL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1649,7 +1649,7 @@ class KernelObjVisitor {
// A visitor function that dispatches to functions as defined in
// SyclKernelFieldHandler by iterating over a free function parameter list.
template <typename... HandlerTys>
void VisitFunctionParameters(FunctionDecl *FreeFunc,
void VisitFunctionParameters(const FunctionDecl *FreeFunc,
HandlerTys &...Handlers) {
for (ParmVarDecl *Param : FreeFunc->parameters())
visitParam(Param, Param->getType(), Handlers...);
Expand Down Expand Up @@ -4822,7 +4822,7 @@ class SyclKernelIntHeaderCreator : public SyclKernelFieldHandler {
}

SyclKernelIntHeaderCreator(SemaSYCL &S, SYCLIntegrationHeader &H,
QualType NameType, FunctionDecl *FreeFunc)
QualType NameType, const FunctionDecl *FreeFunc)
: SyclKernelFieldHandler(S), Header(H) {
Header.startKernel(FreeFunc, NameType, FreeFunc->getLocation(),
false /*IsESIMD*/, true /*IsSYCLUnnamedKernel*/,
Expand Down Expand Up @@ -5849,7 +5849,7 @@ void SemaSYCL::MarkDevices() {
}
}

static bool CheckFreeFunctionDiagnostics(Sema &S, FunctionDecl *FD) {
static bool CheckFreeFunctionDiagnostics(Sema &S, const FunctionDecl *FD) {
if (FD->isVariadic()) {
return S.Diag(FD->getLocation(), diag::err_free_function_variadic_args);
}
Expand All @@ -5875,10 +5875,47 @@ static bool CheckFreeFunctionDiagnostics(Sema &S, FunctionDecl *FD) {
return false;
}

void SemaSYCL::finalizeFreeFunctionKernels() {
// This is called at the end of the translation unit. The kernels that appear
// in this list are kernels that have been declared but not defined. Their
// construction consists only of generating the integration header and setting
// their names manually. The other steps in constructing the kernel cannot be
// done because potentially nothing is known about the arguments of the kernel
// except that they exist.
for (const FunctionDecl *kernel : FreeFunctionDeclarations) {
if (CheckFreeFunctionDiagnostics(SemaRef, kernel))
continue; // Continue in order to diagnose errors in all kernels

SyclKernelIntHeaderCreator IntHeader(*this, getSyclIntegrationHeader(),
kernel->getType(), kernel);
KernelObjVisitor Visitor{*this};
Visitor.VisitFunctionParameters(kernel, IntHeader);
std::unique_ptr<MangleContext> MangleCtx(
getASTContext().createMangleContext());
std::string Name, MangledName;
std::tie(Name, MangledName) =
constructFreeFunctionKernelName(*this, kernel, *MangleCtx);
getSyclIntegrationHeader().updateKernelNames(kernel, Name, MangledName);
}
}

void SemaSYCL::processFreeFunctionDeclaration(const FunctionDecl *FD) {
// FD represents a forward declaration of a free function kernel.
// Save them for the end of the translation unit action. This makes it easier
// to handle the case where a definition is defined later.
if (isFreeFunction(FD))
FreeFunctionDeclarations.insert(FD->getCanonicalDecl());
}

void SemaSYCL::ProcessFreeFunction(FunctionDecl *FD) {
if (isFreeFunction(FD)) {
if (CheckFreeFunctionDiagnostics(SemaRef, FD))
return;

// In case the free function kernel has already been seen by way of a
// forward declaration, flush it out because a definition takes priority.
FreeFunctionDeclarations.erase(FD->getCanonicalDecl());

SyclKernelDecompMarker DecompMarker(*this);
SyclKernelFieldChecker FieldChecker(*this);
SyclKernelUnionChecker UnionChecker(*this);
Expand Down Expand Up @@ -7155,7 +7192,7 @@ void SYCLIntegrationHeader::emit(raw_ostream &O) {
O << "\n// Definition of kernel_id of " << K.Name << "\n";
O << "namespace sycl {\n";
O << "template <>\n";
O << "kernel_id ext::oneapi::experimental::get_kernel_id<__sycl_shim"
O << "inline kernel_id ext::oneapi::experimental::get_kernel_id<__sycl_shim"
<< ShimCounter << "()>() {\n";
O << " return sycl::detail::get_kernel_id_impl(std::string_view{\""
<< K.Name << "\"});\n";
Expand Down
72 changes: 70 additions & 2 deletions clang/test/CodeGenSYCL/free_function_int_header.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,20 @@ void ff_21(AliasType start, AliasType *ptr) {
void ff_22(AliasType start, AliasType *ptr) {
}

// Forward declaration of ff_23.
[[__sycl_detail__::add_ir_attributes_function("sycl-single-task-kernel", 0)]]
void ff_23(int arg);

// Forward declaration of ff_24 followed by a definition just after.
// Note that ff_24 appears earlier than ff_23 in the integration header because kernels which
// only declared and not defined such as ff_23 are handled at the end of the translation unit to wait for a definition if it appears.
[[__sycl_detail__::add_ir_attributes_function("sycl-single-task-kernel", 0)]]
void ff_24(int arg);

[[__sycl_detail__::add_ir_attributes_function("sycl-single-task-kernel", 0)]]
void ff_24(int arg) {
}

// CHECK: const char* const kernel_names[] = {
// CHECK-NEXT: {{.*}}__sycl_kernel_ff_2Piii
// CHECK-NEXT: {{.*}}__sycl_kernel_ff_2Piiii
Expand Down Expand Up @@ -298,6 +312,8 @@ void ff_22(AliasType start, AliasType *ptr) {
// CHECK-NEXT: {{.*}}__sycl_kernel_ff_20N4sycl3_V18accessorIiLi1ELNS0_6access4modeE1026ELNS2_6targetE2014ELNS2_11placeholderE0ENS0_3ext6oneapi22accessor_property_listIJEEEEE
// CHECK-NEXT: {{.*}}__sycl_kernel_ff_217DerivedPS_
// CHECK-NEXT: {{.*}}__sycl_kernel_ff_227DerivedPS_
// CHECK-NEXT: {{.*}}__sycl_kernel_ff_24i"
// CHECK-NEXT: {{.*}}__sycl_kernel_ff_23i"

// CHECK-NEXT: ""
// CHECK-NEXT: };
Expand Down Expand Up @@ -417,6 +433,12 @@ void ff_22(AliasType start, AliasType *ptr) {
// CHECK: //--- _Z19__sycl_kernel_ff_20N4sycl3_V18accessorIiLi1ELNS0_6access4modeE1026ELNS2_6targetE2014ELNS2_11placeholderE0ENS0_3ext6oneapi22accessor_property_listIJEEEEE
// CHECK-NEXT: { kernel_param_kind_t::kind_accessor, 4062, 0 },

// CHECK: //--- _Z19__sycl_kernel_ff_24i
// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 0 },

// CHECK: //--- _Z19__sycl_kernel_ff_23i
// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 0 },

// CHECK: { kernel_param_kind_t::kind_invalid, -987654321, -987654321 },
// CHECK-NEXT: };

Expand Down Expand Up @@ -991,8 +1013,6 @@ void ff_22(AliasType start, AliasType *ptr) {
// CHECK-NEXT: struct ext::oneapi::experimental::is_single_task_kernel<__sycl_shim29()> {
// CHECK-NEXT: static constexpr bool value = true;
// CHECK-NEXT: };
// CHECK-NEXT: }


// CHECK: void ff_21(Derived start, Derived * ptr);
// CHECK-NEXT: static constexpr auto __sycl_shim30() {
Expand Down Expand Up @@ -1022,6 +1042,39 @@ void ff_22(AliasType start, AliasType *ptr) {
// CHECK-NEXT: struct ext::oneapi::experimental::is_single_task_kernel<__sycl_shim31()> {
// CHECK-NEXT: static constexpr bool value = true;
// CHECK-NEXT: };

// CHECK: Definition of _Z19__sycl_kernel_ff_24i as a free function kernel
// CHECK: Forward declarations of kernel and its argument types:
// CHECK: void ff_24(int arg);
// CHECK-NEXT: static constexpr auto __sycl_shim32() {
// CHECK-NEXT: return (void (*)(int))ff_24;
// CHECK-NEXT: }
// CHECK-NEXT: namespace sycl {
// CHECK-NEXT: template <>
// CHECK-NEXT: struct ext::oneapi::experimental::is_kernel<__sycl_shim32()> {
// CHECK-NEXT: static constexpr bool value = true;
// CHECK-NEXT: };
// CHECK-NEXT: template <>
// CHECK-NEXT: struct ext::oneapi::experimental::is_single_task_kernel<__sycl_shim32()> {
// CHECK-NEXT: static constexpr bool value = true;
// CHECK-NEXT: };

// CHECK: Definition of _Z19__sycl_kernel_ff_23i as a free function kernel
// CHECK: Forward declarations of kernel and its argument types:
// CHECK: void ff_23(int arg);
// CHECK-NEXT: static constexpr auto __sycl_shim33() {
// CHECK-NEXT: return (void (*)(int))ff_23;
// CHECK-NEXT: }
// CHECK-NEXT: namespace sycl {
// CHECK-NEXT: template <>
// CHECK-NEXT: struct ext::oneapi::experimental::is_kernel<__sycl_shim33()> {
// CHECK-NEXT: static constexpr bool value = true;
// CHECK-NEXT: };
// CHECK-NEXT: template <>
// CHECK-NEXT: struct ext::oneapi::experimental::is_single_task_kernel<__sycl_shim33()> {
// CHECK-NEXT: static constexpr bool value = true;
// CHECK-NEXT: };

// CHECK-NEXT: }

// CHECK: #include <sycl/kernel_bundle.hpp>
Expand Down Expand Up @@ -1252,5 +1305,20 @@ void ff_22(AliasType start, AliasType *ptr) {
// CHECK-NEXT: template <>
// CHECK-NEXT: kernel_id ext::oneapi::experimental::get_kernel_id<__sycl_shim31()>() {
// CHECK-NEXT: return sycl::detail::get_kernel_id_impl(std::string_view{"_Z19__sycl_kernel_ff_227DerivedPS_"});

// CHECK: // Definition of kernel_id of _Z19__sycl_kernel_ff_24i
// CHECK-NEXT: namespace sycl {
// CHECK-NEXT: template <>
// CHECK-NEXT: inline kernel_id ext::oneapi::experimental::get_kernel_id<__sycl_shim32()>() {
// CHECK-NEXT return sycl::detail::get_kernel_id_impl(std::string_view{"_Z19__sycl_kernel_ff_24i"});
// CHECK-NEXT: }
// CHECK-NEXT: }

// CHECK: // Definition of kernel_id of _Z19__sycl_kernel_ff_23i
// CHECK-NEXT: namespace sycl {
// CHECK-NEXT: template <>
// CHECK-NEXT: inline kernel_id ext::oneapi::experimental::get_kernel_id<__sycl_shim33()>() {
// CHECK-NEXT: return sycl::detail::get_kernel_id_impl(std::string_view{"_Z19__sycl_kernel_ff_23i"});

// CHECK-NEXT: }
// CHECK-NEXT: }
31 changes: 31 additions & 0 deletions sycl/test-e2e/FreeFunctionKernels/ProductKernel.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// This is not meant as a standalone test but rather as a source file that will
// link with SeparateCompilation.cpp to check that separate compilation works
// with free function kernels. Hence the .cc suffix to exclude it from the list
// of picked up tests.

Comment on lines +3 to +5
Copy link
Contributor

Choose a reason for hiding this comment

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

FYI: Everything in every folder named Inputs is also excluded

#include "ProductKernel.hpp"
#include <sycl/ext/oneapi/free_function_queries.hpp>

using namespace sycl;

// Add declarations again to test the compiler with multiple
// declarations of the same free function kernel in the same translation unit

SYCL_EXT_ONEAPI_FUNCTION_PROPERTY(
(ext::oneapi::experimental::nd_range_kernel<1>))
void product(accessor<int, 1> accA, accessor<int, 1> accB,
accessor<int, 1> result);

SYCL_EXT_ONEAPI_FUNCTION_PROPERTY(
(ext::oneapi::experimental::nd_range_kernel<1>))
void product(accessor<int, 1> accA, accessor<int, 1> accB,
accessor<int, 1> result) {
size_t id =
ext::oneapi::this_work_item::get_nd_item<1>().get_global_linear_id();
result[id] = accA[id] * accB[id];
}

SYCL_EXT_ONEAPI_FUNCTION_PROPERTY(
(ext::oneapi::experimental::nd_range_kernel<1>))
void product(accessor<int, 1> accA, accessor<int, 1> accB,
accessor<int, 1> result);
8 changes: 8 additions & 0 deletions sycl/test-e2e/FreeFunctionKernels/ProductKernel.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#pragma once
#include <sycl/accessor.hpp>
#include <sycl/kernel_bundle.hpp>

SYCL_EXT_ONEAPI_FUNCTION_PROPERTY(
(sycl::ext::oneapi::experimental::nd_range_kernel<1>))
void product(sycl::accessor<int, 1> accA, sycl::accessor<int, 1> accB,
sycl::accessor<int, 1> result);
78 changes: 78 additions & 0 deletions sycl/test-e2e/FreeFunctionKernels/SeparateCompilation.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// RUN: %{build} %S/SumKernel.cc %S/ProductKernel.cc -o %t.out
Copy link
Contributor

Choose a reason for hiding this comment

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

How does it work if %s isn't used on this command line, i.e. when the binary being built doesn't have main function? Am I missing something?

Copy link
Contributor Author

@lbushi25 lbushi25 Jun 25, 2025

Choose a reason for hiding this comment

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

I believe the %{build}substitution involves that as well.
Many tests do %{build} -o %t.out for example

// RUN: %{run} %t.out

#include "ProductKernel.hpp"
#include "SumKernel.hpp"
#include <cassert>
#include <numeric>
#include <sycl/detail/core.hpp>
#include <sycl/ext/oneapi/experimental/free_function_traits.hpp>
#include <sycl/kernel_bundle.hpp>

using namespace sycl;

// Add declarations again to test the compiler with multiple declarations of the
// same free function kernel in the translation unit.

SYCL_EXT_ONEAPI_FUNCTION_PROPERTY(
(ext::oneapi::experimental::nd_range_kernel<1>))
void SumKernel::sum(accessor<int, 1> accA, accessor<int, 1> accB,
accessor<int, 1> result);

constexpr size_t SIZE = 16;

int main() {
int data[SIZE];
int result[SIZE];
std::iota(data, data + SIZE, 0);
queue Q;
kernel_bundle bundle =
get_kernel_bundle<bundle_state::executable>(Q.get_context());
kernel_id sumId = ext::oneapi::experimental::get_kernel_id<SumKernel::sum>();
kernel_id productId = ext::oneapi::experimental::get_kernel_id<product>();
kernel sumKernel = bundle.get_kernel(sumId);
kernel productKernel = bundle.get_kernel(productId);

{
buffer<int, 1> databuf{data, SIZE};
buffer<int, 1> resultbuf{result, SIZE};

Q.submit([&](handler &h) {
accessor<int, 1> accdata(databuf, h);
accessor<int, 1> accresult(resultbuf, h);
h.set_args(accdata, accdata, accresult);
h.parallel_for(nd_range{{SIZE}, {SIZE}}, sumKernel);
});
}

int failed = 0;
for (int i = 0; i < SIZE; ++i) {
if (result[i] != 2 * data[i]) {
std::cout << "Failed at index " << i << ": " << result[i]
<< "!=" << (2 * data[i]) << std::endl;
++failed;
}
}

{
buffer<int, 1> databuf{data, SIZE};
buffer<int, 1> resultbuf{result, SIZE};

Q.submit([&](handler &h) {
accessor<int, 1> accdata(databuf, h);
accessor<int, 1> accresult(resultbuf, h);
h.set_args(accdata, accdata, accresult);
h.parallel_for(nd_range{{SIZE}, {SIZE}}, productKernel);
});
}

for (int i = 0; i < SIZE; ++i) {
if (result[i] != data[i] * data[i]) {
std::cout << "Failed at index " << i << ": " << result[i]
<< "!=" << (data[i] * data[i]) << std::endl;
++failed;
}
}

return failed;
}
18 changes: 18 additions & 0 deletions sycl/test-e2e/FreeFunctionKernels/SumKernel.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// This is not meant as a standalone test but rather as a source file that will
// link with SeparateCompilation.cpp to check that separate compilation works
// with free function kernels. Hence the .cc suffix to exclude it from the list
// of picked up tests.

#include "SumKernel.hpp"
#include <sycl/ext/oneapi/free_function_queries.hpp>

using namespace sycl;

SYCL_EXT_ONEAPI_FUNCTION_PROPERTY(
(ext::oneapi::experimental::nd_range_kernel<1>))
void SumKernel::sum(accessor<int, 1> accA, accessor<int, 1> accB,
accessor<int, 1> result) {
size_t id =
ext::oneapi::this_work_item::get_nd_item<1>().get_global_linear_id();
result[id] = accA[id] + accB[id];
}
10 changes: 10 additions & 0 deletions sycl/test-e2e/FreeFunctionKernels/SumKernel.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#pragma once
#include <sycl/accessor.hpp>
#include <sycl/kernel_bundle.hpp>

namespace SumKernel {
SYCL_EXT_ONEAPI_FUNCTION_PROPERTY(
(sycl::ext::oneapi::experimental::nd_range_kernel<1>))
void sum(sycl::accessor<int, 1> accA, sycl::accessor<int, 1> accB,
sycl::accessor<int, 1> result);
} // namespace SumKernel