Skip to content

Commit 3ea7d72

Browse files
authored
[SYCL] Implement updates to the root group extension (#22552)
Implement the updates made to the root group extension as described here: #21838
1 parent f2b0f6f commit 3ea7d72

8 files changed

Lines changed: 531 additions & 6 deletions

File tree

sycl/include/sycl/ext/oneapi/get_kernel_info.hpp

Lines changed: 193 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,103 @@ get_kernel_info(const queue &Q) {
6363
return get_kernel_info<KernelName, Param>(Q.get_context(), Q.get_device());
6464
}
6565

66-
// For free functions.
6766
namespace experimental {
6867

68+
// Param must be info::kernel::max_num_work_groups_sync.
69+
template <typename KernelName, typename Param,
70+
typename LaunchProperties = empty_properties_t>
71+
typename std::enable_if_t<
72+
std::is_same_v<Param, sycl::info::kernel::max_num_work_groups_sync>,
73+
typename Param::return_type>
74+
get_kernel_info(const context &ctxt, const device &dev, sycl::range<1> r,
75+
LaunchProperties props = {}, size_t bytes = 0) {
76+
auto bundle =
77+
sycl::get_kernel_bundle<KernelName, sycl::bundle_state::executable>(ctxt);
78+
sycl::kernel k = bundle.template get_kernel<KernelName>();
79+
return k.ext_oneapi_get_info<Param>(dev, r, props, bytes);
80+
}
81+
82+
// Param must be info::kernel::max_num_work_groups_sync.
83+
template <typename KernelName, typename Param,
84+
typename LaunchProperties = empty_properties_t>
85+
typename std::enable_if_t<
86+
std::is_same_v<Param, sycl::info::kernel::max_num_work_groups_sync>,
87+
typename Param::return_type>
88+
get_kernel_info(const context &ctxt, const device &dev, sycl::range<2> r,
89+
LaunchProperties props = {}, size_t bytes = 0) {
90+
auto bundle =
91+
sycl::get_kernel_bundle<KernelName, sycl::bundle_state::executable>(ctxt);
92+
sycl::kernel k = bundle.template get_kernel<KernelName>();
93+
return k.ext_oneapi_get_info<Param>(dev, r, props, bytes);
94+
}
95+
96+
// Param must be info::kernel::max_num_work_groups_sync.
97+
template <typename KernelName, typename Param,
98+
typename LaunchProperties = empty_properties_t>
99+
typename std::enable_if_t<
100+
std::is_same_v<Param, sycl::info::kernel::max_num_work_groups_sync>,
101+
typename Param::return_type>
102+
get_kernel_info(const context &ctxt, const device &dev, sycl::range<3> r,
103+
LaunchProperties props = {}, size_t bytes = 0) {
104+
auto bundle =
105+
sycl::get_kernel_bundle<KernelName, sycl::bundle_state::executable>(ctxt);
106+
sycl::kernel k = bundle.template get_kernel<KernelName>();
107+
return k.ext_oneapi_get_info<Param>(dev, r, props, bytes);
108+
}
109+
110+
// Param must be info::kernel::max_num_work_groups_sync.
111+
template <typename KernelName, typename Param,
112+
typename LaunchProperties = empty_properties_t>
113+
typename std::enable_if_t<
114+
std::is_same_v<Param, sycl::info::kernel::max_num_work_groups_sync>,
115+
typename Param::return_type>
116+
117+
get_kernel_info(const queue &q, sycl::range<1> r,
118+
119+
LaunchProperties props = {}, size_t bytes = 0) {
120+
sycl::context ctxt = q.get_context();
121+
sycl::device dev = q.get_device();
122+
auto bundle =
123+
sycl::get_kernel_bundle<KernelName, sycl::bundle_state::executable>(ctxt);
124+
sycl::kernel k = bundle.template get_kernel<KernelName>();
125+
return k.ext_oneapi_get_info<Param>(dev, r, props, bytes);
126+
}
127+
128+
// Param must be info::kernel::max_num_work_groups_sync.
129+
template <typename KernelName, typename Param,
130+
typename LaunchProperties = empty_properties_t>
131+
typename std::enable_if_t<
132+
std::is_same_v<Param, sycl::info::kernel::max_num_work_groups_sync>,
133+
typename Param::return_type>
134+
135+
get_kernel_info(const queue &q, sycl::range<2> r, LaunchProperties props = {},
136+
size_t bytes = 0) {
137+
sycl::context ctxt = q.get_context();
138+
sycl::device dev = q.get_device();
139+
auto bundle =
140+
sycl::get_kernel_bundle<KernelName, sycl::bundle_state::executable>(ctxt);
141+
sycl::kernel k = bundle.template get_kernel<KernelName>();
142+
return k.ext_oneapi_get_info<Param>(dev, r, props, bytes);
143+
}
144+
145+
// Param must be info::kernel::max_num_work_groups_sync.
146+
template <typename KernelName, typename Param,
147+
typename LaunchProperties = empty_properties_t>
148+
typename std::enable_if_t<
149+
std::is_same_v<Param, sycl::info::kernel::max_num_work_groups_sync>,
150+
typename Param::return_type>
151+
152+
get_kernel_info(const queue &q, sycl::range<3> r, LaunchProperties props = {},
153+
size_t bytes = 0) {
154+
sycl::context ctxt = q.get_context();
155+
sycl::device dev = q.get_device();
156+
auto bundle =
157+
sycl::get_kernel_bundle<KernelName, sycl::bundle_state::executable>(ctxt);
158+
sycl::kernel k = bundle.template get_kernel<KernelName>();
159+
return k.ext_oneapi_get_info<Param>(dev, r, props, bytes);
160+
}
161+
162+
// For free functions.
69163
template <auto *Func, typename Param>
70164
std::enable_if_t<ext::oneapi::experimental::is_kernel_v<Func>,
71165
typename sycl::detail::is_kernel_info_desc<Param>::return_type>
@@ -106,6 +200,104 @@ get_kernel_info(const context &, const device &) {
106200
return sycl::detail::FreeFunctionInfoData<Func>::getNumParams();
107201
}
108202

203+
// Param must be equal to max_num_work_groups_sync.
204+
template <auto *Func, typename Param,
205+
typename LaunchProperties = empty_properties_t>
206+
std::enable_if_t<
207+
sycl::ext::oneapi::experimental::is_kernel_v<Func> &&
208+
std::is_same_v<Param, sycl::info::kernel::max_num_work_groups_sync>,
209+
typename Param::return_type>
210+
get_kernel_info(const context &ctxt, const device &dev, sycl::range<1> r,
211+
LaunchProperties props = {}, size_t bytes = 0) {
212+
auto bundle = sycl::ext::oneapi::experimental::get_kernel_bundle<
213+
Func, sycl::bundle_state::executable>(ctxt);
214+
sycl::kernel k = bundle.template ext_oneapi_get_kernel<Func>();
215+
return k.ext_oneapi_get_info<Param>(dev, r, props, bytes);
216+
}
217+
218+
// Param must be equal to max_num_work_groups_sync.
219+
template <auto *Func, typename Param,
220+
typename LaunchProperties = empty_properties_t>
221+
std::enable_if_t<
222+
sycl::ext::oneapi::experimental::is_kernel_v<Func> &&
223+
std::is_same_v<Param, sycl::info::kernel::max_num_work_groups_sync>,
224+
typename Param::return_type>
225+
226+
get_kernel_info(const context &ctxt, const device &dev, sycl::range<2> r,
227+
LaunchProperties props = {}, size_t bytes = 0) {
228+
auto bundle = sycl::ext::oneapi::experimental::get_kernel_bundle<
229+
Func, sycl::bundle_state::executable>(ctxt);
230+
sycl::kernel k = bundle.template ext_oneapi_get_kernel<Func>();
231+
return k.ext_oneapi_get_info<Param>(dev, r, props, bytes);
232+
}
233+
234+
// Param must be equal to max_num_work_groups_sync.
235+
template <auto *Func, typename Param,
236+
typename LaunchProperties = empty_properties_t>
237+
std::enable_if_t<
238+
sycl::ext::oneapi::experimental::is_kernel_v<Func> &&
239+
std::is_same_v<Param, sycl::info::kernel::max_num_work_groups_sync>,
240+
typename Param::return_type>
241+
242+
get_kernel_info(const context &ctxt, const device &dev, sycl::range<3> r,
243+
LaunchProperties props = {}, size_t bytes = 0) {
244+
auto bundle = sycl::ext::oneapi::experimental::get_kernel_bundle<
245+
Func, sycl::bundle_state::executable>(ctxt);
246+
sycl::kernel k = bundle.template ext_oneapi_get_kernel<Func>();
247+
return k.ext_oneapi_get_info<Param>(dev, r, props, bytes);
248+
}
249+
250+
// Param must be equal to max_num_work_groups_sync.
251+
template <auto *Func, typename Param,
252+
typename LaunchProperties = empty_properties_t>
253+
std::enable_if_t<
254+
sycl::ext::oneapi::experimental::is_kernel_v<Func> &&
255+
std::is_same_v<Param, sycl::info::kernel::max_num_work_groups_sync>,
256+
typename Param::return_type>
257+
get_kernel_info(const queue &q, sycl::range<1> r, LaunchProperties props = {},
258+
size_t bytes = 0) {
259+
sycl::context ctxt = q.get_context();
260+
sycl::device dev = q.get_device();
261+
auto bundle = sycl::ext::oneapi::experimental::get_kernel_bundle<
262+
Func, sycl::bundle_state::executable>(ctxt);
263+
sycl::kernel k = bundle.template ext_oneapi_get_kernel<Func>();
264+
return k.ext_oneapi_get_info<Param>(dev, r, props, bytes);
265+
}
266+
267+
// Param must be equal to max_num_work_groups_sync.
268+
template <auto *Func, typename Param,
269+
typename LaunchProperties = empty_properties_t>
270+
std::enable_if_t<
271+
sycl::ext::oneapi::experimental::is_kernel_v<Func> &&
272+
std::is_same_v<Param, sycl::info::kernel::max_num_work_groups_sync>,
273+
typename Param::return_type>
274+
get_kernel_info(const queue &q, sycl::range<2> r, LaunchProperties props = {},
275+
size_t bytes = 0) {
276+
sycl::context ctxt = q.get_context();
277+
sycl::device dev = q.get_device();
278+
auto bundle = sycl::ext::oneapi::experimental::get_kernel_bundle<
279+
Func, sycl::bundle_state::executable>(ctxt);
280+
sycl::kernel k = bundle.template ext_oneapi_get_kernel<Func>();
281+
return k.ext_oneapi_get_info<Param>(dev, r, props, bytes);
282+
}
283+
284+
// Param must be equal to max_num_work_groups_sync.
285+
template <auto *Func, typename Param,
286+
typename LaunchProperties = empty_properties_t>
287+
std::enable_if_t<
288+
sycl::ext::oneapi::experimental::is_kernel_v<Func> &&
289+
std::is_same_v<Param, sycl::info::kernel::max_num_work_groups_sync>,
290+
typename Param::return_type>
291+
get_kernel_info(const queue &q, sycl::range<3> r, LaunchProperties props = {},
292+
size_t bytes = 0) {
293+
sycl::context ctxt = q.get_context();
294+
sycl::device dev = q.get_device();
295+
auto bundle = sycl::ext::oneapi::experimental::get_kernel_bundle<
296+
Func, sycl::bundle_state::executable>(ctxt);
297+
sycl::kernel k = bundle.template ext_oneapi_get_kernel<Func>();
298+
return k.ext_oneapi_get_info<Param>(dev, r, props, bytes);
299+
}
300+
109301
} // namespace experimental
110302
} // namespace ext::oneapi
111303
} // namespace _V1

