Skip to content

Commit d71b158

Browse files
[NFCI][SYCL] Introduce oneapi::experimental::detail::property_base (#15993)
This lays some ground base for subsequent refactoring PRs by isolating simple but noisy diff into a separate change. We're anticipating at least two changes that would be built on top of this: * Change implementation of `has_property`/`get_property` to be inheritance-based vs type-lists/boost. * Bigger design-wise refactoring of the compile time properties, e.g. removal of `property_value` class template.
1 parent bcdfc02 commit d71b158

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)