26 int m = 0,
n = 0,
k = 0,
u = 1;
27 static constexpr std::string_view
name =
"reg";
28 static constexpr std::array<std::string_view, 4>
fields{
"m",
"n",
"k",
"u"};
29 std::array<int, 4>
values()
const {
return {
m,
n,
k,
u}; }
30 static Reg from(std::array<int, 4> v) {
return {v[0], v[1], v[2], v[3]}; }
36 int m = 0,
n = 0,
k = 0;
37 static constexpr std::string_view
name =
"wide";
38 static constexpr std::array<std::string_view, 3>
fields{
"m",
"n",
"k"};
39 std::array<int, 3>
values()
const {
return {
m,
n,
k}; }
40 static Wide from(std::array<int, 3> v) {
return {v[0], v[1], v[2]}; }
45using GemmChoice = std::variant<Direct, Tiled, Small, Reg, Wide, Vendor>;
49 bool nn =
false,
nt =
false,
tn =
false,
tt =
false;
61 if (
m == 128 &&
n == 128)
return std::int64_t(4) * ((32 * 132 > 2 *
k *
m ? 32 * 132 : 2 *
k *
m) + 2 *
k *
n);
62 return std::int64_t(4) *
stages * ((
m + 1) *
k + (
k + 1) *
n);
66 {32, 32, 8, 1, 2, 2, 1, {
true,
false,
false,
false},
false},
67 {64, 64, 8, 1, 4, 4, 1, {
true,
false,
false,
false},
false},
68 {64, 64, 16, 1, 4, 4, 1, {
true,
true,
true,
true},
false},
69 {128, 32, 16, 1, 4, 4, 2, {
true,
true,
true,
true},
false},
70 {128, 32, 32, 1, 4, 4, 2, {
true,
true,
true,
true},
true},
71 {128, 64, 16, 1, 4, 4, 1, {
false,
true,
true,
true},
false},
72 {32, 128, 16, 1, 4, 4, 1, {
true,
false,
true,
true},
false},
73 {128, 64, 32, 4, 8, 4, 2, {
true,
false,
false,
false},
true},
74 {128, 64, 32, 2, 8, 4, 2, {
true,
false,
false,
false},
true},
75 {128, 128, 8, 1, 8, 8, 2, {
true,
false,
false,
false},
true},
86 {64, 64, 16, 4, 4,
true,
true,
true},
87 {128, 32, 16, 4, 4,
false,
false,
true},
88 {32, 128, 16, 4, 4,
false,
true,
false},
89 {32, 32, 16, 4, 4,
true,
false,
false},
90 {16, 16, 16, 2, 2,
true,
false,
false},
103 const int nb = max_dim <= 48 ? 48 : 56;
104 return (nb / 4) * (nb / 4);
112inline constexpr bool is_complex_v = !std::is_same_v<T, float> && !std::is_same_v<T, double>;
117 return !(std::is_same_v<T, float> && nn && max_dim > 32 && max_dim <=
kSmallTiledMaxDim);
123 const int mx =
static_cast<int>(max_dim);
130 constexpr std::array<Wide, 5> wides{
Wide{64, 64, 16},
Wide{128, 32, 16},
Wide{32, 128, 16},
Wide{32, 32, 16},
132 if constexpr (std::is_same_v<T, float>) {
133 std::array<GemmChoice, 19> out{};
139 for (
const Wide& w : wides) out[i++] = w;
142 }
else if constexpr (std::is_same_v<T, double>) {
143 return std::array<GemmChoice, 9>{
Direct{},
Tiled{},
Small{}, wides[0], wides[1], wides[2], wides[3],
146 return std::array<GemmChoice, 8>{
Direct{},
Tiled{}, wides[0], wides[1], wides[2], wides[3], wides[4],
152inline constexpr std::array<std::string_view, 2>
last_resort{
"direct",
"vendor"};
157inline constexpr std::array<std::string_view, 7>
key_names{
"ta:exact",
"tb:exact",
"layout:exact",
"m:log",
158 "n:log",
"k:log",
"batch:log"};
163inline constexpr std::array<int, 14>
grid_square{8, 16, 24, 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, 1024};
164inline constexpr std::array<int, 7>
grid_panel_mn{32, 64, 128, 256, 512, 1024, 2048};
165inline constexpr std::array<int, 6>
grid_panel_k{8, 16, 32, 64, 96, 128};
166inline constexpr std::array<int, 6>
grid_skinny_mn{64, 128, 256, 512, 1024, 2048};
168inline constexpr std::array<int, 3>
grid_batch{128, 2048, 32768};
170inline constexpr std::array<std::string_view, 4>
grid_real_forms{
"NN",
"NT",
"TN",
"TT"};
172inline constexpr std::array<std::string_view, 6>
grid_complex_forms{
"NN",
"NT",
"TN",
"NC",
"CN",
"CT"};
constexpr std::array< RegCfg, 10 > reg_configs
constexpr std::array< int, 7 > grid_panel_mn
constexpr std::array< std::string_view, 5 > grid_complex_panel_forms
constexpr std::array< int, 2 > grid_skinny_k
constexpr bool small_needs_sg32(bool nn, int max_dim)
small's batched leg is [[sycl::reqd_sub_group_size(32)]]; only the float NN tiled leg is not.
constexpr std::array< std::string_view, 2 > last_resort
Generality order (§5.5): direct serves every GPU shape, vendor everything else (CPU,...
constexpr std::array< int, 6 > grid_skinny_mn
constexpr std::array< std::string_view, 7 > key_names
Table keys: ta, tb (N|T|C; C folds to T for a real scalar) and layout (packed = A,...
constexpr auto candidates()
Every compiled choice, once, in tie-break order (§6.3): simpler first, vendor last.
constexpr std::array< std::string_view, 3 > grid_real_panel_forms
constexpr int kSmallTiledMaxDim
constexpr std::array< std::string_view, 6 > grid_complex_forms
constexpr std::array< int, 14 > grid_square
The tuner's demand-driven grid; the transcriber (tuned/README.md) spells it again.
constexpr int grid_packed_panel_min
std::variant< Direct, Tiled, Small, Reg, Wide, Vendor > GemmChoice
natives: GPU or vendor-free host, Default precision
constexpr select::OpSpec spec
op, vendor library, rules
constexpr std::array< int, 3 > grid_batch
constexpr std::array< std::string_view, 4 > grid_real_forms
constexpr std::array< int, 6 > grid_panel_k
constexpr int small_wg(bool nn, int max_dim)
The work-group small launches: the batched kernel's 128 lanes, or the float NN tiled leg's (NB/4)^2 w...
bool small_fits(const select::Device &d, bool nn, std::int64_t max_dim)
The shape-and-device half of small's can_run, here so tests can probe synthetic devices.
constexpr bool is_complex_v
constexpr int kSmallMaxDim
constexpr std::array< WideCfg, 5 > wide_configs
constexpr std::int64_t kMaxGridBatch
direct, tiled, reg and wide put the batch in SYCL dim 0 = CUDA grid z (65535); small is 1-D.
Flat kernel selection: one choose() per op over measured per-device tables.
gemm_direct: one work-item per element, any form; max_wg >= 64
One compiled register config: tr/tc thread tile, stages, the forms instantiated, and whether NN takes...
constexpr int threads() const
constexpr std::int64_t slm_bytes() const
Float local memory per work-group (gemm_kernels.cc static_asserts it against each kernel).
gemm_reg, float only: m x n x k macro tile with k unroll u; must name a reg_configs entry that instan...
bool operator==(const Reg &) const =default
static constexpr std::string_view name
static Reg from(std::array< int, 4 > v)
std::array< int, 4 > values() const
static constexpr std::array< std::string_view, 4 > fields
gemm_small: several matrices per work-group; real, see small_fits
gemm_tiled: 16x16 shared-memory tile, any form; max_wg >= 256
backend::gemm_vendor; needs the level-3 library
One compiled wide config.
constexpr int threads() const
gemm_wide, every scalar: 16-byte-granule m x n x k tiles; must name a wide_configs entry that instant...
static constexpr std::array< std::string_view, 3 > fields
std::array< int, 3 > values() const
static Wide from(std::array< int, 3 > v)
static constexpr std::string_view name
bool operator==(const Wide &) const =default
The device facts a can_run predicate and the table lookup read (§5.1).
int max_wg
MAX_WORK_GROUP_SIZE.
Base of a family with no knobs: struct Cta : NoFields<"cta"> {};.
What an op's choice.hh declares once: its name, the library its Vendor family calls (one gate for can...