sycl/include/sycl/info/kernel.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,12 @@ class context;
2323

2424
namespace info {
2525

26-
// A.5 Kernel information desctiptors
26+
// A.5 Kernel information descriptors
2727
namespace kernel {
28+
struct max_num_work_groups_sync {
29+
using return_type = size_t;
30+
};
31+
2832
template <ur_kernel_info_t UrCode>
2933
using kernel_traits =
3034
sycl::detail::ur_traits_base<sycl::detail::info_class::kernel, UrCode>;

sycl/include/sycl/kernel.hpp

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
#include <sycl/detail/export.hpp> // for __SYCL_EXPORT
1414
#include <sycl/detail/owner_less_base.hpp> // for OwnerLessBase
1515
#include <sycl/detail/util.hpp>
16+
#include <sycl/ext/intel/experimental/kernel_execution_properties.hpp> // for cache_config
17+
#include <sycl/ext/oneapi/properties.hpp> // for empty_properties_t
18+
#include <sycl/ext/oneapi/work_group_scratch_memory.hpp> // for work_group_scratch_size
1619
#include <sycl/info/kernel.hpp> // for is_kernel_device_specif...
1720
#include <sycl/kernel_bundle_enums.hpp> // for bundle_state
1821
#include <unified-runtime/ur_api.h> // for ur_native_handle_t
@@ -253,6 +256,75 @@ class __SYCL_EXPORT kernel : public detail::OwnerLessBase<kernel> {
253256
typename detail::is_kernel_queue_specific_info_desc<Param>::return_type
254257
ext_oneapi_get_info(queue Queue, const range<1> &WG) const;
255258

259+
/// Query the maximum number of work-groups that are allowed when the kernel
260+
/// uses root-group synchronization, assuming the kernel is launched with a
261+
/// work-group size of r, kernel launch properties props, and bytes bytes of
262+
/// dynamic work-group local memory. If the kernel can be submitted to the
263+
/// device without an error, the minimum value returned by this query is 1,
264+
/// otherwise it is 0. Param must be equal to max_num_work_groups_sync.
265+
/// \param Dev is a valid SYCL device
266+
/// \param Range is the execution range of the kernel
267+
/// \param Props are the launch properties of the kernel
268+
/// \param Bytes is the amount of dynamic work group local memory allocated by
269+
/// the kernel
270+
template <
271+
typename Param,
272+
typename LaunchProperties = ext::oneapi::experimental::empty_properties_t,
273+
typename = std::enable_if_t<
274+
std::is_same_v<Param, info::kernel::max_num_work_groups_sync>, void>>
275+
typename Param::return_type
276+
ext_oneapi_get_info(const device &Dev, sycl::range<1> Range,
277+
LaunchProperties Props = {}, size_t Bytes = 0) const {
278+
return queryMaxNumWorkGroups<1>(Dev, Range, Bytes,
279+
ProcessLaunchProperties(Props));
280+
}
281+
282+
/// Query the maximum number of work-groups that are allowed when the kernel
283+
/// uses root-group synchronization, assuming the kernel is launched with a
284+
/// work-group size of r, kernel launch properties props, and bytes bytes of
285+
/// dynamic work-group local memory. If the kernel can be submitted to the
286+
/// device without an error, the minimum value returned by this query is 1,
287+
/// otherwise it is 0. Param must be equal to max_num_work_groups_sync.
288+
/// \param Dev is a valid SYCL device
289+
/// \param Range is the execution range of the kernel
290+
/// \param Props are the launch properties of the kernel
291+
/// \param Bytes is the amount of dynamic work group local memory allocated by
292+
/// the kernel
293+
template <
294+
typename Param,
295+
typename LaunchProperties = ext::oneapi::experimental::empty_properties_t,
296+
typename = std::enable_if_t<
297+
std::is_same_v<Param, info::kernel::max_num_work_groups_sync>, void>>
298+
typename Param::return_type
299+
ext_oneapi_get_info(const device &Dev, sycl::range<2> Range,
300+
LaunchProperties Props = {}, size_t Bytes = 0) const {
301+
return queryMaxNumWorkGroups<2>(Dev, Range, Bytes,
302+
ProcessLaunchProperties(Props));
303+
}
304+
305+
/// Query the maximum number of work-groups that are allowed when the kernel
306+
/// uses root-group synchronization, assuming the kernel is launched with a
307+
/// work-group size of r, kernel launch properties props, and bytes bytes of
308+
/// dynamic work-group local memory. If the kernel can be submitted to the
309+
/// device without an error, the minimum value returned by this query is 1,
310+
/// otherwise it is 0. Param must be equal to max_num_work_groups_sync.
311+
/// \param Dev is a valid SYCL device
312+
/// \param Range is the execution range of the kernel
313+
/// \param Props are the launch properties of the kernel
314+
/// \param Bytes is the amount of dynamic work group local memory allocated by
315+
/// the kernel
316+
template <
317+
typename Param,
318+
typename LaunchProperties = ext::oneapi::experimental::empty_properties_t,
319+
typename = std::enable_if_t<
320+
std::is_same_v<Param, info::kernel::max_num_work_groups_sync>, void>>
321+
typename Param::return_type
322+
ext_oneapi_get_info(const device &Dev, sycl::range<3> Range,
323+
LaunchProperties Props = {}, size_t Bytes = 0) const {
324+
return queryMaxNumWorkGroups<3>(Dev, Range, Bytes,
325+
ProcessLaunchProperties(Props));
326+
}
327+
256328
private:
257329
/// Constructs a SYCL kernel object from a valid kernel_impl instance.
258330
kernel(std::shared_ptr<detail::kernel_impl> Impl);
@@ -268,6 +340,47 @@ class __SYCL_EXPORT kernel : public detail::OwnerLessBase<kernel> {
268340
typename detail::ABINeutralT_t<
269341
typename detail::is_kernel_info_desc<Param>::return_type>
270342
get_info_impl() const;
343+
344+
// The type below bundles together some execution information for the kernel
345+
// such as the amount of dynamic work group memory requested represented by
346+
// DynamicWorkGroupMem and the cache config setting represented by
347+
// CacheConfig.
348+
struct KernelExecInfoTy {
349+
size_t DynamicWorkGroupMem;
350+
ur_kernel_cache_config_t CacheConfig;
351+
};
352+
353+
template <int Dimensions>
354+
size_t queryMaxNumWorkGroups(const device &Dev, sycl::range<Dimensions> Range,
355+
size_t Bytes, KernelExecInfoTy ExecInfo) const;
356+
357+
template <
358+
typename LaunchProperties = ext::oneapi::experimental::empty_properties_t>
359+
KernelExecInfoTy ProcessLaunchProperties(LaunchProperties Props) const {
360+
ur_kernel_cache_config_t CacheConfig =
361+
ur_kernel_cache_config_t::UR_KERNEL_CACHE_CONFIG_DEFAULT;
362+
size_t DynamicLocalMem = 0;
363+
if constexpr (LaunchProperties::template has_property<
364+
ext::intel::experimental::cache_config_key>()) {
365+
auto prop = Props.template get_property<
366+
ext::intel::experimental::cache_config_key>();
367+
if (prop.value == ext::intel::experimental::cache_config_enum::large_slm)
368+
CacheConfig =
369+
ur_kernel_cache_config_t::UR_KERNEL_CACHE_CONFIG_LARGE_SLM;
370+
else if (prop.value ==
371+
ext::intel::experimental::cache_config_enum::large_data) {
372+
CacheConfig =
373+
ur_kernel_cache_config_t::UR_KERNEL_CACHE_CONFIG_LARGE_DATA;
374+
}
375+
}
376+
if constexpr (LaunchProperties::template has_property<
377+
ext::oneapi::experimental::work_group_scratch_size>()) {
378+
auto prop = Props.template get_property<
379+
ext::oneapi::experimental::work_group_scratch_size>();
380+
DynamicLocalMem = prop.size;
381+
}
382+
return {DynamicLocalMem, CacheConfig};
383+
}
271384
};
272385
} // namespace _V1
273386
} // namespace sycl

sycl/source/detail/kernel_impl.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,10 @@ class kernel_impl {
243243
: ProgramManager::getInstance().getDeviceKernelInfo(
244244
std::string_view(getName()));
245245
}
246+
template <int Dimensions>
247+
size_t queryMaxNumWorkGroups(queue Queue,
248+
const range<Dimensions> &WorkGroupSize,
249+
size_t DynamicLocalMemorySize) const;
246250

247251
private:
248252
Managed<ur_kernel_handle_t> MKernel;
@@ -273,10 +277,6 @@ class kernel_impl {
273277
bool exceedsOccupancyResourceLimits(const device &Device,
274278
const range<Dimensions> &WorkGroupSize,
275279
size_t DynamicLocalMemorySize) const;
276-
template <int Dimensions>
277-
size_t queryMaxNumWorkGroups(queue Queue,
278-
const range<Dimensions> &WorkGroupSize,
279-
size_t DynamicLocalMemorySize) const;
280280

281281
void enableUSMIndirectAccess() const;
282282
std::optional<unsigned> getFreeFuncKernelArgSize() const;

0 commit comments

Comments
 (0)