group_blas_vector.hh
Go to the documentation of this file.
1#pragma once
2
4
5namespace batchlas::device {
6
7namespace detail::generic {
8
9template <typename Group, typename T, typename Op, typename... Inputs>
10inline constexpr void hadamard(const Group& group,
11 const VectorView<T>& z,
12 Op op,
13 const Inputs&... inputs) {
14 const int local_id = detail::group_local_linear_id(group);
15 const int local_size = detail::group_local_linear_range(group);
16
17 for (int index = local_id; index < z.size(); index += local_size) {
18 z(index) = op(inputs(index)...);
19 }
20}
21
22} // namespace detail::generic
23
24/// @addtogroup api_device_blas
25/// @{
26
27/// @brief \f$ y := x \f$, cooperatively across `group`.
28/// @tparam Group `sycl::group`, `sycl::sub_group` or an `nd_item`; every work-item must call
29/// @param group executor whose work-items share the elements
30/// @param x input vector
31/// @param y output vector
32/// @pre `x.size() == y.size()`; both single vectors (`batch_size() == 1`). Checked by `assert` only.
33template <typename Group, typename T>
34inline constexpr void copy(const Group& group,
35 const VectorView<T>& x,
36 const VectorView<T>& y) {
38 const int local_id = detail::group_local_linear_id(group);
39 const int local_size = detail::group_local_linear_range(group);
40
41 for (int index = local_id; index < x.size(); index += local_size) {
42 y(index) = x(index);
43 }
44}
45
46/// @brief \f$ y := \bar{x} \f$ (a plain copy for real `T`).
47/// @param group executor whose work-items share the elements
48/// @param x input vector
49/// @param y output vector
50/// @pre `x.size() == y.size()`.
51template <typename Group, typename T>
52inline constexpr void copyc(const Group& group,
53 const VectorView<T>& x,
54 const VectorView<T>& y) {
56 const int local_id = detail::group_local_linear_id(group);
57 const int local_size = detail::group_local_linear_range(group);
58
59 for (int index = local_id; index < x.size(); index += local_size) {
60 y(index) = detail::conj(x(index));
61 }
62}
63
64/// @brief \f$ x := \alpha\,x \f$.
65/// @param group executor whose work-items share the elements
66/// @param x vector scaled in place
67/// @param alpha scale
68template <typename Group, typename T>
69inline constexpr void scal(const Group& group,
70 const VectorView<T>& x,
71 T alpha) {
73 const int local_id = detail::group_local_linear_id(group);
74 const int local_size = detail::group_local_linear_range(group);
75
76 for (int index = local_id; index < x.size(); index += local_size) {
77 x(index) *= alpha;
78 }
79}
80
81/// @brief \f$ y := \alpha\,x + y \f$.
82/// @param group executor whose work-items share the elements
83/// @param x input vector
84/// @param y vector updated in place
85/// @param alpha scale of `x`
86/// @pre `x.size() == y.size()`.
87template <typename Group, typename T>
88inline constexpr void axpy(const Group& group,
89 const VectorView<T>& x,
90 const VectorView<T>& y,
91 T alpha = T(1)) {
93 const int local_id = detail::group_local_linear_id(group);
94 const int local_size = detail::group_local_linear_range(group);
95
96 for (int index = local_id; index < x.size(); index += local_size) {
97 y(index) += alpha * x(index);
98 }
99}
100
101/// @brief Element-wise product \f$ z_i := x_i\,y_i \f$.
102/// @param group executor whose work-items share the elements
103/// @param x first factor
104/// @param y second factor
105/// @param z output; may alias `x` or `y`
106/// @pre all three vectors have the same size.
107template <typename Group, typename T>
108inline constexpr void hadamard(const Group& group,
109 const VectorView<T>& x,
110 const VectorView<T>& y,
111 const VectorView<T>& z) {
112 hadamard(group, z, [](const T& lhs, const T& rhs) { return lhs * rhs; }, x, y);
113}
114
115/// @brief Element-wise n-ary map \f$ z_i := \mathrm{op}(u_i, v_i, \ldots) \f$.
116/// @tparam Op callable taking one `T` per input and returning `T`; must be device-callable
117/// @tparam Inputs one or more `VectorView<T>`
118/// @param group executor whose work-items share the elements
119/// @param z output vector
120/// @param op the element-wise function
121/// @param inputs input vectors, each of `z.size()`
122template <typename Group, typename T, typename Op, typename... Inputs>
123 requires(sizeof...(Inputs) > 0 && (detail::VectorOperandFor<T, Inputs> && ...))
124inline constexpr void hadamard(const Group& group,
125 const VectorView<T>& z,
126 Op op,
127 const Inputs&... inputs) {
128 detail::validate_hadamard_operands(z, "hadamard", inputs...);
129 detail::generic::hadamard(group, z, op, inputs...);
130}
131
132/// @brief Unconjugated dot product \f$ \sum_i x_i\,y_i \f$.
133/// @param group executor whose work-items share the elements
134/// @param x first vector
135/// @param y second vector
136/// @return the group-wide sum, on every work-item of `group`
137/// @pre `x.size() == y.size()`.
138template <typename Group, typename T>
139inline constexpr T dotu(const Group& group,
140 const VectorView<T>& x,
141 const VectorView<T>& y) {
143 const int local_id = detail::group_local_linear_id(group);
144 const int local_size = detail::group_local_linear_range(group);
145 T partial = T(0);
146
147 for (int index = local_id; index < x.size(); index += local_size) {
148 partial += x(index) * y(index);
149 }
150
151 return detail::reduce_sum_group(group, partial);
152}
153
154/// @brief Conjugated dot product \f$ \sum_i \bar{x}_i\,y_i \f$ (dotu for real `T`).
155/// @param group executor whose work-items share the elements
156/// @param x conjugated vector
157/// @param y second vector
158/// @return the group-wide sum, on every work-item of `group`
159/// @pre `x.size() == y.size()`.
160template <typename Group, typename T>
161inline constexpr T dotc(const Group& group,
162 const VectorView<T>& x,
163 const VectorView<T>& y) {
165 const int local_id = detail::group_local_linear_id(group);
166 const int local_size = detail::group_local_linear_range(group);
167 T partial = T(0);
168
169 for (int index = local_id; index < x.size(); index += local_size) {
170 partial += detail::conj(x(index)) * y(index);
171 }
172
173 return detail::reduce_sum_group(group, partial);
174}
175
176/// @}
177
178} // namespace batchlas::device
Non-owning view of a batch of strided vectors: the vector argument type of the entry points.
Definition matrix.hh:1754
int size() const
Entries per item.
Definition matrix.hh:1837
constexpr void copy(const Group &group, const VectorView< T > &x, const VectorView< T > &y)
, cooperatively across group.
constexpr void copyc(const Group &group, const VectorView< T > &x, const VectorView< T > &y)
(a plain copy for real T).
constexpr T dotc(const Group &group, const VectorView< T > &x, const VectorView< T > &y)
Conjugated dot product (dotu for real T).
constexpr T dotu(const Group &group, const VectorView< T > &x, const VectorView< T > &y)
Unconjugated dot product .
constexpr void axpy(const Group &group, const VectorView< T > &x, const VectorView< T > &y, T alpha=T(1))
.
constexpr void scal(const Group &group, const VectorView< T > &x, T alpha)
.
constexpr void hadamard(const Group &group, const VectorView< T > &x, const VectorView< T > &y, const VectorView< T > &z)
Element-wise product .
@ Group
the call receives a sycl::group (or sycl::sub_group)
constexpr void hadamard(const Group &group, const VectorView< T > &z, Op op, const Inputs &... inputs)
constexpr int group_local_linear_id(const Group &group)
constexpr void validate_vector_operands(const VectorView< T > &x, const VectorView< T > &y, const char *op_name)
constexpr int group_local_linear_range(const Group &group)
constexpr T reduce_sum_group(const Group &group, const T &value)
constexpr T conj(const T &value)
constexpr void validate_vector_operand(const VectorView< T > &x, const char *op_name)
constexpr void validate_hadamard_operands(const VectorView< T > &z, const char *op_name, const Views &... inputs)