Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
sycl_handler.cpp
Go to the documentation of this file.
1// -------------------------------------------------------//
2//
3// SHAMROCK code for hydrodynamics
4// Copyright (c) 2021-2026 Timothée David--Cléris <tim.shamrock@proton.me>
5// SPDX-License-Identifier: CeCILL Free Software License Agreement v2.1
6// Shamrock is licensed under the CeCILL 2.1 License, see LICENSE for more information
7//
8// -------------------------------------------------------//
9
16#include "shambase/string.hpp"
17#include "shamcmdopt/cmdopt.hpp"
21#include <unordered_map>
22#include <memory>
23#include <ostream>
24#include <stdexcept>
25#include <string>
26#include <vector>
27
28auto check_queue_is_valid(sycl::queue &q) {
29
30 auto test_kernel = [](sycl::queue &q) {
31 sycl::buffer<u32> b{10};
32
33 q.submit([&](sycl::handler &cgh) {
34 sycl::accessor acc{b, cgh, sycl::write_only, sycl::no_init};
35
36 cgh.parallel_for(sycl::range<1>{1}, [=](sycl::item<1> i) {
37 acc[i] = i.get_linear_id();
38 });
39 });
40
41 q.wait();
42 };
43
44 std::exception_ptr eptr;
45 try {
46 test_kernel(q);
47 logger::info_ln(
48 "SYCL Hanlder",
49 "selected queue :",
50 q.get_device().get_info<sycl::info::device::name>(),
51 " working !");
52 } catch (...) {
53 eptr = std::current_exception(); // capture
54 }
55
56 if (eptr) {
57 logger::err_ln(
58 "SYCL Hanlder",
59 "selected queue :",
60 q.get_device().get_info<sycl::info::device::name>(),
61 "does not function properly");
62 std::rethrow_exception(eptr);
63 }
64}
65
66auto exception_handler = [](sycl::exception_list exceptions) {
67 for (std::exception_ptr const &e : exceptions) {
68 try {
69 std::rethrow_exception(e);
70 } catch (sycl::exception const &e) {
71 printf("Caught synchronous SYCL exception: %s\n", e.what());
72 }
73 }
74};
75
76std::string getDeviceTypeName(const sycl::device &Device) {
77 auto DeviceType = Device.get_info<sycl::info::device::device_type>();
78 switch (DeviceType) {
79 case sycl::info::device_type::cpu : return "CPU";
80 case sycl::info::device_type::gpu : return "GPU";
81 case sycl::info::device_type::host : return "HOST";
82 case sycl::info::device_type::accelerator: return "ACCELERATOR";
83 default : return "UNKNOWN";
84 }
85}
86
87void print_device_info(const sycl::device &Device) {
88 std::cout << " - " << Device.get_info<sycl::info::device::name>() << " "
89 << shambase::readable_sizeof(Device.get_info<sycl::info::device::global_mem_size>())
90 << "\n";
91}
92
93namespace sycl_handler {
94 bool already_on = false;
95
96 std::unique_ptr<sycl::queue> compute_queue;
97 std::unique_ptr<sycl::queue> alt_queue;
98
99 sycl::queue &get_compute_queue() {
100 if (!already_on) {
101 throw ShamrockSyclException("sycl handler is not initialized");
102 }
103 return *compute_queue;
104 }
105
106 sycl::queue &get_alt_queue() {
107 if (!already_on) {
108 throw ShamrockSyclException("sycl handler is not initialized");
109 }
110 return *alt_queue;
111 }
112
113 void init() {
114
115 if (already_on) {
116 throw ShamrockSyclException("Sycl Handler is already on");
117 }
118
119 logger::raw_ln(
120 shambase::term_colors::col8b_cyan() + " >>> init SYCL instances <<< "
121 + shambase::term_colors::reset());
122
123 if (opts::has_option("--sycl-cfg")) {
124 std::string sycl_cfg = std::string(opts::get_option("--sycl-cfg"));
125
126 logger::normal_ln("SYCL Handler", "chosen sycl config :", sycl_cfg);
127
128 size_t split_alt_comp = 0;
129 split_alt_comp = sycl_cfg.find(":");
130
131 if (split_alt_comp == std::string::npos) {
132 logger::err_ln("SYCL Handler", "sycl-cfg layout should be x:x");
133 throw ShamrockSyclException("sycl-cfg layout should be x:x");
134 }
135
136 std::string alt_cfg = sycl_cfg.substr(0, split_alt_comp);
137 std::string comp_cfg = sycl_cfg.substr(split_alt_comp + 1, sycl_cfg.length());
138
139 i32 ialt, icomp;
140 try {
141 try {
142 ialt = std::stoi(alt_cfg);
143 } catch (const std::invalid_argument &a) {
144 logger::err_ln("SYCL Handler", "alt config is not an int");
145 throw ShamrockSyclException("alt config is not an int");
146 }
147 } catch (const std::out_of_range &a) {
148 logger::err_ln("SYCL Handler", "alt config is to big for an integer");
149 throw ShamrockSyclException("alt config is to big for an integer");
150 }
151
152 try {
153 try {
154 icomp = std::stoi(comp_cfg);
155 } catch (const std::invalid_argument &a) {
156 logger::err_ln("SYCL Handler", "compute config is not an int");
157 throw ShamrockSyclException("compute config is not an int");
158 }
159 } catch (const std::out_of_range &a) {
160 logger::err_ln("SYCL Handler", "compute config is to big for an integer");
161 throw ShamrockSyclException("compute config is to big for an integer");
162 }
163
164 const auto &Platforms = sycl::platform::get_platforms();
165
166 logger::raw_ln(
167 "--------------------------------------------------------------------------------");
168 logger::raw_ln(
169 "| sel | id | Device name | Platform name | Type |");
170 logger::raw_ln(
171 "--------------------------------------------------------------------------------");
172
173 u32 key_global = 0;
174 for (const auto &Platform : Platforms) {
175 const auto &Devices = Platform.get_devices();
176
177 auto PlatformName = Platform.get_info<sycl::info::platform::name>();
178 for (const auto &Device : Devices) {
179 auto DeviceName = Device.get_info<sycl::info::device::name>();
180
181 auto selected_k = [&](i32 k) {
182 std::string ret = "";
183
184 if (k == ialt) {
185 ret += "a";
186 }
187
188 if (k == icomp) {
189 ret += "c";
190 }
191
192 return ret;
193 };
194
195 std::string selected = selected_k(key_global);
196
197 std::string devname = shambase::trunc_str(DeviceName, 29);
198 std::string platname = shambase::trunc_str(PlatformName, 24);
199 std::string devtype = shambase::trunc_str(getDeviceTypeName(Device), 6);
200
201 logger::raw_ln(
203 "| %-3s | %02d | %-29s | %-24s | %-6s |",
204 selected.c_str(),
205 key_global,
206 devname.c_str(),
207 platname.c_str(),
208 devtype.c_str()));
209
210 if (key_global == ialt) {
211 alt_queue = std::make_unique<sycl::queue>(Device, exception_handler);
212 }
213
214 if (key_global == icomp) {
215 compute_queue = std::make_unique<sycl::queue>(Device, exception_handler);
216 }
217
218 key_global++;
219 }
220 }
221
222 logger::raw_ln(
223 "--------------------------------------------------------------------------------");
224
225 key_global = 0;
226 for (const auto &Platform : Platforms) {
227 auto PlatformName = Platform.get_info<sycl::info::platform::name>();
228 for (const auto &Device : Platform.get_devices()) {
229 auto DeviceName = Device.get_info<sycl::info::device::name>();
230
231 if (key_global == ialt) {
232 logger::info_ln(
233 "SYCL Handler",
234 "init alt queue : ",
235 "|",
236 DeviceName,
237 "|",
238 PlatformName,
239 "|",
240 getDeviceTypeName(Device),
241 "|");
242 alt_queue = std::make_unique<sycl::queue>(Device, exception_handler);
243 }
244
245 if (key_global == icomp) {
246 logger::info_ln(
247 "SYCL Handler",
248 "init comp queue : ",
249 "|",
250 DeviceName,
251 "|",
252 PlatformName,
253 "|",
254 getDeviceTypeName(Device),
255 "|");
256 compute_queue = std::make_unique<sycl::queue>(Device, exception_handler);
257 }
258
259 key_global++;
260 }
261 }
262
263 check_queue_is_valid(*compute_queue);
264 check_queue_is_valid(*alt_queue);
265
266 logger::info_ln("SYCL Handler", "init done");
267
268 logger::info_ln("SYCL Handler", "creating MPI type for interop");
269 create_sycl_mpi_types();
270
271 logger::info_ln("SYCL Handler", "MPI type for interop created");
272
273 } else {
274
275 logger::err_ln("SYCL Handler", "Please specify a sycl configuration (--sycl-cfg x:x)");
276 // std::cout << "[SYCL Handler] Please specify a sycl configuration (--sycl-cfg x:x)" <<
277 // std::endl;
278 throw ShamrockSyclException("Sycl Handler need configuration (--sycl-cfg x:x)");
279 }
280
281 already_on = true;
282 }
283} // namespace sycl_handler
sycl::queue & get_compute_queue(u32 id=0)
sycl::queue & get_alt_queue(u32 id=0)
Get the alternative queue.
std::uint32_t u32
32 bit unsigned integer
std::int32_t i32
32 bit integer
DeviceType
The type of a device.
Definition Device.hpp:67
std::string readable_sizeof(double size)
given a sizeof value return a readble string Example : readable_sizeof(1024*1024*1024) -> "1....
Definition string.hpp:139
std::string trunc_str(std::string s, u32 max_len)
Truncate a string to a specified length, adding an ellipsis if necessary.
Definition string.hpp:215
void throw_with_loc(std::string message, SourceLocation loc=SourceLocation{})
Throw an exception and append the source location to it.
bool has_option(const std::string_view &option_name)
Check if an option is present.
Definition cmdopt.cpp:128
std::string_view get_option(const std::string_view &option_name)
Get the value of an option.
Definition cmdopt.cpp:146
header file to manage sycl