Skip to content

Commit ae040f9

Browse files
[NFCI][SYCL] Introduce oneapi::experimental::detail::property_base
We're planning a refactoring of the compile-timer properties design. One part of it would be to eliminate `property_value` class template and instead use inheritance to simplify properties' creation/implement infrastructure for properties lists. This PR is the first change in that direction. It doesn't bring new functionality but introduces the necessary base class in all existing properties and ensures (via static_assert) that any new property added will have to make use of it as well. Having it in-tree already will simplify subsequent PRs.
1 parent 4d00087 commit ae040f9

File tree

12 files changed

+189
-101
lines changed

12 files changed

+189
-101
lines changed

sycl/include/sycl/ext/intel/esimd/memory_properties.hpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -289,22 +289,34 @@ namespace ext::oneapi::experimental {
289289

290290
template <__ESIMD_NS::cache_hint Hint>
291291
struct property_value<__ESIMD_NS::cache_hint_L1_key,
292-
std::integral_constant<__ESIMD_NS::cache_hint, Hint>> {
293-
using key_t = __ESIMD_NS::cache_hint_L1_key;
292+
std::integral_constant<__ESIMD_NS::cache_hint, Hint>>
293+
: detail::property_base<
294+
property_value<__ESIMD_NS::cache_hint_L1_key,
295+
std::integral_constant<__ESIMD_NS::cache_hint, Hint>>,
296+
oneapi::experimental::detail::PropKind::ESIMDL1CacheHint,
297+
__ESIMD_NS::cache_hint_L1_key> {
294298
static constexpr __ESIMD_NS::cache_level level = __ESIMD_NS::cache_level::L1;
295299
static constexpr __ESIMD_NS::cache_hint hint = Hint;
296300
};
297301
template <__ESIMD_NS::cache_hint Hint>
298302
struct property_value<__ESIMD_NS::cache_hint_L2_key,
299-
std::integral_constant<__ESIMD_NS::cache_hint, Hint>> {
300-
using key_t = __ESIMD_NS::cache_hint_L2_key;
303+
std::integral_constant<__ESIMD_NS::cache_hint, Hint>>
304+
: detail::property_base<
305+
property_value<__ESIMD_NS::cache_hint_L2_key,
306+
std::integral_constant<__ESIMD_NS::cache_hint, Hint>>,
307+
oneapi::experimental::detail::PropKind::ESIMDL2CacheHint,
308+
__ESIMD_NS::cache_hint_L2_key> {
301309
static constexpr __ESIMD_NS::cache_level level = __ESIMD_NS::cache_level::L2;
302310
static constexpr __ESIMD_NS::cache_hint hint = Hint;
303311
};
304312
template <__ESIMD_NS::cache_hint Hint>
305313
struct property_value<__ESIMD_NS::cache_hint_L3_key,
306-
std::integral_constant<__ESIMD_NS::cache_hint, Hint>> {
307-
using key_t = __ESIMD_NS::cache_hint_L3_key;
314+
std::integral_constant<__ESIMD_NS::cache_hint, Hint>>
315+
: detail::property_base<
316+
property_value<__ESIMD_NS::cache_hint_L3_key,
317+
std::integral_constant<__ESIMD_NS::cache_hint, Hint>>,
318+
oneapi::experimental::detail::PropKind::ESIMDL3CacheHint,
319+
__ESIMD_NS::cache_hint_L3_key> {
308320
static constexpr __ESIMD_NS::cache_level level = __ESIMD_NS::cache_level::L3;
309321
static constexpr __ESIMD_NS::cache_hint hint = Hint;
310322
};

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@ inline constexpr cache_config_enum large_slm =
2626
inline constexpr cache_config_enum large_data =
2727
cache_config_enum::large_data;
2828

29-
struct cache_config : oneapi::experimental::detail::run_time_property_key<
30-
oneapi::experimental::detail::PropKind::CacheConfig> {
29+
struct cache_config
30+
: oneapi::experimental::detail::run_time_property_key<
31+
cache_config, oneapi::experimental::detail::PropKind::CacheConfig> {
3132
cache_config(cache_config_enum v) : value(v) {}
3233
cache_config_enum value;
3334
};

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ namespace cuda {
1919
template <int Dim>
2020
struct cluster_size
2121
: ::sycl::ext::oneapi::experimental::detail::run_time_property_key<
22+
cluster_size<Dim>,
2223
::sycl::ext::oneapi::experimental::detail::ClusterLaunch> {
2324
cluster_size(const range<Dim> &size) : size(size) {}
2425
sycl::range<Dim> get_cluster_size() { return size; }

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

Lines changed: 68 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,15 @@ struct device_has_key
6060
std::integral_constant<aspect, Aspects>...>;
6161
};
6262

63-
struct nd_range_kernel_key {
63+
struct nd_range_kernel_key
64+
: detail::compile_time_property_key<detail::PropKind::NDRangeKernel> {
6465
template <int Dims>
6566
using value_t =
6667
property_value<nd_range_kernel_key, std::integral_constant<int, Dims>>;
6768
};
6869

69-
struct single_task_kernel_key {
70+
struct single_task_kernel_key
71+
: detail::compile_time_property_key<detail::PropKind::SingleTaskKernel> {
7072
using value_t = property_value<single_task_kernel_key>;
7173
};
7274

@@ -87,15 +89,18 @@ struct max_linear_work_group_size_key
8789

8890
template <size_t Dim0, size_t... Dims>
8991
struct property_value<work_group_size_key, std::integral_constant<size_t, Dim0>,
90-
std::integral_constant<size_t, Dims>...> {
92+
std::integral_constant<size_t, Dims>...>
93+
: detail::property_base<
94+
property_value<work_group_size_key,
95+
std::integral_constant<size_t, Dim0>,
96+
std::integral_constant<size_t, Dims>...>,
97+
detail::PropKind::WorkGroupSize, work_group_size_key> {
9198
static_assert(
9299
sizeof...(Dims) + 1 <= 3,
93100
"work_group_size property currently only supports up to three values.");
94101
static_assert(detail::AllNonZero<Dim0, Dims...>::value,
95102
"work_group_size property must only contain non-zero values.");
96103

97-
using key_t = work_group_size_key;
98-
99104
constexpr size_t operator[](int Dim) const {
100105
return std::array<size_t, sizeof...(Dims) + 1>{Dim0, Dims...}[Dim];
101106
}
@@ -104,75 +109,94 @@ struct property_value<work_group_size_key, std::integral_constant<size_t, Dim0>,
104109
template <size_t Dim0, size_t... Dims>
105110
struct property_value<work_group_size_hint_key,
106111
std::integral_constant<size_t, Dim0>,
107-
std::integral_constant<size_t, Dims>...> {
112+
std::integral_constant<size_t, Dims>...>
113+
: detail::property_base<
114+
property_value<work_group_size_hint_key,
115+
std::integral_constant<size_t, Dim0>,
116+
std::integral_constant<size_t, Dims>...>,
117+
detail::PropKind::WorkGroupSizeHint, work_group_size_hint_key> {
108118
static_assert(sizeof...(Dims) + 1 <= 3,
109119
"work_group_size_hint property currently "
110120
"only supports up to three values.");
111121
static_assert(
112122
detail::AllNonZero<Dim0, Dims...>::value,
113123
"work_group_size_hint property must only contain non-zero values.");
114124

115-
using key_t = work_group_size_hint_key;
116-
117125
constexpr size_t operator[](int Dim) const {
118126
return std::array<size_t, sizeof...(Dims) + 1>{Dim0, Dims...}[Dim];
119127
}
120128
};
121129

122130
template <uint32_t Size>
123131
struct property_value<sub_group_size_key,
124-
std::integral_constant<uint32_t, Size>> {
132+
std::integral_constant<uint32_t, Size>>
133+
: detail::property_base<
134+
property_value<sub_group_size_key,
135+
std::integral_constant<uint32_t, Size>>,
136+
detail::PropKind::SubGroupSize, sub_group_size_key> {
125137
static_assert(Size != 0,
126138
"sub_group_size_key property must contain a non-zero value.");
127139

128-
using key_t = sub_group_size_key;
129140
using value_t = std::integral_constant<uint32_t, Size>;
130141
static constexpr uint32_t value = Size;
131142
};
132143

133144
template <aspect... Aspects>
134145
struct property_value<device_has_key,
135-
std::integral_constant<aspect, Aspects>...> {
136-
using key_t = device_has_key;
146+
std::integral_constant<aspect, Aspects>...>
147+
: detail::property_base<
148+
property_value<device_has_key,
149+
std::integral_constant<aspect, Aspects>...>,
150+
detail::PropKind::DeviceHas, device_has_key> {
137151
static constexpr std::array<aspect, sizeof...(Aspects)> value{Aspects...};
138152
};
139153

140154
template <int Dims>
141-
struct property_value<nd_range_kernel_key, std::integral_constant<int, Dims>> {
155+
struct property_value<nd_range_kernel_key, std::integral_constant<int, Dims>>
156+
: detail::property_base<property_value<nd_range_kernel_key,
157+
std::integral_constant<int, Dims>>,
158+
detail::PropKind::NDRangeKernel,
159+
nd_range_kernel_key> {
142160
static_assert(
143161
Dims >= 1 && Dims <= 3,
144162
"nd_range_kernel_key property must use dimension of 1, 2 or 3.");
145163

146-
using key_t = nd_range_kernel_key;
147164
using value_t = int;
148165
static constexpr int dimensions = Dims;
149166
};
150167

151-
template <> struct property_value<single_task_kernel_key> {
152-
using key_t = single_task_kernel_key;
153-
};
168+
template <>
169+
struct property_value<single_task_kernel_key>
170+
: detail::property_base<property_value<single_task_kernel_key>,
171+
detail::PropKind::SingleTaskKernel,
172+
single_task_kernel_key> {};
154173

155174
template <size_t Dim0, size_t... Dims>
156175
struct property_value<max_work_group_size_key,
157176
std::integral_constant<size_t, Dim0>,
158-
std::integral_constant<size_t, Dims>...> {
177+
std::integral_constant<size_t, Dims>...>
178+
: detail::property_base<
179+
property_value<max_work_group_size_key,
180+
std::integral_constant<size_t, Dim0>,
181+
std::integral_constant<size_t, Dims>...>,
182+
detail::PropKind::MaxWorkGroupSize, max_work_group_size_key> {
159183
static_assert(sizeof...(Dims) + 1 <= 3,
160184
"max_work_group_size property currently "
161185
"only supports up to three values.");
162186
static_assert(
163187
detail::AllNonZero<Dim0, Dims...>::value,
164188
"max_work_group_size property must only contain non-zero values.");
165189

166-
using key_t = max_work_group_size_key;
167-
168190
constexpr size_t operator[](int Dim) const {
169191
return std::array<size_t, sizeof...(Dims) + 1>{Dim0, Dims...}[Dim];
170192
}
171193
};
172194

173-
template <> struct property_value<max_linear_work_group_size_key> {
174-
using key_t = max_linear_work_group_size_key;
175-
};
195+
template <>
196+
struct property_value<max_linear_work_group_size_key>
197+
: detail::property_base<property_value<max_linear_work_group_size_key>,
198+
detail::PropKind::MaxLinearWorkGroupSize,
199+
max_linear_work_group_size_key> {};
176200

177201
template <size_t Dim0, size_t... Dims>
178202
inline constexpr work_group_size_key::value_t<Dim0, Dims...> work_group_size;
@@ -235,8 +259,13 @@ template <forward_progress_guarantee Guarantee,
235259
struct property_value<
236260
work_group_progress_key,
237261
std::integral_constant<forward_progress_guarantee, Guarantee>,
238-
std::integral_constant<execution_scope, CoordinationScope>> {
239-
using key_t = work_group_progress_key;
262+
std::integral_constant<execution_scope, CoordinationScope>>
263+
: detail::property_base<
264+
property_value<
265+
work_group_progress_key,
266+
std::integral_constant<forward_progress_guarantee, Guarantee>,
267+
std::integral_constant<execution_scope, CoordinationScope>>,
268+
detail::PropKind::WorkGroupProgress, work_group_progress_key> {
240269
static constexpr forward_progress_guarantee guarantee = Guarantee;
241270
static constexpr execution_scope coordinationScope = CoordinationScope;
242271
};
@@ -246,8 +275,13 @@ template <forward_progress_guarantee Guarantee,
246275
struct property_value<
247276
sub_group_progress_key,
248277
std::integral_constant<forward_progress_guarantee, Guarantee>,
249-
std::integral_constant<execution_scope, CoordinationScope>> {
250-
using key_t = work_group_progress_key;
278+
std::integral_constant<execution_scope, CoordinationScope>>
279+
: detail::property_base<
280+
property_value<
281+
sub_group_progress_key,
282+
std::integral_constant<forward_progress_guarantee, Guarantee>,
283+
std::integral_constant<execution_scope, CoordinationScope>>,
284+
detail::PropKind::SubGroupProgress, sub_group_progress_key> {
251285
static constexpr forward_progress_guarantee guarantee = Guarantee;
252286
static constexpr execution_scope coordinationScope = CoordinationScope;
253287
};
@@ -257,8 +291,13 @@ template <forward_progress_guarantee Guarantee,
257291
struct property_value<
258292
work_item_progress_key,
259293
std::integral_constant<forward_progress_guarantee, Guarantee>,
260-
std::integral_constant<execution_scope, CoordinationScope>> {
261-
using key_t = work_group_progress_key;
294+
std::integral_constant<execution_scope, CoordinationScope>>
295+
: detail::property_base<
296+
property_value<
297+
work_item_progress_key,
298+
std::integral_constant<forward_progress_guarantee, Guarantee>,
299+
std::integral_constant<execution_scope, CoordinationScope>>,
300+
detail::PropKind::WorkItemProgress, work_item_progress_key> {
262301
static constexpr forward_progress_guarantee guarantee = Guarantee;
263302
static constexpr execution_scope coordinationScope = CoordinationScope;
264303
};

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,15 @@ struct property_value<
5858
intel::experimental::latency_constraint_key,
5959
std::integral_constant<int, Target>,
6060
std::integral_constant<intel::experimental::latency_control_type, Type>,
61-
std::integral_constant<int, Cycle>> {
62-
using key_t = intel::experimental::latency_constraint_key;
61+
std::integral_constant<int, Cycle>>
62+
: detail::property_base<
63+
property_value<intel::experimental::latency_constraint_key,
64+
std::integral_constant<int, Target>,
65+
std::integral_constant<
66+
intel::experimental::latency_control_type, Type>,
67+
std::integral_constant<int, Cycle>>,
68+
oneapi::experimental::detail::PropKind::LatencyConstraint,
69+
intel::experimental::latency_constraint_key> {
6370
static constexpr int target = Target;
6471
static constexpr intel::experimental::latency_control_type type = Type;
6572
static constexpr int cycle = Cycle;

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,10 @@ template <typename PropertiesT> class properties {
200200
static_assert(NumContainedProps == sizeof...(PropertyValueTs),
201201
"One or more property argument is not a property in the "
202202
"property list.");
203+
// We're in process of refactoring properties infrastructure, make sure that
204+
// any newly added properties use `detail::property_base`!
205+
static_assert(
206+
(std::is_base_of_v<detail::property_tag, PropertyValueTs> && ...));
203207
}
204208

205209
template <typename PropertyT>

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

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ enum PropKind : uint32_t {
9494
namespace sycl::ext::oneapi::experimental {
9595
9696
// (2.)
97-
struct foo : detail::run_time_property_key<PropKind::Foo> {
97+
struct foo : detail::run_time_property_key<foo, PropKind::Foo> {
9898
foo(int v) : value(v) {}
9999
int value;
100100
};
@@ -215,10 +215,35 @@ enum PropKind : uint32_t {
215215
PropKindSize = 79,
216216
};
217217

218+
template <typename PropertyT> struct PropertyToKind {
219+
static constexpr PropKind Kind = PropertyT::Kind;
220+
};
221+
222+
struct property_tag {};
223+
template <typename property_t, PropKind Kind,
224+
typename property_key_t = property_t>
225+
struct property_base : property_tag {
226+
using key_t = property_key_t;
227+
#if !defined(_MSC_VER)
228+
// Temporary, to ensure new code matches previous behavior and to catch any
229+
// silly copy-paste mistakes. MSVC can't compile it, but linux-only is enough
230+
// for this temporary check.
231+
static_assert([]() constexpr {
232+
if constexpr (std::is_same_v<property_t, key_t>)
233+
// key_t is incomplete at this point for runtime properties.
234+
return true;
235+
else
236+
return Kind == PropertyToKind<key_t>::Kind;
237+
}());
238+
#endif
239+
};
240+
218241
struct property_key_base_tag {};
219242
struct compile_time_property_key_base_tag : property_key_base_tag {};
220243

221-
template <PropKind Kind_> struct run_time_property_key : property_key_base_tag {
244+
template <typename property_t, PropKind Kind_>
245+
struct run_time_property_key : property_key_base_tag,
246+
property_base<property_t, Kind_> {
222247
protected:
223248
static constexpr PropKind Kind = Kind_;
224249

@@ -235,12 +260,6 @@ struct compile_time_property_key : compile_time_property_key_base_tag {
235260
friend struct PropertyToKind;
236261
};
237262

238-
// This trait must be specialized for all properties and must have a unique
239-
// constexpr PropKind member named Kind.
240-
template <typename PropertyT> struct PropertyToKind {
241-
static constexpr PropKind Kind = PropertyT::Kind;
242-
};
243-
244263
// Get unique ID for property.
245264
template <typename PropertyT> struct PropertyID {
246265
static constexpr int value =

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,11 @@ struct PropertyValueBase<T> : public detail::SingleNontypePropertyValueBase<T> {
4141
} // namespace detail
4242

4343
template <typename PropertyT, typename... Ts>
44-
struct property_value : public detail::PropertyValueBase<Ts...> {
45-
using key_t = PropertyT;
46-
};
44+
struct property_value
45+
: public detail::PropertyValueBase<Ts...>,
46+
public detail::property_base<property_value<PropertyT, Ts...>,
47+
detail::PropertyToKind<PropertyT>::Kind,
48+
PropertyT> {};
4749

4850
template <typename PropertyT, typename... A, typename... B>
4951
constexpr std::enable_if_t<detail::IsCompileTimeProperty<PropertyT>::value,

0 commit comments

Comments
 (0)