44#ifdef SYCL_LANGUAGE_VERSION
46#include <sycl/sycl.hpp>
83#if defined(SYCL_LANGUAGE_VERSION) && defined(BUILD_SYCL_MODULE)
93inline size_t PreferredWorkGroupSize(
const sycl::device&
sycl_device) {
95 sycl_device.get_info<sycl::info::device::max_work_group_size>();
96 size_t wg = std::min<size_t>(256, max_wg);
97 auto sg_sizes =
sycl_device.get_info<sycl::info::device::sub_group_sizes>();
98 size_t sg = sg_sizes.empty()
100 : *std::max_element(sg_sizes.begin(), sg_sizes.end());
101 if (sg > 1 && wg >= sg) {
104 return std::max<size_t>(wg, 1);
110inline size_t PreferredWorkGroupSize(
const Device& device) {
111 return PreferredWorkGroupSize(
GetQueue(device).get_device());
122inline size_t MaxWorkGroupSizeForSLM(
const sycl::device&
sycl_device,
123 size_t slm_bytes_per_wi,
125 size_t wg =
sycl_device.get_info<sycl::info::device::max_work_group_size>();
126 if (slm_bytes_per_wi > 0) {
127 size_t local_mem_size =
128 sycl_device.get_info<sycl::info::device::local_mem_size>();
129 wg = std::min<size_t>(wg, local_mem_size / slm_bytes_per_wi);
131 size_t sg = std::max<size_t>(sg_size, 1);
132 if (sg > 1 && wg >= sg) {
135 return std::max<size_t>(wg, sg);
141inline size_t MaxWorkGroupSizeForSLM(
const Device& device,
142 size_t slm_bytes_per_wi,
144 return MaxWorkGroupSizeForSLM(
GetQueue(device).get_device(),
145 slm_bytes_per_wi, sg_size);
154inline size_t MaxWorkGroupSizeForSLM(
const Device& device,
155 size_t slm_bytes_per_wi) {
157 const size_t sg_size =
158 props.sub_group_sizes.empty()
160 : *std::max_element(props.sub_group_sizes.begin(),
161 props.sub_group_sizes.end());
162 return MaxWorkGroupSizeForSLM(device, slm_bytes_per_wi, sg_size);
192template <
int N,
typename scalar_t,
typename Func>
193inline void PersistentReduce(sycl::queue&
queue,
196 scalar_t* global_sum_ptr,
197 Func&& compute_local_sum) {
198 const size_t compute_units =
199 SYCLContext::GetInstance().GetComputeUnits(
queue.get_device());
200 const int64_t natural_num_groups =
201 std::max<int64_t>(1, (n + int64_t(wgs) - 1) / int64_t(wgs));
205 const size_t num_groups =
static_cast<size_t>(std::min<int64_t>(
206 std::max<int64_t>(1, int64_t(compute_units)), natural_num_groups));
208 sycl::buffer<scalar_t, 1> partial_sum_buf(sycl::range<1>(num_groups * N));
209 sycl::buffer<int, 1> ticket_buf(sycl::range<1>(1));
210 queue.submit([&](sycl::handler& cgh) {
213 .template get_access<sycl::access::mode::discard_write>(
215 cgh.single_task([=]() { ticket_acc[0] = 0; });
218 queue.submit([&](sycl::handler& cgh) {
222 auto partial_sum_acc = partial_sum_buf.template get_access<
223 sycl::access::mode::read_write>(cgh);
224 auto ticket_acc = ticket_buf.template get_access<
225 sycl::access::mode::read_write>(cgh);
226 sycl::local_accessor<int, 1> is_last(sycl::range<1>(1), cgh);
228 sycl::nd_range<1>{num_groups * wgs, wgs},
229 [=](sycl::nd_item<1> item) {
230 const size_t group_id = item.get_group(0);
231 const size_t lid = item.get_local_id(0);
232 const int64_t global_stride =
233 int64_t(num_groups) * int64_t(wgs);
235 scalar_t local_sum[N] = {};
236 for (int64_t gid = int64_t(group_id * wgs + lid);
237 gid < n; gid += global_stride) {
238 compute_local_sum(gid, local_sum);
241 auto grp = item.get_group();
242 for (
int k = 0; k < N; ++k) {
243 scalar_t v = sycl::reduce_over_group(
244 grp, local_sum[k], sycl::plus<scalar_t>{});
246 partial_sum_acc[
size_t(k) * num_groups +
252 sycl::atomic_ref<
int, sycl::memory_order::acq_rel,
253 sycl::memory_scope::device>
254 tick_ref(ticket_acc[0]);
255 int my_ticket = tick_ref.fetch_add(1);
256 is_last[0] = (my_ticket ==
257 static_cast<int>(num_groups) - 1);
259 item.barrier(sycl::access::fence_space::local_space);
270 for (
int k = 0; k < N; ++k) {
271 scalar_t partial = 0;
272 for (
size_t g = lid; g < num_groups;
274 partial += partial_sum_acc
275 [
size_t(k) * num_groups + g];
277 scalar_t v = sycl::reduce_over_group(
278 grp, partial, sycl::plus<scalar_t>{});
280 global_sum_ptr[k] = v;
sycl::device sycl_device
Definition SYCLContext.cpp:87
sycl::queue queue
Definition SYCLContext.cpp:88
SYCL device properties and (when built) queue manager.
void PrintSYCLDevices(bool print_all)
Definition SYCLUtils.cpp:70
std::vector< Device > GetAvailableSYCLDevices()
Return a list of available SYCL devices.
Definition SYCLUtils.cpp:179
void enablePersistentJITCache()
Definition SYCLUtils.cpp:187
sycl::queue GetQueue(const Device &device)
Definition SYCLContext.cpp:183
bool IsCPUDevice(const Device &device)
Definition SYCLUtils.cpp:175
size_t GetDeviceCount()
Return the number of available SYCL devices.
Definition SYCLUtils.h:77
bool IsAvailable()
Returns true if there is at least one SYCL device available.
Definition SYCLUtils.cpp:148
bool IsDeviceAvailable(const Device &device)
Returns true if the specified SYCL device is available.
Definition SYCLUtils.cpp:156
SYCLDevice GetSYCLDeviceProperties(const Device &device)
Definition SYCLUtils.cpp:164
const char const char value recording_handle imu_sample recording_handle uint8_t size_t data_size k4a_record_configuration_t config target_format k4a_capture_t capture_handle k4a_imu_sample_t imu_sample playback_handle k4a_logging_message_cb_t void min_level device_handle k4a_imu_sample_t timeout_in_ms capture_handle capture_handle capture_handle image_handle temperature_c k4a_image_t image_handle uint8_t image_handle image_handle image_handle image_handle image_handle timestamp_usec white_balance image_handle k4a_device_configuration_t config device_handle char size_t serial_number_size bool int32_t int32_t int32_t int32_t k4a_color_control_mode_t default_mode value const const k4a_calibration_t calibration char size_t
Definition K4aPlugin.cpp:719
const char const char value recording_handle imu_sample recording_handle uint8_t size_t data_size k4a_record_configuration_t config target_format k4a_capture_t capture_handle k4a_imu_sample_t imu_sample playback_handle k4a_logging_message_cb_t void min_level device_handle k4a_imu_sample_t timeout_in_ms capture_handle capture_handle capture_handle image_handle temperature_c int
Definition K4aPlugin.cpp:474
Definition PinholeCameraIntrinsic.cpp:16