10template <
typename Tag,
typename Group,
typename T>
11inline constexpr void rank2k(
const Group& group,
21 for (
int linear_index = local_id; linear_index < extent * extent; linear_index += local_size) {
22 const int row = linear_index % extent;
23 const int col = linear_index / extent;
29 for (
int k = 0; k < contract_extent; ++k) {
34 partial += operand.
alpha * lhs1 * rhs1 + alpha2 * lhs2 * rhs2;
37 T value = operand.
beta * operand.
c(row, col) + partial;
39 if constexpr (Tag::hermitian) {
41 value = T(value.real(),
typename T::value_type(0));
45 operand.
c(row, col) = value;
49template <
typename Tag,
typename Group,
typename T>
50inline constexpr void rankk(
const Group& group,
59 for (
int linear_index = local_id; linear_index < extent * extent; linear_index += local_size) {
60 const int row = linear_index % extent;
61 const int col = linear_index / extent;
67 for (
int k = 0; k < contract_extent; ++k) {
72 T value = operand.
beta * operand.
c(row, col) + partial;
74 if constexpr (Tag::hermitian) {
76 value = T(value.real(),
typename T::value_type(0));
80 operand.
c(row, col) = value;
88template <
typename Item,
typename T>
109 for (
int tile_row = tile_row_start; tile_row < row_tiles; tile_row += tile_row_stride) {
110 for (
int tile_col = tile_col_start; tile_col < col_tiles; tile_col += tile_col_stride) {
125 auto lhs1_loader = [&](
int tile_r,
int global_k) {
126 const int global_row = tile_row_base + tile_r;
127 if (global_row >= extent) {
132 auto rhs1_loader = [&](
int tile_c,
int global_k) {
133 const int global_col = tile_col_base + tile_c;
134 if (global_col >= extent) {
139 auto lhs2_loader = [&](
int tile_r,
int global_k) {
140 const int global_row = tile_row_base + tile_r;
141 if (global_row >= extent) {
146 auto rhs2_loader = [&](
int tile_c,
int global_k) {
147 const int global_col = tile_col_base + tile_c;
148 if (global_col >= extent) {
155 item, workspace, linear_tid, subgroup_id, local_row, local_col, contract_extent, lhs1_loader, rhs1_loader, accum);
157 item, workspace, linear_tid, subgroup_id, local_row, local_col, contract_extent, lhs2_loader, rhs2_loader, accum);
164template <
typename Item,
typename T>
185 for (
int tile_row = tile_row_start; tile_row < row_tiles; tile_row += tile_row_stride) {
186 for (
int tile_col = tile_col_start; tile_col < col_tiles; tile_col += tile_col_stride) {
201 auto lhs_loader = [&](
int tile_r,
int global_k) {
202 const int global_row = tile_row_base + tile_r;
203 if (global_row >= extent) {
208 auto rhs_loader = [&](
int tile_c,
int global_k) {
209 const int global_col = tile_col_base + tile_c;
210 if (global_col >= extent) {
217 item, workspace, linear_tid, subgroup_id, local_row, local_col, contract_extent, lhs_loader, rhs_loader, accum);
224template <
typename Item,
typename T>
245 for (
int tile_row = tile_row_start; tile_row < row_tiles; tile_row += tile_row_stride) {
246 for (
int tile_col = tile_col_start; tile_col < col_tiles; tile_col += tile_col_stride) {
261 auto lhs1_loader = [&](
int tile_r,
int global_k) {
263 if (global_row >= extent) {
268 auto rhs1_loader = [&](
int tile_c,
int global_k) {
270 if (global_col >= extent) {
275 auto lhs2_loader = [&](
int tile_r,
int global_k) {
277 if (global_row >= extent) {
282 auto rhs2_loader = [&](
int tile_c,
int global_k) {
284 if (global_col >= extent) {
298template <
typename Item,
typename T>
319 for (
int tile_row = tile_row_start; tile_row < row_tiles; tile_row += tile_row_stride) {
320 for (
int tile_col = tile_col_start; tile_col < col_tiles; tile_col += tile_col_stride) {
335 auto lhs_loader = [&](
int tile_r,
int global_k) {
337 if (global_row >= extent) {
342 auto rhs_loader = [&](
int tile_c,
int global_k) {
344 if (global_col >= extent) {
361template <
typename Tag, DeviceBlasPolicy Policy,
typename T>
364 int contract_extent) {
365 assert(extent >= 0 && contract_extent >= 0 &&
"device::rank2k workspace query expects non-negative extents");
377template <
typename Tag, DeviceBlasPolicy Policy,
typename T>
380 int contract_extent) {
381 assert(extent >= 0 && contract_extent >= 0 &&
"device::rankk workspace query expects non-negative extents");
393template <
typename Tag, DeviceBlasPolicy Policy,
typename Exec,
typename T>
397 T* workspace =
nullptr) {
416 if constexpr (std::is_same_v<std::remove_cvref_t<Exec>, sycl::nd_item<3>>) {
428template <
typename Tag, DeviceBlasPolicy Policy,
typename Exec,
typename T>
432 T* workspace =
nullptr) {
451 if constexpr (std::is_same_v<std::remove_cvref_t<Exec>, sycl::nd_item<3>>) {
484template <Uplo UploV = Uplo::Upper, Transpose TransV = Transpose::NoTrans,
typename Group,
typename T>
485inline constexpr void syrk(
const Group& group,
488 T* workspace =
nullptr) {
498inline constexpr void syrk(
const Group& group,
501 T* workspace =
nullptr) {
511template <
typename T, Uplo UploV = Uplo::Upper, Transpose TransV = Transpose::NoTrans>
514 int contract_extent) {
530 int contract_extent) {
535template <Uplo UploV = Uplo::Upper, Transpose TransV = Transpose::NoTrans,
typename Group,
typename T>
536inline constexpr void syrk(
const Group& group,
541 T* workspace =
nullptr) {
551inline constexpr void syrk(
const Group& group,
556 T* workspace =
nullptr) {
569template <Uplo UploV = Uplo::Upper, Transpose TransV = Transpose::NoTrans,
typename Group,
typename T>
570inline constexpr void herk(
const Group& group,
573 T* workspace =
nullptr) {
583inline constexpr void herk(
const Group& group,
586 T* workspace =
nullptr) {
596template <
typename T, Uplo UploV = Uplo::Upper, Transpose TransV = Transpose::NoTrans>
599 int contract_extent) {
615 int contract_extent) {
620template <Uplo UploV = Uplo::Upper, Transpose TransV = Transpose::NoTrans,
typename Group,
typename T>
621inline constexpr void herk(
const Group& group,
626 T* workspace =
nullptr) {
636inline constexpr void herk(
const Group& group,
641 T* workspace =
nullptr) {
656template <Uplo UploV = Uplo::Upper, Transpose TransV = Transpose::NoTrans,
typename Group,
typename T>
657inline constexpr void syr2k(
const Group& group,
660 T* workspace =
nullptr) {
670inline constexpr void syr2k(
const Group& group,
673 T* workspace =
nullptr) {
683template <
typename T, Uplo UploV = Uplo::Upper, Transpose TransV = Transpose::NoTrans>
686 int contract_extent) {
702 int contract_extent) {
707template <Uplo UploV = Uplo::Upper, Transpose TransV = Transpose::NoTrans,
typename Group,
typename T>
708inline constexpr void syr2k(
const Group& group,
714 T* workspace =
nullptr) {
724inline constexpr void syr2k(
const Group& group,
730 T* workspace =
nullptr) {
742template <Uplo UploV = Uplo::Upper, Transpose TransV = Transpose::NoTrans,
typename Group,
typename T>
743inline constexpr void her2k(
const Group& group,
746 T* workspace =
nullptr) {
756inline constexpr void her2k(
const Group& group,
759 T* workspace =
nullptr) {
769template <
typename T, Uplo UploV = Uplo::Upper, Transpose TransV = Transpose::NoTrans>
772 int contract_extent) {
788 int contract_extent) {
793template <Uplo UploV = Uplo::Upper, Transpose TransV = Transpose::NoTrans,
typename Group,
typename T>
794inline constexpr void her2k(
const Group& group,
800 T* workspace =
nullptr) {
810inline constexpr void her2k(
const Group& group,
816 T* workspace =
nullptr) {
A std::complex scalar (std::complex<float>, std::complex<double>).
Policy
Synchronous or asynchronous execution policy.
constexpr std::size_t syr2k_workspace_elements(const DeviceBlasLaunchInfo &launch, int extent, int contract_extent)
Local memory, in elements of T, that syr2k() can use; 0 means pass nullptr.
constexpr std::size_t herk_workspace_elements(const DeviceBlasLaunchInfo &launch, int extent, int contract_extent)
Local memory, in elements of T, that herk() can use; 0 means pass nullptr.
constexpr std::size_t her2k_workspace_elements(const DeviceBlasLaunchInfo &launch, int extent, int contract_extent)
Local memory, in elements of T, that her2k() can use; 0 means pass nullptr.
constexpr std::size_t syrk_workspace_elements(const DeviceBlasLaunchInfo &launch, int extent, int contract_extent)
Local memory, in elements of T, that syrk() can use for this launch and shape.
constexpr MatrixMatrixOperand< T > make_matmat_operand(const KernelMatrixView< T, MatrixFormat::Dense > &b, const KernelMatrixView< T, MatrixFormat::Dense > &c, T alpha=T(1), T beta=T(0))
Builds a MatrixMatrixOperand.
constexpr RankKOperand< T > make_rankk_operand(const KernelMatrixView< T, MatrixFormat::Dense > &c, T alpha=T(1), T beta=T(0))
Builds a RankKOperand.
constexpr void herk(const Group &group, const KernelMatrixView< T, MatrixFormat::Dense > &a, RankKOperand< T > operand, T *workspace=nullptr)
Hermitian rank-k update (NoTrans) or , on the UploV triangle.
constexpr void her2k(const Group &group, const KernelMatrixView< T, MatrixFormat::Dense > &a, MatrixMatrixOperand< T > operand, T *workspace=nullptr)
Hermitian rank-2k update (NoTrans) or , on the UploV triangle.
DeviceBlasPolicy
Which implementation family a device BLAS call may use.
constexpr void syr2k(const Group &group, const KernelMatrixView< T, MatrixFormat::Dense > &a, MatrixMatrixOperand< T > operand, T *workspace=nullptr)
Symmetric rank-2k update (NoTrans) or , on the UploV triangle.
constexpr void syrk(const Group &group, const KernelMatrixView< T, MatrixFormat::Dense > &a, RankKOperand< T > operand, T *workspace=nullptr)
Symmetric rank-k update (NoTrans) or , on the UploV triangle of C only.
@ Auto
any eligible path; the sub-group fast paths accept sub-group size 16 or 32
Transpose
The operator op() applied to an operand: op(A) = A, A^T or A^H.
Uplo
Which triangle of a symmetric, Hermitian or triangular operand is referenced.
@ Upper
The upper triangle (i <= j).
@ Lower
The lower triangle (i >= j).
constexpr void rank2k(const Group &group, const KernelMatrixView< T, MatrixFormat::Dense > &a, MatrixMatrixOperand< T > operand)
constexpr void rankk(const Group &group, const KernelMatrixView< T, MatrixFormat::Dense > &a, RankKOperand< T > operand)
constexpr bool can_use_rankk_register_fast_path(const Item &item, int extent, int contract_extent, DeviceBlasPolicy policy)
constexpr int kComplexRank2kTileN
constexpr void rank2k_register_tiled(const Item &item, const KernelMatrixView< T, MatrixFormat::Dense > &a, MatrixMatrixOperand< T > operand, SymmetricRank2kTransform transform, RegisterMatrixWorkspace< T > *workspace)
constexpr bool can_use_rank2k_register_fast_path(const Item &item, int extent, int contract_extent, DeviceBlasPolicy policy)
constexpr bool register_matrix_workspace_supported_v
constexpr int kRegisterMatrixTileN
constexpr void rankk_register_tiled(const Item &item, const KernelMatrixView< T, MatrixFormat::Dense > &a, RankKOperand< T > operand, SymmetricRankKTransform transform, RegisterMatrixWorkspace< T > *workspace)
constexpr int subgroup_group_id(const Item &item)
constexpr int matrix_tile_group_row(const Item &)
constexpr int kRegisterMatrixLocalCols
constexpr void accumulate_rank2k_register_tiled_pass(const Item &item, RegisterMatrixWorkspace< T > *workspace, int linear_tid, int subgroup_id, int contract_extent, LhsLoader &&lhs_loader, RhsLoader &&rhs_loader, RegisterMatrixAccumTile< T > &accum)
constexpr void rank2k_complex_tiled(const Item &item, const KernelMatrixView< T, MatrixFormat::Dense > &a, MatrixMatrixOperand< T > operand, SymmetricRank2kTransform transform, ComplexRank2kWorkspace< T > *workspace)
constexpr bool complex_rank2k_workspace_supported_v
constexpr int matrix_tile_group_col(const Item &)
constexpr int kComplexRank2kThreadTileCols
constexpr int kComplexRank2kThreadTileRows
constexpr int kRegisterMatrixThreadTileRows
constexpr int matrix_tile_group_row_stride(const Item &)
constexpr int matrix_tile_group_col_stride(const Item &)
constexpr bool can_use_complex_rank2k_tiled_fast_path(const Item &item, int extent, int contract_extent, DeviceBlasPolicy policy)
constexpr int kRegisterMatrixTileM
constexpr void accumulate_complex_rank2k_tiled_pass_impl(const Item &item, Workspace *workspace, int linear_tid, int subgroup_id, int local_row, int local_col, int contract_extent, LhsLoader &&lhs_loader, RhsLoader &&rhs_loader, ComplexRank2kAccumTile< T > &accum)
constexpr int kComplexRank2kLocalCols
constexpr void rankk_complex_tiled(const Item &item, const KernelMatrixView< T, MatrixFormat::Dense > &a, RankKOperand< T > operand, SymmetricRankKTransform transform, ComplexRank2kWorkspace< T > *workspace)
constexpr int kComplexRank2kTileM
constexpr void write_rank2k_register_tile(MatrixMatrixOperand< T > operand, Transform transform, int row_base, int col_base, int extent, const RegisterMatrixAccumTile< T > &accum)
constexpr bool can_use_complex_rankk_tiled_fast_path(const Item &item, int extent, int contract_extent, DeviceBlasPolicy policy)
constexpr void write_complex_rank2k_tile(MatrixMatrixOperand< T > operand, Transform transform, int row_base, int col_base, int extent, const ComplexRank2kAccumTile< T > &accum)
constexpr int kRegisterMatrixThreadTileCols
constexpr std::size_t rankk_workspace_elements(const DeviceBlasLaunchInfo &launch, int extent, int contract_extent)
constexpr int output_size(const KernelMatrixView< T, MatrixFormat::Dense > &a, Transpose trans)
constexpr Transpose rank2k_rhs_transform()
constexpr int group_local_linear_id(const Group &group)
constexpr void dispatch_rank2k(const Exec &exec, const KernelMatrixView< T, MatrixFormat::Dense > &a, MatrixMatrixOperand< T > operand, T *workspace=nullptr)
constexpr int input_size(const KernelMatrixView< T, MatrixFormat::Dense > &a, Transpose trans)
constexpr int group_local_linear_range(const Group &group)
constexpr Workspace * workspace_ptr_cast(T *workspace)
constexpr Transpose rankk_rhs_transform()
constexpr void validate_rank2k_operand(const KernelMatrixView< T, MatrixFormat::Dense > &a, const MatrixMatrixOperand< T > &operand, SymmetricRank2kTransform transform)
constexpr T matrix_entry(const KernelMatrixView< T, MatrixFormat::Dense > &a, int row, int col, Transpose trans)
constexpr void dispatch_rankk(const Exec &exec, const KernelMatrixView< T, MatrixFormat::Dense > &a, RankKOperand< T > operand, T *workspace=nullptr)
constexpr int item_local_linear_id(const Item &item)
constexpr std::size_t rank2k_workspace_elements(const DeviceBlasLaunchInfo &launch, int extent, int contract_extent)
constexpr std::size_t workspace_elements_v
constexpr void validate_rankk_operand(const KernelMatrixView< T, MatrixFormat::Dense > &a, const RankKOperand< T > &operand, SymmetricRankKTransform transform)
constexpr bool triangular_storage_contains(int row, int col)
constexpr T secondary_rank2k_alpha(const T &alpha)
Trivially copyable view of a MatrixView for use inside a SYCL kernel.
Host-side description of a launch, for the *_workspace_elements queries.
Operands of a matrix-matrix operation: .
KernelMatrixView< T, MatrixFormat::Dense > c
output matrix; read (scaled by beta) and overwritten
T alpha
scale of the product
T beta
scale of the input C; 0 still reads C
KernelMatrixView< T, MatrixFormat::Dense > b
second input matrix
Operands of a rank-k update: .
T alpha
scale of the product
KernelMatrixView< T, MatrixFormat::Dense > c
square output; only the uplo triangle is touched
T beta
scale of the input C; 0 still reads C