Skip to content

Commit 33325d4

Browse files
[SYCL] Fix enqueue functions taking both kernel and properties (#14743)
The current implementation of the enqueue free functions taking both a launch_config and a kernel do not properly process the properties. This commit addresses this and adds a static assert about the properties passed to these only applying to the launch of the kernel and not how the compiler handles compiling the kernel. --------- Signed-off-by: Larsen, Steffen <steffen.larsen@intel.com> Co-authored-by: Sergey Semenov <sergey.semenov@intel.com>
1 parent 6ac800b commit 33325d4

File tree

10 files changed

+289
-35
lines changed

10 files changed

+289
-35
lines changed

sycl/include/sycl/ext/intel/experimental/fpga_kernel_properties.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,15 @@ struct is_property_key_of<
104104
: std::true_type {};
105105

106106
namespace detail {
107+
template <intel::experimental::streaming_interface_options_enum option>
108+
struct HasCompileTimeEffect<
109+
intel::experimental::streaming_interface_key::value_t<option>>
110+
: std::true_type {};
111+
template <intel::experimental::register_map_interface_options_enum option>
112+
struct HasCompileTimeEffect<
113+
intel::experimental::register_map_interface_key::value_t<option>>
114+
: std::true_type {};
115+
107116
template <intel::experimental::streaming_interface_options_enum Stall_Free>
108117
struct PropertyMetaInfo<
109118
intel::experimental::streaming_interface_key::value_t<Stall_Free>> {

sycl/include/sycl/ext/oneapi/experimental/enqueue_functions.hpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,16 @@ template <typename RangeT>
3434
constexpr bool is_range_or_nd_range_v = is_range_or_nd_range<RangeT>::value;
3535

3636
template <typename LCRangeT, typename LCPropertiesT> struct LaunchConfigAccess;
37+
38+
// Checks that none of the properties in the property list has compile-time
39+
// effects on the kernel.
40+
template <typename T>
41+
struct NoPropertyHasCompileTimeKernelEffect : std::false_type {};
42+
template <typename... Ts>
43+
struct NoPropertyHasCompileTimeKernelEffect<properties_t<Ts...>> {
44+
static constexpr bool value =
45+
!(HasCompileTimeEffect<Ts>::value || ... || false);
46+
};
3747
} // namespace detail
3848

3949
// Available only when Range is range or nd_range
@@ -42,6 +52,11 @@ template <
4252
typename = std::enable_if_t<
4353
ext::oneapi::experimental::detail::is_range_or_nd_range_v<RangeT>>>
4454
class launch_config {
55+
static_assert(ext::oneapi::experimental::detail::
56+
NoPropertyHasCompileTimeKernelEffect<PropertiesT>::value,
57+
"launch_config does not allow properties with compile-time "
58+
"kernel effects.");
59+
4560
public:
4661
launch_config(RangeT Range, PropertiesT Properties = {})
4762
: MRange{Range}, MProperties{Properties} {}
@@ -187,7 +202,8 @@ void parallel_for(handler &CGH,
187202
Properties>
188203
ConfigAccess(Config);
189204
CGH.set_args<ArgsT...>(std::forward<ArgsT>(Args)...);
190-
CGH.parallel_for(ConfigAccess.getRange(), KernelObj);
205+
sycl::detail::HandlerAccess::parallelForImpl(
206+
CGH, ConfigAccess.getRange(), ConfigAccess.getProperties(), KernelObj);
191207
}
192208

193209
template <int Dimensions, typename Properties, typename... ArgsT>
@@ -263,7 +279,8 @@ void nd_launch(handler &CGH,
263279
Properties>
264280
ConfigAccess(Config);
265281
CGH.set_args<ArgsT...>(std::forward<ArgsT>(Args)...);
266-
CGH.parallel_for(ConfigAccess.getRange(), KernelObj);
282+
sycl::detail::HandlerAccess::parallelForImpl(
283+
CGH, ConfigAccess.getRange(), ConfigAccess.getProperties(), KernelObj);
267284
}
268285

269286
template <int Dimensions, typename Properties, typename... ArgsT>

sycl/include/sycl/ext/oneapi/kernel_properties/properties.hpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,19 @@ template <> struct is_property_key<work_item_progress_key> : std::true_type {};
240240

241241
namespace detail {
242242

243+
template <size_t... Dims>
244+
struct HasCompileTimeEffect<work_group_size_key::value_t<Dims...>>
245+
: std::true_type {};
246+
template <size_t... Dims>
247+
struct HasCompileTimeEffect<work_group_size_hint_key::value_t<Dims...>>
248+
: std::true_type {};
249+
template <uint32_t Size>
250+
struct HasCompileTimeEffect<sub_group_size_key::value_t<Size>>
251+
: std::true_type {};
252+
template <sycl::aspect... Aspects>
253+
struct HasCompileTimeEffect<device_has_key::value_t<Aspects...>>
254+
: std::true_type {};
255+
243256
template <size_t Dim0, size_t... Dims>
244257
struct PropertyMetaInfo<work_group_size_key::value_t<Dim0, Dims...>> {
245258
static constexpr const char *name = "sycl-work-group-size";

sycl/include/sycl/ext/oneapi/properties/property.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,8 @@ template <typename PropertyT> struct PropertyMetaInfo {
266266
static constexpr std::nullptr_t value = nullptr;
267267
};
268268

269+
template <typename> struct HasCompileTimeEffect : std::false_type {};
270+
269271
} // namespace detail
270272

271273
template <typename T>

sycl/include/sycl/handler.hpp

Lines changed: 71 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -970,28 +970,11 @@ class __SYCL_EXPORT handler {
970970
}
971971
}
972972

973-
/// Process kernel properties.
973+
/// Process runtime kernel properties.
974974
///
975975
/// Stores information about kernel properties into the handler.
976-
template <
977-
typename KernelName,
978-
typename PropertiesT = ext::oneapi::experimental::empty_properties_t>
979-
void processProperties(PropertiesT Props) {
980-
using KI = detail::KernelInfo<KernelName>;
981-
static_assert(
982-
ext::oneapi::experimental::is_property_list<PropertiesT>::value,
983-
"Template type is not a property list.");
984-
static_assert(
985-
!PropertiesT::template has_property<
986-
sycl::ext::intel::experimental::fp_control_key>() ||
987-
(PropertiesT::template has_property<
988-
sycl::ext::intel::experimental::fp_control_key>() &&
989-
KI::isESIMD()),
990-
"Floating point control property is supported for ESIMD kernels only.");
991-
static_assert(
992-
!PropertiesT::template has_property<
993-
sycl::ext::oneapi::experimental::indirectly_callable_key>(),
994-
"indirectly_callable property cannot be applied to SYCL kernels");
976+
template <typename PropertiesT>
977+
void processLaunchProperties(PropertiesT Props) {
995978
if constexpr (PropertiesT::template has_property<
996979
sycl::ext::intel::experimental::cache_config_key>()) {
997980
auto Config = Props.template get_property<
@@ -1042,6 +1025,32 @@ class __SYCL_EXPORT handler {
10421025
checkAndSetClusterRange(Props);
10431026
}
10441027

1028+
/// Process kernel properties.
1029+
///
1030+
/// Stores information about kernel properties into the handler.
1031+
template <
1032+
typename KernelName,
1033+
typename PropertiesT = ext::oneapi::experimental::empty_properties_t>
1034+
void processProperties(PropertiesT Props) {
1035+
using KI = detail::KernelInfo<KernelName>;
1036+
static_assert(
1037+
ext::oneapi::experimental::is_property_list<PropertiesT>::value,
1038+
"Template type is not a property list.");
1039+
static_assert(
1040+
!PropertiesT::template has_property<
1041+
sycl::ext::intel::experimental::fp_control_key>() ||
1042+
(PropertiesT::template has_property<
1043+
sycl::ext::intel::experimental::fp_control_key>() &&
1044+
KI::isESIMD()),
1045+
"Floating point control property is supported for ESIMD kernels only.");
1046+
static_assert(
1047+
!PropertiesT::template has_property<
1048+
sycl::ext::oneapi::experimental::indirectly_callable_key>(),
1049+
"indirectly_callable property cannot be applied to SYCL kernels");
1050+
1051+
processLaunchProperties(Props);
1052+
}
1053+
10451054
/// Checks whether it is possible to copy the source shape to the destination
10461055
/// shape(the shapes are described by the accessor ranges) by using
10471056
/// copying by regions of memory and not copying element by element
@@ -1440,18 +1449,44 @@ class __SYCL_EXPORT handler {
14401449
///
14411450
/// \param NumWorkItems is a range defining indexing space.
14421451
/// \param Kernel is a SYCL kernel function.
1443-
template <int Dims>
1444-
void parallel_for_impl(range<Dims> NumWorkItems, kernel Kernel) {
1452+
/// \param Properties is the properties.
1453+
template <int Dims, typename PropertiesT>
1454+
void parallel_for_impl(range<Dims> NumWorkItems, PropertiesT Props,
1455+
kernel Kernel) {
14451456
throwIfActionIsCreated();
14461457
MKernel = detail::getSyclObjImpl(std::move(Kernel));
14471458
detail::checkValueRange<Dims>(NumWorkItems);
14481459
setNDRangeDescriptor(std::move(NumWorkItems));
1460+
processLaunchProperties<PropertiesT>(Props);
14491461
setType(detail::CGType::Kernel);
14501462
setNDRangeUsed(false);
14511463
extractArgsAndReqs();
14521464
MKernelName = getKernelName();
14531465
}
14541466

1467+
/// Defines and invokes a SYCL kernel function for the specified range and
1468+
/// offsets.
1469+
///
1470+
/// The SYCL kernel function is defined as SYCL kernel object.
1471+
///
1472+
/// \param NDRange is a ND-range defining global and local sizes as
1473+
/// well as offset.
1474+
/// \param Properties is the properties.
1475+
/// \param Kernel is a SYCL kernel function.
1476+
template <int Dims, typename PropertiesT>
1477+
void parallel_for_impl(nd_range<Dims> NDRange, PropertiesT Props,
1478+
kernel Kernel) {
1479+
throwIfActionIsCreated();
1480+
MKernel = detail::getSyclObjImpl(std::move(Kernel));
1481+
detail::checkValueRange<Dims>(NDRange);
1482+
setNDRangeDescriptor(std::move(NDRange));
1483+
processLaunchProperties(Props);
1484+
setType(detail::CGType::Kernel);
1485+
setNDRangeUsed(true);
1486+
extractArgsAndReqs();
1487+
MKernelName = getKernelName();
1488+
}
1489+
14551490
/// Hierarchical kernel invocation method of a kernel defined as a lambda
14561491
/// encoding the body of each work-group to launch.
14571492
///
@@ -2163,15 +2198,18 @@ class __SYCL_EXPORT handler {
21632198
}
21642199

21652200
void parallel_for(range<1> NumWorkItems, kernel Kernel) {
2166-
parallel_for_impl(NumWorkItems, Kernel);
2201+
parallel_for_impl(NumWorkItems,
2202+
ext::oneapi::experimental::empty_properties_t{}, Kernel);
21672203
}
21682204

21692205
void parallel_for(range<2> NumWorkItems, kernel Kernel) {
2170-
parallel_for_impl(NumWorkItems, Kernel);
2206+
parallel_for_impl(NumWorkItems,
2207+
ext::oneapi::experimental::empty_properties_t{}, Kernel);
21712208
}
21722209

21732210
void parallel_for(range<3> NumWorkItems, kernel Kernel) {
2174-
parallel_for_impl(NumWorkItems, Kernel);
2211+
parallel_for_impl(NumWorkItems,
2212+
ext::oneapi::experimental::empty_properties_t{}, Kernel);
21752213
}
21762214

21772215
/// Defines and invokes a SYCL kernel function for the specified range and
@@ -2205,14 +2243,8 @@ class __SYCL_EXPORT handler {
22052243
/// well as offset.
22062244
/// \param Kernel is a SYCL kernel function.
22072245
template <int Dims> void parallel_for(nd_range<Dims> NDRange, kernel Kernel) {
2208-
throwIfActionIsCreated();
2209-
MKernel = detail::getSyclObjImpl(std::move(Kernel));
2210-
detail::checkValueRange<Dims>(NDRange);
2211-
setNDRangeDescriptor(std::move(NDRange));
2212-
setType(detail::CGType::Kernel);
2213-
setNDRangeUsed(true);
2214-
extractArgsAndReqs();
2215-
MKernelName = getKernelName();
2246+
parallel_for_impl(NDRange, ext::oneapi::experimental::empty_properties_t{},
2247+
Kernel);
22162248
}
22172249

22182250
/// Defines and invokes a SYCL kernel function.
@@ -3741,6 +3773,12 @@ class HandlerAccess {
37413773
static void internalProfilingTagImpl(handler &Handler) {
37423774
Handler.internalProfilingTagImpl();
37433775
}
3776+
3777+
template <typename RangeT, typename PropertiesT>
3778+
static void parallelForImpl(handler &Handler, RangeT Range, PropertiesT Props,
3779+
kernel Kernel) {
3780+
Handler.parallel_for_impl(Range, Props, Kernel);
3781+
}
37443782
};
37453783
} // namespace detail
37463784

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// RUN: %clangxx -ferror-limit=0 %fsycl-host-only -fsyntax-only -Xclang -verify -Xclang -verify-ignore-unexpected=note,warning %s
2+
3+
// Negative tests for kernel properties.
4+
5+
#include <sycl/sycl.hpp>
6+
7+
namespace oneapi = sycl::ext::oneapi::experimental;
8+
9+
extern sycl::kernel TestKernel;
10+
11+
int main() {
12+
sycl::queue Q{};
13+
14+
oneapi::properties props1{oneapi::sub_group_size<8>};
15+
oneapi::properties props2{
16+
oneapi::sub_group_size<8>,
17+
oneapi::work_group_progress<oneapi::forward_progress_guarantee::parallel,
18+
oneapi::execution_scope::root_group>};
19+
20+
// expected-error-re@sycl/ext/oneapi/experimental/enqueue_functions.hpp:* {{static assertion failed due to requirement {{.*}} launch_config does not allow properties with compile-time kernel effects.}}
21+
oneapi::launch_config<sycl::range<1>, decltype(props1)> LC1{{1}, props1};
22+
23+
// expected-error-re@sycl/ext/oneapi/experimental/enqueue_functions.hpp:* {{static assertion failed due to requirement {{.*}} launch_config does not allow properties with compile-time kernel effects.}}
24+
oneapi::launch_config<sycl::range<1>, decltype(props2)> LC22{{1}, props2};
25+
}

sycl/test/extensions/properties/properties_kernel.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,15 @@ int main() {
4242
static_assert(is_property_key<sub_group_size_key>::value);
4343
static_assert(is_property_key<device_has_key>::value);
4444

45+
static_assert(sycl::ext::oneapi::experimental::detail::HasCompileTimeEffect<
46+
work_group_size_key::value_t<1>>::value);
47+
static_assert(sycl::ext::oneapi::experimental::detail::HasCompileTimeEffect<
48+
work_group_size_hint_key::value_t<1>>::value);
49+
static_assert(sycl::ext::oneapi::experimental::detail::HasCompileTimeEffect<
50+
sub_group_size_key::value_t<28>>::value);
51+
static_assert(sycl::ext::oneapi::experimental::detail::HasCompileTimeEffect<
52+
device_has_key::value_t<aspect::fp64>>::value);
53+
4554
static_assert(is_property_value<decltype(work_group_size<1>)>::value);
4655
static_assert(is_property_value<decltype(work_group_size<2, 2>)>::value);
4756
static_assert(is_property_value<decltype(work_group_size<3, 3, 3>)>::value);

sycl/test/extensions/properties/properties_kernel_fpga.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,17 @@ int main() {
1616
static_assert(oneapi::experimental::is_property_key<
1717
intel::experimental::pipelined_key>::value);
1818

19+
// Check that oneapi::experimental::detail::HasCompileTimeEffect is
20+
// correctly specialized
21+
static_assert(oneapi::experimental::detail::HasCompileTimeEffect<
22+
intel::experimental::register_map_interface_key::value_t<
23+
intel::experimental::register_map_interface_options_enum::
24+
wait_for_done_write>>::value);
25+
static_assert(oneapi::experimental::detail::HasCompileTimeEffect<
26+
intel::experimental::streaming_interface_key::value_t<
27+
intel::experimental::streaming_interface_options_enum::
28+
accept_downstream_stall>>::value);
29+
1930
// Check that oneapi::experimental::is_property_value is correctly specialized
2031
static_assert(oneapi::experimental::is_property_value<
2132
decltype(intel::experimental::streaming_interface<

sycl/unittests/Extensions/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ add_sycl_unittest(ExtensionsTests OBJECT
1313
EnqueueFunctionsEvents.cpp
1414
DiscardEvent.cpp
1515
ProfilingTag.cpp
16+
KernelProperties.cpp
1617
)
1718

1819
add_subdirectory(CommandGraph)

0 commit comments

Comments
 (0)