sycl-device-queue.hh
Go to the documentation of this file.
1#pragma once
2#include <memory>
3#include <vector>
4#include <string>
5#include <algorithm>
6#include <complex>
7#include <stdexcept>
8#include <cstdint>
9#include <optional>
10#include <utility>
11#include <iosfwd>
12#include <string_view>
13#include <type_traits>
14
15/// @file
16/// @brief batchlas::Device, batchlas::Event and batchlas::Queue: where work runs and how it is
17/// ordered.
18///
19/// Every entry point enqueues on a Queue and returns an Event immediately; results are readable
20/// only after waiting on the Event or the Queue. See "Devices and queues" and "Synchronisation and
21/// threading" in @ref md_docs_2cpp-api.
22/// @ingroup api_core
23
24// error.hh first, so every header that reaches a Queue sees the exception hierarchy; it is
25// dependency-free, so this cannot form a cycle.
26#include <batchlas/error.hh>
27#include <batchlas/export.hh>
30
31namespace batchlas {
32
33/// @brief Synchronous or asynchronous execution policy.
34/// @ingroup api_core
35enum class Policy
36{
37 SYNC, ///< Wait for completion.
38 ASYNC ///< Return after enqueueing.
39};
40
41/// @brief The kind of SYCL device.
42/// @ingroup api_core
43enum class DeviceType
44{
45 CPU, ///< A CPU device.
46 GPU, ///< A GPU device.
47 ACCELERATOR, ///< An accelerator device.
48 HOST, ///< The SYCL host device.
49 NUM_DEV_TYPES ///< Number of device types (not a device type).
50};
51
52/// @brief Device vendor, parsed from the SYCL vendor string by str_to_vendor().
53/// @ingroup api_core
54enum class Vendor
55{
56 AMD, ///< AMD.
57 ARM, ///< Arm.
58 INTEL, ///< Intel.
59 NVIDIA, ///< NVIDIA.
60 APPLE, ///< Apple (Apple-silicon GPUs through AdaptiveCpp Metal).
61 OTHER ///< Any other vendor.
62};
63
64// to_string() must share the enums' namespace or ADL will not find it.
65/// @brief Name of a Policy value.
66/// @ingroup api_core_lowlevel
67inline constexpr std::string_view to_string(Policy v) {
68 switch (v) {
69 case Policy::SYNC: return "SYNC";
70 case Policy::ASYNC: return "ASYNC";
71 }
72 return "Policy(?)";
73}
74
75/// @brief Name of a DeviceType value.
76/// @ingroup api_core_lowlevel
77inline constexpr std::string_view to_string(DeviceType v) {
78 switch (v) {
79 case DeviceType::CPU: return "CPU";
80 case DeviceType::GPU: return "GPU";
81 case DeviceType::ACCELERATOR: return "ACCELERATOR";
82 case DeviceType::HOST: return "HOST";
83 case DeviceType::NUM_DEV_TYPES: return "NUM_DEV_TYPES";
84 }
85 return "DeviceType(?)";
86}
87
88/// @brief Name of a Vendor value.
89/// @ingroup api_core_lowlevel
90inline constexpr std::string_view to_string(Vendor v) {
91 switch (v) {
92 case Vendor::AMD: return "AMD";
93 case Vendor::ARM: return "ARM";
94 case Vendor::INTEL: return "INTEL";
95 case Vendor::NVIDIA: return "NVIDIA";
96 case Vendor::APPLE: return "APPLE";
97 case Vendor::OTHER: return "OTHER";
98 }
99 return "Vendor(?)";
100}
101
102// One overload per enum, NOT a constrained template: the concrete parameter is what wins partial
103// ordering against the enum-streaming template in blas/enums.hh; a template here would tie.
104/// @brief Stream a Policy by name.
105/// @ingroup api_core_lowlevel
106template <typename CharT, typename Traits>
107std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os, Policy value) {
108 return os << to_string(value);
109}
110
111/// @brief Stream a DeviceType by name.
112/// @ingroup api_core_lowlevel
113template <typename CharT, typename Traits>
114std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os, DeviceType value) {
115 return os << to_string(value);
116}
117
118/// @brief Stream a Vendor by name.
119/// @ingroup api_core_lowlevel
120template <typename CharT, typename Traits>
121std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os, Vendor value) {
122 return os << to_string(value);
123}
124
125/// @brief Classify a SYCL vendor string (case-insensitive substring match).
126/// @param v the vendor string, e.g. from `sycl::info::device::vendor`
127/// @return the matching Vendor, or Vendor::OTHER
128/// @ingroup api_core_lowlevel
129inline Vendor str_to_vendor(std::string&& v) {
130 std::transform(v.begin(), v.end(), v.begin(), ::tolower);
131 if (v.find("amd") != std::string::npos || v.find("advanced micro devices") != std::string::npos) {
132 return Vendor::AMD;
133 } else if (v.find("apple") != std::string::npos) {
134 return Vendor::APPLE;
135 } else if (v.find("arm") != std::string::npos) {
136 return Vendor::ARM;
137 } else if (v.find("intel") != std::string::npos) {
138 return Vendor::INTEL;
139 } else if (v.find("nvidia") != std::string::npos) {
140 return Vendor::NVIDIA;
141 } else {
142 return Vendor::OTHER;
143 }
144}
145
146/// @brief A device property queryable with Device::get_property(); each maps to the SYCL
147/// `sycl::info::device` descriptor of the same name.
148/// @ingroup api_core
150{
151 MAX_WORK_GROUP_SIZE, ///< Maximum work-group size.
152 MAX_CLOCK_FREQUENCY, ///< Maximum clock frequency (MHz).
153 MAX_COMPUTE_UNITS, ///< Number of compute units.
154 MAX_MEM_ALLOC_SIZE, ///< Largest single allocation (bytes).
155 GLOBAL_MEM_SIZE, ///< Global memory size (bytes).
156 LOCAL_MEM_SIZE, ///< Local (shared) memory per work-group (bytes).
157 MAX_NUM_SUB_GROUPS, ///< Maximum sub-groups per work-group.
158 MAX_SUB_GROUP_SIZE, ///< Largest supported sub-group size; see Device::supports_sub_group_size().
159 MEM_BASE_ADDR_ALIGN, ///< Base address alignment (bits).
160 GLOBAL_MEM_CACHE_LINE_SIZE, ///< Global memory cache line (bytes).
161 GLOBAL_MEM_CACHE_SIZE, ///< Global memory cache size (bytes).
162 NUMBER_OF_PROPERTIES ///< Number of properties (not a property).
163};
164
165/// @brief True for consumer Blackwell (RTX 50xx / RTX PRO 6000, sm_120/121).
166/// @param cuda_cc a value of Device::cuda_compute_capability()
167/// @ingroup api_core_lowlevel
168// evidence: docs/perf/blackwell.md
169constexpr bool is_sm120_family(int cuda_cc) { return cuda_cc >= 120 && cuda_cc < 130; }
170
171/// @brief A handle to one SYCL device: its type and its index among devices of that type.
172///
173/// @code
174/// auto gpus = Device::get_devices(DeviceType::GPU);
175/// Queue ctx(gpus.at(1)); // the second GPU
176/// Queue cpu("cpu"); // the first CPU device
177/// @endcode
178/// @ingroup api_core
179struct BATCHLAS_API Device{
180 /// @brief Every device of `type`, in the SYCL runtime's order.
181 static std::vector<Device> get_devices(DeviceType type);
182
183 /// @brief The host device (index 0).
184 Device() = default;
185
186 /// @brief The `idx`-th device of `type`, as numbered by get_devices().
188
189 /// @brief The first device of the named type.
190 /// @param type `"cpu"`, `"gpu"` or `"accelerator"` (case-insensitive)
191 /// @throws batchlas::device_error if no device of that type exists
192 /// @throws batchlas::invalid_argument for any other string
193 Device(std::string type) {
194 std::transform(type.begin(), type.end(), type.begin(), ::tolower);
195 auto pick = [](std::vector<Device> devs, const std::string& name) -> Device {
196 if (devs.empty()) throw batchlas::device_error("No " + name + " device available");
197 return devs.at(0);
198 };
199 if(type == "cpu") {
200 *this = pick(get_devices(DeviceType::CPU), "cpu");
201 } else if(type == "gpu") {
202 *this = pick(get_devices(DeviceType::GPU), "gpu");
203 } else if(type == "accelerator") {
204 *this = pick(get_devices(DeviceType::ACCELERATOR), "accelerator");
205 } else {
206 throw batchlas::invalid_argument("Invalid device type: " + type);
207 }
208 }
209
210 /// @brief As Device(std::string).
211 Device(const char* type) : Device(std::string(type)) {}
212
213 /// @brief The first GPU, else the first CPU, else the host device.
214 inline static Device default_device() {
215 if(!get_devices(DeviceType::GPU).empty()) {
216 return get_devices(DeviceType::GPU).at(0);
217 } else if(!get_devices(DeviceType::CPU).empty()) {
218 return get_devices(DeviceType::CPU).at(0);
219 } else {
220 return get_devices(DeviceType::HOST).at(0);
221 }
222 }
223
224 /// @brief default_device(), except the first CPU device for a double or complex<double> @p T
225 /// when that default is a GPU without fp64 (an Apple GPU), which cannot run @p T kernels.
226 template <typename T>
228 Device dev = default_device();
229 if constexpr (std::is_same_v<T, double> || std::is_same_v<T, std::complex<double>>) {
230 if (dev.type == DeviceType::GPU && !dev.supports_fp64() && !get_devices(DeviceType::CPU).empty())
231 dev = get_devices(DeviceType::CPU).front();
232 }
233 return dev;
234 }
235
236 /// @brief The device's name as reported by SYCL.
237 std::string get_name() const;
238 /// @brief The device's vendor.
240 /// @brief The value of one device property (units as documented on DeviceProperty).
241 size_t get_property(DeviceProperty property) const;
242
243 /// @brief True when `size` is one of the device's supported sub-group sizes.
244 // ENUMERATED from sycl::info::device::sub_group_sizes, not
245 // get_property(MAX_SUB_GROUP_SIZE): a false accept aborts a
246 // [[sycl::reqd_sub_group_size]] launch. evidence: docs/perf/gemv.md#the-sub-route-gates
247 bool supports_sub_group_size(size_t size) const;
248
249 /// @brief CUDA compute capability as major*10+minor (89 = sm_89, 120 = sm_120), or 0 for a
250 /// non-CUDA device. Memoized per device. Kernel selection derives its device key from it
251 /// (`sm_89`), which picks the per-device table in `tuned/`.
252 // Parsed from info::device::version, because ext_oneapi_architecture reports
253 // "unknown" for sm_100/sm_120 on current DPC++.
255
256 /// @brief True when the device runs double-precision kernels (`sycl::aspect::fp64`).
257 /// Memoized per device. False on Apple GPUs, where a Backend::SYCL build without
258 /// `BATCHLAS_HAS_DEVICE_FP64` has no double or complex<double> kernels.
259 bool supports_fp64() const;
260
261
262
263 size_t idx = 0; ///< Index among devices of `type`.
264 DeviceType type = DeviceType::HOST; ///< The device's type.
265};
266
267struct EventImpl;
268
269/// @brief Completion handle of enqueued work, returned by every entry point.
270///
271/// Waiting on it (or on the Queue) is what makes results readable. On the default in-order Queue,
272/// later calls on the same Queue are already ordered after it, so it may be ignored there; it is
273/// needed to order work across an out-of-order Queue, a second Queue sharing the context, or raw
274/// SYCL (see `<batchlas/sycl_interop.hh>`). The type is `[[nodiscard]]`: discard one deliberately
275/// with `(void)`. Movable, not copyable.
276/// @ingroup api_core
277// Per-member BATCHLAS_API is forced (GCC rejects [[nodiscard]] plus a GNU attribute on the
278// class-key). evidence: docs/design/symbol-visibility.md#symbol-visibility-event-carries-per-member-exports
279struct [[nodiscard]] Event {
280 std::unique_ptr<EventImpl> impl_; ///< Implementation; null only for a moved-from Event.
281
282 /// @brief An empty Event, already complete.
283 BATCHLAS_API Event();
284 BATCHLAS_API ~Event();
285 BATCHLAS_API Event& operator=(EventImpl&& impl);
286 BATCHLAS_API Event(EventImpl&& impl);
287 BATCHLAS_API Event(Event&& other);
288 BATCHLAS_API Event& operator=(Event&& other);
289 /// @brief Block until the work this Event tracks has completed.
290 /// @pre The Event is not moved-from.
291 BATCHLAS_API void wait() const;
292 BATCHLAS_API EventImpl* operator->() const;
293 BATCHLAS_API EventImpl& operator*() const;
294
295 /// @brief `{command_start, command_end}` in nanoseconds, or `std::nullopt` when profiling is
296 /// not enabled on the underlying SYCL queue (see DiagnosticsSettings::profiling).
297 BATCHLAS_API std::optional<std::pair<std::uint64_t, std::uint64_t>> profiling_command_start_end_ns() const;
298};
299
300struct QueueImpl;
301
302/// @brief Where BatchLAS work runs: a device, a backend, an ordered SYCL queue and a workspace
303/// arena.
304///
305/// @code
306/// Queue ctx; // default device, in-order, backend AUTO
307/// Queue ooo(device, /*in_order=*/false); // out-of-order
308/// Queue host(device, Backend::NETLIB); // backend pinned
309/// Queue sibling(ctx, /*in_order=*/true); // shares ctx's context and device
310/// @endcode
311/// Every entry point takes its backend from the Queue and leases its default workspace from the
312/// Queue's arena (see WorkspaceLease). Movable, not copyable. Constructing the first Queue in
313/// the process closes batchlas::configure().
314/// @warning A Queue is single-threaded: it owns an unsynchronised arena and a cached last event,
315/// and workspace(), trim_workspace(), submissions, enqueue(), get_event() and
316/// create_event_after_external_work() throw batchlas::api_misuse when called from a
317/// thread other than the owner. Use one Queue per thread, or hand one over with
318/// attach_to_current_thread().
319/// @see "Synchronisation and threading" in @ref md_docs_2cpp-api
320/// @ingroup api_core
321struct BATCHLAS_API Queue{
322
323 /// @brief A Queue on Device::default_device(), in-order, backend AUTO.
326
327 /// @brief A Queue on `device` with backend AUTO.
328 /// @param device the device
329 /// @param in_order true (default) for an in-order queue; out-of-order queues make arena-backed
330 /// workspace releases drain the queue
332 /// @brief A Queue on `device` pinned to `backend`.
333 /// @throws batchlas::unsupported if `backend` is not compiled in (see set_backend())
335 /// @brief A Queue sharing `base`'s SYCL context and device, so USM pointers and workspaces
336 /// allocated for `base` stay usable. It has its own arena and event chain.
337 Queue(const Queue& base, bool in_order);
338 Queue(Queue&& other); //= default;
339 Queue& operator=(Queue&& other);// = default;
340 Queue(const Queue& other) = delete;
341 Queue& operator=(const Queue& other) = delete;
342
343
344 QueueImpl* operator->() const;
345 QueueImpl& operator*() const;
346
347 /// @brief Order all later work on this Queue after `event`, without a host wait.
348 /// A moved-from Event is ignored; a default-constructed one is already complete.
349 void enqueue(Event& event);
350 /// @brief An Event that completes after everything enqueued on this Queue so far.
352 /// @brief Like get_event(), but also ordered after work submitted directly to the native
353 /// stream (cuBLAS, rocBLAS, your own kernels) that bypassed SYCL submission.
355
356 /// @brief enqueue() each Event in `events`.
357 template <typename EventContainer>
358 void enqueue(EventContainer& events){
359 for(auto& event : events){
360 enqueue(event);
361 }
362 }
363
364 /// @brief Block until all work enqueued on this Queue has completed.
365 void wait() const;
366 /// @brief As wait(), then rethrow any asynchronous error the device reported.
367 void wait_and_throw() const;
368
369 /// @brief Transfer single-thread ownership to the calling thread (a move, not a share).
370 /// @pre No other thread uses the Queue during or after the call (unchecked).
371 /// @throws batchlas::api_misuse if a workspace lease is outstanding
372 // BATCHLAS_API on the member is required (inline member defined in src/queue.hh).
373 // evidence: docs/design/symbol-visibility.md#symbol-visibility-exported-inline-queue-members
374 BATCHLAS_API void attach_to_current_thread();
375
376 /// @brief Borrow `bytes` of device scratch from this Queue's arena.
377 ///
378 /// The Queue owns the memory: it stays valid until the lease is released, not until the
379 /// caller returns. Keep the lease in a named variable (`auto ws = ctx.workspace(n);`).
380 [[nodiscard]] batchlas::WorkspaceLease workspace(size_t bytes);
381
382 /// @brief Bytes the arena currently holds. It grows to the peak requested and keeps it.
383 size_t workspace_capacity() const;
384
385 /// @brief Return the arena's memory to the runtime (otherwise it is freed only in ~Queue).
386 /// @return false, doing nothing, while any lease is outstanding
387 /// @note Waits for the queue to be idle first, so it can throw an asynchronous error.
388 [[nodiscard]] bool trim_workspace();
389
390 std::unique_ptr<QueueImpl> impl_; ///< Implementation (SYCL queue, arena, event chain).
391
392 /// @brief The device this Queue runs on.
393 Device device() const { return device_; }
394 /// @brief True for an in-order Queue.
395 bool in_order() const { return in_order_; }
396
397 /// @brief The backend calls dispatch to; never Backend::AUTO (an AUTO Queue resolves once, on
398 /// first query, from the device vendor and the compiled-in backends).
399 /// @throws batchlas::unsupported if AUTO finds no compiled-in backend that serves the device
401 /// @brief The backend as requested, possibly Backend::AUTO.
402 batchlas::Backend requested_backend() const { return backend_; }
403
404 /// @brief Pin this Queue to `backend`, or pass Backend::AUTO to hand it back to automatic
405 /// selection.
406 /// @throws batchlas::unsupported if `backend` is not compiled into this build
408
409 /// @brief True when `backend` is compiled into this build.
411
412 /// @brief True for any USM allocation in this Queue's context, and for any non-null pointer on
413 /// a host/CPU device.
414 // docs/cpp-api.md#where-the-memory-has-to-live-the-usm-contract
415 bool is_device_accessible(const void* ptr) const;
416
417 /// @brief As is_device_accessible(), but throws.
418 /// @param ptr the pointer to check
419 /// @param what names the call-site parameter in the message, e.g. `"gemm: A"`
420 /// @throws batchlas::invalid_argument if `ptr` is null or not reachable from the device
421 void require_device_accessible(const void* ptr, const char* what) const;
422
423 /// @brief The native stream as an opaque pointer: a `CUstream` when the device runs on the
424 /// CUDA SYCL backend, a `hipStream_t` on HIP, `nullptr` elsewhere.
425 ///
426 /// Keyed off the device, not backend(). Owned by the Queue: do not destroy it or use it past
427 /// the Queue's lifetime. Work pushed to it runs after BatchLAS's; to make BatchLAS wait for
428 /// that work, call create_event_after_external_work().
429 BATCHLAS_API void* native_handle() const;
430
431 private:
432 Device device_;
433 bool in_order_;
435 mutable batchlas::Backend resolved_backend_ = batchlas::Backend::AUTO;
436};
437
438} // namespace batchlas
439
440// Transitional global-scope shim; define BATCHLAS_NO_GLOBAL_NAMES to switch it off.
441#ifndef BATCHLAS_NO_GLOBAL_NAMES
442using batchlas::Device;
445using batchlas::Event;
446using batchlas::EventImpl;
447using batchlas::Policy;
448using batchlas::Queue;
449using batchlas::QueueImpl;
450using batchlas::Vendor;
451// str_to_vendor needs the shim (a std::string argument never reaches batchlas by ADL).
452// to_string/operator<< are deliberately NOT shimmed: that would drag the whole enums.hh overload
453// set into the global namespace, and ADL already finds them.
455#endif
A borrow of scratch memory from a Queue's workspace arena, returned to the arena when the handle goes...
Definition workspace.hh:46
The device or its vendor runtime failed.
Definition error.hh:138
The call violates the API contract.
Definition error.hh:77
Enumerations, scalar traits and scalar concepts shared by every public header.
The BatchLAS exception hierarchy.
Vendor str_to_vendor(std::string &&v)
Classify a SYCL vendor string (case-insensitive substring match).
constexpr bool is_sm120_family(int cuda_cc)
True for consumer Blackwell (RTX 50xx / RTX PRO 6000, sm_120/121).
DeviceType
The kind of SYCL device.
Vendor
Device vendor, parsed from the SYCL vendor string by str_to_vendor().
DeviceProperty
A device property queryable with Device::get_property(); each maps to the SYCL sycl::info::device des...
Policy
Synchronous or asynchronous execution policy.
@ NUM_DEV_TYPES
Number of device types (not a device type).
@ HOST
The SYCL host device.
@ ACCELERATOR
An accelerator device.
@ OTHER
Any other vendor.
@ APPLE
Apple (Apple-silicon GPUs through AdaptiveCpp Metal).
@ GLOBAL_MEM_CACHE_LINE_SIZE
Global memory cache line (bytes).
@ MAX_WORK_GROUP_SIZE
Maximum work-group size.
@ MAX_NUM_SUB_GROUPS
Maximum sub-groups per work-group.
@ MAX_COMPUTE_UNITS
Number of compute units.
@ MAX_SUB_GROUP_SIZE
Largest supported sub-group size; see Device::supports_sub_group_size().
@ MAX_CLOCK_FREQUENCY
Maximum clock frequency (MHz).
@ GLOBAL_MEM_SIZE
Global memory size (bytes).
@ MAX_MEM_ALLOC_SIZE
Largest single allocation (bytes).
@ GLOBAL_MEM_CACHE_SIZE
Global memory cache size (bytes).
@ MEM_BASE_ADDR_ALIGN
Base address alignment (bits).
@ NUMBER_OF_PROPERTIES
Number of properties (not a property).
@ LOCAL_MEM_SIZE
Local (shared) memory per work-group (bytes).
@ SYNC
Wait for completion.
@ ASYNC
Return after enqueueing.
std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, E value)
Prints any BatchLAS enum as its enumerator spelling, via its to_string().
Definition enums.hh:596
constexpr std::string_view to_string(MatrixFormat v)
Spelling of v as in source.
Definition enums.hh:84
Backend
Library family an entry point dispatches to, used as a template argument.
Definition enums.hh:111
@ AUTO
A request, not a backend: the Queue resolves it from its device on first query.
Definition enums.hh:112
A handle to one SYCL device: its type and its index among devices of that type.
size_t idx
Index among devices of type.
Device()=default
The host device (index 0).
static std::vector< Device > get_devices(DeviceType type)
Every device of type, in the SYCL runtime's order.
int cuda_compute_capability() const
CUDA compute capability as major*10+minor (89 = sm_89, 120 = sm_120), or 0 for a non-CUDA device.
static Device default_device()
The first GPU, else the first CPU, else the host device.
static Device default_device_for()
default_device(), except the first CPU device for a double or complex<double> T when that default is ...
Device(std::string type)
The first device of the named type.
Device(const char *type)
As Device(std::string).
DeviceType type
The device's type.
Device(size_t idx, DeviceType type)
The idx-th device of type, as numbered by get_devices().
Vendor get_vendor() const
The device's vendor.
bool supports_fp64() const
True when the device runs double-precision kernels (sycl::aspect::fp64).
std::string get_name() const
The device's name as reported by SYCL.
size_t get_property(DeviceProperty property) const
The value of one device property (units as documented on DeviceProperty).
bool supports_sub_group_size(size_t size) const
True when size is one of the device's supported sub-group sizes.
Completion handle of enqueued work, returned by every entry point.
Event(EventImpl &&impl)
Event & operator=(Event &&other)
Event(Event &&other)
EventImpl * operator->() const
void wait() const
Block until the work this Event tracks has completed.
Event()
An empty Event, already complete.
std::unique_ptr< EventImpl > impl_
Implementation; null only for a moved-from Event.
std::optional< std::pair< std::uint64_t, std::uint64_t > > profiling_command_start_end_ns() const
{command_start, command_end} in nanoseconds, or std::nullopt when profiling is not enabled on the und...
Event & operator=(EventImpl &&impl)
EventImpl & operator*() const
Where BatchLAS work runs: a device, a backend, an ordered SYCL queue and a workspace arena.
Event get_event() const
An Event that completes after everything enqueued on this Queue so far.
QueueImpl & operator*() const
size_t workspace_capacity() const
Bytes the arena currently holds. It grows to the peak requested and keeps it.
void wait_and_throw() const
As wait(), then rethrow any asynchronous error the device reported.
Queue(Device device, batchlas::Backend backend, bool in_order=true)
A Queue on device pinned to backend.
static bool backend_available(batchlas::Backend backend)
True when backend is compiled into this build.
QueueImpl * operator->() const
batchlas::Backend backend() const
The backend calls dispatch to; never Backend::AUTO (an AUTO Queue resolves once, on first query,...
bool is_device_accessible(const void *ptr) const
True for any USM allocation in this Queue's context, and for any non-null pointer on a host/CPU devic...
Queue()
A Queue on Device::default_device(), in-order, backend AUTO.
void * native_handle() const
The native stream as an opaque pointer: a CUstream when the device runs on the CUDA SYCL backend,...
Queue(const Queue &other)=delete
Queue & operator=(Queue &&other)
Queue(Queue &&other)
void set_backend(batchlas::Backend backend)
Pin this Queue to backend, or pass Backend::AUTO to hand it back to automatic selection.
Queue(const Queue &base, bool in_order)
A Queue sharing base's SYCL context and device, so USM pointers and workspaces allocated for base sta...
std::unique_ptr< QueueImpl > impl_
Implementation (SYCL queue, arena, event chain).
Event create_event_after_external_work()
Like get_event(), but also ordered after work submitted directly to the native stream (cuBLAS,...
Queue(Device device, bool in_order=true)
A Queue on device with backend AUTO.
void enqueue(Event &event)
Order all later work on this Queue after event, without a host wait.
Queue & operator=(const Queue &other)=delete
batchlas::Backend requested_backend() const
The backend as requested, possibly Backend::AUTO.
bool in_order() const
True for an in-order Queue.
void enqueue(EventContainer &events)
enqueue() each Event in events.
Device device() const
The device this Queue runs on.
void wait() const
Block until all work enqueued on this Queue has completed.
void attach_to_current_thread()
Transfer single-thread ownership to the calling thread (a move, not a share).
void require_device_accessible(const void *ptr, const char *what) const
As is_device_accessible(), but throws.
batchlas::WorkspaceLease workspace(size_t bytes)
Borrow bytes of device scratch from this Queue's arena.
bool trim_workspace()
Return the arena's memory to the runtime (otherwise it is freed only in ~Queue).
WorkspaceLease: a scoped borrow of scratch memory from a Queue's workspace arena.