Open3D (C++ API)  0.19.0
Loading...
Searching...
No Matches
SYCLUtils.h
Go to the documentation of this file.
1// ----------------------------------------------------------------------------
2// - Open3D: www.open3d.org -
3// ----------------------------------------------------------------------------
4// Copyright (c) 2018-2024 www.open3d.org
5// SPDX-License-Identifier: MIT
6// ----------------------------------------------------------------------------
7
14
15#pragma once
16
17#include <cstdint>
18#include <vector>
19
20#include "open3d/core/Device.h"
22
23#ifdef SYCL_LANGUAGE_VERSION
24#include <algorithm>
25#include <sycl/sycl.hpp>
26#endif
27
28namespace open3d {
29namespace core {
30namespace sy {
31
34int SYCLDemo();
35
40void PrintSYCLDevices(bool print_all = false);
41
43bool IsAvailable();
44
46bool IsDeviceAvailable(const Device& device);
47
50SYCLDevice GetSYCLDeviceProperties(const Device& device);
51
54bool IsCPUDevice(const Device& device);
55
57std::vector<Device> GetAvailableSYCLDevices();
58
60inline size_t GetDeviceCount() { return GetAvailableSYCLDevices().size(); }
61
65
66#if defined(SYCL_LANGUAGE_VERSION) && defined(BUILD_SYCL_MODULE)
67
69inline size_t PreferredWorkGroupSize(const Device& device) {
70 auto device_props = SYCLContext::GetInstance().GetDeviceProperties(device);
71 return std::min<size_t>(256, device_props.max_work_group_size);
72}
73
85template <int N, typename scalar_t, typename Func>
86inline void PersistentReduce(sycl::queue& queue,
87 int64_t n,
88 size_t wgs,
89 scalar_t* global_sum_ptr,
90 Func&& compute_local_sum) {
91 // optimal for A770 dGPU for reduction widths in [21, 157]
92 constexpr size_t kPersistentReduceGroups = 256;
93 const int64_t natural_num_groups =
94 std::max<int64_t>(1, (n + int64_t(wgs) - 1) / int64_t(wgs));
95 const size_t num_groups = static_cast<size_t>(
96 std::min<int64_t>(kPersistentReduceGroups, natural_num_groups));
97
98 scalar_t* partial_sum_ptr =
99 sycl::malloc_device<scalar_t>(num_groups * N, queue);
100 int* ticket_ptr = sycl::malloc_device<int>(1, queue);
101 queue.memset(ticket_ptr, 0, sizeof(int));
102
103 queue.submit([&](sycl::handler& cgh) {
104 sycl::local_accessor<int, 1> is_last(sycl::range<1>(1), cgh);
105 sycl::local_accessor<scalar_t, 1> slm_sum(sycl::range<1>(N), cgh);
106 cgh.parallel_for(
107 sycl::nd_range<1>{num_groups * wgs, wgs},
108 [=](sycl::nd_item<1> item) {
109 const size_t group_id = item.get_group(0);
110 const size_t lid = item.get_local_id(0);
111 const int64_t global_stride =
112 int64_t(num_groups) * int64_t(wgs);
113
114 scalar_t local_sum[N] = {};
115 for (int64_t gid = int64_t(group_id * wgs + lid);
116 gid < n; gid += global_stride) {
117 compute_local_sum(gid, local_sum);
118 }
119
120 auto grp = item.get_group();
121 for (int k = 0; k < N; ++k) {
122 scalar_t v = sycl::reduce_over_group(
123 grp, local_sum[k], sycl::plus<scalar_t>{});
124 if (lid == 0) {
125 partial_sum_ptr[group_id * N + k] = v;
126 }
127 }
128
129 if (lid == 0) {
130 sycl::atomic_ref<int, sycl::memory_order::acq_rel,
131 sycl::memory_scope::device>
132 tick_ref(*ticket_ptr);
133 int my_ticket = tick_ref.fetch_add(1);
134 is_last[0] = (my_ticket ==
135 static_cast<int>(num_groups) - 1);
136 }
137 item.barrier(sycl::access::fence_space::local_space);
138
139 if (is_last[0]) {
140 for (size_t k = lid; k < size_t(N); k += wgs) {
141 slm_sum[k] = 0;
142 }
143 item.barrier(
144 sycl::access::fence_space::local_space);
145
146 const size_t total_elems = num_groups * N;
147 for (size_t idx = lid; idx < total_elems;
148 idx += wgs) {
149 size_t k = idx % N;
150 sycl::atomic_ref<
151 scalar_t, sycl::memory_order::relaxed,
152 sycl::memory_scope::work_group,
153 sycl::access::address_space::
154 local_space>
155 ref(slm_sum[k]);
156 ref += partial_sum_ptr[idx];
157 }
158 item.barrier(
159 sycl::access::fence_space::local_space);
160 for (size_t k = lid; k < size_t(N); k += wgs) {
161 global_sum_ptr[k] = slm_sum[k];
162 }
163 }
164 });
165 }).wait_and_throw();
166
167 sycl::free(partial_sum_ptr, queue);
168 sycl::free(ticket_ptr, queue);
169}
170
171#endif // SYCL_LANGUAGE_VERSION && BUILD_SYCL_MODULE
172
173} // namespace sy
174} // namespace core
175} // namespace open3d
sycl::queue queue
Definition SYCLContext.cpp:51
SYCL device properties and (when built) queue manager.
Definition Device.h:18
void PrintSYCLDevices(bool print_all)
Definition SYCLUtils.cpp:121
std::vector< Device > GetAvailableSYCLDevices()
Return a list of available SYCL devices.
Definition SYCLUtils.cpp:230
void enablePersistentJITCache()
Definition SYCLUtils.cpp:238
int SYCLDemo()
Definition SYCLUtils.cpp:34
bool IsCPUDevice(const Device &device)
Definition SYCLUtils.cpp:226
size_t GetDeviceCount()
Return the number of available SYCL devices.
Definition SYCLUtils.h:60
bool IsAvailable()
Returns true if there is at least one SYCL device available.
Definition SYCLUtils.cpp:199
bool IsDeviceAvailable(const Device &device)
Returns true if the specified SYCL device is available.
Definition SYCLUtils.cpp:207
SYCLDevice GetSYCLDeviceProperties(const Device &device)
Definition SYCLUtils.cpp:215
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