9template <
typename Tag,
typename T>
11 if constexpr (Tag::hermitian) {
19 static constexpr int kTile = 16;
30template <
typename Group>
37 return local_size >= 16;
40 return local_size >= 32;
42 return local_size >= 16;
45template <
typename Tag,
typename Group,
typename T>
54template <
typename T,
typename Group>
62template <
typename Tag,
typename Group,
typename T>
69 T* matrix_tile = workspace->matrix;
70 T* x_col_tile = workspace->x_col;
71 T* x_row_tile = workspace->x_row;
74 const int extent = a.
rows();
76 for (
int output_index = local_id; output_index < extent; output_index += local_size) {
77 operand.
y(output_index) *= operand.
beta;
79 sycl::group_barrier(group);
81 for (
int col_base = 0; col_base < extent; col_base += Tile) {
82 const int col_extent = std::min(Tile, extent - col_base);
84 for (
int col = local_id; col < col_extent; col += local_size) {
85 x_col_tile[col] = operand.
x(col_base + col);
87 sycl::group_barrier(group);
89 for (
int linear_index = local_id; linear_index < col_extent * col_extent; linear_index += local_size) {
90 const int row = linear_index % col_extent;
91 const int col = linear_index / col_extent;
95 value = a(col_base + row, col_base + col);
101 value = a(col_base + row, col_base + col);
108 sycl::group_barrier(group);
110 for (
int row = local_id; row < col_extent; row += local_size) {
112 for (
int col = 0; col < col_extent; ++col) {
115 operand.
y(col_base + row) += operand.
alpha * sum;
117 sycl::group_barrier(group);
120 for (
int row_base = col_base + Tile; row_base < extent; row_base += Tile) {
121 const int row_extent = std::min(Tile, extent - row_base);
122 for (
int row = local_id; row < row_extent; row += local_size) {
123 x_row_tile[row] = operand.
x(row_base + row);
125 for (
int linear_index = local_id; linear_index < row_extent * col_extent; linear_index += local_size) {
126 const int row = linear_index % row_extent;
127 const int col = linear_index / row_extent;
130 sycl::group_barrier(group);
132 for (
int row = local_id; row < row_extent; row += local_size) {
134 for (
int col = 0; col < col_extent; ++col) {
137 operand.
y(row_base + row) += operand.
alpha * sum;
139 for (
int col = local_id; col < col_extent; col += local_size) {
141 for (
int row = 0; row < row_extent; ++row) {
144 operand.
y(col_base + col) += operand.
alpha * sum;
146 sycl::group_barrier(group);
149 for (
int row_base = 0; row_base < col_base; row_base += Tile) {
150 const int row_extent = std::min(Tile, col_base - row_base);
151 for (
int row = local_id; row < row_extent; row += local_size) {
152 x_row_tile[row] = operand.
x(row_base + row);
154 for (
int linear_index = local_id; linear_index < row_extent * col_extent; linear_index += local_size) {
155 const int row = linear_index % row_extent;
156 const int col = linear_index / row_extent;
159 sycl::group_barrier(group);
161 for (
int row = local_id; row < row_extent; row += local_size) {
163 for (
int col = 0; col < col_extent; ++col) {
166 operand.
y(row_base + row) += operand.
alpha * sum;
168 for (
int col = local_id; col < col_extent; col += local_size) {
170 for (
int row = 0; row < row_extent; ++row) {
173 operand.
y(col_base + col) += operand.
alpha * sum;
175 sycl::group_barrier(group);
181template <
typename Tag,
typename Group,
typename T>
182inline constexpr void symv(
const Group& group,
187 const int extent = a.
rows();
189 for (
int output_index = local_id; output_index < extent; output_index += local_size) {
190 operand.
y(output_index) *= operand.
beta;
192 sycl::group_barrier(group);
194 for (
int col = 0; col < extent; ++col) {
195 const T x_col = operand.
x(col);
196 T mirrored_partial{};
199 for (
int row = col + 1 + local_id; row < extent; row += local_size) {
200 const T a_row_col = a(row, col);
201 operand.
y(row) += operand.
alpha * a_row_col * x_col;
205 for (
int row = local_id; row < col; row += local_size) {
206 const T a_row_col = a(row, col);
207 operand.
y(row) += operand.
alpha * a_row_col * x_col;
214 operand.
y(col) += operand.
alpha * (a(col, col) * x_col + mirrored_partial);
216 sycl::group_barrier(group);
224template <
typename Tag, DeviceBlasPolicy Policy,
typename T>
227 assert(extent >= 0 &&
"device::symv workspace query expects a non-negative matrix extent");
234template <
typename Tag, DeviceBlasPolicy Policy,
typename Group,
typename T>
238 T* workspace =
nullptr) {
241 SymmetricTransform{.side = Tag::side, .uplo = Tag::uplo, .hermitian = Tag::hermitian});
267template <Uplo UploV = Uplo::Upper,
typename Group,
typename T>
268inline constexpr void symv(
const Group& group,
271 T* workspace =
nullptr) {
276template <DeviceBlasPolicy Policy, Uplo UploV = Uplo::Upper,
typename Group,
typename T>
277inline constexpr void symv(
const Group& group,
280 T* workspace =
nullptr) {
289template <
typename T, Uplo UploV = Uplo::Upper>
300template <
typename T, DeviceBlasPolicy Policy, Uplo UploV = Uplo::Upper>
307template <Uplo UploV = Uplo::Upper,
typename Group,
typename T>
308inline constexpr void symv(
const Group& group,
314 T* workspace =
nullptr) {
319template <DeviceBlasPolicy Policy, Uplo UploV = Uplo::Upper,
typename Group,
typename T>
320inline constexpr void symv(
const Group& group,
326 T* workspace =
nullptr) {
338template <Uplo UploV = Uplo::Upper,
typename Group,
typename T>
339inline constexpr void hemv(
const Group& group,
342 T* workspace =
nullptr) {
347template <DeviceBlasPolicy Policy, Uplo UploV = Uplo::Upper,
typename Group,
typename T>
348inline constexpr void hemv(
const Group& group,
351 T* workspace =
nullptr) {
360template <
typename T, Uplo UploV = Uplo::Upper>
371template <
typename T, DeviceBlasPolicy Policy, Uplo UploV = Uplo::Upper>
378template <Uplo UploV = Uplo::Upper,
typename Group,
typename T>
379inline constexpr void hemv(
const Group& group,
385 T* workspace =
nullptr) {
390template <DeviceBlasPolicy Policy, Uplo UploV = Uplo::Upper,
typename Group,
typename T>
391inline constexpr void hemv(
const Group& group,
397 T* workspace =
nullptr) {
Non-owning view of a batch of strided vectors: the vector argument type of the entry points.
Policy
Synchronous or asynchronous execution policy.
constexpr std::size_t symv_workspace_elements(const DeviceBlasLaunchInfo &launch, int extent)
Local memory, in elements of T, that symv() can use; 0 means pass nullptr.
constexpr MatrixVectorOperand< T > make_matvec_operand(const VectorView< T > &x, const VectorView< T > &y, T alpha=T(1), T beta=T(0))
Builds a MatrixVectorOperand.
constexpr std::size_t hemv_workspace_elements(const DeviceBlasLaunchInfo &launch, int extent)
Local memory, in elements of T, that hemv() can use; 0 means pass nullptr.
DeviceBlasPolicy
Which implementation family a device BLAS call may use.
constexpr void symv(const Group &group, const KernelMatrixView< T, MatrixFormat::Dense > &a, MatrixVectorOperand< T > operand, T *workspace=nullptr)
Symmetric matrix-vector product , reading only the UploV triangle of A.
constexpr void hemv(const Group &group, const KernelMatrixView< T, MatrixFormat::Dense > &a, MatrixVectorOperand< T > operand, T *workspace=nullptr)
Hermitian matrix-vector product ; symv() with conjugated mirroring.
@ Subgroup16
fast paths only when the actual sub-group size is 16
@ Auto
any eligible path; the sub-group fast paths accept sub-group size 16 or 32
@ Subgroup32
fast paths only when the actual sub-group size is 32
@ Generic
the portable group-reduction path only; never stages through local memory
@ Lower
The lower triangle (i >= j).
constexpr void symv(const Group &group, const KernelMatrixView< T, MatrixFormat::Dense > &a, MatrixVectorOperand< T > operand)
void symv_tiled(const Group &group, const KernelMatrixView< T, MatrixFormat::Dense > &a, MatrixVectorOperand< T > operand, T *workspace_ptr)
constexpr bool symv_tiled_policy_matches(const Group &group, DeviceBlasPolicy policy)
constexpr T symmetric_mirror(const T &value)
constexpr bool can_use_tiled_symv(const Group &group, const KernelMatrixView< T, MatrixFormat::Dense > &a, DeviceBlasPolicy policy)
constexpr int symv_transpose_tile_index(int row, int col)
constexpr std::size_t symv_workspace_elements(const DeviceBlasLaunchInfo &launch, int extent)
constexpr int group_local_linear_id(const Group &group)
constexpr void validate_symmetric_operand(const KernelMatrixView< T, MatrixFormat::Dense > &a, const MatrixVectorOperand< T > &operand, SymmetricTransform transform)
constexpr int group_local_linear_range(const Group &group)
constexpr Workspace * workspace_ptr_cast(T *workspace)
constexpr T reduce_sum_group(const Group &group, const T &value)
constexpr T conj(const T &value)
constexpr std::size_t workspace_elements_v
void dispatch_symv(const Group &group, const KernelMatrixView< T, MatrixFormat::Dense > &a, MatrixVectorOperand< T > operand, T *workspace=nullptr)
constexpr bool group_is_leader(const Group &group)
Trivially copyable view of a MatrixView for use inside a SYCL kernel.
auto rows() const
Row count (the capacity on a heterogeneous batch).
auto cols() const
Column count (the capacity on a heterogeneous batch).
Host-side description of a launch, for the *_workspace_elements queries.
Operands of a matrix-vector operation: .
VectorView< T > x
input vector
T beta
scale of the input y; 0 still reads y
T alpha
scale of the product
VectorView< T > y
output vector; read (scaled by beta) and overwritten
T matrix[kTile *(kTile+1)]
static constexpr int kTile