choice.hh
Go to the documentation of this file.
1#pragma once
2
3/// @file
4/// @brief syrk: gram, triangular, vendor. evidence: docs/perf/level3.md @ingroup api_selection_ops
5
7
8#include <algorithm>
9#include <array>
10#include <cstdint>
11#include <string>
12#include <string_view>
13#include <type_traits>
14#include <variant>
15
17
18struct Gram : select::NoFields<"gram"> {}; ///< syrk_gram_tiles: one tile covers C; n <= 128, tile SLM fits
19struct Triangular : select::NoFields<"triangular"> {}; ///< syrk_triangular_tiles<float>: 128-wide tiles of one half
20struct Vendor : select::NoFields<"vendor"> {}; ///< backend::syrk_vendor (per-item ?syrk loop)
21
22using SyrkChoice = std::variant<Gram, Triangular, Vendor>; ///< fieldless (tile, leg derived); natives: CUDA GPU
23
24template <class T> /// Every compiled choice in tie-break order (§6.3); triangular is float only (R7).
25constexpr auto candidates() {
26 if constexpr (std::is_same_v<T, float>) return std::array<SyrkChoice, 3>{Gram{}, Triangular{}, Vendor{}};
27 else return std::array<SyrkChoice, 2>{Gram{}, Vendor{}};
28}
29
30inline constexpr std::array<std::string_view, 3> last_resort{"triangular", "gram", "vendor"}; ///< none runs
31inline constexpr select::OpSpec spec{Op::syrk, select::Lib::level3, {last_resort}}; ///< op, vendor library, rules
32
33/// Keys: form (transcribed squareish ratio of n, k) and trans N|T|C exact; n weight 2 (work ~ n^2 k batch);
34/// k = op(A)'s inner.
35inline constexpr std::array<std::string_view, 5> key_names{"form:exact", "trans:exact", "n:log:2", "k:log",
36 "batch:log"};
37
38inline std::string_view form_of(std::int64_t a, std::int64_t b) {
39 return 2 * std::min(a, b) >= std::max(a, b) ? "sq" : (a > 2 * b ? "tall" : "wide");
40}
41
42// Both sides of every transcribed threshold (n 128|129 and each 128-tile band edge,
43// k 7|8, every band's batch floor); the transcriber spells the same grid.
44inline constexpr std::array<int, 30> grid_n{1, 2, 4, 8, 16, 32, 64, 128, 129, 256,
45 257, 384, 385, 512, 513, 640, 641, 768, 769, 896,
46 897, 1024, 1025, 1152, 1153, 1536, 1537, 2176, 2177, 4096}; ///< n axis
47// N and T take the full product; C only the n axis at k = batch = 1 (vendor-first everywhere).
48inline constexpr std::array<std::string_view, 3> grid_trans{"N", "T", "C"}; ///< trans axis of the grid
49inline constexpr std::array<int, 6> grid_k{1, 7, 8, 64, 512, 4096}; ///< k axis of the grid
50inline constexpr std::array<int, 17> grid_batch{1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 15, 16, 26, 27, 128, 1024, 32768};
51
52// Both tile kernels put the batch in a grid dimension, and triangular its T(T+1)/2 tiles
53// (T = ceil(n/128)) in another; each is capped at 65535 work-groups, past which the launch throws.
54inline constexpr std::int64_t kMaxGridBatch = 65535; ///< batch ceiling of both tile kernels
55inline constexpr std::int64_t kMaxGridTiles = 65535; ///< triangular's tile-count ceiling
56inline constexpr int kTriangularWg = 256; ///< syrk_triangular_tiles' 16 x 16 work-group
57inline constexpr std::int64_t triangular_groups(std::int64_t n, std::int64_t tile) { // T(T+1)/2, T = ceil(n/tile)
58 const std::int64_t t = (n + tile - 1) / tile;
59 return t * (t + 1) / 2;
60}
61
62// gram's launch for real T (syrk_gram_tiles.hh): 4x4 thread tiles meeting the triangle, KC = 32.
63inline constexpr int gram_tile(std::int64_t n) { return n <= 32 ? 32 : (n <= 64 ? 64 : 128); } // tile width
64inline constexpr int gram_threads(std::int64_t n) { // the lanes meeting the triangle, warp-rounded
65 const int lanes = gram_tile(n) / 4;
66 return (lanes * (lanes + 1) / 2 + 31) / 32 * 32;
67}
68template <class T>
69constexpr std::int64_t gram_slm_bytes(std::int64_t n) { // the staged [KC][tile] operand
70 return std::int64_t(32) * gram_tile(n) * std::int64_t(sizeof(T));
71}
72
73/// herk's opt-in to the conjugating gram kernel: syrk's pin is exactly `gram`.
74inline bool herk_gram_pinned() {
75 std::string source;
76 const auto text = select::detail::pin_text("syrk", &source);
77 return text && *text == "gram";
78}
79
80} // namespace batchlas::ops::syrk
bool herk_gram_pinned()
herk's opt-in to the conjugating gram kernel: syrk's pin is exactly gram.
Definition choice.hh:74
constexpr std::array< int, 17 > grid_batch
Definition choice.hh:50
constexpr std::int64_t kMaxGridBatch
batch ceiling of both tile kernels
Definition choice.hh:54
constexpr std::array< std::string_view, 5 > key_names
Keys: form (transcribed squareish ratio of n, k) and trans N|T|C exact; n weight 2 (work ~ n^2 k batc...
Definition choice.hh:35
std::string_view form_of(std::int64_t a, std::int64_t b)
Definition choice.hh:38
constexpr std::int64_t triangular_groups(std::int64_t n, std::int64_t tile)
Definition choice.hh:57
constexpr std::int64_t kMaxGridTiles
triangular's tile-count ceiling
Definition choice.hh:55
constexpr std::int64_t gram_slm_bytes(std::int64_t n)
Definition choice.hh:69
constexpr int gram_tile(std::int64_t n)
Definition choice.hh:63
constexpr select::OpSpec spec
op, vendor library, rules
Definition choice.hh:31
constexpr auto candidates()
Every compiled choice in tie-break order (§6.3); triangular is float only (R7).
Definition choice.hh:25
constexpr std::array< int, 6 > grid_k
k axis of the grid
Definition choice.hh:49
constexpr std::array< std::string_view, 3 > last_resort
none runs
Definition choice.hh:30
std::variant< Gram, Triangular, Vendor > SyrkChoice
fieldless (tile, leg derived); natives: CUDA GPU
Definition choice.hh:22
constexpr std::array< int, 30 > grid_n
n axis
Definition choice.hh:44
constexpr std::array< std::string_view, 3 > grid_trans
trans axis of the grid
Definition choice.hh:48
constexpr int gram_threads(std::int64_t n)
Definition choice.hh:64
constexpr int kTriangularWg
syrk_triangular_tiles' 16 x 16 work-group
Definition choice.hh:56
std::optional< std::string > pin_text(std::string_view op, std::string *source)
Flat kernel selection: one choose() per op over measured per-device tables.
syrk_gram_tiles: one tile covers C; n <= 128, tile SLM fits
Definition choice.hh:18
syrk_triangular_tiles<float>: 128-wide tiles of one half
Definition choice.hh:19
backend::syrk_vendor (per-item ?syrk loop)
Definition choice.hh:20
Base of a family with no knobs: struct Cta : NoFields<"cta"> {};.
Definition select.hh:101
What an op's choice.hh declares once: its name, the library its Vendor family calls (one gate for can...
Definition select.hh:529