diff --git a/sycl/include/CL/sycl.hpp b/sycl/include/CL/sycl.hpp index 659dee0ed6aa3..383725dcc4b88 100644 --- a/sycl/include/CL/sycl.hpp +++ b/sycl/include/CL/sycl.hpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -48,6 +49,7 @@ #include #include #include +#include #include #include #include diff --git a/sycl/include/CL/sycl/detail/cg_types.hpp b/sycl/include/CL/sycl/detail/cg_types.hpp index f8acc96550fda..5faa502102ba3 100644 --- a/sycl/include/CL/sycl/detail/cg_types.hpp +++ b/sycl/include/CL/sycl/detail/cg_types.hpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -122,6 +123,97 @@ class NDRDescT { size_t Dims; }; +template struct check_fn_signature { + static_assert(std::integral_constant::value, + "Second template parameter is required to be of function type"); +}; + +template +struct check_fn_signature { +private: + template + static constexpr auto check(T *) -> typename std::is_same< + decltype(std::declval().operator()(std::declval()...)), + RetT>::type; + + template static constexpr std::false_type check(...); + + using type = decltype(check(0)); + +public: + static constexpr bool value = type::value; +}; + +template +static constexpr bool check_kernel_lambda_takes_args() { + return check_fn_signature, void(Args...)>::value; +} + +// isKernelLambdaCallableWithKernelHandlerImpl checks if LambdaArgType is void +// (e.g., in single_task), and based on that, calls +// check_kernel_lambda_takes_args with proper set of arguments. Also this type +// trait workarounds compilation error which happens only with msvc. + +template ::value> + * = nullptr> +constexpr bool isKernelLambdaCallableWithKernelHandlerImpl() { + return check_kernel_lambda_takes_args(); +} + +template ::value> + * = nullptr> +constexpr bool isKernelLambdaCallableWithKernelHandlerImpl() { + return check_kernel_lambda_takes_args(); +} + +// Type traits to find out if kernal lambda has kernel_handler argument + +template +constexpr bool isKernelLambdaCallableWithKernelHandler() { + return check_kernel_lambda_takes_args(); +} + +template +constexpr bool isKernelLambdaCallableWithKernelHandler() { + return isKernelLambdaCallableWithKernelHandlerImpl(); +} + +// Helpers for running kernel lambda on the host device + +template ()> * = nullptr> +constexpr void runKernelWithoutArg(KernelType KernelName) { + kernel_handler KH; + KernelName(KH); +} + +template ()> * = nullptr> +constexpr void runKernelWithoutArg(KernelType KernelName) { + KernelName(); +} + +template ()> * = nullptr> +constexpr void runKernelWithArg(KernelType KernelName, ArgType Arg) { + kernel_handler KH; + KernelName(Arg, KH); +} + +template ()> * = nullptr> +constexpr void runKernelWithArg(KernelType KernelName, ArgType Arg) { + KernelName(Arg); +} + // The pure virtual class aimed to store lambda/functors of any type. class HostKernelBase { public: @@ -197,7 +289,7 @@ class HostKernel : public HostKernelBase { template typename detail::enable_if_t::value> runOnHost(const NDRDescT &) { - MKernel(); + runKernelWithoutArg(MKernel); } template @@ -218,18 +310,18 @@ class HostKernel : public HostKernelBase { UpperBound[I] = Range[I] + Offset[I]; } - detail::NDLoop::iterate(/*LowerBound=*/Offset, Stride, UpperBound, - [&](const sycl::id &ID) { - sycl::item Item = - IDBuilder::createItem( - Range, ID, Offset); - - if (StoreLocation) { - store_id(&ID); - store_item(&Item); - } - MKernel(ID); - }); + detail::NDLoop::iterate( + /*LowerBound=*/Offset, Stride, UpperBound, + [&](const sycl::id &ID) { + sycl::item Item = + IDBuilder::createItem(Range, ID, Offset); + + if (StoreLocation) { + store_id(&ID); + store_item(&Item); + } + runKernelWithArg &>(MKernel, ID); + }); } template @@ -253,7 +345,7 @@ class HostKernel : public HostKernelBase { store_id(&ID); store_item(&ItemWithOffset); } - MKernel(Item); + runKernelWithArg>(MKernel, Item); }); } @@ -276,18 +368,18 @@ class HostKernel : public HostKernelBase { UpperBound[I] = Range[I] + Offset[I]; } - detail::NDLoop::iterate(/*LowerBound=*/Offset, Stride, UpperBound, - [&](const sycl::id &ID) { - sycl::item Item = - IDBuilder::createItem( - Range, ID, Offset); - - if (StoreLocation) { - store_id(&ID); - store_item(&Item); - } - MKernel(Item); - }); + detail::NDLoop::iterate( + /*LowerBound=*/Offset, Stride, UpperBound, + [&](const sycl::id &ID) { + sycl::item Item = + IDBuilder::createItem(Range, ID, Offset); + + if (StoreLocation) { + store_id(&ID); + store_item(&Item); + } + runKernelWithArg>(MKernel, Item); + }); } template @@ -336,7 +428,7 @@ class HostKernel : public HostKernelBase { auto g = NDItem.get_group(); store_group(&g); } - MKernel(NDItem); + runKernelWithArg>(MKernel, NDItem); }); }); } @@ -364,7 +456,7 @@ class HostKernel : public HostKernelBase { detail::NDLoop::iterate(NGroups, [&](const id &GroupID) { sycl::group Group = IDBuilder::createGroup(GlobalSize, LocalSize, NGroups, GroupID); - MKernel(Group); + runKernelWithArg>(MKernel, Group); }); } diff --git a/sycl/include/CL/sycl/detail/kernel_desc.hpp b/sycl/include/CL/sycl/detail/kernel_desc.hpp index 535c7069c2974..7fbe0d1dffe76 100644 --- a/sycl/include/CL/sycl/detail/kernel_desc.hpp +++ b/sycl/include/CL/sycl/detail/kernel_desc.hpp @@ -26,7 +26,8 @@ enum class kernel_param_kind_t { kind_accessor = 0, kind_std_layout = 1, // standard layout object parameters kind_sampler = 2, - kind_pointer = 3 + kind_pointer = 3, + kind_specialization_constants_buffer = 4, }; // describes a kernel parameter diff --git a/sycl/include/CL/sycl/handler.hpp b/sycl/include/CL/sycl/handler.hpp index c16b151b64b7d..2523e917890e1 100644 --- a/sycl/include/CL/sycl/handler.hpp +++ b/sycl/include/CL/sycl/handler.hpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -116,27 +117,6 @@ template struct get_kernel_wrapper_name_t { typename get_kernel_name_t::name>; }; -template struct check_fn_signature { - static_assert(std::integral_constant::value, - "Second template parameter is required to be of function type"); -}; - -template -struct check_fn_signature { -private: - template - static constexpr auto check(T *) -> typename std::is_same< - decltype(std::declval().operator()(std::declval()...)), - RetT>::type; - - template static constexpr std::false_type check(...); - - using type = decltype(check(0)); - -public: - static constexpr bool value = type::value; -}; - __SYCL_EXPORT device getDeviceFromHandler(handler &); #if __SYCL_ID_QUERIES_FIT_IN_INT__ @@ -533,6 +513,13 @@ class __SYCL_EXPORT handler { template void StoreLambda(KernelType KernelFunc) { + if (detail::isKernelLambdaCallableWithKernelHandler() && + MIsHost) { + throw cl::sycl::feature_not_supported( + "kernel_handler is not yet supported by host device.", + PI_INVALID_OPERATION); + } MHostKernel.reset( new detail::HostKernel( KernelFunc)); @@ -822,17 +809,14 @@ class __SYCL_EXPORT handler { if (getenv("SYCL_PARALLEL_FOR_RANGE_ROUNDING_TRACE") != nullptr) std::cout << "parallel_for range adjusted from " << NumWorkItems[0] << " to " << NewValX << std::endl; - auto Wrapper = [=](TransformedArgType Arg) { - if (Arg[0] >= NumWorkItems[0]) - return; - Arg.set_allowed_range(NumWorkItems); - KernelFunc(Arg); - }; + + auto Wrapper = getRangeRoundedKernelLambda( + KernelFunc, NumWorkItems); range AdjustedRange = NumWorkItems; AdjustedRange.set_range_dim0(NewValX); #ifdef __SYCL_DEVICE_ONLY__ - kernel_parallel_for(Wrapper); + kernel_parallel_for_wrapper(Wrapper); #else detail::checkValueRange(AdjustedRange); MNDRDesc.set(std::move(AdjustedRange)); @@ -847,7 +831,7 @@ class __SYCL_EXPORT handler { { #ifdef __SYCL_DEVICE_ONLY__ (void)NumWorkItems; - kernel_parallel_for(KernelFunc); + kernel_parallel_for_wrapper(KernelFunc); #else detail::checkValueRange(NumWorkItems); MNDRDesc.set(std::move(NumWorkItems)); @@ -891,6 +875,18 @@ class __SYCL_EXPORT handler { KernelFunc(); } + // NOTE: the name of this function - "kernel_single_task" - is used by the + // Front End to determine kernel invocation kind. + template + __attribute__((sycl_kernel)) void +#ifdef __SYCL_NONCONST_FUNCTOR__ + kernel_single_task(KernelType KernelFunc, kernel_handler KH) { +#else + kernel_single_task(const KernelType &KernelFunc, kernel_handler KH) { +#endif + KernelFunc(KH); + } + // NOTE: the name of these functions - "kernel_parallel_for" - are used by the // Front End to determine kernel invocation kind. template @@ -903,6 +899,18 @@ class __SYCL_EXPORT handler { KernelFunc(detail::Builder::getElement(detail::declptr())); } + // NOTE: the name of these functions - "kernel_parallel_for" - are used by the + // Front End to determine kernel invocation kind. + template + __attribute__((sycl_kernel)) void +#ifdef __SYCL_NONCONST_FUNCTOR__ + kernel_parallel_for(KernelType KernelFunc, kernel_handler KH) { +#else + kernel_parallel_for(const KernelType &KernelFunc, kernel_handler KH) { +#endif + KernelFunc(detail::Builder::getElement(detail::declptr()), KH); + } + // NOTE: the name of this function - "kernel_parallel_for_work_group" - is // used by the Front End to determine kernel invocation kind. template @@ -915,6 +923,103 @@ class __SYCL_EXPORT handler { KernelFunc(detail::Builder::getElement(detail::declptr())); } + // NOTE: the name of this function - "kernel_parallel_for_work_group" - is + // used by the Front End to determine kernel invocation kind. + template + __attribute__((sycl_kernel)) void +#ifdef __SYCL_NONCONST_FUNCTOR__ + kernel_parallel_for_work_group(KernelType KernelFunc, kernel_handler KH) { +#else + kernel_parallel_for_work_group(const KernelType &KernelFunc, + kernel_handler KH) { +#endif + KernelFunc(detail::Builder::getElement(detail::declptr()), KH); + } + + // Wrappers for kernel_*** functions above with and without support of + // additional kernel_handler argument. + + // NOTE: to support kernel_handler argument in kernel lambdas, only + // kernel_***_wrapper functions must be called in this code + + // Wrappers for kernel_single_task(...) + + template + std::enable_if_t< + detail::isKernelLambdaCallableWithKernelHandler(), void> +#ifdef __SYCL_NONCONST_FUNCTOR__ + kernel_single_task_wrapper(KernelType KernelFunc) { +#else + kernel_single_task_wrapper(const KernelType &KernelFunc) { +#endif + kernel_handler KH; + kernel_single_task(KernelFunc, KH); + } + + template + std::enable_if_t< + !detail::isKernelLambdaCallableWithKernelHandler(), void> +#ifdef __SYCL_NONCONST_FUNCTOR__ + kernel_single_task_wrapper(KernelType KernelFunc) { +#else + kernel_single_task_wrapper(const KernelType &KernelFunc) { +#endif + kernel_single_task(KernelFunc); + } + + // Wrappers for kernel_parallel_for(...) + + template + std::enable_if_t(), + void> +#ifdef __SYCL_NONCONST_FUNCTOR__ + kernel_parallel_for_wrapper(KernelType KernelFunc) { +#else + kernel_parallel_for_wrapper(const KernelType &KernelFunc) { +#endif + kernel_handler KH; + kernel_parallel_for(KernelFunc, KH); + } + + template + std::enable_if_t(), + void> +#ifdef __SYCL_NONCONST_FUNCTOR__ + kernel_parallel_for_wrapper(KernelType KernelFunc) { +#else + kernel_parallel_for_wrapper(const KernelType &KernelFunc) { +#endif + kernel_parallel_for(KernelFunc); + } + + // Wrappers for kernel_parallel_for_work_group(...) + + template + std::enable_if_t(), + void> +#ifdef __SYCL_NONCONST_FUNCTOR__ + kernel_parallel_for_work_group_wrapper(KernelType KernelFunc) { +#else + kernel_parallel_for_work_group_wrapper(const KernelType &KernelFunc) { +#endif + kernel_handler KH; + kernel_parallel_for_work_group(KernelFunc, KH); + } + + template + std::enable_if_t(), + void> +#ifdef __SYCL_NONCONST_FUNCTOR__ + kernel_parallel_for_work_group_wrapper(KernelType KernelFunc) { +#else + kernel_parallel_for_work_group_wrapper(const KernelType &KernelFunc) { +#endif + kernel_parallel_for_work_group(KernelFunc); + } #endif std::shared_ptr @@ -1061,7 +1166,7 @@ class __SYCL_EXPORT handler { using NameT = typename detail::get_kernel_name_t::name; #ifdef __SYCL_DEVICE_ONLY__ - kernel_single_task(KernelFunc); + kernel_single_task_wrapper(KernelFunc); #else // No need to check if range is out of INT_MAX limits as it's compile-time // known constant. @@ -1175,7 +1280,7 @@ class __SYCL_EXPORT handler { #ifdef __SYCL_DEVICE_ONLY__ (void)NumWorkItems; (void)WorkItemOffset; - kernel_parallel_for(KernelFunc); + kernel_parallel_for_wrapper(KernelFunc); #else detail::checkValueRange(NumWorkItems, WorkItemOffset); MNDRDesc.set(std::move(NumWorkItems), std::move(WorkItemOffset)); @@ -1207,7 +1312,7 @@ class __SYCL_EXPORT handler { sycl::detail::lambda_arg_type>; #ifdef __SYCL_DEVICE_ONLY__ (void)ExecutionRange; - kernel_parallel_for(KernelFunc); + kernel_parallel_for_wrapper(KernelFunc); #else detail::checkValueRange(ExecutionRange); MNDRDesc.set(std::move(ExecutionRange)); @@ -1440,7 +1545,7 @@ class __SYCL_EXPORT handler { sycl::detail::lambda_arg_type>; #ifdef __SYCL_DEVICE_ONLY__ (void)NumWorkGroups; - kernel_parallel_for_work_group(KernelFunc); + kernel_parallel_for_work_group_wrapper(KernelFunc); #else detail::checkValueRange(NumWorkGroups); MNDRDesc.setNumWorkGroups(NumWorkGroups); @@ -1474,7 +1579,7 @@ class __SYCL_EXPORT handler { #ifdef __SYCL_DEVICE_ONLY__ (void)NumWorkGroups; (void)WorkGroupSize; - kernel_parallel_for_work_group(KernelFunc); + kernel_parallel_for_work_group_wrapper(KernelFunc); #else nd_range ExecRange = nd_range(NumWorkGroups * WorkGroupSize, WorkGroupSize); @@ -1610,7 +1715,7 @@ class __SYCL_EXPORT handler { #ifdef __SYCL_DEVICE_ONLY__ (void)Kernel; (void)NumWorkItems; - kernel_parallel_for(KernelFunc); + kernel_parallel_for_wrapper(KernelFunc); #else detail::checkValueRange(NumWorkItems); MNDRDesc.set(std::move(NumWorkItems)); @@ -1646,7 +1751,7 @@ class __SYCL_EXPORT handler { (void)Kernel; (void)NumWorkItems; (void)WorkItemOffset; - kernel_parallel_for(KernelFunc); + kernel_parallel_for_wrapper(KernelFunc); #else detail::checkValueRange(NumWorkItems, WorkItemOffset); MNDRDesc.set(std::move(NumWorkItems), std::move(WorkItemOffset)); @@ -1682,7 +1787,7 @@ class __SYCL_EXPORT handler { #ifdef __SYCL_DEVICE_ONLY__ (void)Kernel; (void)NDRange; - kernel_parallel_for(KernelFunc); + kernel_parallel_for_wrapper(KernelFunc); #else detail::checkValueRange(NDRange); MNDRDesc.set(std::move(NDRange)); @@ -1722,7 +1827,7 @@ class __SYCL_EXPORT handler { #ifdef __SYCL_DEVICE_ONLY__ (void)Kernel; (void)NumWorkGroups; - kernel_parallel_for_work_group(KernelFunc); + kernel_parallel_for_work_group_wrapper(KernelFunc); #else detail::checkValueRange(NumWorkGroups); MNDRDesc.setNumWorkGroups(NumWorkGroups); @@ -1761,7 +1866,7 @@ class __SYCL_EXPORT handler { (void)Kernel; (void)NumWorkGroups; (void)WorkGroupSize; - kernel_parallel_for_work_group(KernelFunc); + kernel_parallel_for_work_group_wrapper(KernelFunc); #else nd_range ExecRange = nd_range(NumWorkGroups * WorkGroupSize, WorkGroupSize); @@ -2170,6 +2275,34 @@ class __SYCL_EXPORT handler { access::target); friend class ::MockHandler; + + template < + typename TransformedArgType, int Dims, typename KernelType, + typename std::enable_if_t()> * = nullptr> + auto getRangeRoundedKernelLambda(KernelType KernelFunc, + range NumWorkItems) { + return [=](TransformedArgType Arg, kernel_handler KH) { + if (Arg[0] >= NumWorkItems[0]) + return; + Arg.set_allowed_range(NumWorkItems); + KernelFunc(Arg, KH); + }; + } + + template ()> * = nullptr> + auto getRangeRoundedKernelLambda(KernelType KernelFunc, + range NumWorkItems) { + return [=](TransformedArgType Arg) { + if (Arg[0] >= NumWorkItems[0]) + return; + Arg.set_allowed_range(NumWorkItems); + KernelFunc(Arg); + }; + } }; } // namespace sycl } // __SYCL_INLINE_NAMESPACE(cl) diff --git a/sycl/include/CL/sycl/kernel_handler.hpp b/sycl/include/CL/sycl/kernel_handler.hpp new file mode 100644 index 0000000000000..0a3f77381b364 --- /dev/null +++ b/sycl/include/CL/sycl/kernel_handler.hpp @@ -0,0 +1,73 @@ +//==------ kernel_handler.hpp -- SYCL standard header file -----*- C++ -*---==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#pragma once + +__SYCL_INLINE_NAMESPACE(cl) { +namespace sycl { +namespace detail { + +// This guard is needed because the libsycl.so can compiled with C++ <=14 +// while the code requires C++17. This code is not supposed to be used by the +// libsycl.so so it should not be a problem. +#if __cplusplus > 201402L +template struct specialization_id_name_generator {}; +#endif + +} // namespace detail + +/// Reading the value of a specialization constant +/// +/// \ingroup sycl_api +class kernel_handler { +public: +#if __cplusplus > 201402L + template + typename std::remove_reference_t get_specialization_constant() { +#ifdef __SYCL_DEVICE_ONLY__ + return getSpecializationConstantOnDevice(); +#else + // TODO: add support of host device + throw cl::sycl::feature_not_supported( + "kernel_handler::get_specialization_constant() is not yet supported by " + "host device.", + PI_INVALID_OPERATION); +#endif // __SYCL_DEVICE_ONLY__ + } +#endif // __cplusplus > 201402L + +private: + void __init_specialization_constants_buffer( + char *SpecializationConstantsBuffer = nullptr) { + MSpecializationConstantsBuffer = SpecializationConstantsBuffer; + } + +#ifdef __SYCL_DEVICE_ONLY__ + template , + std::enable_if_t> * = nullptr> + T getSpecializationConstantOnDevice() { + const char *SymbolicID = __builtin_unique_stable_name( + detail::specialization_id_name_generator); + return __sycl_getScalar2020SpecConstantValue( + SymbolicID, &S, MSpecializationConstantsBuffer); + } + template , + std::enable_if_t> * = nullptr> + T getSpecializationConstantOnDevice() { + const char *SymbolicID = __builtin_unique_stable_name( + detail::specialization_id_name_generator); + return __sycl_getComposite2020SpecConstantValue( + SymbolicID, &S, MSpecializationConstantsBuffer); + } +#endif // __SYCL_DEVICE_ONLY__ + + char *MSpecializationConstantsBuffer = nullptr; +}; + +} // namespace sycl +} // __SYCL_INLINE_NAMESPACE(cl) diff --git a/sycl/include/CL/sycl/specialization_id.hpp b/sycl/include/CL/sycl/specialization_id.hpp new file mode 100644 index 0000000000000..cc4f25d8ebad6 --- /dev/null +++ b/sycl/include/CL/sycl/specialization_id.hpp @@ -0,0 +1,35 @@ +//==---- specialization_id.hpp -- SYCL standard header file ----*- C++ -*---==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#pragma once + +__SYCL_INLINE_NAMESPACE(cl) { +namespace sycl { + +/// Declaring a specialization constant +/// +/// \ingroup sycl_api +template class specialization_id { +public: + using value_type = T; + + template + explicit constexpr specialization_id(Args &&... args) + : MDefaultValue(std::forward(args)...) {} + + specialization_id(const specialization_id &rhs) = delete; + specialization_id(specialization_id &&rhs) = delete; + specialization_id &operator=(const specialization_id &rhs) = delete; + specialization_id &operator=(specialization_id &&rhs) = delete; + +private: + T MDefaultValue; +}; + +} // namespace sycl +} // __SYCL_INLINE_NAMESPACE(cl) diff --git a/sycl/source/detail/scheduler/commands.cpp b/sycl/source/detail/scheduler/commands.cpp index 99b6f13a4c823..1072c23fbdafd 100644 --- a/sycl/source/detail/scheduler/commands.cpp +++ b/sycl/source/detail/scheduler/commands.cpp @@ -1696,6 +1696,12 @@ pi_result ExecCGCommand::SetKernelParamsAndLaunch( Arg.MSize, Arg.MPtr); break; } + case kernel_param_kind_t::kind_specialization_constants_buffer: { + throw cl::sycl::feature_not_supported( + "SYCL2020 specialization constants are not yet fully supported", + PI_INVALID_OPERATION); + break; + } } ++NextTrueIndex; } diff --git a/sycl/source/handler.cpp b/sycl/source/handler.cpp index 68ad4f9094d1e..9ba4887ca935f 100644 --- a/sycl/source/handler.cpp +++ b/sycl/source/handler.cpp @@ -335,6 +335,12 @@ void handler::processArg(void *Ptr, const detail::kernel_param_kind_t &Kind, Index + IndexShift); break; } + case kernel_param_kind_t::kind_specialization_constants_buffer: { + throw cl::sycl::feature_not_supported( + "SYCL2020 specialization constants are not yet fully supported", + PI_INVALID_OPERATION); + break; + } } } diff --git a/sycl/test/function-pointers/fp-as-kernel-arg.cpp b/sycl/test/function-pointers/fp-as-kernel-arg.cpp index 5973c2b419bc8..65b6d0c6be988 100644 --- a/sycl/test/function-pointers/fp-as-kernel-arg.cpp +++ b/sycl/test/function-pointers/fp-as-kernel-arg.cpp @@ -1,4 +1,4 @@ -// RUN: %clangxx -Xclang -fsycl-allow-func-ptr -std=c++14 -fsycl %s -o %t.out +// RUN: %clangxx -Xclang -fsycl-allow-func-ptr -fsycl %s -o %t.out // RUN: %RUN_ON_HOST %t.out // FIXME: This test should use runtime early exit once correct check for // corresponding extension is implemented diff --git a/sycl/test/function-pointers/pass-fp-through-buffer.cpp b/sycl/test/function-pointers/pass-fp-through-buffer.cpp index 60ca4cd5f4c71..aef94716ecd85 100644 --- a/sycl/test/function-pointers/pass-fp-through-buffer.cpp +++ b/sycl/test/function-pointers/pass-fp-through-buffer.cpp @@ -1,4 +1,4 @@ -// RUN: %clangxx -Xclang -fsycl-allow-func-ptr -std=c++14 -fsycl %s -o %t.out +// RUN: %clangxx -Xclang -fsycl-allow-func-ptr -fsycl %s -o %t.out // RUN: %RUN_ON_HOST %t.out // FIXME: This test should use runtime early exit once correct check for // corresponding extension is implemented diff --git a/sycl/test/on-device/basic_tests/specialization_constants/kernel_lambda_with_kernel_handler_arg.cpp b/sycl/test/on-device/basic_tests/specialization_constants/kernel_lambda_with_kernel_handler_arg.cpp new file mode 100644 index 0000000000000..7adf90fe48b7a --- /dev/null +++ b/sycl/test/on-device/basic_tests/specialization_constants/kernel_lambda_with_kernel_handler_arg.cpp @@ -0,0 +1,112 @@ +// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out +// RUN: %t.out + +// This test checks all possible scenarios of running single_task, parallel_for +// and parallel_for_work_group to verify that this code compiles and runs +// correctly with user's lambda with and without sycl::kernel_handler argument + +// TODO: enable cuda support when non-native spec constants started to be +// supported +// UNSUPPORTED: cuda + +#include + +int main() { + sycl::queue q; + + // single_task w/o kernel_handler arg + q.submit([&](sycl::handler &cgh) { + cgh.single_task([=]() {}); + }); + + // single_task with kernel_handler arg + q.submit([&](sycl::handler &cgh) { + cgh.single_task( + [=](sycl::kernel_handler kh) {}); + }); + + // parallel_for with id and w/o kernel_handler arg + q.submit([&](sycl::handler &cgh) { + cgh.parallel_for( + sycl::range<1>(1), [](sycl::id<1> i) {}); + }); + + // parallel_for with id and kernel_handler args + q.submit([&](sycl::handler &cgh) { + cgh.parallel_for( + sycl::range<1>(1), [](sycl::id<1> i, sycl::kernel_handler kh) {}); + }); + + // parallel_for with item and w/o kernel_handler arg + q.submit([&](sycl::handler &cgh) { + cgh.parallel_for( + sycl::range<3>(3, 3, 3), [](sycl::item<3> it) {}); + }); + + // parallel_for with item and kernel_handler args + q.submit([&](sycl::handler &cgh) { + cgh.parallel_for( + sycl::range<3>(3, 3, 3), + [](sycl::item<3> it, sycl::kernel_handler kh) {}); + }); + + // parallel_for with nd_item and w/o kernel_handler arg + q.submit([&](sycl::handler &cgh) { + cgh.parallel_for( + sycl::nd_range<3>(sycl::range<3>(4, 4, 4), sycl::range<3>(2, 2, 2)), + [=](sycl::nd_item<3> item) {}); + }); + + // parallel_for with nd_item and kernel_handler args + q.submit([&](sycl::handler &cgh) { + cgh.parallel_for( + sycl::nd_range<3>(sycl::range<3>(4, 4, 4), sycl::range<3>(2, 2, 2)), + [=](sycl::nd_item<3> item, sycl::kernel_handler kh) {}); + }); + + // parallel_for with generic lambda w/o kernel_handler arg + q.submit([&](sycl::handler &cgh) { + cgh.parallel_for( + sycl::range<3>(3, 3, 3), [](auto it) {}); + }); + + // parallel_for with generic lambda with kernel_handler arg + q.submit([&](sycl::handler &cgh) { + cgh.parallel_for( + sycl::range<3>(3, 3, 3), [](auto it, sycl::kernel_handler kh) {}); + }); + + // parallel_for with integral type arg and w/o kernel_handler arg + q.submit([&](sycl::handler &cgh) { + cgh.parallel_for( + sycl::range<1>(1), [](int index) {}); + }); + + // parallel_for with integral type and kernel_handler args + q.submit([&](sycl::handler &cgh) { + cgh.parallel_for( + sycl::range<1>(1), [](int index, sycl::kernel_handler kh) {}); + }); + + // parallel_for_work_group without kernel_handler arg + q.submit([&](sycl::handler &cgh) { + cgh.parallel_for_work_group< + class KernelParallelForWorkGroupWithKernelHandler>( + sycl::range<3>(2, 2, 2), sycl::range<3>(2, 2, 2), + [=](sycl::group<3> myGroup) { + myGroup.parallel_for_work_item([&](sycl::h_item<3> myItem) {}); + myGroup.parallel_for_work_item([&](sycl::h_item<3> myItem) {}); + }); + }); + + // parallel_for_work_group with kernel_handler arg + q.submit([&](sycl::handler &cgh) { + cgh.parallel_for_work_group< + class KernelParallelForWorkGroupWithoutKernelHandler>( + sycl::range<3>(2, 2, 2), sycl::range<3>(2, 2, 2), + [=](sycl::group<3> myGroup, sycl::kernel_handler kh) { + myGroup.parallel_for_work_item([&](sycl::h_item<3> myItem) {}); + myGroup.parallel_for_work_item([&](sycl::h_item<3> myItem) {}); + }); + }); +} diff --git a/sycl/test/regression/sycl-include-gnu14.cpp b/sycl/test/regression/sycl-include-gnu17.cpp similarity index 74% rename from sycl/test/regression/sycl-include-gnu14.cpp rename to sycl/test/regression/sycl-include-gnu17.cpp index 0147acf143de5..f56d262c1f0bd 100644 --- a/sycl/test/regression/sycl-include-gnu14.cpp +++ b/sycl/test/regression/sycl-include-gnu17.cpp @@ -1,4 +1,4 @@ -// RUN: %clangxx -std=gnu++14 -fsycl -fsycl-targets=%sycl_triple %s -o %t.out +// RUN: %clangxx -std=gnu++17 -fsycl -fsycl-targets=%sycl_triple %s -o %t.out // RUN: %RUN_ON_HOST %t.out // UNSUPPORTED: system-windows