sycl-span.hh
Go to the documentation of this file.
1#pragma once
2#include <cassert>
3#include <iterator>
4#include <array>
5#include <type_traits>
6#include <batchlas/export.hh>
8
9/// @file
10/// @brief batchlas::Span, the non-owning pointer + length every entry point takes for 1-D data.
11
12namespace batchlas {
13
14/// @brief True for `std::array<T, N>`, false otherwise.
15/// @ingroup api_matrix
16template <typename T>
17struct is_std_array : std::false_type {};
18
19/// @brief Specialisation for `std::array<T, N>`.
20/// @ingroup api_matrix
21template <typename T, std::size_t N>
22struct is_std_array<std::array<T, N>> : std::true_type {};
23
24/// @brief Non-owning view of `size()` contiguous elements of type `T`.
25///
26/// The 1-D argument type of the entry points: eigenvalues, singular values,
27/// pivots, tau vectors, info arrays and caller-supplied workspace. A Span does
28/// not own or free its memory, and copying one copies the pointer. The memory
29/// must be USM that the device of the Queue it is used with can access; the
30/// entry points check this at the call.
31///
32/// Element access asserts the bounds in a debug build only.
33/// @tparam T element type
34/// @ingroup api_matrix
35// The out-of-line members (USM advice calls, operator==) are explicitly instantiated in
36// src/util/sycl-util-impl.cc, so Span crosses the shared-library boundary like Matrix.
37template <typename T>
38struct BATCHLAS_API Span
39{
40 using value_type = T; ///< Element type.
41 using pointer = T*; ///< Pointer to an element.
42 using size_t = std::size_t; ///< Size and index type.
43 /// @brief An empty span (null data, size 0).
44 inline constexpr Span() : data_(nullptr), size_(0) {}
45 /// @brief Views @p size elements starting at @p data.
46 inline constexpr Span(T *data, size_t size) : data_(data), size_(size) {}
47 /// @brief Views the range [@p begin, @p end).
48 inline constexpr Span(T *begin, T *end) : data_(begin), size_(std::distance(begin, end)) {}
49 /// @brief Copies the pointer and size; the elements are not copied.
50 inline constexpr Span(const Span<T> &other) = default;
51 /// @brief Same as the copy constructor.
52 inline constexpr Span(Span<T> &&other) = default;
53 /// @brief Views @p other with its first @p offset elements dropped.
54 /// @pre offset <= other.size()
55 inline constexpr Span(const Span<T>& other, size_t offset) : data_(other.data_ + offset), size_(other.size_ - offset) { assert(offset <= other.size_); }
56 /// @brief Views @p other with its first @p offset elements dropped.
57 /// @pre offset <= other.size()
58 inline constexpr Span(Span<T>&& other, size_t offset) : data_(other.data_ + offset), size_(other.size_ - offset) { assert(offset <= other.size_); }
59 /// @brief A one-element span over @p value.
60 ///
61 /// Explicit on purpose: implicitly, a scalar lvalue became a length-1 buffer
62 /// wherever a Span parameter's element type is not deduced from the argument,
63 /// so `syev(q, A, W[i * n], ...)` (the LAPACK idiom minus the `&`) compiled
64 /// and overran the caller's array. Write `Span(x)` when one element is meant.
65 /// @see @ref matrix-model-span-and-unifiedvector
66 inline constexpr explicit Span(T& value) : data_(&value), size_(1) {}
67
68 /// @name USM memory hints
69 /// Advice for USM shared memory on the device of @p ctx. Each returns the event of
70 /// the advice, or an empty Event when the span is empty or the runtime rejects
71 /// the advice (errors are swallowed: these are hints). Pass the Queue the data
72 /// will be used on; the default Queue() is a new queue on Device::default_device().
73 /// @{
74 Event set_preferred_location(const Queue &ctx = Queue()) const; ///< Prefer residence on the device of @p ctx.
75 Event set_access_device(const Queue &ctx = Queue()) const; ///< Map for access by the device of @p ctx.
76 Event prefetch(const Queue &ctx = Queue()) const; ///< Migrate to the device of @p ctx.
77 /// @}
78
79 /// @brief Reinterprets the bytes as elements of type @p U; the size is `size_bytes() / sizeof(U)`.
80 template <typename U>
81 inline constexpr Span<U> as_span() const {
82 return Span<U>(reinterpret_cast<U*>(data_), (sizeof(T) * size_ / sizeof(U)) );
83 }
84
85 /// @brief Elements [@p offset, size()).
86 inline constexpr Span<T> subspan(size_t offset) const { assert(offset <= size_); return Span<T>(data_ + offset, size_ - offset); }
87 /// @brief Elements [@p offset, @p offset + @p count). @pre offset + count <= size()
88 inline constexpr Span<T> subspan(size_t offset, size_t count) const { assert(offset + count <= size_); return Span<T>(data_ + offset, count); }
89 /// @brief Rebinds this span to @p other's pointer and size; no elements are copied.
90 inline constexpr Span<T>& operator= (const Span<T> &other) { data_ = other.data_; size_ = other.size_; return *this; }
91 /// @brief Same as the copy assignment.
92 inline constexpr Span<T>& operator= (Span<T> &&other) { return *this = other; }
93 /// @brief Element-wise comparison on the host.
94 ///
95 /// Spans of different sizes compare unequal. Real floating-point elements
96 /// compare with a relative tolerance of 20 epsilon; every other type, complex
97 /// included, compares exactly. Two spans over the same pointer are equal
98 /// without reading the data.
99 /// @pre the memory is host-readable and no kernel is writing it
100 bool operator==(const Span<T> other) const;
101 /// @brief Element @p index. @pre index < size()
102 inline constexpr T &operator[](size_t index) const {assert(index < size_); assert(data_); return data_[index];}
103 /// @brief Element @p index. @pre index < size() (asserted, not thrown)
104 inline constexpr T &at(size_t index) const{assert(index < size_); assert(data_); return data_[index];}
105 inline constexpr T *data() const { return data_; } ///< Pointer to the first element (may be null).
106 inline constexpr size_t size() const { return size_; } ///< Number of elements.
107 inline constexpr bool empty() const { return size_ == 0; } ///< True when size() == 0.
108 /// @brief `size() * sizeof(T)`.
109 inline constexpr size_t size_bytes() const { return size_ * sizeof(T); }
110 inline constexpr T *begin() const { return data_; } ///< Iterator to the first element.
111 inline constexpr T *end() const { return data_ + size_; } ///< Iterator one past the last element.
112 inline constexpr T &front() const { return data_[0]; } ///< First element. @pre !empty()
113 inline constexpr T &back() const { return data_[size_ - 1]; } ///< Last element. @pre !empty()
114 /// @brief Prints the elements on the host as `[a, b, c]`. @pre the memory is host-readable
115 template <typename U>
116 friend std::ostream &operator<<(std::ostream &os, const Span<U> &vec);
117
118private:
119 T *data_;
120 size_t size_;
121};
122
123/// @name Span deduction guides
124/// `Span(p, n)`, `Span(first, last)` and the explicit `Span(x)` deduce `T`.
125/// @{
126template <typename T>
127Span(T*, typename Span<T>::size_t) -> Span<T>;
128
129template <typename T>
130Span(T*, std::size_t) -> Span<T>;
131
132template <typename T>
133Span(T*, T*) -> Span<T>;
134
135template <typename T>
137/// @}
138
139} // namespace batchlas
140
141// Transitional shim: Span and is_std_array used to live at global scope. Define
142// BATCHLAS_NO_GLOBAL_NAMES to drop these; CTAD still works because the deduction
143// guides are found in Span's own namespace.
144#ifndef BATCHLAS_NO_GLOBAL_NAMES
145using batchlas::Span;
147#endif
148
Completion handle of enqueued work, returned by every entry point.
Where BatchLAS work runs: a device, a backend, an ordered SYCL queue and a workspace arena.
Non-owning view of size() contiguous elements of type T.
Definition sycl-span.hh:39
std::size_t size_t
Size and index type.
Definition sycl-span.hh:42
T value_type
Element type.
Definition sycl-span.hh:40
constexpr size_t size_bytes() const
size() * sizeof(T).
Definition sycl-span.hh:109
constexpr Span< T > subspan(size_t offset) const
Elements [offset, size()).
Definition sycl-span.hh:86
constexpr Span(T *data, size_t size)
Views size elements starting at data.
Definition sycl-span.hh:46
Event set_access_device(const Queue &ctx=Queue()) const
Map for access by the device of ctx.
bool operator==(const Span< T > other) const
Element-wise comparison on the host.
constexpr Span(T *begin, T *end)
Views the range [begin, end).
Definition sycl-span.hh:48
constexpr T & back() const
Last element.
Definition sycl-span.hh:113
constexpr T * begin() const
Iterator to the first element.
Definition sycl-span.hh:110
constexpr bool empty() const
True when size() == 0.
Definition sycl-span.hh:107
constexpr Span()
An empty span (null data, size 0).
Definition sycl-span.hh:44
constexpr T & operator[](size_t index) const
Element index.
Definition sycl-span.hh:102
friend std::ostream & operator<<(std::ostream &os, const Span< U > &vec)
Prints the elements on the host as [a, b, c].
constexpr Span(Span< T > &&other)=default
Same as the copy constructor.
constexpr size_t size() const
Number of elements.
Definition sycl-span.hh:106
constexpr T & front() const
First element.
Definition sycl-span.hh:112
constexpr Span< U > as_span() const
Reinterprets the bytes as elements of type U; the size is size_bytes() / sizeof(U).
Definition sycl-span.hh:81
constexpr T * end() const
Iterator one past the last element.
Definition sycl-span.hh:111
constexpr T * data() const
Pointer to the first element (may be null).
Definition sycl-span.hh:105
Event set_preferred_location(const Queue &ctx=Queue()) const
Prefer residence on the device of ctx.
constexpr Span(Span< T > &&other, size_t offset)
Views other with its first offset elements dropped.
Definition sycl-span.hh:58
constexpr Span< T > subspan(size_t offset, size_t count) const
Elements [offset, offset + count).
Definition sycl-span.hh:88
constexpr Span(T &value)
A one-element span over value.
Definition sycl-span.hh:66
Event prefetch(const Queue &ctx=Queue()) const
Migrate to the device of ctx.
T * pointer
Pointer to an element.
Definition sycl-span.hh:41
constexpr T & at(size_t index) const
Element index.
Definition sycl-span.hh:104
constexpr Span(const Span< T > &other)=default
Copies the pointer and size; the elements are not copied.
constexpr Span(const Span< T > &other, size_t offset)
Views other with its first offset elements dropped.
Definition sycl-span.hh:55
True for std::array<T, N>, false otherwise.
Definition sycl-span.hh:17
batchlas::Device, batchlas::Event and batchlas::Queue: where work runs and how it is ordered.