tiled_general.hh
Go to the documentation of this file.
1#pragma once
2#include <cstddef>
3
6
7#include <sycl/sycl.hpp>
8
9namespace batchlas::sycl_gemm {
10
11template <typename T, int Tile, Transpose OpA, Transpose OpB>
13
14template <typename T, int Tile, Transpose OpA, Transpose OpB>
19 T alpha,
20 T beta,
21 const char* (*kernel_trace_name)(KernelVariant)) {
22 BATCHLAS_KERNEL_TRACE_SCOPE(kernel_trace_name(KernelVariant::Tiled16));
23
24 const auto [m, k] = get_effective_dims(A, OpA);
25 const auto [_, n] = get_effective_dims(B, OpB);
26 static_cast<void>(_);
27
28 const sycl::range<3> local(1, Tile, Tile);
29 const sycl::range<3> global(static_cast<size_t>(A.batch_size()),
30 static_cast<size_t>(((m + Tile - 1) / Tile) * Tile),
31 static_cast<size_t>(((n + Tile - 1) / Tile) * Tile));
32
33 ctx->submit([&](sycl::handler& h) {
34 sycl::local_accessor<T, 1> tile_a(sycl::range<1>(Tile * Tile), h);
35 sycl::local_accessor<T, 1> tile_b(sycl::range<1>(Tile * Tile), h);
36
37 const T* a_ptr = A.data_ptr();
38 const T* b_ptr = B.data_ptr();
39 T* c_ptr = C.data_ptr();
40 const int lda = A.ld();
41 const int ldb = B.ld();
42 const int ldc = C.ld();
43 const int stride_a = A.stride();
44 const int stride_b = B.stride();
45 const int stride_c = C.stride();
46 const int batch = A.batch_size();
47
48 batchlas::impl::parallel_for<GemmTiledGeneralKernel<T, Tile, OpA, OpB>>(h, sycl::nd_range<3>(global, local), [=](sycl::nd_item<3> item) {
49 const int bid = static_cast<int>(item.get_group(0));
50 const int local_row = static_cast<int>(item.get_local_id(1));
51 const int local_col = static_cast<int>(item.get_local_id(2));
52 const int row = static_cast<int>(item.get_group(1) * Tile + local_row);
53 const int col = static_cast<int>(item.get_group(2) * Tile + local_col);
54 if (bid >= batch) {
55 return;
56 }
57
58 // Rebased per item in 64 bits (bid * stride passes 2^31); offsets within an item stay int.
59 const T* const a_item = a_ptr + static_cast<std::ptrdiff_t>(bid) * stride_a;
60 const T* const b_item = b_ptr + static_cast<std::ptrdiff_t>(bid) * stride_b;
61 T* const c_item = c_ptr + static_cast<std::ptrdiff_t>(bid) * stride_c;
62 constexpr int batch_a = 0, batch_b = 0, batch_c = 0;
63 T sum = T(0);
64
65 for (int kk0 = 0; kk0 < k; kk0 += Tile) {
66 const int tile_col = kk0 + local_col;
67 const int tile_row = kk0 + local_row;
68 tile_a[local_row * Tile + local_col] = (row < m && tile_col < k)
69 ? OperandAccessor<T, OpA>::load(a_item, lda, batch_a, row, tile_col)
70 : T(0);
71 tile_b[local_row * Tile + local_col] = (col < n && tile_row < k)
72 ? OperandAccessor<T, OpB>::load(b_item, ldb, batch_b, tile_row, col)
73 : T(0);
74
75 item.barrier(sycl::access::fence_space::local_space);
76 for (int t = 0; t < Tile && kk0 + t < k; ++t) {
77 sum += tile_a[local_row * Tile + t] * tile_b[t * Tile + local_col];
78 }
79 item.barrier(sycl::access::fence_space::local_space);
80 }
81
82 if (row < m && col < n) {
83 LinearEpilogue<T>::store(c_item + batch_c + col * ldc + row, alpha, beta, sum);
84 }
85 });
86 });
87
88 return ctx.get_event();
89}
90
91} // namespace batchlas::sycl_gemm
Non-owning view of a batch of matrices: the argument type of every entry point.
Definition matrix.hh:485
T * data_ptr() const
Base pointer of item 0.
Definition matrix.hh:600
int ld() const
Leading dimension: element distance between columns.
Definition matrix.hh:818
int stride() const
Batch stride: element distance between items.
Definition matrix.hh:823
int batch_size() const
Number of batch items.
Definition matrix.hh:603
std::pair< int, int > get_effective_dims(const MatrixView< T, MType > &mat, Transpose trans)
Shape (rows, cols) of op(mat) for trans: swapped unless NoTrans.
Definition matrix.hh:2159
Event launch_tiled_general(Queue &ctx, const MatrixView< T, MatrixFormat::Dense > &A, const MatrixView< T, MatrixFormat::Dense > &B, const MatrixView< T, MatrixFormat::Dense > &C, T alpha, T beta, const char *(*kernel_trace_name)(KernelVariant))
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.
Event get_event() const
An Event that completes after everything enqueued on this Queue so far.
static void store(T *dst, T alpha, T beta, T accum)
static T load(const T *ptr, int ld, int batch_offset, int row, int col)
Definition accessors.hh:36