From d0b67a5e8ed700ea4cc1983ed90aede3ceb7f340 Mon Sep 17 00:00:00 2001 From: Albert Wang Date: Thu, 25 Jun 2026 23:03:15 +0800 Subject: [PATCH 1/2] docs(i18n): add Chinese site and language switch Integrate the Chinese translation into the main English repository under /zh while keeping the English site at the root path. Add a language switcher for documentation pages and standalone demo pages, copy translated images and demo assets, and customize the sidebar so English pages use the English TOC while Chinese pages use the Chinese TOC. --- _extra/viz-base.js | 11 + .../zh/_static/tirx-layout-demo/index.html | 167 + .../_static/tirx-layout-demo/layout-demo.js | 805 +++ .../zh/_static/tirx-layout-demo/viz-base.css | 113 + .../zh/_static/tirx-layout-demo/viz-base.js | 72 + _extra_zh/zh/code-highlight.css | 139 + _extra_zh/zh/code-highlight.js | 224 + _extra_zh/zh/demo/barrier_intro.html | 387 ++ _extra_zh/zh/demo/cta_cluster.html | 113 + .../zh/demo/mbarrier_arrive_timeline.html | 470 ++ _extra_zh/zh/demo/mbarrier_mechanism.html | 220 + .../zh/demo/mbarrier_tcgen05_timeline.html | 479 ++ _extra_zh/zh/demo/mbarrier_tma_timeline.html | 490 ++ _extra_zh/zh/demo/phase_tracking.html | 201 + _extra_zh/zh/demo/pipeline_arch.html | 509 ++ _extra_zh/zh/demo/sf_tmem.html | 148 + _extra_zh/zh/demo/sm_architecture.html | 397 ++ _extra_zh/zh/demo/swizzle_128B.html | 432 ++ _extra_zh/zh/demo/swizzle_8x8.html | 384 ++ _extra_zh/zh/demo/swizzle_atom_general.html | 472 ++ _extra_zh/zh/demo/tcgen05_intro.html | 331 ++ _extra_zh/zh/demo/thread_hierarchy.html | 112 + _extra_zh/zh/demo/thread_register.html | 252 + _extra_zh/zh/demo/tile_distributed.html | 480 ++ _extra_zh/zh/demo/tiled_layout.html | 278 ++ _extra_zh/zh/demo/tiling_constraint.html | 343 ++ _extra_zh/zh/demo/tirx_dispatch.html | 159 + _extra_zh/zh/demo/tma_3d.html | 353 ++ _extra_zh/zh/demo/tma_intro.html | 358 ++ _extra_zh/zh/viz-base.css | 90 + _extra_zh/zh/viz-base.js | 66 + _templates/sbt-sidebar-nav.html | 32 + conf.py | 71 +- static/lang-switch.js | 80 + zh/appendix/debugging_warp_specialized.md | 209 + zh/appendix/index.md | 16 + zh/chapter_async_barriers/index.md | 143 + zh/chapter_background/index.md | 168 + zh/chapter_clc/index.md | 111 + zh/chapter_data_layout/index.md | 256 + zh/chapter_flash_attention/index.md | 607 +++ zh/chapter_gemm_advanced/index.md | 964 ++++ zh/chapter_gemm_async/index.md | 765 +++ zh/chapter_gemm_basics/index.md | 693 +++ zh/chapter_intro_tirx/index.md | 261 + zh/chapter_layout_generations/index.md | 345 ++ zh/chapter_performance/index.md | 308 ++ zh/chapter_tensor_cores/index.md | 247 + zh/chapter_tirx_layout_api/index.md | 783 +++ zh/chapter_tma/index.md | 192 + zh/chapter_tmem/index.md | 115 + zh/img/flash_attention_main_handoff.png | Bin 0 -> 155084 bytes zh/img/flash_attention_pipeline_v2.png | Bin 0 -> 136538 bytes zh/img/flash_attention_softmax_correction.png | Bin 0 -> 155152 bytes zh/img/gemm_perf.png | Bin 0 -> 53609 bytes zh/img/ldstmatrix.svg | 3643 ++++++++++++++ zh/img/memory_dataflow.png | Bin 0 -> 60455 bytes zh/img/mma_block_scaled.svg | 2907 +++++++++++ zh/img/mma_cg1_m128.svg | 1065 ++++ zh/img/mma_cg1_m64.svg | 1804 +++++++ zh/img/mma_cg2_m128.svg | 2013 ++++++++ zh/img/mma_cg2_m256.svg | 2228 +++++++++ zh/img/pipe_depth2.png | Bin 0 -> 21362 bytes zh/img/roofline.png | Bin 0 -> 129790 bytes zh/img/sf_scale_vec.svg | 3319 +++++++++++++ zh/img/smem_descriptor.svg | 4405 +++++++++++++++++ zh/img/swizzle_conflict.svg | 4324 ++++++++++++++++ zh/img/tcgen05_ldst.svg | 3847 ++++++++++++++ zh/img/tma_sync_flow.png | Bin 0 -> 126882 bytes zh/img/tmem_grid.png | Bin 0 -> 85253 bytes zh/img/tmem_layout_v3.png | Bin 0 -> 109974 bytes zh/img/warp_specialization_timeline.png | Bin 0 -> 94127 bytes zh/index.md | 83 + zh/tirx_guide/arch/index.rst | 28 + zh/tirx_guide/arch/lowering_pipeline.rst | 200 + .../language_reference/cuda/buffers.rst | 471 ++ .../language_reference/cuda/control_flow.rst | 122 + .../language_reference/cuda/data_types.rst | 117 + .../language_reference/cuda/parser_utils.rst | 79 + .../language_reference/cuda/threads_sync.rst | 139 + zh/tirx_guide/language_reference/index.rst | 35 + 81 files changed, 46248 insertions(+), 2 deletions(-) create mode 100644 _extra_zh/zh/_static/tirx-layout-demo/index.html create mode 100644 _extra_zh/zh/_static/tirx-layout-demo/layout-demo.js create mode 100644 _extra_zh/zh/_static/tirx-layout-demo/viz-base.css create mode 100644 _extra_zh/zh/_static/tirx-layout-demo/viz-base.js create mode 100644 _extra_zh/zh/code-highlight.css create mode 100644 _extra_zh/zh/code-highlight.js create mode 100644 _extra_zh/zh/demo/barrier_intro.html create mode 100644 _extra_zh/zh/demo/cta_cluster.html create mode 100644 _extra_zh/zh/demo/mbarrier_arrive_timeline.html create mode 100644 _extra_zh/zh/demo/mbarrier_mechanism.html create mode 100644 _extra_zh/zh/demo/mbarrier_tcgen05_timeline.html create mode 100644 _extra_zh/zh/demo/mbarrier_tma_timeline.html create mode 100644 _extra_zh/zh/demo/phase_tracking.html create mode 100644 _extra_zh/zh/demo/pipeline_arch.html create mode 100644 _extra_zh/zh/demo/sf_tmem.html create mode 100644 _extra_zh/zh/demo/sm_architecture.html create mode 100644 _extra_zh/zh/demo/swizzle_128B.html create mode 100644 _extra_zh/zh/demo/swizzle_8x8.html create mode 100644 _extra_zh/zh/demo/swizzle_atom_general.html create mode 100644 _extra_zh/zh/demo/tcgen05_intro.html create mode 100644 _extra_zh/zh/demo/thread_hierarchy.html create mode 100644 _extra_zh/zh/demo/thread_register.html create mode 100644 _extra_zh/zh/demo/tile_distributed.html create mode 100644 _extra_zh/zh/demo/tiled_layout.html create mode 100644 _extra_zh/zh/demo/tiling_constraint.html create mode 100644 _extra_zh/zh/demo/tirx_dispatch.html create mode 100644 _extra_zh/zh/demo/tma_3d.html create mode 100644 _extra_zh/zh/demo/tma_intro.html create mode 100644 _extra_zh/zh/viz-base.css create mode 100644 _extra_zh/zh/viz-base.js create mode 100644 _templates/sbt-sidebar-nav.html create mode 100644 static/lang-switch.js create mode 100644 zh/appendix/debugging_warp_specialized.md create mode 100644 zh/appendix/index.md create mode 100644 zh/chapter_async_barriers/index.md create mode 100644 zh/chapter_background/index.md create mode 100644 zh/chapter_clc/index.md create mode 100644 zh/chapter_data_layout/index.md create mode 100644 zh/chapter_flash_attention/index.md create mode 100644 zh/chapter_gemm_advanced/index.md create mode 100644 zh/chapter_gemm_async/index.md create mode 100644 zh/chapter_gemm_basics/index.md create mode 100644 zh/chapter_intro_tirx/index.md create mode 100644 zh/chapter_layout_generations/index.md create mode 100644 zh/chapter_performance/index.md create mode 100644 zh/chapter_tensor_cores/index.md create mode 100644 zh/chapter_tirx_layout_api/index.md create mode 100644 zh/chapter_tma/index.md create mode 100644 zh/chapter_tmem/index.md create mode 100644 zh/img/flash_attention_main_handoff.png create mode 100644 zh/img/flash_attention_pipeline_v2.png create mode 100644 zh/img/flash_attention_softmax_correction.png create mode 100644 zh/img/gemm_perf.png create mode 100644 zh/img/ldstmatrix.svg create mode 100644 zh/img/memory_dataflow.png create mode 100644 zh/img/mma_block_scaled.svg create mode 100644 zh/img/mma_cg1_m128.svg create mode 100644 zh/img/mma_cg1_m64.svg create mode 100644 zh/img/mma_cg2_m128.svg create mode 100644 zh/img/mma_cg2_m256.svg create mode 100644 zh/img/pipe_depth2.png create mode 100644 zh/img/roofline.png create mode 100644 zh/img/sf_scale_vec.svg create mode 100644 zh/img/smem_descriptor.svg create mode 100644 zh/img/swizzle_conflict.svg create mode 100644 zh/img/tcgen05_ldst.svg create mode 100644 zh/img/tma_sync_flow.png create mode 100644 zh/img/tmem_grid.png create mode 100644 zh/img/tmem_layout_v3.png create mode 100644 zh/img/warp_specialization_timeline.png create mode 100644 zh/index.md create mode 100644 zh/tirx_guide/arch/index.rst create mode 100644 zh/tirx_guide/arch/lowering_pipeline.rst create mode 100644 zh/tirx_guide/language_reference/cuda/buffers.rst create mode 100644 zh/tirx_guide/language_reference/cuda/control_flow.rst create mode 100644 zh/tirx_guide/language_reference/cuda/data_types.rst create mode 100644 zh/tirx_guide/language_reference/cuda/parser_utils.rst create mode 100644 zh/tirx_guide/language_reference/cuda/threads_sync.rst create mode 100644 zh/tirx_guide/language_reference/index.rst diff --git a/_extra/viz-base.js b/_extra/viz-base.js index f3339bc2..ce3e1a3f 100644 --- a/_extra/viz-base.js +++ b/_extra/viz-base.js @@ -3,6 +3,17 @@ document.addEventListener('DOMContentLoaded', function() { var p = new URLSearchParams(location.search); if (p.has('notitle')) document.body.classList.add('notitle'); + // Directly opened demo pages are copied outside Sphinx templates, so they do + // not receive html_js_files. Load the same language switch used by book pages. + if (window.parent === window && !p.has('notitle')) { + var langSwitchPath = window.location.pathname.indexOf('/zh/demo/') >= 0 + ? '../../_static/lang-switch.js' + : '../_static/lang-switch.js'; + var s = document.createElement('script'); + s.src = new URL(langSwitchPath, window.location.href).href; + document.head.appendChild(s); + } + // Forward arrow keys to parent (reveal.js) when embedded if (window.parent !== window) { document.addEventListener('keydown', function(e) { diff --git a/_extra_zh/zh/_static/tirx-layout-demo/index.html b/_extra_zh/zh/_static/tirx-layout-demo/index.html new file mode 100644 index 00000000..ae2ec85e --- /dev/null +++ b/_extra_zh/zh/_static/tirx-layout-demo/index.html @@ -0,0 +1,167 @@ + + + + + + +TIRx Tensor Layout — Interactive Demo + + + + + + +

TIRx Tensor Layout

+
how a TileLayout (shard / replica / offset) maps logical tensor elements to physical threads
+ +
+ load an example + + ↓ fills the two fields below +
+ +
+
+ + +
+
+ +
+ + +
+
+
+ + +
+
+
+ +
+
+

Logical tensor

+
+
+
+
+

Physical threads

+
+
+
+ +
+ +
+
+ + + + diff --git a/_extra_zh/zh/_static/tirx-layout-demo/layout-demo.js b/_extra_zh/zh/_static/tirx-layout-demo/layout-demo.js new file mode 100644 index 00000000..ec117acc --- /dev/null +++ b/_extra_zh/zh/_static/tirx-layout-demo/layout-demo.js @@ -0,0 +1,805 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * TIRx tensor-layout visualizer. + * + * The page shell, CSS vocabulary, and the draw()/hover/arrow interaction + * pattern are adapted from the team's own course material + * (mlsyscourse/slides-modern-gpu-programming, data-layout/site/demo/ + * tile_distributed.html). The TIRx S/R/O parser and the logical->physical + * mapper below are original and mirror tvm/python/tvm/tirx/layout.py + * (_flatten_coord / _split_coord and the TileLayout forward mapping). + * This file is NOT derived from any third-party layout demo. + */ + +'use strict'; + +// ── TIRx named axes (from tvm/python/tvm/tirx/layout.py _AXIS_NAMES, plus the +// device axis `pid` used by distributed layouts) ────────────────────────────── +const AXIS_ORDER = [ + 'pid', 'bx', 'by', 'bz', 'cbx', 'cby', 'cbz', 'tx', + 'warpid', 'laneid', 'wgid', 'tid_in_wg', 'wid_in_wg', 'tid', + 'm', 'P', 'F', 'Bank', 'TCol', 'TLane', +]; +// "Owner" axes name a physical unit that owns data (threads, devices); the rest +// (m, P, F, Bank, TCol, TLane) are storage/memory coordinates within an owner. +const OWNER_AXES = new Set([ + 'pid', 'bx', 'by', 'bz', 'cbx', 'cby', 'cbz', 'tx', + 'warpid', 'laneid', 'wgid', 'tid_in_wg', 'wid_in_wg', 'tid', +]); +const KNOWN_AXES = new Set(AXIS_ORDER); +const MAX_ELEMENTS = 1024; // render cap + +function isOwnerAxis(a) { return OWNER_AXES.has(a); } +function product(arr) { return arr.reduce((a, b) => a * b, 1); } + +// ── Parser ─────────────────────────────────────────────────────────────────── +// Grammar mirrors layout.py: S[shape:stride] + R[shape:stride] + offset, +// stride/offset terms are "n@axis" (a bare int defaults to axis "m"). + +function splitTopLevel(s, sep) { + const out = []; + let depth = 0, cur = ''; + for (const ch of s) { + if (ch === '(' || ch === '[') depth++; + else if (ch === ')' || ch === ']') { + depth--; + if (depth < 0) throw new Error('unmatched closing bracket or parenthesis'); + } + if (ch === sep && depth === 0) { out.push(cur); cur = ''; } + else cur += ch; + } + if (depth !== 0) throw new Error('unmatched opening bracket or parenthesis'); + out.push(cur); + return out; +} + +function stripParens(s) { + s = s.trim(); + if (s.startsWith('(') && s.endsWith(')')) return s.slice(1, -1); + return s; +} + +function parseIntStrict(s) { + const t = s.trim(); + if (!/^-?\d+$/.test(t)) throw new Error(`expected integer, got "${t}"`); + return parseInt(t, 10); +} + +function parseTerm(tok) { + const t = tok.trim(); + if (t.includes('@')) { + const parts = t.split('@'); + if (parts.length !== 2) throw new Error(`bad term "${t}"`); + const numPart = parts[0].trim(); + const axis = parts[1].trim(); + if (!KNOWN_AXES.has(axis)) throw new Error(`unknown axis "${axis}"`); + const stride = numPart === '' ? 1 : parseIntStrict(numPart); + return { stride, axis }; + } + if (/^-?\d+$/.test(t)) return { stride: parseInt(t, 10), axis: 'm' }; + if (KNOWN_AXES.has(t)) return { stride: 1, axis: t }; + throw new Error(`bad term "${t}"`); +} + +function defaultStrides(extents) { + const n = extents.length; + const strides = new Array(n).fill(1); + for (let i = n - 2; i >= 0; i--) strides[i] = strides[i + 1] * extents[i + 1]; + return strides; +} + +function parseExtents(s) { + // Parse a comma-separated extent list and reject non-positive / oversized + // extents, so bad input (e.g. R[1000000:...] or a 0/negative extent) can't + // NaN-propagate or freeze the tab with huge loops in physOwners(). + const extents = splitTopLevel(stripParens(s), ',').map(parseIntStrict); + for (const e of extents) { + if (e <= 0) throw new Error(`extent must be positive, got ${e}`); + if (e > MAX_ELEMENTS) throw new Error(`extent ${e} exceeds maximum ${MAX_ELEMENTS}`); + } + return extents; +} + +function parseBracket(inner) { + const parts = splitTopLevel(inner, ':'); + if (parts.length === 1) { + const extents = parseExtents(parts[0]); + const strides = defaultStrides(extents); + return extents.map((e, i) => ({ extent: e, stride: strides[i], axis: 'm' })); + } + if (parts.length !== 2) throw new Error('layout bracket must be "shape : stride"'); + const extents = parseExtents(parts[0]); + const terms = splitTopLevel(stripParens(parts[1]), ',').map(parseTerm); + if (extents.length !== terms.length) { + throw new Error(`shape has ${extents.length} dims but stride has ${terms.length}`); + } + return extents.map((e, i) => ({ extent: e, stride: terms[i].stride, axis: terms[i].axis })); +} + +function bracketBody(piece, prefix) { + const open = piece.indexOf('['); + const close = piece.lastIndexOf(']'); + if (open < 0 || close < 0 || close < open) throw new Error(`malformed ${prefix}[...]`); + return piece.slice(open + 1, close); +} + +function parseSwizzlePrefix(src) { + // Optional "Swizzle(per_element, swizzle_len, atom_len[, inner]) [∘|o|*] ". + const m = src.match(/^Swizzle\s*\(([^)]*)\)\s*(?:∘|o|\.|\*)?\s*([\s\S]*)$/i); + if (!m) return { swizzle: null, rest: src }; + const a = m[1].split(',').map((s) => s.trim()).filter((s) => s.length); + if (a.length < 3) throw new Error('Swizzle needs (per_element, swizzle_len, atom_len)'); + const per_element = parseIntStrict(a[0]); + const swizzle_len = parseIntStrict(a[1]); + const atom_len = parseIntStrict(a[2]); + if (per_element < 0 || swizzle_len < 0 || atom_len < swizzle_len + || per_element >= 31 || atom_len >= 31) { + // atom_len/per_element feed 32-bit bitwise shifts in swizzleAddr; cap < 31. + throw new Error('swizzle requires 0≤per_element<31, swizzle_len≥0, swizzle_len≤atom_len<31'); + } + const inner = a[3] === undefined ? true : (a[3] === 'true' || a[3] === '1'); + return { swizzle: { per_element, swizzle_len, atom_len, inner }, rest: m[2].trim() }; +} + +function parseLayout(srcRaw) { + const { swizzle, rest } = parseSwizzlePrefix(srcRaw.trim()); + const src = rest; + const layout = { shard: [], replica: [], offset: {}, swizzle }; + let sawShard = false; + for (let piece of splitTopLevel(src, '+')) { + piece = piece.trim(); + if (piece === '') continue; + if (piece.startsWith('S[')) { + layout.shard = parseBracket(bracketBody(piece, 'S')); + sawShard = true; + } else if (piece.startsWith('R[')) { + layout.replica = parseBracket(bracketBody(piece, 'R')); + } else { + const t = parseTerm(piece); + layout.offset[t.axis] = (layout.offset[t.axis] || 0) + t.stride; + } + } + if (!sawShard) throw new Error('layout needs a shard term, e.g. S[...]'); + return layout; +} + +// ── Mapper (mirrors layout.py _flatten_coord / _split_coord + forward map) ───── + +function flattenCoord(coord, shape) { + let flat = 0; + for (let i = 0; i < shape.length; i++) flat = flat * shape[i] + coord[i]; + return flat; +} + +function splitCoord(flat, extents) { + const n = extents.length; + const res = new Array(n); + let remaining = flat; + for (let i = n - 1; i >= 0; i--) { + if (i === 0) res[0] = remaining; + else { res[i] = remaining % extents[i]; remaining = Math.floor(remaining / extents[i]); } + } + return res; +} + +function coordFromFlat(flat, shape) { return splitCoord(flat, shape); } + +function forwardBase(coord, shape, layout) { + const flat = flattenCoord(coord, shape); + const comps = splitCoord(flat, layout.shard.map((it) => it.extent)); + const phys = {}; + for (let k = 0; k < layout.shard.length; k++) { + const it = layout.shard[k]; + phys[it.axis] = (phys[it.axis] || 0) + comps[k] * it.stride; + } + for (const axis of Object.keys(layout.offset)) { + phys[axis] = (phys[axis] || 0) + layout.offset[axis]; + } + return phys; +} + +// Replica broadcasts the same logical element onto multiple physical owners: +// L(x) = { D(x) + r + O | r in R }. +function physOwners(coord, shape, layout) { + let owners = [forwardBase(coord, shape, layout)]; + for (const rep of layout.replica) { + const next = []; + for (const o of owners) { + for (let k = 0; k < rep.extent; k++) { + const o2 = Object.assign({}, o); + o2[rep.axis] = (o2[rep.axis] || 0) + k * rep.stride; + next.push(o2); + } + } + owners = next; + } + return owners; +} + +function axesUsed(layout) { + const s = new Set(); + for (const it of layout.shard) s.add(it.axis); + for (const it of layout.replica) s.add(it.axis); + for (const a of Object.keys(layout.offset)) s.add(a); + return AXIS_ORDER.filter((a) => s.has(a)); +} + +function coordStr(phys, axes) { + return axes.map((a) => `${a}=${phys[a] || 0}`).join(' '); +} + +// Swizzle a linear memory address (mirrors src/tirx/ir/layout/swizzle_layout.cc +// SwizzleLayoutNode::Apply): low `per_element` bits are kept; above them, the +// swizzle bits are XOR'd to scatter bank conflicts. +function swizzleAddr(m, sw) { + const base = 1 << sw.per_element; + const innerMask = (1 << sw.swizzle_len) - 1; + const outerMask = innerMask << sw.atom_len; + const x = Math.floor(m / base); + const fx = sw.inner ? (x ^ ((x & outerMask) >> sw.atom_len)) + : (x ^ ((x & innerMask) << sw.atom_len)); + return fx * base + (m % base); +} + +// Resolve the swizzle from the dtype + mode dropdowns (mirrors +// tma_utils.mma_atom_layout): per_element = bit_length(128//bits) - 1, +// swizzle_len = mode, atom_len = 3. Falls back to a typed Swizzle(...) prefix. +const SWIZZLE_LEN = { none: 0, '32': 1, '64': 2, '128': 3 }; +function computeSwizzle() { + const mode = swmodeSel ? swmodeSel.value : 'off'; + if (mode === 'off') return (ST.layout && ST.layout.swizzle) ? ST.layout.swizzle : null; + const bits = +(dtypeSel ? dtypeSel.value : 16) || 16; + const per_element = Math.floor(128 / bits).toString(2).length - 1; + return { + per_element, swizzle_len: SWIZZLE_LEN[mode] || 0, atom_len: 3, inner: true, + bits, mode, + }; +} + +// ── State + recompute ──────────────────────────────────────────────────────-- +function getComputedStyleVar(name) { + return getComputedStyle(document.documentElement).getPropertyValue(name).trim(); +} +const PALETTE = Array.from({ length: 8 }, (_, i) => + getComputedStyleVar(`--color-group-${i}`) || '#5b9bd5'); +function paletteColor(v) { const n = PALETTE.length; return PALETTE[((v % n) + n) % n]; } + +const ST = { + shape: [4, 8], + layout: null, + error: null, + tooBig: false, + banks: 32, + swizzle: null, + gridAxes: [], yAxis: null, xAxis: null, cellAxes: [], + yVals: [], xVals: [], + byFlat: [], // flat -> { owners:[phys], keys:[gridKey], color } + byCell: new Map(), // "y#x" -> [{flat, slot}] +}; +let hovFlat = null; +let drawing = false; + +function mk(t, c) { const d = document.createElement(t); if (c) d.className = c; return d; } +function gridKey(phys, axes) { return axes.map((a) => phys[a] || 0).join(','); } + +function recompute() { + ST.error = null; ST.tooBig = false; + try { + ST.shape = splitTopLevel(stripParens(shapeInput.value), ',').map(parseIntStrict); + if (ST.shape.length === 0 || ST.shape.some((x) => x <= 0)) throw new Error('shape must be positive ints'); + ST.layout = parseLayout(exprInput.value); + } catch (e) { ST.error = e.message; return; } + + const total = product(ST.shape); + if (total > MAX_ELEMENTS) { ST.tooBig = true; return; } + + ST.shapeTotal = total; + ST.shardTotal = product(ST.layout.shard.map((it) => it.extent)); + ST.mismatch = ST.shardTotal !== total; + ST.swizzle = computeSwizzle(); + // elements that share one 4-byte bank word (e.g. 2 fp16, 4 fp8, 1 fp32) + ST.elemsPerBank = ST.swizzle ? Math.max(1, Math.round(4 / ((ST.swizzle.bits || 32) / 8))) : 1; + + // 1) owners per element; in swizzle mode, also map the memory address through + // the swizzle and derive synthetic line/bank coordinates. + ST.byFlat = new Array(total); + for (let flat = 0; flat < total; flat++) { + const owners = physOwners(coordFromFlat(flat, ST.shape), ST.shape, ST.layout); + if (ST.swizzle) { + // A shared-memory bank is 4 bytes; an element occupies dtype_bytes, so the + // bank word index is floor(element_addr * dtype_bytes / 4). 32 banks per line. + const bytes = (ST.swizzle.bits || 32) / 8; + for (const o of owners) { + const sm = swizzleAddr(o.m || 0, ST.swizzle); + const word = Math.floor((sm * bytes) / 4); + o.__sm = sm; o.__word = word; o.bank = word % ST.banks; o.line = Math.floor(word / ST.banks); + } + } + ST.byFlat[flat] = { owners }; + } + + // 2) choose grid + color axes + if (ST.swizzle) { + ST.gridAxes = ['line', 'bank']; ST.yAxis = 'line'; ST.xAxis = 'bank'; + ST.cellAxes = []; ST.colorAxis = 'bank'; + } else { + const used = axesUsed(ST.layout); + const owners = used.filter(isOwnerAxis); + ST.gridAxes = owners.length ? owners : used.filter((a) => !isOwnerAxis(a)); + ST.yAxis = ST.gridAxes[0] || null; + ST.xAxis = ST.gridAxes[1] || null; + ST.cellAxes = used.filter((a) => !ST.gridAxes.includes(a)); + // color axis = first grid axis from shard/offset, so a replica-only row axis + // doesn't collapse every element to one color. + const shardOffsetAxes = new Set(ST.layout.shard.map((it) => it.axis)); + for (const a of Object.keys(ST.layout.offset)) shardOffsetAxes.add(a); + ST.colorAxis = ST.gridAxes.find((a) => shardOffsetAxes.has(a)) || ST.gridAxes[0] || null; + } + + // 3) build cells, hover keys, colors + ST.byCell = new Map(); + const yset = new Set(), xset = new Set(), cset = new Set(); + for (let flat = 0; flat < total; flat++) { + const rec = ST.byFlat[flat]; + const keys = []; + for (const o of rec.owners) { + const y = ST.yAxis ? (o[ST.yAxis] || 0) : 0; + const x = ST.xAxis ? (o[ST.xAxis] || 0) : 0; + yset.add(y); xset.add(x); + keys.push(gridKey(o, ST.gridAxes)); + const ck = y + '#' + x; + if (!ST.byCell.has(ck)) ST.byCell.set(ck, []); + ST.byCell.get(ck).push({ flat, slot: ST.swizzle ? ('addr ' + o.__sm) : coordStr(o, ST.cellAxes) }); + } + rec.keys = keys; + const cv = ST.colorAxis ? (rec.owners[0][ST.colorAxis] || 0) : 0; + rec.color = paletteColor(cv); + cset.add(cv); + } + ST.yVals = [...yset].sort((a, b) => a - b); + ST.xVals = [...xset].sort((a, b) => a - b); + ST.colorVals = [...cset].sort((a, b) => a - b); +} + +// ── Display geometry for the logical grid ──────────────────────────────────-- +function logicalGridDims() { + if (ST.shape.length === 2) return { rows: ST.shape[0], cols: ST.shape[1] }; + if (ST.shape.length === 1) return { rows: 1, cols: ST.shape[0] }; + return { rows: 1, cols: product(ST.shape) }; // N-D -> flat strip +} + +// ── Draw ──────────────────────────────────────────────────────────────────── +function resetFit() { + const p = document.getElementById('panels'); + if (p) { p.style.transform = 'none'; p.style.marginBottom = ''; } +} +function fitEmbed() { + if (!document.body.classList.contains('lock')) return; + const p = document.getElementById('panels'); + if (!p) return; + const natural = p.offsetWidth; + const pad = 2 * parseFloat(getComputedStyle(document.body).paddingLeft || '0'); + const avail = document.documentElement.clientWidth - pad; + if (avail > 0 && natural > avail) { + const sc = avail / natural; + p.style.transformOrigin = 'top left'; + p.style.transform = 'scale(' + sc + ')'; + p.style.marginBottom = (-(p.offsetHeight * (1 - sc))) + 'px'; + } +} +function postHeight() { + if (window.parent === window) return; + const h = Math.ceil(document.body.scrollHeight); + window.parent.postMessage({ tirxLayoutDemoHeight: h + 4 }, '*'); +} +function draw() { + drawing = true; + resetFit(); + const status = document.getElementById('status'); + const g0 = document.getElementById('g0'); + const phys = document.getElementById('phys'); + const fb = document.getElementById('fb'); + const lg = document.getElementById('lg'); + + if (ST.error) { + status.innerHTML = `parse error: ${escapeHtml(ST.error)}`; + g0.innerHTML = ''; phys.innerHTML = ''; lg.innerHTML = ''; + fb.innerHTML = '
Fix the layout expression to continue.
'; + setTimeout(() => { drawing = false; }, 0); return; + } + if (ST.tooBig) { + status.innerHTML = `${product(ST.shape)} elements exceeds the ${MAX_ELEMENTS} render cap — use a smaller shape.`; + g0.innerHTML = ''; phys.innerHTML = ''; lg.innerHTML = ''; + fb.innerHTML = '
Shape too large to visualize.
'; + setTimeout(() => { drawing = false; }, 0); return; + } + + status.innerHTML = `ok   ` + + `${product(ST.shape)} logical elements  |  ` + + `${ST.yVals.length * (ST.xVals.length || 1)} physical cells`; + if (ST.mismatch) { + status.innerHTML += `  ` + + `⚠ shard total ${ST.shardTotal} ≠ shape total ${ST.shapeTotal} — mapping may be ill-formed`; + } + if (ST.swizzle) { + const s = ST.swizzle; + const label = s.mode ? (s.mode === 'none' ? 'no swizzle' : s.mode + 'B swizzle') : 'swizzle'; + status.innerHTML += `  ` + + `${label}${s.bits ? ', ' + s.bits + '-bit' : ''} → Swizzle(${s.per_element},${s.swizzle_len},${s.atom_len})`; + } + document.getElementById('n0').textContent = `logical shape (${ST.shape.join(', ')})`; + document.getElementById('nphys').textContent = + (ST.xAxis ? `rows = ${ST.yAxis}, cols = ${ST.xAxis}` : `tiles = ${ST.yAxis || '(none)'}`) + + (ST.cellAxes.length ? ' · in-cell: ' + ST.cellAxes.join(', ') : ''); + + const hovKeys = hovFlat !== null ? new Set(ST.byFlat[hovFlat].keys) : null; + drawLogical(hovKeys); + drawPhysical(hovKeys); + drawFormula(); + drawArrow(); + drawLegend(); + fitEmbed(); + postHeight(); + setTimeout(() => { drawing = false; }, 0); +} + +function sharesOwner(flat, hovKeys) { + if (!hovKeys) return false; + return ST.byFlat[flat].keys.some((k) => hovKeys.has(k)); +} + +function drawLogical(hovKeys) { + const g = document.getElementById('g0'); + g.innerHTML = ''; + const { rows, cols } = logicalGridDims(); + g.style.gridTemplateColumns = '30px repeat(' + cols + ', 46px)'; + g.appendChild(mk('div', 'hdr')); + for (let c = 0; c < cols; c++) { const h = mk('div', 'hdr'); h.textContent = 'c' + c; g.appendChild(h); } + for (let r = 0; r < rows; r++) { + const rl = mk('div', 'rl'); rl.textContent = (rows > 1) ? ('r' + r) : ''; g.appendChild(rl); + for (let c = 0; c < cols; c++) { + const flat = r * cols + c; + const d = mk('div', 'cell'); + d.dataset.flat = flat; + d.textContent = flat; + d.style.background = ST.byFlat[flat].color; + d.style.color = '#fff'; + if (hovFlat !== null) { + if (flat === hovFlat) d.classList.add('hov'); + else if (!sharesOwner(flat, hovKeys)) d.classList.add('dm'); + } + g.appendChild(d); + } + } +} + +function cellEntries(y, x) { return ST.byCell.get(y + '#' + x) || []; } + +function makeSlot(entry) { + const s = mk('div', 'gcell'); + s.style.background = ST.byFlat[entry.flat].color; + s.style.color = '#fff'; + s.dataset.flat = entry.flat; + s.textContent = entry.flat; + s.title = entry.slot ? `element ${entry.flat} @ ${entry.slot}` : `element ${entry.flat}`; + if (hovFlat !== null) { + if (entry.flat === hovFlat) s.classList.add('hov'); + else s.classList.add('dm'); + } + return s; +} + +function drawPhysical(hovKeys) { + const wrap = document.getElementById('phys'); + wrap.innerHTML = ''; + if (!ST.yAxis) { wrap.textContent = '(no physical axes)'; return; } + + if (ST.xAxis) { + // 2D table: rows = yAxis values, cols = xAxis values. + const table = mk('div', 'phys-table' + (ST.swizzle ? ' bank-mode' : '')); + // In bank mode a cell is one 4-byte bank word holding elemsPerBank elements + // laid out horizontally; otherwise a fixed 54px cell. + const colW = ST.swizzle ? (ST.elemsPerBank * 48 + 8) : 54; + table.style.gridTemplateColumns = '44px repeat(' + ST.xVals.length + ', ' + colW + 'px)'; + table.appendChild(corner()); + for (const x of ST.xVals) table.appendChild(axHdr(String(x), false, `${ST.xAxis}=${x}`)); + for (const y of ST.yVals) { + table.appendChild(axHdr(String(y), true, `${ST.yAxis}=${y}`)); + for (const x of ST.xVals) { + const cell = mk('div', 'pcell'); + const entries = cellEntries(y, x); + if (hovFlat !== null && entries.some((e) => e.flat === hovFlat)) cell.classList.add('hov-cell'); + else if (hovFlat !== null && entries.length) cell.classList.add('dm-cell'); + for (const e of entries) cell.appendChild(makeSlot(e)); + table.appendChild(cell); + } + } + wrap.appendChild(table); + } else { + // 1D: wrapped list of owner tiles, one per yAxis value. + const list = mk('div', 'phys-1d'); + for (const y of ST.yVals) { + const tile = mk('div', 'thread-tile'); + const lbl = mk('div', 'thread-lbl'); lbl.textContent = `${ST.yAxis}=${y}`; tile.appendChild(lbl); + const slots = mk('div', 'thread-slots'); + const entries = cellEntries(y, 0).slice().sort((a, b) => a.flat - b.flat); + if (hovFlat !== null && entries.some((e) => e.flat === hovFlat)) tile.classList.add('hov-tile'); + else if (hovFlat !== null && entries.length) tile.classList.add('dm-tile'); + for (const e of entries) slots.appendChild(makeSlot(e)); + tile.appendChild(slots); + list.appendChild(tile); + } + wrap.appendChild(list); + } +} + +function corner() { + const d = mk('div', 'ax-hdr corner'); + d.textContent = '↘'; + if (ST.yAxis) d.title = `rows = ${ST.yAxis}` + (ST.xAxis ? `, cols = ${ST.xAxis}` : ''); + return d; +} +function axHdr(text, isRow, title) { + const d = mk('div', 'ax-hdr' + (isRow ? ' row' : '')); + d.textContent = text; + if (title) d.title = title; + return d; +} + +function drawFormula() { + const fb = document.getElementById('fb'); + if (hovFlat === null) { fb.innerHTML = '
Click a logical element to see its mapping.
'; return; } + const flat = hovFlat; + const coord = coordFromFlat(flat, ST.shape); + const comps = splitCoord(flat, ST.layout.shard.map((it) => it.extent)); + const perAxis = {}; + const termStrings = []; + for (let k = 0; k < ST.layout.shard.length; k++) { + const it = ST.layout.shard[k]; + perAxis[it.axis] = (perAxis[it.axis] || 0) + comps[k] * it.stride; + termStrings.push(`${comps[k]}·${it.stride}@${it.axis}`); + } + const offStrings = []; + for (const axis of Object.keys(ST.layout.offset)) { + perAxis[axis] = (perAxis[axis] || 0) + ST.layout.offset[axis]; + offStrings.push(`${ST.layout.offset[axis]}@${axis}`); + } + const owners = ST.byFlat[flat].owners; + let html = `
element ${flat} at logical (${coord.join(', ')})` + + `  →  shard split = (${comps.join(', ')})
`; + html += '
'; + html += `terms: ${termStrings.join(' + ')}` + + (offStrings.length ? ` + offset[${offStrings.join(', ')}]` : '') + '
'; + const baseParts = AXIS_ORDER.filter((a) => perAxis[a] !== undefined).map((a) => `${perAxis[a]}@${a}`); + html += `base location: ${baseParts.join(' , ')}`; + if (ST.swizzle) { + const o0 = owners[0]; + const sw = ST.swizzle; + const bytes = (sw.bits || 32) / 8; + html += `
swizzle(${sw.per_element},${sw.swizzle_len},${sw.atom_len}): ` + + `m=${o0.m || 0} → elem ${o0.__sm} → byte ${o0.__sm * bytes} → ` + + `bank ${o0.bank}, line ${o0.line} (${bytes}-byte dtype, 4-byte banks ×32)`; + } + if (owners.length > 1) { + html += `
owners (×${owners.length} via replica): ` + + owners.map((o) => '{ ' + coordStr(o, ST.gridAxes) + ' }').join(' , '); + } + html += '
'; + fb.innerHTML = html; +} + +// ── Arrow overlay (adapted from the course draw pattern) ───────────────────-- +const panels = document.getElementById('panels'); +const arrowSvg = document.getElementById('arrow'); + +function drawArrow() { + arrowSvg.innerHTML = ''; + if (hovFlat === null) return; + const leftCell = document.querySelector('#g0 .cell.hov'); + const rightCells = document.querySelectorAll('#phys .gcell.hov'); + if (!leftCell || rightCells.length === 0) return; + const pr = panels.getBoundingClientRect(); + const ns = 'http://www.w3.org/2000/svg'; + const defs = document.createElementNS(ns, 'defs'); + const marker = document.createElementNS(ns, 'marker'); + marker.setAttribute('id', 'ah'); marker.setAttribute('markerWidth', '8'); marker.setAttribute('markerHeight', '6'); + marker.setAttribute('refX', '7'); marker.setAttribute('refY', '3'); marker.setAttribute('orient', 'auto'); + const poly = document.createElementNS(ns, 'polygon'); + poly.setAttribute('points', '0 0, 8 3, 0 6'); poly.setAttribute('fill', '#222'); + marker.appendChild(poly); defs.appendChild(marker); arrowSvg.appendChild(defs); + const a = leftCell.getBoundingClientRect(); + const x1 = a.left + a.width / 2 - pr.left, y1 = a.top + a.height / 2 - pr.top; + rightCells.forEach((rc) => { + const b = rc.getBoundingClientRect(); + const x2 = b.left + b.width / 2 - pr.left, y2 = b.top + b.height / 2 - pr.top; + const mx = (x1 + x2) / 2, my = Math.min(y1, y2) - 24; + const path = document.createElementNS(ns, 'path'); + path.setAttribute('d', `M${x1},${y1} Q${mx},${my} ${x2},${y2}`); + path.setAttribute('marker-end', 'url(#ah)'); + arrowSvg.appendChild(path); + }); +} + +function clearHov() { + document.querySelectorAll('.cell.hov, .gcell.hov').forEach((d) => d.classList.remove('hov')); + arrowSvg.innerHTML = ''; + hovFlat = null; +} + +panels.addEventListener('click', (e) => { + const cell = e.target.closest('.cell') || e.target.closest('.gcell'); + if (!cell || cell.dataset.flat === undefined) return; + const flat = +cell.dataset.flat; + if (hovFlat === flat) { clearHov(); draw(); return; } + clearHov(); + hovFlat = flat; + draw(); +}); + +// ── Legend ────────────────────────────────────────────────────────────────── +function swatchEl(color) { const w = mk('div', 'swtch'); w.style.background = color; return w; } + +function drawLegend() { + const lg = document.getElementById('lg'); + lg.innerHTML = ''; + + // Color key: an actual swatch-per-value table using the same palette as the grid. + const r0 = mk('div', 'leg-row'); + const lead = mk('div', 'li'); + lead.innerHTML = `color = ${ST.colorAxis || 'physical'} value:`; + r0.appendChild(lead); + const vals = ST.colorVals || []; + if (vals.length <= 8) { + for (const v of vals) { + const li = mk('div', 'li'); + li.appendChild(swatchEl(paletteColor(v))); + li.appendChild(document.createTextNode(String(v))); + r0.appendChild(li); + } + } else { + for (let k = 0; k < 8; k++) { + const li = mk('div', 'li'); + li.appendChild(swatchEl(PALETTE[k])); + li.appendChild(document.createTextNode('≡' + k)); + r0.appendChild(li); + } + const note = mk('div', 'li'); + note.textContent = `(${ST.colorAxis} mod 8; ${vals.length} values)`; + r0.appendChild(note); + } + lg.appendChild(r0); + + const r1 = mk('div', 'leg-row'); + const c2 = mk('div', 'li'); c2.textContent = 'number = logical element index'; r1.appendChild(c2); + if (ST.layout.replica.length) { + r1.appendChild(mk('div', 'leg-sep')); + const c3 = mk('div', 'li'); + c3.textContent = 'replica → identical copies: the same color appears in multiple physical cells'; + r1.appendChild(c3); + } + lg.appendChild(r1); + + const r2 = mk('div', 'leg-row'); + const m = mk('div', 'li'); + const owners = axesUsed(ST.layout).filter(isOwnerAxis); + const mem = axesUsed(ST.layout).filter((a) => !isOwnerAxis(a)); + m.textContent = 'owner axes: ' + (owners.join(', ') || '(none — pure memory layout)') + + ' · memory axes: ' + (mem.join(', ') || '(none)'); + r2.appendChild(m); + lg.appendChild(r2); +} + +function escapeHtml(s) { + return s.replace(/[&<>"]/g, (c) => ({ '&': '&', '<': '<', '>': '>', '"': '"' }[c])); +} + +// ── Presets + controls ─────────────────────────────────────────────────────── +// Case-study presets use scaled-down shapes so every element renders; the +// mapping semantics match the full-size examples in the docs. +const PRESETS = [ + { label: 'Shard → lanes (intro)', shape: '4, 8', expr: 'S[(4,8):(8@laneid,1@laneid)]' }, + { label: 'Shard + registers', shape: '4, 8', expr: 'S[(4,2,4):(8@laneid,1@m,1@laneid)]' }, + { label: 'Shard + replica', shape: '4, 8', expr: 'S[(4,8):(8@laneid,1@laneid)] + R[2:1@warpid]' }, + { + label: 'Tensor-core tile (doc example)', shape: '8, 16', + expr: 'S[(8,2,4,2):(4@laneid,1@warpid,1@laneid,1)] + R[2:4@warpid] + 5@warpid', + }, + { label: 'Distributed 2×2 GPU mesh (pid)', shape: '4, 4', expr: 'S[(2,2,2,2):(1@pid,2@m,2@pid,1@m)]' }, + { label: 'Mesh + replica (pid)', shape: '4, 4', expr: 'S[(2,2,4):(1@pid,2@m,1@m)] + R[2:2@pid]' }, + { label: 'Accelerator scratchpad (P/F)', shape: '4, 8', expr: 'S[(2,4,4):(4@F,1@P,1@F)]' }, + { label: 'Blackwell tensor memory (TLane/TCol)', shape: '4, 8', expr: 'S[(2,4,4):(4@TCol,1@TLane,1@TCol)]' }, + { label: 'SMEM, no swizzle (bank conflicts)', shape: '8, 64', expr: 'S[(8,64):(64@m,1@m)]', dtype: 16, mode: 'none' }, + { label: 'SMEM swizzle 128B (fp16)', shape: '8, 64', expr: 'S[(8,64):(64@m,1@m)]', dtype: 16, mode: '128' }, + { label: '1-D shard', shape: '8', expr: 'S[8:4@laneid]' }, + { label: 'Extents only (default strides)', shape: '8, 4', expr: 'S[(8,4)]' }, +]; + +const DTYPES = [ + { label: 'float16 (16-bit)', bits: 16 }, + { label: 'bfloat16 (16-bit)', bits: 16 }, + { label: 'float8 (8-bit)', bits: 8 }, + { label: 'float32 (32-bit)', bits: 32 }, + { label: 'tfloat32 (32-bit)', bits: 32 }, + { label: 'float64 (64-bit)', bits: 64 }, +]; +const SWMODES = [ + { label: 'off (general layout)', value: 'off' }, + { label: 'none — raw banks', value: 'none' }, + { label: '32B swizzle', value: '32' }, + { label: '64B swizzle', value: '64' }, + { label: '128B swizzle', value: '128' }, +]; + +const shapeInput = document.getElementById('shape'); +const exprInput = document.getElementById('expr'); +const presetSel = document.getElementById('preset'); +const dtypeSel = document.getElementById('dtype'); +const swmodeSel = document.getElementById('swmode'); + +function applyPreset(i) { + const p = PRESETS[i]; + shapeInput.value = p.shape; + exprInput.value = p.expr; + if (dtypeSel) dtypeSel.value = String(p.dtype || 16); + if (swmodeSel) swmodeSel.value = p.mode || 'off'; + refresh(); +} +function refresh() { clearHov(); recompute(); draw(); } + +function init() { + PRESETS.forEach((p, i) => { + const o = document.createElement('option'); + o.value = i; o.textContent = p.label; presetSel.appendChild(o); + }); + DTYPES.forEach((d) => { + const o = document.createElement('option'); + o.value = d.bits; o.textContent = d.label; dtypeSel.appendChild(o); + }); + SWMODES.forEach((s) => { + const o = document.createElement('option'); + o.value = s.value; o.textContent = s.label; swmodeSel.appendChild(o); + }); + presetSel.addEventListener('change', () => applyPreset(+presetSel.value)); + shapeInput.addEventListener('input', refresh); + exprInput.addEventListener('input', refresh); + dtypeSel.addEventListener('change', refresh); + swmodeSel.addEventListener('change', refresh); + window.addEventListener('resize', () => { resetFit(); fitEmbed(); postHeight(); }); + window.addEventListener('load', () => { resetFit(); fitEmbed(); postHeight(); }); + // Deep-linking for embeds: ?preset=¬itle + const params = new URLSearchParams(location.search); + let presetIdx = 0; + const want = params.get('preset'); + if (want !== null) { + const slug = (x) => x.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, ''); + if (/^\d+$/.test(want)) { + presetIdx = Math.min(PRESETS.length - 1, Math.max(0, parseInt(want, 10))); + } else { + const w = slug(want); + const found = PRESETS.findIndex((p) => slug(p.label).includes(w)); + if (found >= 0) presetIdx = found; + } + } + presetSel.value = presetIdx; + if (params.has('notitle')) document.body.classList.add('notitle'); + if (params.has('lock')) document.body.classList.add('lock'); + applyPreset(presetIdx); +} + +init(); diff --git a/_extra_zh/zh/_static/tirx-layout-demo/viz-base.css b/_extra_zh/zh/_static/tirx-layout-demo/viz-base.css new file mode 100644 index 00000000..624194ce --- /dev/null +++ b/_extra_zh/zh/_static/tirx-layout-demo/viz-base.css @@ -0,0 +1,113 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * Derived from mlsyscourse/slides-modern-gpu-programming + * (data-layout/site/viz-base.css). Shared base styles for the + * TIRx layout visualization; not derived from any third-party demo. + */ + +/* Shared base styles for all viz HTMLs + * Colors: --bg gray, --accent blue, --surface white + * Fonts: Inter (body), SF Mono (code/notation) + */ + +:root { + --bg:#fff; --surface:#fff; --border:#dfe1e6; --text:#222; --dim:#888; --accent:#3b82f6; + + /* ── Group palette (tiles, lanes, banks, sectors) ─────── */ + --color-group-0: #5b9bd5; + --color-group-1: #ed9a3c; + --color-group-2: #d95555; + --color-group-3: #45b5a5; + --color-group-4: #5fb85f; + --color-group-5: #e0b828; + --color-group-6: #9d6eb5; + --color-group-7: #e87888; + + /* ── Interaction ──────────────────────────────────────── */ + --color-hover-bg: #dbeafe; + --color-hover-text: #1e40af; + + /* ── Status ───────────────────────────────────────────── */ + --color-good: #2e7d32; + --color-bad: #c62828; + + /* ── Boundaries & neutrals ────────────────────────────── */ + --color-boundary: #8C1515; + --color-cell-bg: #f0f1f3; + --color-cell-bg-alt: #e8eaed; +} +* { box-sizing:border-box; margin:0; padding:0; } +body { background:var(--bg); color:var(--text); font-family:'Inter','SF Pro','Segoe UI',system-ui,sans-serif; padding:24px; } +body.figure h1, body.figure .sub { display:none; } +body.notitle h1, body.notitle .sub { display:none; } +h1 { text-align:center; font-size:15px; font-weight:700; margin-bottom:2px; } +.sub { text-align:center; color:var(--dim); font-size:13px; margin-bottom:20px; font-family:'SF Mono','Fira Code',monospace; } + +/* Controls */ +.controls { display:flex; gap:18px; justify-content:center; align-items:center; margin-bottom:10px; flex-wrap:wrap; } +.lbl { font-size:13px; color:var(--dim); margin-right:4px; font-weight:600; } +.bg { display:inline-flex; gap:2px; } +.btn { + padding:5px 11px; border:1px solid var(--border); background:var(--surface); color:var(--text); + cursor:pointer; border-radius:5px; font-size:10px; font-family:inherit; font-weight:500; transition:all .12s; +} +.btn:hover { background:#eef0f4; } +.btn.on { background:var(--accent); border-color:var(--accent); color:#fff; } +.btn.on:hover { background:#2563eb; } + +/* Side-by-side panels */ +.panels { display:grid; grid-template-columns:1fr 1fr; gap:20px; max-width:1100px; margin:0 auto; position:relative; } +.panel { background:var(--surface); border-radius:10px; padding:16px 14px; border:1px solid var(--border); + box-shadow:0 1px 3px rgba(0,0,0,.06); } +.panel h2 { text-align:center; font-size:10px; font-weight:700; margin-bottom:2px; } +.panel .nota { text-align:center; font-size:8px; color:var(--accent); font-family:'SF Mono','Fira Code',monospace; + margin-bottom:8px; font-weight:600; } + +/* Grid cells */ +.grid { display:grid; gap:3px; } +.hdr { font-size:7px; color:var(--dim); text-align:center; padding:2px 0; font-weight:600; } +.rl { font-size:7px; color:var(--dim); display:flex; align-items:center; justify-content:flex-end; padding-right:3px; font-weight:600; } +.cell { + aspect-ratio:1; border-radius:5px; display:flex; flex-direction:column; align-items:center; justify-content:center; + font-size:10px; font-weight:700; border:2.5px solid transparent; transition:all .18s; + min-width:0; cursor:pointer; line-height:1.15; +} +.cell.hov { border-color:#222; border-width:3px; z-index:2; box-shadow:0 0 8px rgba(59,130,246,.4); } +.cell.dm { opacity:.25; } + +/* Arrow SVG overlay */ +.arrow-svg { position:absolute; top:0; left:0; width:100%; height:100%; pointer-events:none; z-index:10; overflow:visible; } +.arrow-svg path { fill:none; stroke:#222; stroke-width:1.5; } +.arrow-svg text { font-size:8px; font-weight:600; fill:#222; font-family:inherit; } + +/* Formula bar */ +.formula-bar { max-width:1100px; margin:18px auto 0; background:var(--surface); border-radius:10px; + padding:12px 18px; border:1px solid var(--border); box-shadow:0 1px 3px rgba(0,0,0,.06); } +.formula-bar .ftitle { font-size:15px; font-weight:700; margin-bottom:6px; } +.formula-bar .fcontent { font-size:15px; font-family:'SF Mono','Fira Code',monospace; color:var(--accent); line-height:1.6; } + +/* Legend */ +.leg { display:flex; flex-direction:column; align-items:center; gap:4px; margin-top:14px; } +.leg-row { display:flex; gap:12px; justify-content:center; flex-wrap:wrap; } +.leg-group { display:flex; gap:10px; align-items:center; } +.leg-sep { width:1px; height:16px; background:var(--border); } +.li { display:flex; align-items:center; gap:4px; font-size:9px; color:var(--dim); } +.swtch { width:14px; height:14px; border-radius:3px; } + +@media(max-width:700px) { .panels { grid-template-columns:1fr; } } diff --git a/_extra_zh/zh/_static/tirx-layout-demo/viz-base.js b/_extra_zh/zh/_static/tirx-layout-demo/viz-base.js new file mode 100644 index 00000000..c5ef10f1 --- /dev/null +++ b/_extra_zh/zh/_static/tirx-layout-demo/viz-base.js @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * Derived from mlsyscourse/slides-modern-gpu-programming + * (data-layout/site/viz-base.js). Shared behavior for the TIRx + * layout visualization; not derived from any third-party demo. + */ + +// Shared behavior for all viz HTMLs +document.addEventListener('DOMContentLoaded', function() { + var p = new URLSearchParams(location.search); + if (p.has('notitle')) document.body.classList.add('notitle'); + + // Forward arrow keys to parent (reveal.js) when embedded + if (window.parent !== window) { + document.addEventListener('keydown', function(e) { + if ([37, 38, 39, 40, 27, 32].indexOf(e.keyCode) !== -1) { + // Left, Up, Right, Down, Escape, Space + window.parent.postMessage({ type: 'revealKey', keyCode: e.keyCode }, '*'); + } + }); + } +}); + +// Auto-height: when embedded in the book, measure our own content height and post +// it to the parent so it can size the iframe to fit (no inner scrollbar). This +// demo is responsive (it fills the iframe width), so only the HEIGHT needs to +// follow content. Push-based, so it catches our own DOM changes (editing the +// layout, clicking a cell, switching presets) that an outside observer can miss. +(function () { + if (window.parent === window) return; + var lastH = 0; + function report() { + var b = document.body, de = document.documentElement; + var h = (b ? b.scrollHeight : 0) || (de ? de.scrollHeight : 0) || 0; + if (h && Math.abs(h - lastH) > 1) { + lastH = h; + window.parent.postMessage({ type: 'demoHeight', height: h }, '*'); + } + } + var scheduled = false; + function schedule() { + if (scheduled) return; + scheduled = true; + requestAnimationFrame(function () { scheduled = false; report(); }); + } + try { new ResizeObserver(schedule).observe(document.documentElement); } catch (e) {} + try { + new MutationObserver(schedule).observe(document.documentElement, { + subtree: true, childList: true, attributes: true, characterData: true + }); + } catch (e) {} + document.addEventListener('DOMContentLoaded', schedule); + window.addEventListener('load', schedule); + window.addEventListener('click', function () { setTimeout(schedule, 0); }, true); + [100, 300, 600, 1200].forEach(function (t) { setTimeout(schedule, t); }); +})(); diff --git a/_extra_zh/zh/code-highlight.css b/_extra_zh/zh/code-highlight.css new file mode 100644 index 00000000..bc953fa1 --- /dev/null +++ b/_extra_zh/zh/code-highlight.css @@ -0,0 +1,139 @@ +/* ── Syntax highlight — shared across all demo slides ── + * + * Usage: + * + *
or
+ * + * Token classes: + * .kw — keyword (if, def, for, while, with, return, True, False) + * .fn — callable (function/method calls — the prominent highlight) + * .str — string literal + * .num — number literal + * .cmt — comment + * .op — operator (+, -, ==, =, :) + * .typ — type name + * .dec — decorator (@) + * + * Convention: only wrap the callable name in .fn, NOT the namespace prefix. + * ✓ Tx.copy_async(...) + * ✗ Tx.copy_async(...) + */ + +/* ── Dark theme (dark bg, bright tokens) ────────────── */ +.code-dark { + background: #0f172a; color: #e2e8f0; + font-family: 'SF Mono','Fira Code',monospace; + font-size: 12px; line-height: 1.6; + border-radius: 8px; padding: 12px 16px; + overflow-x: auto; +} +.code-dark .kw { color: #c084fc; } /* purple — keywords */ +.code-dark .fn { color: #60a5fa; } /* blue — callables (prominent) */ +.code-dark .str { color: #34d399; } /* green — strings */ +.code-dark .num { color: #fbbf24; } /* yellow — numbers */ +.code-dark .cmt { color: #64748b; font-style: italic; } /* gray — comments */ +.code-dark .op { color: #94a3b8; } /* slate — operators */ +.code-dark .typ { color: #7dd3fc; } /* cyan — types */ +.code-dark .dec { color: #c084fc; } /* purple — decorators */ + +/* ── Light theme (white bg, muted tokens) ───────────── */ +.code-light { + background: #f8fafc; color: #1e293b; + font-family: 'SF Mono','Fira Code',monospace; + font-size: 12px; line-height: 1.6; + border-radius: 8px; padding: 12px 16px; + border: 1px solid #e2e8f0; + overflow-x: auto; +} +.code-light .kw { color: #7c3aed; } /* purple — keywords */ +.code-light .fn { color: #2563eb; } /* blue — callables (prominent) */ +.code-light .str { color: #059669; } /* green — strings */ +.code-light .num { color: #d97706; } /* amber — numbers */ +.code-light .cmt { color: #6b7280; font-style: italic; } /* gray — comments */ +.code-light .op { color: #64748b; } /* slate — operators */ +.code-light .typ { color: #0369a1; } /* cyan — types */ +.code-light .dec { color: #7c3aed; } /* purple — decorators */ + +/* ── Code block panel (used by createCodeBlock) ────── + * + * Structure: + *
— wrapper with rounded corners + *
Title
— optional title bar + *
         — code container (scrollable)
+ *       (regions and lines rendered by createCodeBlock)
+ *     
+ *
+ * + * Or without panel wrapper, just
 works too.
+ */
+
+.cb-panel {
+  border-radius: 8px;
+  overflow: hidden;
+}
+.cb-panel > .code-dark,
+.cb-panel > .code-light {
+  border-radius: 0;
+}
+
+/* Header bar */
+.cb-panel .cb-header {
+  padding: 6px 14px;
+  font-size: 11px;
+  font-weight: 600;
+  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
+}
+.cb-panel.dark .cb-header {
+  background: #1e293b;
+  color: #94a3b8;
+  border-bottom: 1px solid rgba(255,255,255,0.06);
+}
+.cb-panel.light .cb-header {
+  background: #f1f5f9;
+  color: #64748b;
+  border-bottom: 1px solid #e2e8f0;
+}
+
+/* Dark scrollbar */
+.code-dark {
+  scrollbar-width: thin;
+  scrollbar-color: rgba(255,255,255,0.15) transparent;
+}
+.code-dark::-webkit-scrollbar { width: 6px; height: 6px; }
+.code-dark::-webkit-scrollbar-track { background: transparent; }
+.code-dark::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.15); border-radius: 3px; }
+.code-dark::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,0.25); }
+
+/* Light scrollbar */
+.code-light {
+  scrollbar-width: thin;
+  scrollbar-color: rgba(0,0,0,0.15) transparent;
+}
+.code-light::-webkit-scrollbar { width: 6px; height: 6px; }
+.code-light::-webkit-scrollbar-track { background: transparent; }
+.code-light::-webkit-scrollbar-thumb { background: rgba(0,0,0,0.12); border-radius: 3px; }
+.code-light::-webkit-scrollbar-thumb:hover { background: rgba(0,0,0,0.2); }
+
+/* Regions */
+.cb-region {
+  border-left: 3px solid transparent;
+  padding: 0.35rem 0 0.35rem 0.85rem;
+  margin: 0.15rem 0;
+  border-radius: 2px;
+  cursor: pointer;
+  transition: background 0.2s;
+}
+.code-dark .cb-region:hover  { background: rgba(255,255,255,0.05); }
+.code-dark .cb-region.active { background: rgba(255,255,255,0.07); }
+.code-light .cb-region:hover  { background: rgba(0,0,0,0.04); }
+.code-light .cb-region.active { background: rgba(0,0,0,0.06); }
+
+/* Lines */
+.cb-line {
+  display: block;
+  white-space: pre;
+}
+.cb-line.cb-focus {
+  margin-left: -0.85rem;
+  padding-left: 0.85rem;
+}
diff --git a/_extra_zh/zh/code-highlight.js b/_extra_zh/zh/code-highlight.js
new file mode 100644
index 00000000..1e36669c
--- /dev/null
+++ b/_extra_zh/zh/code-highlight.js
@@ -0,0 +1,224 @@
+/* ── Code highlight — shared TIRx/Python tokenizer + code block builder ──
+ *
+ * Usage:
+ *   
+ *   
+ *
+ * API:
+ *   highlightCode(text)  — tokenize text, return HTML with  tokens
+ *   escapeHtml(text)     — escape < > & for safe HTML insertion
+ *
+ *   createCodeBlock(container, code, options)
+ *     Renders highlighted code into container with optional regions + focus lines.
+ *     options:
+ *       blockDefs:    [{ key, start, end, color }]              — clickable regions
+ *       focusLines:   { key: [lineNos] } or { key: { lines, color } } — per-region line highlights
+ *       onBlockClick: function(key)                             — callback on region click
+ *
+ * Auto-init:
+ *   Elements with class "auto-hl" get their textContent highlighted on load.
+ *   Combine with code-dark / code-light for theme:
+ *     
Tx.copy_async(Asmem, A[...])
+ * + * Panel structure (optional wrapper for header + rounded corners): + *
+ *
Title
+ *

+ *     
+ * + * Token classes (same as code-highlight.css): + * .kw — keyword .fn — callable .str — string + * .num — number .cmt — comment .op — operator + * .typ — type .dec — decorator + * + * Namespace convention: only the callable name gets .fn, NOT the prefix. + * Tx.copy_async → Tx.copy_async + * T.ptx.tcgen05.mma → T.ptx.tcgen05.mma + */ + +(function (root) { + "use strict"; + + function escapeHtml(text) { + return text + .replace(/&/g, "&") + .replace(//g, ">"); + } + + var KEYWORDS = /^(def|with|for|in|if|else|elif|and|or|not|return|True|False|None|range|class|import|from|as|pass|break|continue|while|try|except|finally|raise|yield|lambda|assert|del|global|nonlocal)$/; + + function classifyToken(tok) { + if (tok.startsWith("#")) return "cmt"; + if (tok.startsWith("@")) return "dec"; + if (tok.startsWith('"') || tok.startsWith("'")) return "str"; + if (/^\d[\d.]*$/.test(tok)) return "num"; + if (KEYWORDS.test(tok)) return "kw"; + if (/^(?:Tx|T)(\.[A-Za-z_]\w*)+$/.test(tok)) return "fn"; + if (/^[A-Za-z_]\w*$/.test(tok)) return "fn"; + return ""; + } + + var TOKEN_RE = /("(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|#.*$|@[A-Za-z_][\w.]*|\b(?:def|with|for|in|if|else|elif|and|or|not|return|True|False|None|range|class|import|from|as|pass|break|continue|while|try|except|finally|raise|yield|lambda|assert|del|global|nonlocal)\b|\b\d[\d.]*\b|(?:Tx|T)(?:\.[A-Za-z_]\w*)+|\b[A-Za-z_]\w*(?=\())/gm; + + function highlightCode(text) { + TOKEN_RE.lastIndex = 0; + var out = ""; + var last = 0; + var m; + while ((m = TOKEN_RE.exec(text)) !== null) { + out += escapeHtml(text.slice(last, m.index)); + var tok = m[0]; + var cls = classifyToken(tok); + if (cls === "fn" && tok.indexOf(".") !== -1) { + // Namespace.callable — only wrap the last component + var lastDot = tok.lastIndexOf("."); + out += escapeHtml(tok.substring(0, lastDot + 1)); + out += '' + escapeHtml(tok.substring(lastDot + 1)) + ""; + } else if (cls) { + out += '' + escapeHtml(tok) + ""; + } else { + out += escapeHtml(tok); + } + last = TOKEN_RE.lastIndex; + } + out += escapeHtml(text.slice(last)); + return out; + } + + // Auto-init: highlight elements with class "auto-hl" + if (typeof document !== "undefined") { + document.addEventListener("DOMContentLoaded", function () { + var els = document.querySelectorAll(".auto-hl"); + for (var i = 0; i < els.length; i++) { + els[i].innerHTML = highlightCode(els[i].textContent); + } + }); + } + + // ── createCodeBlock: render code with optional regions + focus lines ── + + function hexToRgb(hex) { + return [ + parseInt(hex.slice(1, 3), 16), + parseInt(hex.slice(3, 5), 16), + parseInt(hex.slice(5, 7), 16) + ]; + } + + function createCodeBlock(container, code, options) { + options = options || {}; + var blockDefs = options.blockDefs; + var focusLines = options.focusLines; + var onBlockClick = options.onBlockClick; + var lines = code.split("\n"); + + if (blockDefs) { + // Render code split into clickable regions + container.innerHTML = blockDefs.map(function (b) { + var lineHtml = lines.slice(b.start - 1, b.end).map(function (line, idx) { + var lineNo = b.start + idx; + var content = line.length ? highlightCode(line) : " "; + return '
' + content + "
"; + }).join(""); + var style = b.color ? ' style="border-left-color:' + b.color + '"' : ""; + return '
" + lineHtml + "
"; + }).join(""); + + // Color map for hover/active/focus + var colorMap = {}; + blockDefs.forEach(function (b) { if (b.color) colorMap[b.key] = b.color; }); + + var regions = container.querySelectorAll(".cb-region"); + var allLines = container.querySelectorAll(".cb-line"); + var activeKey = null; + + function clearFocus() { + for (var i = 0; i < allLines.length; i++) { + allLines[i].classList.remove("cb-focus"); + allLines[i].style.background = ""; + } + } + + function applyFocus(key) { + if (!focusLines || !focusLines[key]) return; + var fl = focusLines[key]; + var lns = Array.isArray(fl) ? fl : fl.lines; + var color = Array.isArray(fl) ? null : fl.color; + if (!color && colorMap[key]) { + var rgb = hexToRgb(colorMap[key]); + color = "rgba(" + rgb.join(",") + ",0.18)"; + } + if (!color) color = "rgba(255,255,255,0.15)"; + for (var i = 0; i < lns.length; i++) { + var el = container.querySelector('.cb-line[data-ln="' + lns[i] + '"]'); + if (el) { + el.classList.add("cb-focus"); + el.style.background = color; + } + } + } + + for (var r = 0; r < regions.length; r++) { + (function (el) { + var regionKey = el.dataset.region; + + // Hover with region color + if (colorMap[regionKey]) { + var rgb = hexToRgb(colorMap[regionKey]); + var hoverBg = "rgba(" + rgb.join(",") + ",0.15)"; + el.addEventListener("mouseenter", function () { + if (!el.classList.contains("active")) el.style.background = hoverBg; + }); + el.addEventListener("mouseleave", function () { + if (!el.classList.contains("active")) el.style.background = ""; + }); + } + + // Click to activate + el.addEventListener("click", function () { + if (regionKey === activeKey) return; + activeKey = regionKey; + for (var j = 0; j < regions.length; j++) { + regions[j].classList.remove("active"); + regions[j].style.background = ""; + } + el.classList.add("active"); + if (colorMap[regionKey]) { + var rgb2 = hexToRgb(colorMap[regionKey]); + el.style.background = "rgba(" + rgb2.join(",") + ",0.15)"; + } + clearFocus(); + applyFocus(regionKey); + if (onBlockClick) onBlockClick(regionKey); + }); + })(regions[r]); + } + } else { + // Simple highlighted code, no regions + container.innerHTML = lines.map(function (line, idx) { + var content = line.length ? highlightCode(line) : " "; + return '
' + content + "
"; + }).join(""); + } + } + + // ── renderAnnotatedCode: highlight with per-line CSS classes ── + + function renderAnnotatedCode(container, code, lineClasses) { + lineClasses = lineClasses || {}; + var lines = code.split("\n"); + container.innerHTML = lines.map(function (line, idx) { + var content = line.length ? highlightCode(line) : " "; + var cls = lineClasses[idx + 1]; + if (cls) return '
' + content + "
"; + return "
" + content + "
"; + }).join(""); + } + + // Export + root.highlightCode = highlightCode; + root.escapeHtml = escapeHtml; + root.createCodeBlock = createCodeBlock; + root.renderAnnotatedCode = renderAnnotatedCode; +})(typeof window !== "undefined" ? window : this); diff --git a/_extra_zh/zh/demo/barrier_intro.html b/_extra_zh/zh/demo/barrier_intro.html new file mode 100644 index 00000000..9973f691 --- /dev/null +++ b/_extra_zh/zh/demo/barrier_intro.html @@ -0,0 +1,387 @@ + + + + +异步协作:Barrier + + + + + + +

异步协作:Barrier

+
硬件单元完成后 signal mbarrier;warp group 在继续前等待
+ +
+
+ +
GMEM
A, B
+
+ +
TMA 加载
+
+
SMEM
+
+ +
tcgen05.mma
+
+
TMEM
累加器
+
+ +
tcgen05.ld
+
+
寄存器
cast
+
+ +
存储
+
+
SMEM
+
+ +
TMA 存储
+
+
GMEM
D
+ + +
+ + +
+
Warp 0 — 生产者
+
TMA 派发
+
+
+
Warp 1 — 消费者
+
tcgen05 派发
+
+
+
Warp 0 — 下一阶段
+
TMA 派发
+
+ + +
+ + +
TMA
引擎
+
+ +
complete-tx
+
+
mbar
TMA 就绪
+
Tensor
Core
+
mbar
SMEM 空闲
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ 协作: +
+
+ +
    +
  • mbarrier (mbar) — 用于协调线程和硬件单元之间的异步操作
  • +
  • 不同 warp 可并行运行在操作的不同阶段
  • +
+ + + + diff --git a/_extra_zh/zh/demo/cta_cluster.html b/_extra_zh/zh/demo/cta_cluster.html new file mode 100644 index 00000000..47e16dbb --- /dev/null +++ b/_extra_zh/zh/demo/cta_cluster.html @@ -0,0 +1,113 @@ + + + + + +2-CTA Cluster + + + + + +

2-CTA Cluster:通过跨 CTA SMEM 读取实现协作 MMA

+
点击任意部分查看说明;两个 CTA 在 cluster 内共享 stored-B 行切片(DSMEM)
+ +
+ CLUSTER — 跨 SM 的 2 个 CTA · DSMEM +
+
+
CTA 0 · SM-0
+
Asmem(本 CTA)A 行 0–127
+
BsmemB stored 行 0–127
+
D[0:128, 0:256]
+
+
+
跨 CTA
读取 ↔
+
+
+
CTA 1 · SM-1
+
Asmem(本 CTA)A 行 128–255
+
BsmemB stored 行 128–255
+
D[128:256, 0:256]
+
+
+
Cluster 输出:256 × 256 — 是单个 CTA 独立计算 128 × 128 的两倍
+
+ +
+
+
+
+ + + + diff --git a/_extra_zh/zh/demo/mbarrier_arrive_timeline.html b/_extra_zh/zh/demo/mbarrier_arrive_timeline.html new file mode 100644 index 00000000..e2856809 --- /dev/null +++ b/_extra_zh/zh/demo/mbarrier_arrive_timeline.html @@ -0,0 +1,470 @@ + + + + + +MBarrier arrive 时间线 + + + + + +

用于跨线程同步的 MBarrier

+ +
+ +
+
+ + +
T0(生产者)
+
+ + +
MBar
+
+ + +
T1(消费者)
+
+ + +
+ 时间线 +
+
+
+ + + +
+
+
+ + +
+
+
工作 / 活跃 +
+
+
Signal 操作 +
+
+
阻塞 / 等待 +
+
+
Barrier 状态 +
+
+
空闲 +
+
+ Signal 并改变 mbar 状态 +
+
+
init 后同步线程 +
+
+ +
+
+

设置(T0)

+

mbarrier.init(mbar, 1) — 对所有运行只设置一次,设置后显式同步。

+
+
+

生产者(T0)

+

mbarrier.arrive(mbar) 递减 pending_count;当它变为 0 时,phase 完成。

+
+
+

消费者(T1)

+

mbarrier.try_wait(mbar, phase) 挂起 T1,直到 phase 完成。

+
+
+ + + + diff --git a/_extra_zh/zh/demo/mbarrier_mechanism.html b/_extra_zh/zh/demo/mbarrier_mechanism.html new file mode 100644 index 00000000..16dbb513 --- /dev/null +++ b/_extra_zh/zh/demo/mbarrier_mechanism.html @@ -0,0 +1,220 @@ + + + + + +MBarrier 机制 + + + + + +

MBarrier:数据结构与 API

+ +
+
+

MBarrier 对象(64-bit,位于 shared memory)

+
+
phase
0 或 1
+
pending_count
剩余 arrival
+
expected_count
预期总数
+
tx-count
待完成字节
+
+
+ phase + 当前 phase(0 或 1)。完成后自动翻转。 +
+
+ pending_count + phase 完成前仍需要的 arrival 数量。 +
+
+ expected_count + 每个 phase 预期的 arrival 总数(由 init 设置)。 +
+
+ tx-count + 尚未完成的异步字节数。由 arrive.expect_tx 增加,由硬件在传输完成时减少。 +
+
+ +
+

Phase 完成条件

+
+ pending_count == 0
+ &&
+ tx-count ≤ 0 +
+
+ 当 所有预期线程都已 arrive所有预期异步字节都已传输完成 时,一个 phase 完成。 + 完成后,barrier 会自动重置:phase 翻转,pending_count 重置为 expected_count,tx-count 重置为 0。 +
+
+
+ +
+

核心 API

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
指令角色对 MBarrier 的影响
mbarrier.init 设置用预期 arrival 数初始化 barrierphase=0, pending=count, tx=0
mbarrier.arrive 生产者线程向 barrier signal arrivalpending_count -= 1
mbarrier.arrive.expect_tx 生产者Arrive 并声明预期异步传输字节数pending -= 1, tx_count += txCount
tcgen05.commit 生产者Tensor Core signal MMA 完成在 mbarrier 上执行 arrive::one
mbarrier.try_wait 消费者等待(挂起线程)直到 phase 完成阻塞直到 phase 完成
+
+ +
+ 三种 arrival 模式: (1) mbarrier.arrive — 线程直接递减 pending_count。 + (2) arrive.expect_tx — 线程 arrive 并声明字节数;TMA 引擎在传输完成时自动递减 tx_count。 + (3) tcgen05.commit — Tensor Core 在 MMA 完成时自动 arrive。 +
+ + + diff --git a/_extra_zh/zh/demo/mbarrier_tcgen05_timeline.html b/_extra_zh/zh/demo/mbarrier_tcgen05_timeline.html new file mode 100644 index 00000000..6889526f --- /dev/null +++ b/_extra_zh/zh/demo/mbarrier_tcgen05_timeline.html @@ -0,0 +1,479 @@ + + + + + +MBarrier tcgen05.commit 时间线 + + + + + +

用 MBarrier signal tcgen05 完成

+ +
+ +
+
+ + +
T0(生产者)
+
+ + +
Tensor Core
+
+ + +
MBar
+
+ + +
T1(消费者)
+
+ + +
+ 时间线 +
+
+
+ + + +
+
+
+ + +
+
+
工作 / 活跃 +
+
+
Signal 操作 +
+
+
派发到 Tensor Core +
+
+
阻塞 / 等待 +
+
+
Barrier 状态 +
+
+
空闲 +
+
+ Signal 并改变 mbar 状态 +
+
+
init 后同步线程 +
+
+ +
+
+

生产者(T0)

+

tcgen05.mma 发起异步矩阵乘。tcgen05.commit(mbar) 告诉 barrier 跟踪它;硬件完成后会执行 arrive::one

+
+
+

Tensor Core

+

执行 T0 排队的 tcgen05.mmatcgen05.commit

+
+
+

消费者(T1)

+

mbarrier.try_wait(mbar, phase) 会挂起 T1,直到 phase 完成。结果随后可在 TMEM 中读取。

+
+
+ + + + diff --git a/_extra_zh/zh/demo/mbarrier_tma_timeline.html b/_extra_zh/zh/demo/mbarrier_tma_timeline.html new file mode 100644 index 00000000..6ae2808a --- /dev/null +++ b/_extra_zh/zh/demo/mbarrier_tma_timeline.html @@ -0,0 +1,490 @@ + + + + + +MBarrier TMA 时间线 + + + + + +

用 MBarrier signal TMA 完成

+ +
+ +
+
+ + +
T0(生产者)
+
+ + +
TMA 引擎
+
+ + +
MBar
+
+ + +
T1(消费者)
+
+ + +
+ 时间线 +
+
+
+ + + +
+
+
+ + +
+
+
工作 / 活跃 +
+
+
Signal 操作 +
+
+
派发到 TMA +
+
+
阻塞 / 等待 +
+
+
Barrier 状态 +
+
+
空闲 +
+
+ Signal 并改变 mbar 状态 +
+
+
init 后同步线程 +
+
+ +
+
+

生产者(T0)

+

arrive.expect_tx(4096) 将 pending 递减到 0,并设置 tx_count。cp.async.bulk 触发 TMA 传输。

+
+
+

TMA 引擎

+

执行从 T0 派发的 cp.async.bulk。完成时自动递减 tx_count。

+
+
+

消费者(T1)

+

try_wait 会挂起,直到 pending==0 且 tx==0。硬件在传输完成时自动递减 tx_count。

+
+
+ + + + diff --git a/_extra_zh/zh/demo/phase_tracking.html b/_extra_zh/zh/demo/phase_tracking.html new file mode 100644 index 00000000..94c82c34 --- /dev/null +++ b/_extra_zh/zh/demo/phase_tracking.html @@ -0,0 +1,201 @@ + + + + + +Phase 跟踪 + + + + + +

Phase 跟踪

+

Barrier 通过在 phase 0 ↔ 1 间翻转,在多次迭代之间复用

+ +
+ + +
+ +
+
phase = 0
迭代 0
+
phase = 1
迭代 1
+
phase = 0
迭代 2
+
phase = 1
迭代 3
+
phase = 0
迭代 4
+
phase = 1
迭代 5
+
phase = 0
迭代 6
+
phase = 1
迭代 7
+
+ +
+
+

工作方式

+
+ 每个 barrier 都有一个 phase bit(0 或 1)。所有预期 arrival 到达后,barrier 会翻转 phase 并重置,准备好服务下一次迭代;无需重新初始化。 +
+
1
生产者 arrive 到 barrier(phase 0)
+
2
消费者调用 try_wait(phase=0) — 解除阻塞
+
3
Barrier 翻转到 phase 1,phase ^= 1
+
+
+
+ +
+

为什么要跟踪 phase?

+
+ 在流水线 kernel 中,barrier 会在 K-loop 的每次迭代中复用。phase 跟踪解决的问题是:“这次 barrier 触发对应的是迭代 i,还是迭代 i-1?” +
+ phase_tma = 0
+ for k in range(K):
+   try_wait(tma_bar, phase_tma)
+   phase_tma ^= 1  # 翻转 +
+
+
+
+ + + + + diff --git a/_extra_zh/zh/demo/pipeline_arch.html b/_extra_zh/zh/demo/pipeline_arch.html new file mode 100644 index 00000000..469773bc --- /dev/null +++ b/_extra_zh/zh/demo/pipeline_arch.html @@ -0,0 +1,509 @@ + + + + + +Blackwell 上的 GEMM 数据流水线 + + + + + +

Blackwell 上的 GEMM 数据流水线

+

D = A × B — 点击一个操作,在架构图中查看对应的数据路径

+ + +
+
+
GMEM
A, B
+
+
+ +
TMA 加载
+
+
+
SMEM
+
+
+ +
tcgen05.mma
+
+
+
TMEM
累加器
+
+
+ +
tcgen05.ld
+
+
+
寄存器
cast
+
+
+ +
存储
+
+
+
SMEM
+
+
+ +
TMA 存储
+
+
+
GMEM
D
+
+
+ +
+
+ Blackwell 架构 +
+
+ + +
+
+
+
流式多处理器 (SM)
+ +
+
+
Tensor Core (tcgen05)
+
第 5 代 MMA
+
+
+
+
CUDA Core
+
FP/INT 单元
+
+
+ +
+
+
Shared Memory (SMEM)
+
每个 SM 228 KB
+
+
+
Tensor Memory (TMEM)
+
128 条 lane
+
+
+
寄存器文件
+
+
+ +
+
+
TMA 引擎
+
数据搬运器
+
+
+
+
+
+
+
SM ...
+ × N +
+
+ +
+
全局内存 (GMEM)
+
+ + + +
+ + +
+
+
点击流水线中的一个操作以高亮对应的数据路径。
+
+ + + + diff --git a/_extra_zh/zh/demo/sf_tmem.html b/_extra_zh/zh/demo/sf_tmem.html new file mode 100644 index 00000000..48093a83 --- /dev/null +++ b/_extra_zh/zh/demo/sf_tmem.html @@ -0,0 +1,148 @@ + + + + +TMEM 中的 Scale Factor + + + + + +

TMEM 中的 Scale Factor(nvfp4)

+
M = 128,一个 MMA-K block(SF_K = 4) ·  warpx4 broadcast R[4 : 32@TLane]
+ +
+ +
+

逻辑 SFA  (M × SF_K)

+
点击 cell = SFA[m, sfk]  ·  颜色 = m // 32 分组
+
+
+
+

TMEM  (128 条 lane × 16 字节)

+
w0: m 0–31 · w1: m 32–63 · w2: m 64–95 · w3: m 96–127  ·  byte = sfk
+
+
+
+ +
+
布局  SFA[m, sfk] → TMEM
+
+ TLane = m mod 32  ·  + word = m div 32  ·  + byte = sfk  ·  + TCol = word·4 + byte  ·  + warpx4 → lanes { TLane, +32, +64, +96 } +
+
点击左侧 cell…
+
+ + + + diff --git a/_extra_zh/zh/demo/sm_architecture.html b/_extra_zh/zh/demo/sm_architecture.html new file mode 100644 index 00000000..77de85ca --- /dev/null +++ b/_extra_zh/zh/demo/sm_architecture.html @@ -0,0 +1,397 @@ + + + + + +Blackwell SM 架构 + + + + + +

Blackwell SM 架构

+ +
+
+
+
流式多处理器 (SM)
+ + +
+
+
Tensor Core (tcgen05)
+
第 5 代 MMA
+
+
+
+
CUDA Core
+
FP/INT 单元
+
+
+ + +
+
+
Shared Memory (SMEM)
+
每个 SM 228 KB
+
+
+
Tensor Memory (TMEM)
+
TMEM — 128 条 lane
+
+
+
寄存器文件
+
+
+
+ + +
+
+
TMA 引擎
+
数据搬运器
+
+
+
+
+
+
+
SM ...
+ × N +
+
+ + +
+
全局内存 (GMEM)
+
+ + + +
+ + +
+
+
点击硬件单元查看详情。实线箭头表示加载路径,虚线箭头表示存储路径。
+
+ + + + + diff --git a/_extra_zh/zh/demo/swizzle_128B.html b/_extra_zh/zh/demo/swizzle_128B.html new file mode 100644 index 00000000..e33b8886 --- /dev/null +++ b/_extra_zh/zh/demo/swizzle_128B.html @@ -0,0 +1,432 @@ + + + + +Swizzle 布局 — SWIZZLE_128B + + + + + + +

Swizzle 布局 — SWIZZLE_128B

+
physical_sector = logical_sector XOR row  |  8 行 × 32 个 bank,每个 sector 4 个 bank
+ +
+
读取 +
+ + +
+
+
索引
+
+ +
+ +

不使用 Swizzle

+
+
32 个 Bank
+
+
+
+

SWIZZLE_128B

+
+
32 个 Bank
+
+
+
+
+
+ +
+
按 cycle 展示读取
+
+
+

不使用 Swizzle

+

SWIZZLE_128B

+
+
+ +
+ 1 个元素 = 1 个 bank(4 字节)。一个 32 线程 warp 读取 32 个元素;bank conflict 会被串行化成额外 cycle。
+ 列 tile (8×4):8 行 × 4 列(1 个 sector)= 32 次读取。 + 使用 swizzle:1 个 cycle;不使用:8 个 cycle(8 路冲突)。
+ 行 tile (1×32):1 行 × 32 列 = 32 次读取。 + 始终是 1 个 cycle(同一行内 32 个 bank 全部不同)。 +
+ + + + diff --git a/_extra_zh/zh/demo/swizzle_8x8.html b/_extra_zh/zh/demo/swizzle_8x8.html new file mode 100644 index 00000000..def1575e --- /dev/null +++ b/_extra_zh/zh/demo/swizzle_8x8.html @@ -0,0 +1,384 @@ + + + + +Swizzle 布局 + + + + + + +

Swizzle 布局 — 8×8

+
mapped_col = logical_col XOR row  |  8×8 矩阵,1 个元素 = 1 个 bank
+ +
+
读取 +
+ + +
+
+
索引
+
+ +
+ +

不使用 Swizzle

+
Bank 活跃情况
+
+
+

使用 Swizzle(XOR)

+
Bank 活跃情况
+
+
+
+
+ +
+
按 cycle 展示读取
+
+
+

不使用 Swizzle

+

使用 Swizzle(XOR)

+
+
+ + + + diff --git a/_extra_zh/zh/demo/swizzle_atom_general.html b/_extra_zh/zh/demo/swizzle_atom_general.html new file mode 100644 index 00000000..fd2e7379 --- /dev/null +++ b/_extra_zh/zh/demo/swizzle_atom_general.html @@ -0,0 +1,472 @@ + + + + +Swizzle Atom — 全部格式 + + + + + + +

Swizzle Atom — 全部格式

+
swizzle atom 是内存中应用 swizzle 的基本连续区域
+ +
+
+ 格式 + + + + + + +
+ + +
+ +
+
读取 +
+ + +
+
+
索引
+
+
+
dtype +
+ + + +
+
+
+
+ +
+ +

不使用 Swizzle

+
Bank sector 活跃情况(全部 8 个)
+
+
+

使用 Swizzle(XOR)

+
Bank sector 活跃情况(全部 8 个)
+
+
+
+
+
+
关键:使用 swizzle 后,读取任意 8×16B 列都没有冲突!
+ +
+
按 cycle 展示读取
+
+
+

不使用 Swizzle

+

使用 Swizzle(XOR)

+
+
+ + + + diff --git a/_extra_zh/zh/demo/tcgen05_intro.html b/_extra_zh/zh/demo/tcgen05_intro.html new file mode 100644 index 00000000..90692ea0 --- /dev/null +++ b/_extra_zh/zh/demo/tcgen05_intro.html @@ -0,0 +1,331 @@ + + + + +Tensor Core:tcgen05.mma + + + + + + +

tcgen05.mma

+ +
+
转置 A +
+ + +
+
+
转置 B +
+ + +
+
+
+
+
M(输出行) +
+ +
+
+
N(输出列) +
+ + + + +
+
+
K +
+ +
+
+
+
+
行分组
+
列分组
+
+ +
+
+

A (SMEM)

+ +
+
+
×
+
+

B (SMEM)

+
+
+
+
+
+
Tensor Core
+
tcgen05.mma
+
+
+
+
+

C (TMEM)

+
+
+
128 条 lane(M)
+
+
+
列(N)— 由 tmem.alloc 分配
+
+
+
+
+ +
+ K 迭代: +
+
+ +
+
+ +
+
+
SMEM 描述符(A, B)
+
smem_desc = base_addr | leading_byte_offset | stride_byte_offset | start_addr_off
+
+
+
tcgen05.mma PTX
+
tcgen05.mma.cta_group::1.kind::f16 taddr, a_desc, b_desc, idesc, enable;
+
+
+ + + + diff --git a/_extra_zh/zh/demo/thread_hierarchy.html b/_extra_zh/zh/demo/thread_hierarchy.html new file mode 100644 index 00000000..8c49996f --- /dev/null +++ b/_extra_zh/zh/demo/thread_hierarchy.html @@ -0,0 +1,112 @@ + + + + + +Blackwell 线程层级 + + + + + +

Blackwell 线程层级

+
点击一个层级:thread → warp → warpgroup → CTA → cluster → grid
+ +
+
+ GRID — 一次 kernel launch +
+ CLUSTER — 跨 SM 的 CTA(DSMEM) +
+
+ CTA — 线程块 · 一个 SM +
+ WARPGROUP — 4 个 warp · 128 个线程 +
+
+ WARP — 32 个线程(SIMT) +
+
+
warp 1
+
warp 2
+
warp 3
+
+
+
+
CTA 1
+
+
+
+
+ +
+
+
+
+ + + + diff --git a/_extra_zh/zh/demo/thread_register.html b/_extra_zh/zh/demo/thread_register.html new file mode 100644 index 00000000..99029747 --- /dev/null +++ b/_extra_zh/zh/demo/thread_register.html @@ -0,0 +1,252 @@ + + + + +线程 + 寄存器布局 + + + + + + +

Layout: S[(8, 4, 2) : (4@laneid, 1@laneid, 1@reg)]

+
点击 cell 查看分配关系
+ +
+
+

逻辑 8×8 矩阵

+
+
+
+
+

线程分配

+
+
+
+
+ +
+ +
+
+ + + + diff --git a/_extra_zh/zh/demo/tile_distributed.html b/_extra_zh/zh/demo/tile_distributed.html new file mode 100644 index 00000000..f0c45819 --- /dev/null +++ b/_extra_zh/zh/demo/tile_distributed.html @@ -0,0 +1,480 @@ + + + + +分布式布局 + + + + + + +

分布式布局 — 2×2 GPU Mesh 上的 8×8 矩阵

+
完全 shard 到 4 个 GPU  |  点击 cell 查看放置位置
+ +
+
布局 +
+ + + +
+
+
+ +
+
+

+
+
+
+
+

GPU Mesh(2×2)

+
+
+
+ +
+ +
+
+ + + + diff --git a/_extra_zh/zh/demo/tiled_layout.html b/_extra_zh/zh/demo/tiled_layout.html new file mode 100644 index 00000000..fbe7c961 --- /dev/null +++ b/_extra_zh/zh/demo/tiled_layout.html @@ -0,0 +1,278 @@ + + + + +Tiled 布局 + + + + + + +

S[(4, 2, 2, 4) : (16, 4, 8, 1)]

+
逻辑视图 vs 物理内存  |  点击 cell 查看映射
+ +
+
+

逻辑矩阵

+
+
+
+
+
+
+

物理内存(2×4 tiled)

+
+
+
+
+
+ +
+ +
+ + + + diff --git a/_extra_zh/zh/demo/tiling_constraint.html b/_extra_zh/zh/demo/tiling_constraint.html new file mode 100644 index 00000000..16480f68 --- /dev/null +++ b/_extra_zh/zh/demo/tiling_constraint.html @@ -0,0 +1,343 @@ + + + + +Swizzle 带来的 tiling 约束 + + + + + + +

Swizzle 带来的 tiling 约束

+
在 16×16 矩阵上使用 128B swizzle — 切成 16×8 分组即可消除 bank conflict
+ +
+
是否 tile +
+ + +
+
+
行范围 +
+ + +
+
+
+
+
+
+ +
+
+

原始 16×16 矩阵

+
+
+ +
+
+
+

为 128B Swizzle 进行 tiling(两个 16×8 分组)

+
+
+
+
+
Bank sector 活跃情况
+
+
+
+
+
dtype +
+ + + +
+
+
+
+
+
硬件会基于物理偏移计算 swizzle_col,等价于假设每行只有 8 个元素。若每行有 16 个元素,则每个原始行在 swizzle 计算中会被当成 2 行处理。
+
+
+
+ + + + diff --git a/_extra_zh/zh/demo/tirx_dispatch.html b/_extra_zh/zh/demo/tirx_dispatch.html new file mode 100644 index 00000000..0470045b --- /dev/null +++ b/_extra_zh/zh/demo/tirx_dispatch.html @@ -0,0 +1,159 @@ + + + + + +TIRx:Scope、Layout、Dispatch + + + + + +

TIRx:Scope、Layout、Dispatch

+
点击一个设计元素,查看它控制 single-MMA GEMM 中的哪些代码行
+ +
+ + + +
+ +
+
+ + + + diff --git a/_extra_zh/zh/demo/tma_3d.html b/_extra_zh/zh/demo/tma_3d.html new file mode 100644 index 00000000..e118e70b --- /dev/null +++ b/_extra_zh/zh/demo/tma_3d.html @@ -0,0 +1,353 @@ + + + + +用 3D TMA 做 tiling 与 swizzle + + + + + + +

用 3D TMA 做 tiling 与 swizzle

+
使用 3D TMA 将数据复制到 tiled shared memory
+ +
+
Swizzle +
+ + +
+
+
列偏移
+
+ +
+ + +
+

Global Memory

+
16×256 fp16(连续布局,row = 512B)
+
+
+ +
+
+
3D TMA
+
+
+ +
+

Shared Memory(tiled & swizzle 后)

+
+
+
+ +
+ +
+
+
+ + + + diff --git a/_extra_zh/zh/demo/tma_intro.html b/_extra_zh/zh/demo/tma_intro.html new file mode 100644 index 00000000..65a79ed4 --- /dev/null +++ b/_extra_zh/zh/demo/tma_intro.html @@ -0,0 +1,358 @@ + + + + +TMA:Tensor Memory Accelerator + + + + + + +

TMA:从 Global Memory 到 Shared Memory

+
硬件 2D copy,可选 swizzle — 一条指令,无需线程搬运
+ +
+
Swizzle +
+ + +
+
+
行偏移
+
列偏移
+
+ +
+ + +
+

Global Memory

+
16×128 fp16(每个 cell = 16B = 1×8 fp16)
+
+
+ +
+
+
TMA 引擎
+
数据搬运器
+
+
+
cp.async.bulk.tensor.2d
+ SWIZZLE_128B
+
+ +
+

Shared Memory

+
8×8 个 sector(swizzle 后)
+
+
+
+ +
+ +
+
+
+ +
    +
  • 单线程派发(非阻塞)
  • +
  • 自动 swizzle — 数据到达时天然避免 bank conflict
  • +
  • 双向:load(GMEM→SMEM)和 store(SMEM→GMEM)
  • +
+ + + + diff --git a/_extra_zh/zh/viz-base.css b/_extra_zh/zh/viz-base.css new file mode 100644 index 00000000..314d742d --- /dev/null +++ b/_extra_zh/zh/viz-base.css @@ -0,0 +1,90 @@ +/* Shared base styles for all viz HTMLs + * Colors: --bg gray, --accent blue, --surface white + * Fonts: Inter (body), SF Mono (code/notation) + */ + +:root { + --bg:#fff; --surface:#fff; --border:#dfe1e6; --text:#222; --dim:#888; --accent:#3b82f6; + + /* ── Group palette (tiles, lanes, banks, sectors) ─────── */ + --color-group-0: #5b9bd5; + --color-group-1: #ed9a3c; + --color-group-2: #d95555; + --color-group-3: #45b5a5; + --color-group-4: #5fb85f; + --color-group-5: #e0b828; + --color-group-6: #9d6eb5; + --color-group-7: #e87888; + + /* ── Interaction ──────────────────────────────────────── */ + --color-hover-bg: #dbeafe; + --color-hover-text: #1e40af; + + /* ── Status ───────────────────────────────────────────── */ + --color-good: #2e7d32; + --color-bad: #c62828; + + /* ── Boundaries & neutrals ────────────────────────────── */ + --color-boundary: #8C1515; + --color-cell-bg: #f0f1f3; + --color-cell-bg-alt: #e8eaed; +} +* { box-sizing:border-box; margin:0; padding:0; } +body { background:var(--bg); color:var(--text); font-family:'Inter','SF Pro','Segoe UI',system-ui,sans-serif; padding:24px; } +body.figure h1, body.figure .sub { display:none; } +body.notitle h1, body.notitle .sub { display:none; } +h1 { text-align:center; font-size:21px; font-weight:700; margin-bottom:2px; } +.sub { text-align:center; color:var(--dim); font-size:14px; margin-bottom:20px; font-family:'SF Mono','Fira Code',monospace; } + +/* Controls */ +.controls { display:flex; gap:18px; justify-content:center; align-items:center; margin-bottom:10px; flex-wrap:wrap; } +.lbl { font-size:13px; color:var(--dim); margin-right:4px; font-weight:600; } +.bg { display:inline-flex; gap:2px; } +.btn { + padding:5px 11px; border:1px solid var(--border); background:var(--surface); color:var(--text); + cursor:pointer; border-radius:5px; font-size:13px; font-family:inherit; font-weight:500; transition:all .12s; +} +.btn:hover { background:#eef0f4; } +.btn.on { background:var(--accent); border-color:var(--accent); color:#fff; } +.btn.on:hover { background:#2563eb; } + +/* Side-by-side panels */ +.panels { display:grid; grid-template-columns:1fr 1fr; gap:20px; max-width:1100px; margin:0 auto; position:relative; } +.panel { background:var(--surface); border-radius:10px; padding:16px 14px; border:1px solid var(--border); + box-shadow:0 1px 3px rgba(0,0,0,.06); } +.panel h2 { text-align:center; font-size:14px; font-weight:700; margin-bottom:2px; } +.panel .nota { text-align:center; font-size:11px; color:var(--accent); font-family:'SF Mono','Fira Code',monospace; + margin-bottom:8px; font-weight:600; } + +/* Grid cells */ +.grid { display:grid; gap:3px; } +.hdr { font-size:10px; color:var(--dim); text-align:center; padding:2px 0; font-weight:600; } +.rl { font-size:10px; color:var(--dim); display:flex; align-items:center; justify-content:flex-end; padding-right:3px; font-weight:600; } +.cell { + aspect-ratio:1; border-radius:5px; display:flex; flex-direction:column; align-items:center; justify-content:center; + font-size:13px; font-weight:700; border:2.5px solid transparent; transition:all .18s; + min-width:0; cursor:pointer; line-height:1.15; +} +.cell.hov { border-color:#222; border-width:3px; z-index:2; box-shadow:0 0 8px rgba(59,130,246,.4); } +.cell.dm { opacity:.25; } + +/* Arrow SVG overlay */ +.arrow-svg { position:absolute; top:0; left:0; width:100%; height:100%; pointer-events:none; z-index:10; overflow:visible; } +.arrow-svg path { fill:none; stroke:#222; stroke-width:1.5; } +.arrow-svg text { font-size:11px; font-weight:600; fill:#222; font-family:inherit; } + +/* Formula bar */ +.formula-bar { max-width:1100px; margin:18px auto 0; background:var(--surface); border-radius:10px; + padding:12px 18px; border:1px solid var(--border); box-shadow:0 1px 3px rgba(0,0,0,.06); } +.formula-bar .ftitle { font-size:13px; font-weight:700; margin-bottom:6px; } +.formula-bar .fcontent { font-size:13px; font-family:'SF Mono','Fira Code',monospace; color:var(--accent); line-height:1.6; } + +/* Legend */ +.leg { display:flex; flex-direction:column; align-items:center; gap:4px; margin-top:14px; } +.leg-row { display:flex; gap:12px; justify-content:center; flex-wrap:wrap; } +.leg-group { display:flex; gap:10px; align-items:center; } +.leg-sep { width:1px; height:16px; background:var(--border); } +.li { display:flex; align-items:center; gap:4px; font-size:12px; color:var(--dim); } +.swtch { width:14px; height:14px; border-radius:3px; } + +@media(max-width:700px) { .panels { grid-template-columns:1fr; } } diff --git a/_extra_zh/zh/viz-base.js b/_extra_zh/zh/viz-base.js new file mode 100644 index 00000000..ce3e1a3f --- /dev/null +++ b/_extra_zh/zh/viz-base.js @@ -0,0 +1,66 @@ +// Shared behavior for all viz HTMLs +document.addEventListener('DOMContentLoaded', function() { + var p = new URLSearchParams(location.search); + if (p.has('notitle')) document.body.classList.add('notitle'); + + // Directly opened demo pages are copied outside Sphinx templates, so they do + // not receive html_js_files. Load the same language switch used by book pages. + if (window.parent === window && !p.has('notitle')) { + var langSwitchPath = window.location.pathname.indexOf('/zh/demo/') >= 0 + ? '../../_static/lang-switch.js' + : '../_static/lang-switch.js'; + var s = document.createElement('script'); + s.src = new URL(langSwitchPath, window.location.href).href; + document.head.appendChild(s); + } + + // Forward arrow keys to parent (reveal.js) when embedded + if (window.parent !== window) { + document.addEventListener('keydown', function(e) { + if ([37, 38, 39, 40, 27, 32].indexOf(e.keyCode) !== -1) { + // Left, Up, Right, Down, Escape, Space + window.parent.postMessage({ type: 'revealKey', keyCode: e.keyCode }, '*'); + } + }); + } +}); + +// Auto-height: when embedded in the book (demo-embed.js), the demo measures its +// OWN content height and posts it to the parent, which sizes the iframe to fit so +// there is never an inner scrollbar. This is push-based on purpose — the demo +// catches its own DOM changes (a click that appends rows, expands a panel, …), +// which a parent watching the iframe's from outside can miss. Measuring +// body.scrollHeight (not documentElement, which is floored to the viewport) lets +// the reported height grow AND shrink with the content. +(function () { + if (window.parent === window) return; // only when embedded + var lastH = 0; + function report() { + var b = document.body, de = document.documentElement; + var h = (b ? b.scrollHeight : 0) || (de ? de.scrollHeight : 0) || 0; + if (h && Math.abs(h - lastH) > 1) { + lastH = h; + window.parent.postMessage({ type: 'demoHeight', height: h }, '*'); + } + } + var scheduled = false; + function schedule() { + if (scheduled) return; + scheduled = true; + requestAnimationFrame(function () { scheduled = false; report(); }); + } + // documentElement exists even while we are still in , so observers can be + // attached immediately; the first read happens in the rAF after layout. + try { new ResizeObserver(schedule).observe(document.documentElement); } catch (e) {} + try { + new MutationObserver(schedule).observe(document.documentElement, { + subtree: true, childList: true, attributes: true, characterData: true + }); + } catch (e) {} + document.addEventListener('DOMContentLoaded', schedule); + window.addEventListener('load', schedule); + // Clicks often trigger async content changes; re-measure right after. + window.addEventListener('click', function () { setTimeout(schedule, 0); }, true); + // Catch late settling (fonts, deferred render). + [100, 300, 600, 1200].forEach(function (t) { setTimeout(schedule, t); }); +})(); diff --git a/_templates/sbt-sidebar-nav.html b/_templates/sbt-sidebar-nav.html new file mode 100644 index 00000000..1b39afbc --- /dev/null +++ b/_templates/sbt-sidebar-nav.html @@ -0,0 +1,32 @@ + diff --git a/conf.py b/conf.py index 0a03f5a5..1315caf4 100644 --- a/conf.py +++ b/conf.py @@ -44,12 +44,13 @@ html_title = project html_logo = "static/mlc-logo-with-text-landscape.svg" html_favicon = "static/mlc-favicon.ico" +templates_path = ["_templates"] html_static_path = ["static"] # Interactive slide demos (self-contained HTML+CSS+JS) copied verbatim into the # site root, then embedded via + +``` +*交互:一个 `mbarrier` 状态视图,展示 arrival counter、phase bit,以及 `init`、`arrive` 和 `wait` 操作;点击字段可以聚焦。* + +barrier 从初始化开始。在 `init` 期间,kernel 设置这个 barrier 应该期望多少个 arrival。 +barrier 从 phase 0 开始,counter 被加载为预期 arrival count。从那时起,barrier 就在等待所有必需的 producer +或某个资源的使用者报告自己已经完成。 + +arrival 会减少 barrier 仍在等待的工作量。kernel 的不同部分可以用不同方式 arrive 到 barrier,而这种区别很重要。 + +对于 TMA load,常见 arrival path 是 tx-count arrival。像 `mbarrier.arrive.expect_tx(bytes)` 这样的操作会做两件事: +第一,它算作 issuing thread 在 barrier 上的 arrival。第二,它记录 TMA engine 预计传输的字节数。 +barrier 不会仅仅因为 issuing thread 已经 arrive 就完成。它还会等待 TMA engine 随着传输结束把 byte count drain 掉。 +只有两个条件都满足时,phase 才会翻转:普通 arrival count 到达零,pending tx byte count 也到达零。 + +这就是为什么不应该把 `expect_tx` 理解为“又一个普通 arrival”。它为异步 copy 设置 byte budget。 +硬件稍后通过 complete-tx update 记账实际 copy completion。只有 arrival 和 byte transfer 都完成时,barrier 才完成。 + +对于 Tensor Core 工作,arrival path 不同。`tcgen05` MMA 不会仅仅因为 MMA 已经发射就自动推进 barrier。 +kernel 必须显式地把 barrier arrival 附着到 commit path 上,例如使用 `tcgen05.commit.mbarrier::arrive` 操作。 +当这个 committed group 完成时,Tensor Core 侧会执行 barrier arrival。如果 kernel 忘了这个 commit arrival, +等待 barrier 的 consumer 会永远等下去。 + +普通 thread 也可以直接 arrive 到 barrier。当普通 thread code 是 producer,或一组 thread 在宣布自己已经用完某个资源时,会使用这种方式。 +例如,consumer 读完 shared-memory buffer 后,可以 arrive 到一个 barrier,告诉 producer 这个 buffer 可以复用了。 + +waiting 是同一协议的 consumer 侧。consumer 会等待,直到 barrier 完成当前 iteration 所期望的 phase。 +只有这时,读取数据或复用该 barrier 保护的资源才是安全的。 + +重要的一点是,异步硬件不仅会跑在程序前面;它也会通过 barrier 把 completion 报告回来。 +TMA 可以 signal 一个 shared-memory tile 已经 ready。Tensor Core 工作可以 signal TMEM 结果已经 ready。 +普通 thread 可以 signal 某个 buffer 不再被使用。barrier 给这些情况统一了 producer-consumer 形状: +producer arrive,consumer wait。 + +## Phase Tracking + +barrier 通常不会只为一次使用而分配。pipelined K-loop 可能执行同一个 handoff 数百次, +如果每次 iteration 都分配新的 shared-memory barrier,就不现实。因此,kernel 会保留一小组固定 barrier, +并随着 loop 推进反复使用它们。 + +phase bit 让这种复用变得安全。 + +```{raw} html +
+ +
+``` +*交互:一个在多个 pipeline iteration 中复用的 barrier,展示 phase bit 如何在每个完成轮次后翻转。* + +每当 barrier 完成当前轮的所有 arrival,它都会翻转 phase:phase 0 变成 phase 1,phase 1 变成 phase 0,如此往复。 +wait 操作会检查 consumer 期望的 phase。这个 expected phase 由 kernel 保存在寄存器中。 +当某个 stage 成功等待一轮后,kernel 会在下一轮使用该 barrier 前切换自己的本地 phase value。 + +这防止 kernel 把旧 completion 误认为新 completion。假设某个 barrier 用于一次 TMA load 并已经完成。 +如果下一个 loop iteration 复用同一个 barrier 却不追踪 phase,consumer 可能观察到上一次 completion, +并错误地认为新的 load 已经 ready。phase bit 把这两轮分开:iteration 0 等待一个 phase, +iteration 1 等待相反 phase,iteration 2 再次等待第一个 phase,模式持续下去。 + +在真实 pipeline 中,bookkeeping 通常按 stage 进行。kernel 有固定数量的 shared-memory stage, +匹配固定数量的 barrier,以及寄存器中一小组 phase value。随着 loop 前进,每个逻辑 iteration 映射到一个物理 stage, +phase value 告诉 wait 操作它正在等待这个物理 barrier 的哪一轮。 + +这就是为什么后面的 GEMM 代码不需要每个 K tile 一个 barrier({ref}`zh_chap_gemm_async`)。 +它需要每个 reusable stage 一个 barrier,再加上 phase tracking。stage index 选择 shared-memory buffer 和 barrier。 +phase value 区分这个 stage 当前使用和上一次使用。 + +**可以让你的 agent 试试**:给它一个 two-stage pipeline,让它追踪四次 iteration。 +对每次 iteration,列出 stage index、本地 phase value、barrier 何时翻转,以及如果 stage 复用前没有切换 phase 会出什么问题。 + +## 同步规则 + +一旦 barrier 和 phase 机制清楚了,tensor-core kernel 中的同步 pattern 就相当机械。 +每当一条路径产生数据,或释放另一条路径将要消费的资源时,handoff 都必须显式完成。 + +常见有三种情况。 + +第一种情况是 thread code 为异步引擎产生数据。如果 thread 写 shared memory,后续 TMA store 或 MMA 指令会读取这块 shared memory, +kernel 就必须在引擎读取前让 thread 写入可见。这需要合适的 thread-level synchronization 或 fence。 +精确指令取决于 handoff 的 scope,但原因始终相同:引擎不能在 producer thread 完成写入前观察 shared-memory buffer。 + +第二种情况是 TMA 为 MMA 产生数据。TMA load 会异步填充 shared-memory tile。 +MMA 路径不能只因为 TMA 指令已经发射,就推断 tile 已经 ready。 +TMA 操作必须关联一个 `mbarrier`,而 MMA 路径必须在读取 tile 前 wait 这个 barrier。 + +第三种情况是 MMA 为 epilogue 产生数据。`tcgen05` MMA 会异步把结果写入 TMEM。 +在 Tensor Core 完成相关工作之前,epilogue 不能安全读取 accumulator。 +因此 MMA commit path 会 arrive 到一个 completion barrier,epilogue 在读取 TMEM 前 wait 这个 barrier。 + +```{raw} html +
+ +
+``` +*交互:TMA load 通过 `mbarrier` signal completion。MMA 路径在读取 shared-memory tile 前等待 barrier。 +Tensor Core 到 epilogue 的 handoff 形状相同,只是执行 arrival 的不是 TMA,而是 Tensor Core commit path。* + +同一个思想也适用于 resource reuse。barrier 不只是 data-ready signal,也可以是“resource is free” signal。 +在旧 tile 的所有 consumer 都用完它之前,shared-memory stage 不能被覆写。 +在前一个使用者完成读写之前,TMEM region 不能被复用。在这些情况下,arrival 表示“我用完这个资源了”, +wait 表示“现在可以安全地为下一个 stage 复用这个资源了”。 + +这正是阅读 pipelined GEMM kernel 中同步逻辑的正确方式。wait 和 arrive 并不是作为 defensive programming 四处散落。 +每一个都标记一次具体 ownership transfer:tile 变得 ready、accumulator 变得可读,或 buffer 变得可复用。 +一旦识别出这些 handoff,control flow 就会容易跟随得多。 diff --git a/zh/chapter_background/index.md b/zh/chapter_background/index.md new file mode 100644 index 00000000..c69a3541 --- /dev/null +++ b/zh/chapter_background/index.md @@ -0,0 +1,168 @@ +(zh_chap_background)= +# GPU 执行模型 + +:::{admonition} Overview +:class: overview + +- 一个 kernel 会在一套线程层级(thread → warp → warpgroup → CTA → cluster → grid)上运行,并跨越不同的内存空间(寄存器、SMEM、GMEM、TMEM)。 +- 计算被划分到 CUDA core 和 Tensor Core;像 TMA 这样的专用引擎负责搬运供它们消费的数据。 +- 一个 kernel 本质上是一条 pipeline:它把数据暂存到这些内存空间中,并在彼此独立的计算引擎和数据移动引擎之间交接工作;反复出现的目标,是让这些引擎同时保持忙碌。 +::: + +要写出高速 GPU 程序,理解硬件本身以及代码如何在硬件上运行非常重要。本章概览 GPU 的执行模型: +执行工作的线程层级,存放和移动数据的内存空间,以及承担重活的计算引擎和数据移动引擎。 +我们会先逐一介绍这些部件,然后把它们组合进一条 GEMM pipeline 中,从而看清数据和执行如何流经硬件。 +本书后续几乎每一种优化,本质上都是以某种方式在这些相同部件之间安排工作。 + +现代 GPU 还包含许多专门化的硬件单元。为了先建立一个直观印象,在深入每个部件之前,下面的交互式演示展示了 +Blackwell streaming multiprocessor 内部的主要元素。你可以点击各个部分查看细节。 + +```{raw} html +
+ +
+``` +*交互:Blackwell SM,展示其中的 warp/warpgroup、shared memory、Tensor Memory,以及 +Tensor Core 和 TMA 引擎。* + +## 执行层级 + +我们从真正执行工作的线程开始。GPU 并不会把成千上万个线程呈现为一个扁平的池子,而是把它们组织成嵌套层级。 +这样做的原因是,协作会同时发生在几个不同尺度上。每一层的存在,都是为了让某个尺度上的协作更廉价。 +下图展示了 Blackwell 上的线程层级;你可以点击每一层来高亮它。 + +```{raw} html + +``` +*交互:点击某一层:thread → warp → warpgroup → CTA → cluster → grid。* + +- **Thread**:标量执行单元。每个 thread 都有自己的程序计数器和寄存器,并通过它在所属 warp 内的 lane ID 来标识。 +- **Warp**:以 SIMT(*single instruction, multiple threads*)方式执行的 32 个 thread。一个 warp 的各个 lane 会一起发射同一条指令, + 但每个 lane 保留自己的寄存器,也可以被单独 mask 掉;这正是单个 warp 中不同 lane 能够走不同分支的原因。 +- **Warpgroup**:四个连续的 warp,也就是 128 个 thread。Hopper 引入 warpgroup,作为发射 warpgroup 级 MMA(`wgmma`)的单位; + 在 Blackwell 上,它又承担了第二个角色:Tensor Memory 访问的协作单位。128 个 thread 会一起把一个 TMEM tile 移入或移出寄存器。 +- **CTA**(*Cooperative Thread Array*,也就是 CUDA 所说的 thread block):硬件调度的基本单位。 + 一个 CTA 运行在单个 SM 上,并拥有该 SM 内一块私有的 shared-memory 分配。同一个 SM 上可以同时驻留多个 CTA; + 这种情况下,它们会瓜分该 SM 的 shared-memory 容量。 +- **Cluster**:一组相互协作的 CTA,它们可能位于不同的 SM 上。cluster 内的 CTA 可以彼此同步,也可以读写彼此的 shared memory; + 这种能力称为 distributed shared memory。 + +这些层级值得多停留一下,因为不同于更早的架构,Blackwell 的关键操作**并不全都由同一组线程发射**。 +TMA copy 由单个 thread 发起,随后由硬件执行。TMEM 到寄存器的 load 是 warpgroup-distributed 的: +四个 warp 共同协作,每个 warp 移动 TMEM tile 中属于自己的切片。`tcgen05` MMA 由一个被选出的 thread 提交, +而 clustered MMA 会一次跨越两个 CTA。因此,每种操作都有自己的自然粒度;运行该操作的线程集合, +就是我们所说的该操作的 **scope**。scope 是本书反复回到的三个设计元素(scope、layout 和 dispatch)中的第一个。 + +## 内存空间 + +这一层级中的线程能跑多快,取决于数据能多快到达它们手中。因此接下来我们看数据住在哪里。 +不存在一种既大又快的单一内存;物理规律迫使容量和速度之间做取舍。所以 GPU 提供的不是一种内存,而是多种内存, +每一种都在不同的位置取得这种折中;kernel 的工作,就是让数据流经这些内存空间。每个空间都有自己的容量、 +延迟,以及关于谁能访问它的规则。 + +| 内存 | 所属范围 | 作用 | 说明 | +|--------|-----------|------|-------| +| **Global (GMEM)** | 整个 device | 持久化 tensor 存储 | 大容量 HBM,由所有 SM 共享 | +| **Shared (SMEM)** | 每个 CTA(一个 SM) | tile 暂存 | 低延迟 scratchpad;B200 上最高 228 KB/SM | +| **Tensor Memory (TMEM)** | 每个 CTA | MMA accumulator 存储 | Blackwell 新增;供 `tcgen05` 使用 | +| **Register File (RF)** | 每个 thread | 标量和每线程 tile fragment | 很快;保存 epilogue/临时值 | + +按顺序读,这些空间描述了一条路径。本书中几乎每个 kernel 的数据路径都是 +**GMEM → SMEM →(compute)→ registers → SMEM → GMEM**;对于 tensor-core kernel,TMEM 位于这条路径中间, +在数学计算运行时保存 accumulator。 + +在这四者中,**Tensor Memory (TMEM)** 是唯一一个在 Blackwell 之前没有对应物的空间;完整细节会留到 +{ref}`zh_chap_tensor_cores`。不过,现在先理解它的动机很有价值。早期 GPU 把大型 MMA accumulator 保存在寄存器中, +而寄存器是稀缺资源,accumulator 会与其他值竞争。Blackwell 则把 `tcgen05` 的 accumulator 输出写入 TMEM: +这是一个 CTA 作用域的二维 scratchpad,每个 CTA 有 128 个 lane,最多 512 个 32-bit column +(这个数组物理上位于 SM 上)。随后 kernel 必须在 epilogue 之前显式地把 TMEM 读回寄存器。 +这个额外步骤并不是免费的,它带来的两个后果会贯穿全书。第一,TMEM read 是**显式且 warpgroup-distributed** 的, +由一个 warpgroup 的四个 warp 协作完成。第二,TMEM 不同于寄存器,必须被**显式分配和释放**。 + +### 跨 cluster 的 Distributed Shared Memory + +cluster 是这个层级中唯一一个成员可以跨越多个 SM 的层级;这种可达范围带来了一种其他层级没有的内存能力。 +一个 CTA 运行在一个 SM 上,并使用该 SM 的 shared memory,但单个 CTA 的 SMEM 预算有限,而大 tile 通常需要比一个 block +单独能提供的更多 operand 存储,或者更多复用。Hopper 给出的答案是 **thread block cluster**: +一组比独立 block 更紧密协作的 CTA;它们可以一起同步,也可以读写彼此的 shared memory,这种能力称为 +**distributed shared memory (DSMEM)**。Blackwell 保留了 cluster,并在此基础上加入动态调度 +({ref}`zh_chap_clc`)和 2-CTA cooperative MMA。 + +DSMEM 允许一个 CTA 直接寻址并访问另一个 peer CTA 的 shared memory。一个 thread 可以命名 peer 的 SMEM 中的某个位置, +并把一个 tile 从自己的 SMEM 直接 bulk-copy 到对方 SMEM 中;当字节落地后,会触发 completion barrier +({ref}`zh_chap_async_barriers`)。第三部分中的 2-CTA cluster GEMM 正是建立在这个机制之上:它利用 DSMEM 在一对 CTA +之间共享 operand tile,而不需要把数据绕回 global memory。 + +下图展示了 CTA cluster 让额外的 DSMEM hop 成为可能;点击某个部分,可以看到每个 CTA 拥有什么,以及 cross-CTA read +发生在哪里。 + +```{raw} html +
+ +
+``` +*交互:一个 2-CTA cluster,其中每个 CTA 拥有 A 的一半和 B 的一半,通过 cluster(DSMEM)读取对方的 B, +两者共同产生一个 256×256 的输出 tile。* + +## 计算:CUDA Core 与 Tensor Core + +线程以及它们搬运的数据,最终必须在算术单元处相遇。一个 SM 提供的不是一种数学引擎,而是两种不同的数学引擎。 +二者之间的分工塑造了几乎每个 kernel 的写法,并且它们扮演互补角色。 + +- **CUDA core** 是通用 SIMT ALU。它们运行标量和向量指令,用于处理索引算术、elementwise 计算、 + reduction 和控制流,也就是围绕重型矩阵工作的“胶水逻辑”。 +- **Tensor Core** 是固定功能单元,在 *tile* 粒度执行 dense matrix multiply-accumulate, + 用一条指令计算 $D = AB + C$。 + +这种划分之所以重要,是因为 Tensor Core 提供的算术吞吐远高于 CUDA core,FLOP/s 通常高出一个数量级甚至更多。 +因此,dense linear algebra(GEMM、convolution 和 attention)只有运行在 Tensor Core 上,才能接近峰值性能。 +所以,获得性能在很大程度上就是让这些 Tensor Core 持续有数据可算。不同 GPU 世代之间变化的是 Tensor Core +**如何**被编程,以及它们的结果**落在哪里**。Hopper 引入了异步 warpgroup MMA(`wgmma.mma_async`); +Blackwell 的第五代 Tensor Core,即 `tcgen05`,把 accumulator 放在 Tensor Memory 中,而不是寄存器中; +我们会用 {ref}`zh_chap_tensor_cores` 专门介绍它。 + +cluster 以两种方式扩展这些引擎,而这两种方式会在 GEMM 章节中反复出现。**2-CTA cooperative MMA** +让两个 CTA 各自贡献自己的 SMEM operand,共同形成一个更大的 Tensor Core MMA tile。**TMA multicast** +让数据移动引擎的一次 load 同时把同一个 GMEM tile 送到多个 CTA,消除本来由多次独立 load 造成的冗余 global traffic。 +二者都建立在前面介绍的 distributed shared memory 之上。 + +## GEMM 数据 Pipeline + +到目前为止,我们已经分别介绍了各个硬件单元。为了看清它们如何协同工作,可以用一条典型的通用矩阵乘法(GEMM) +pipeline 作为例子。下面的交互式演示展示了三阶段 GEMM tile pipeline 中涉及的单元;点击诸如 `tma load` +这样的动作,可以高亮它穿过各硬件单元时所走的数据路径。 + +```{raw} html +
+ +
+``` +*交互:Blackwell 上的 load → MMA → epilogue pipeline;点击一个动作,追踪它跨硬件单元的数据路径。* + +一个 GEMM tile 会流经三个阶段。 + +1. **Load。** 一个 TMA copy({ref}`zh_chap_tma`)把 A 或 B operand tile 从 GMEM 流式搬入 SMEM。 + 一个 thread 发射这次 copy,并预先记录预计会到达多少字节。当字节落地时,TMA 引擎报告进度; + 只有当所有预期字节都已送达后,completion barrier 才会翻转。 +2. **Compute。** 一个 `tcgen05` MMA({ref}`zh_chap_tensor_cores`)从 SMEM 中读取 operand tile, + 并把乘积累加进一个 TMEM tile。一个被选出的 thread 发射它;数学计算完成后,它会 signal 一个 barrier。 +3. **Epilogue。** warpgroup 把 TMEM accumulator 读回寄存器,把结果 cast 成输出 dtype,然后存到 GMEM; + 这通常会先暂存到 SMEM,再发射一次 TMA store。 + +这样写出来,三个阶段看上去是严格串行的;但慢 kernel 和快 kernel 的全部差异,就在于 **overlap**。 +朴素 kernel 确实会按顺序执行这些步骤(load、wait、compute、wait、store),于是每个引擎在等待前一个引擎时都会闲置。 +快速 kernel 则把它们 pipeline 起来:Tensor Core 正在计算 tile `k` 时,TMA 引擎已经在获取 tile `k+1`, +epilogue 也正在忙着排空 tile `k-1`,因此三个引擎可以同时保持占用。让三个异步引擎安全地相互交接工作, +正是 barrier 和 phase 模型({ref}`zh_chap_async_barriers`)的职责;第三部分的 GEMM 阶梯就是建立在这个模型之上。 + +## 接下来读什么 + +现在我们已经看过高层图景,可以继续阅读深入解释主要机制的章节: + +- {ref}`zh_chap_tensor_cores` 详细解释 `tcgen05` 计算和 Tensor Memory。 +- {ref}`zh_chap_tma` 介绍基于 TMA 的异步数据移动。 +- {ref}`zh_chap_async_barriers` 介绍用于协调这些引擎的 mbarrier 和 phase 模型。 diff --git a/zh/chapter_clc/index.md b/zh/chapter_clc/index.md new file mode 100644 index 00000000..671d7623 --- /dev/null +++ b/zh/chapter_clc/index.md @@ -0,0 +1,111 @@ +(zh_chap_clc)= +# 进阶:Cluster Launch Control + +:::{admonition} 概览 +:class: overview + +- persistent kernel 会保持一组固定 CTA 或 CTA cluster 驻留(通常让规模大致达到每个 SM 一个活跃 work owner,但不依赖保证的 1:1 映射),并让它们循环处理许多 output tile,而不是每个 tile 启动一个 CTA。 +- Cluster Launch Control 是 Blackwell 的硬件机制,允许驻留 cluster 在运行时请求另一个 tile。它是一条围绕两条 PTX 指令构建的硬件 work-stealing 路径:一条指令请求工作,另一条读回请求是否成功。 +- 主要收益是更好的 tail behavior。当 tile 成本不均,或者 tile 数量不能均匀分配到可用 SM 时,提前完成的 CTA 可以拉取更多工作,而不是闲置。 +::: + +persistent GEMM 不会把 CUDA grid 当成固定的“每个 output tile 一个 CTA”的 launch。 +相反,它启动一组更小的、长生命周期的 CTA 或 CTA cluster。每一个计算一个 tile,前进到另一个 tile,再次计算, +并持续执行,直到输出空间完成。这正是 {ref}`zh_chap_gemm_advanced` 中逐步构建的执行模式。 + +一旦 kernel 是 persistent 的,主要调度问题就变得很简单:当一个 CTA 或 cluster 完成当前 tile 后,下一个 tile 从哪里来? + +最简单的答案是静态公式。例如,kernel 可以从 CTA id 计算 tile coordinate,然后按 grid stride 前进。 +这很容易实现,并且当所有 tile 成本大致相同、tile 数量能均匀分布到 GPU 上时效果很好。 +但 schedule 是在实际工作运行前决定的。如果少数 tile 花费更久,或者最后几个 tile 分配不均, +有些 SM 会提前完成自己的份额,而另一些仍在处理 tail。 + +Cluster Launch Control,即 CLC,会改变这个调度模型。persistent cluster 不再预先决定整个 assignment, +而是可以向硬件 grid scheduler 请求另一个尚未 launch 的 cluster 的工作。如果请求成功,当前 cluster 接管那个 cluster coordinate, +并计算对应 tile。如果请求失败,就没有更多工作可偷,loop 退出。 + +这与 thread block cluster 本身不是一回事。thread block cluster(一起 launch 的 CTA,具有 cluster-level synchronization, +并能访问 distributed shared memory)是在 Hopper 中引入的({ref}`zh_chap_background`)。 +CLC 是 Blackwell 增加的机制,让这些 cluster coordinate 上的调度变为动态。 +cluster 已经是 launch 单位;CLC 让已经运行的 cluster 可以取消一个 pending launch,并继承它的坐标。 + +## 两条指令 + +Cluster Launch Control 通过两条 PTX 指令暴露。第一条指令向 grid scheduler 发送异步请求,第二条指令读取响应。 + +请求指令是 `clusterlaunchcontrol.try_cancel.async`。 + +`try_cancel` 会要求 scheduler 取消一个 pending cluster 的 launch,并把该 cluster 的坐标返回给调用者。 +响应会作为 16-byte record 写入 shared memory。由于请求是异步的,指令不会等待响应到达。 +completion 会通过 `mbarrier` 报告,使用与 TMA 相同的 barrier-and-phase 模型。 + +这是一个重要细节,因为它意味着 CLC 没有引入新的等待模型。kernel 发射请求,把它关联到一个 barrier, +随后在读取响应前等待 barrier。响应到达通过带 byte-count completion 的 barrier signal, +整体风格与其他异步硬件操作相同(见 {ref}`zh_chap_async_barriers`)。 + +一旦 barrier 触发,kernel 使用 query 指令。 + +第一个 query 是 `clusterlaunchcontrol.query_cancel.is_canceled`。它返回一个 predicate,告诉 kernel cancel 是否成功。 +predicate 为 true 表示 scheduler 找到了一个 pending cluster launch、取消了它,并返回了其坐标。 +predicate 为 false 表示没有剩余 pending work 可取。 + +只有当 `is_canceled` 为 true 时,kernel 才应该读取 coordinate。它通过 +`clusterlaunchcontrol.query_cancel.get_first_ctaid` 完成这件事,该指令提取被取消 cluster 的第一个 CTA id。 +这个 CTA id 是 coordinate vector,通常读作 `(x, y, z)`,kernel 会把它 decode 成接下来应该计算的 output tile。 + +这个协议里没有数值形式的 sentinel tile id。kernel 根据 predicate 分支。如果 predicate 为 true,coordinate 有效。 +如果 predicate 为 false,work-stealing loop 结束。 + +在底层,这个形状直接来自 CLC 正在做的事。硬件不是从软件队列中分配一个抽象 task; +它是在取消一个尚未发生的 cluster launch。因此,成功响应包含一个真实 cluster coordinate; +失败响应只是表示 launch queue 已经耗尽。 + +## Work-Stealing Loop + +有了这两条指令,persistent scheduler 就变成一个短 loop。 + +在 loop 的任意时刻,cluster 都有一个自己负责计算的 tile。在开始这个 tile 之前,它会为下一个 tile 发送 `try_cancel` 请求。 +请求异步运行。当 scheduler 处理这个请求时,cluster 计算自己的当前 tile。 + +当前 tile 完成后,cluster 会等待与 `try_cancel` 响应关联的 `mbarrier`。 +响应 ready 后,它调用 `query_cancel.is_canceled`。如果 predicate 为 true,它调用 `query_cancel.get_first_ctaid`, +decode 返回的 coordinate,并把它作为下一个 tile。如果 predicate 为 false,就没有剩余工作,cluster 退出。 + +代码形态上,这个 loop 是: + +1. 为可能的下一个 tile 发射 `try_cancel`; +2. 在请求 in flight 时计算当前 tile; +3. 等待 response barrier; +4. 查询 cancellation 是否成功; +5. 要么用返回的 coordinate 继续,要么退出。 + +请求的位置正是这个 loop 有用的原因。cluster 不会等当前 tile 完成后才请求更多工作。 +它先请求,再计算。这样就把 scheduler request 与有用工作 overlap 起来。 +当当前 tile 完成时,下一个 tile 的答案往往已经可用。 + +这与 persistent kernel 在其他地方使用异步 copy 和 tensor-core barrier 的基本原因相同: +kernel 避免把长延迟操作直接放到 critical path 上。CLC 把同样想法应用到 tile scheduling: +提前请求下一份工作,计算当前工作,然后在需要时消费调度结果。 + +## 与 Persistent GEMM 的关系 + +{ref}`zh_chap_gemm_advanced` 中的 persistent GEMM 在主线讲解中使用 static scheduler。 +static scheduler 更容易解释,因为下一个 tile 可以直接从 loop state 计算出来。 +例如,像 `ClusterPersistentScheduler2D` 这样的 scheduler 可以在 output tile space 上用 grid-stride pattern 分配 tile。 + +CLC 是这种 static assignment 的动态替代。outer loop 保持不变:每个 resident cluster 反复计算一个 output tile, +然后前进到另一个 tile。变化的是下一个 tile 从哪里来。使用 static scheduler 时,下一个 tile 由公式计算。 +使用 CLC 时,下一个 tile 由硬件 work stealing 返回。 + +这种差异在 launch tail 附近最重要。在 static schedule 中,剩余工作可能分布不均。 +有些 SM 可能已经耗尽 assigned tile,而其他 SM 仍有几个 tile。使用 CLC 时,提前完成的 cluster 会请求另一个 pending cluster coordinate。 +只要 launch queue 中还有工作,提前完成者就会继续拉取更多 tile。 + +当 tile cost 不均匀时,这也很重要。一些 GEMM tile 可能因为边界、masking、sparsity、grouped scheduling, +或主矩阵乘法周围的 fused work 而走不同路径。static schedule 在观察到这些成本之前,就假设 tile assignment 足够好。 +CLC 不需要这个假设。它只在某个 cluster 变得可用之后,才分配更多工作。 + +因此,在 TIRx 中,CLC 可以暴露为 dynamic tile scheduler。编程模型不需要改变 tile 的计算。 +tile body 仍然是 static scheduler 使用的同一个 persistent GEMM body。scheduler 从“用公式计算我的下一个 tile coordinate” +变成“向硬件请求下一个可用 cluster coordinate”。结果仍然是同一个 persistent loop, +但工作分布由硬件驱动,而不是由固定 launch-time schedule 决定。 diff --git a/zh/chapter_data_layout/index.md b/zh/chapter_data_layout/index.md new file mode 100644 index 00000000..5b299eba --- /dev/null +++ b/zh/chapter_data_layout/index.md @@ -0,0 +1,256 @@ +(zh_chap_data_layout)= +# 数据布局及其记法 + +:::{admonition} 概览 +:class: overview + +- *数据布局*把 tensor 的逻辑索引映射到物理位置,并决定 coalescing、bank conflict,以及某个引擎能否读取一个 tile。 +- 本书用一种记法书写布局:`S[(shape) : (strides)]`,并配合 named axes(`@laneid`、`@TLane` 等)以及用于 broadcast 或复制数据的 replication 项 `R[...]`。 +- Swizzle 是一种对地址做 XOR 重映射的机制,用来消除 shared-memory bank conflict。 +::: + +同一组数字,如果以不同的物理排列写入内存,在同一块 GPU 上的运行速度可能相差一个数量级。 + +原因在于,tensor 的逻辑索引并不会说明它的字节实际位于哪里。硬件对这个位置极其敏感: +它决定了 32 个 lane 的 load 是 coalesce 成一次 transaction,还是散成 32 次; +决定了它们的地址是落在不同 memory bank 中,还是碰撞并串行化; +甚至决定了一个 tile 的字节排列是否能被 Tensor Core 读取。 + +机器学习程序通常用逻辑 shape 来描述 tensor。**数据布局**补上缺失的物理部分: +它说明具有逻辑索引 `(i, j, …)` 的元素住在哪里,是在内存、寄存器,还是某种其他硬件存储中。 + +本章介绍现代 GPU 编程中出现的主要布局。为了让讨论可控,我们发展出一种紧凑的**记法**, +用它描述机器学习系统会遇到的多种场景。最后我们会讨论 **swizzling**: +它是一种让同一个 tile 的按行访问和按列访问都能同时高效的机制。 + +## Shape–Stride 模型 + +在进入 GPU 特有布局之前,值得先从最简单的布局开始,因为本章后面的所有内容都建立在它之上。 +从核心上说,一个 layout 只有两部分:一个 **shape**,以及一组匹配的 **strides**。 +我们把这对信息写成 `S[(shape) : (strides)]`;要找到某个逻辑索引的位置,只需把该索引与 strides 做点积。 +例如,一个 row-major 的 4×4 矩阵可以写成: + +```text +S[(4, 4) : (4, 1)] addr(i, j) = i·4 + j·1 +``` + +这不过是经典 shape/stride 模型的一种紧凑写法(也是 CuTe 记法的 row-major 简化版),后续一切都从它构建出来。 + +事实上,你几乎肯定已经用过这个模型。任何写过 PyTorch 或 NumPy 的人都用过,因为这些库里的 tensor +本质上就是一个 shape,加上一组作用于扁平 storage buffer 的 stride: + +```python +import torch +t = torch.arange(12).reshape(3, 4) +t.shape # torch.Size([3, 4]) +t.stride() # (4, 1) ← exactly S[(3, 4) : (4, 1)] +``` + +一旦你这样看待 tensor,就会明白为什么许多“reshape”操作根本不触碰数据。 +它们只是重写 strides,并返回同一份 storage 上的一个 **view**。最清楚的例子是 transpose,也就是 permute: + +```python +tt = t.permute(1, 0) # or t.T +tt.shape # torch.Size([4, 3]) +tt.stride() # (1, 4) ← strides swapped, no data moved +tt.data_ptr() == t.data_ptr() # True, same bytes +``` + +这里,`t.permute(1, 0)` 是同一块内存上的 `S[(4, 3) : (1, 4)]`: +transpose 纯粹是 stride 的变化,没有移动任何一个字节。对 contiguous tensor 做 `reshape` 或 `view` 也是同样故事: +在旧 storage 上给出新的 shape 和新的 strides。(NumPy 的行为完全相同;唯一差别是它的 `.strides` +以字节为单位,而不是以元素为单位。) + +GPU 上的 layout 正是这样工作的。本章剩余内容其实都是同一个思想的各种变体: +一个 tile 的映射(无论映射到内存,还是通过稍后介绍的 named axes 映射到 lane 和寄存器)都是固定 buffer 上的一条 stride 规则, +所以重新排列 tile 通常是改变 *layout*,而不是 copy。不过,我们也要小心这种推理的边界。 +zero-copy 的故事对于单一线性地址空间上的逻辑 view 非常清晰;但在 GPU 上,只有当新的 view 与既有字节排列和 ownership +安排兼容时才成立。一旦你改变某个元素由哪个 thread 或 register 拥有,或者改变 SMEM swizzle, +通常就需要真实的数据移动:load、store、shuffle、`ldmatrix`、transpose。 + +## Tile Layout + +到目前为止,我们描述的是整个 tensor 的 layout。不过,GPU kernel 很少一次操作整张矩阵; +它们处理更小的 tile,而这些 tile 会由硬件的不同部分 load、transform 和 compute。 +好消息是,tiling 并不需要新概念。它仍然只是一个 layout,只是现在多写了几个维度。 +把一个 8×8 矩阵切成 2×4 的 tile,就得到一个 4-D layout,其坐标为 +`(tile_row, row_in_tile, tile_col, col_in_tile)`,并选择 strides 让每个 tile 保持 contiguous: + +```text +S[(4, 2, 2, 4) : (16, 4, 8, 1)] +``` + +一个逻辑 `(i, j)` 会先变成 `(i//2, i%2, j//4, j%4)`,然后通过 strides 计算地址。 +值得注意的是,这个记法完全不需要特殊的“tile”概念就能表达 tiling: +它仍然是前面的 shape–stride 模型,只是把索引拆成了外层和内层坐标。 + +下面的交互式可视化展示了逻辑矩阵索引如何被分解成 tile 坐标,然后映射到物理地址。 + +```{raw} html + +``` +*交互:点击一个单元格,查看它的 tiled index 和 address。* + +## Named Axes + +到目前为止,`S[...]` 中的每个 stride 都表示线性内存中的 offset,而我们也把 address 当成内存中的位置。 +但在 GPU 上,数据可以住在不止一个地方:除了内存,一个 tile 也可能分散在 warp lane、thread register, +或者 TMEM lane 和 column 之中。为了统一描述这些情况,我们用 **named axes** 扩展记法。 +思路是让每个 stride 系数携带一个轴标签,说明它沿着哪个空间移动: +`@m` 表示普通内存,`@laneid` 表示 warp lane,`@reg` 表示寄存器,`@warpid` 表示 warp, +`@TLane` / `@TCol` 表示 TMEM 坐标。有了这些标签,单个 layout 不仅能描述数据位于内存何处, +还能描述它如何分布在负责操作它的硬件资源上。 + +一旦显式标出 memory tag,内存中一个 row-major 的 8×16 tile 就只是: + +```text +S[(8, 16) : (16@m, 1@m)] +``` + +当 layout 描述的不是内存中的排列,而是*跨 thread 分布*的数据时,这些 tag 就开始发挥价值。 +以 `S[(8, 4, 2) : (4@laneid, 1@laneid, 1@reg)]` 为例:它不是指向线性内存, +而是把行和列映射到 lane ID 以及每个 lane 的一个寄存器。这里的 `laneid` 表示 warp 内的 lane index, +即 `thread_index % warp_size`。这正是你会在 {ref}`zh_chap_layout_generations` 中遇到的 tensor-core register fragment。 + +下面的交互式可视化展示了 layout 如何把 tensor 元素分布到 warp lane 和 per-lane register 上, +而不是把它们放在线性内存中。 + +```{raw} html + +``` +*交互:一个位于 `@laneid` 和 `@reg` 上的 layout;点击一个单元格,查看哪个 lane/register 持有它。* + +## Distributed Layout + +named axes 之所以有用,是因为它们让我们能在系统的许多层级上统一描述 placement, +甚至包括*跨整个 device* 的 placement。我们刚刚把它们用于单个 GPU 内部的 lane 和 register, +但同一个思想也可以向外延伸:像 `@gpuid_x` 和 `@gpuid_y` 这样的轴可以说明数据位于 GPU mesh 的哪里, +于是这个记法也能捕捉分布式训练和推理中出现的 sharding pattern。 +这些轴尚未捕捉到的一件事是 *replication*,也就是数据被复制到不止一个位置。 +因此我们加入记法 `R[n : stride]`,其中 `R` 标记 replicated dimension。 +例如,`R[2 : 1@gpuid_x]` 描述沿 `@gpuid_x` 轴的 replication。把二者合在一起, +一个表达式就能同时把 tensor shard 到 2×2 GPU mesh 上,并沿一个轴复制它: + +```text +S[(2, 4, 8) : (1@gpuid_y, 8@m, 1@m)] + R[2 : 1@gpuid_x] +``` + +下面的演示在一个小型 GPU mesh 上展示这种 partition-and-replication 组合模式。 +点击任意单元格,可以看到哪个 device 持有它;也可以观察 `@gpuid_x` replication 如何把相同副本放到配对 device 上。 +按钮可以在 fully-sharded、shard + replica 和 shard + offset layout 之间切换。 + +```{raw} html + +``` +*交互:一个分布在 2×2 GPU mesh 上的 layout;点击一个单元格,查看哪些 device 持有它。* + +### Kernel 内部的 Replication Pattern:TMEM 中的 Scale Factor + +我们刚刚为 GPU mesh 引入的 replication dimension `R[...]`,并不只与多个 device 有关。 +同一个结构也能描述完全发生在单个 kernel 内部的事情:硬件把数据*跨 lane broadcast*。 +Blackwell 的 block-scaled MMA({ref}`zh_chap_layout_generations`)就是一个很好的例子。 +它的 scale factor 位于 TMEM 中,其中一个 128-row scale vector 只存储在 **32 个 TMEM lane** 中: +逻辑行 `r` 会去到 TMEM lane `r % 32`,而 `r // 32` 沿 column 方向展开。 +这 32 个已存储的 TMEM lane 随后会**沿 TMEM `TLane` 轴复制**,从 32 个扩展到 128 个 TMEM lane, +让读取 warpgroup 中四个 warp 的每一个,都能在自己的 32-lane TMEM window 中找到一份副本。 +这是一种 `warpx4` broadcast,我们用 replication dimension 来书写它。读取本身由这些 warp 的 thread 执行: + +```text +S[(32, …) : (1@TLane, …)] + R[4 : 32@TLane] +``` + +这会给出四个副本,副本之间相隔 32 个 TMEM lane:TMEM lane `l`、`l+32`、`l+64` 和 `l+96` +都持有同一个 scale。和之前一样,replication dimension 不携带新数据;它只是说“同一个值,位于四个 TMEM-lane 位置上”, +就像刚才 `@gpuid_x` 把一行 broadcast 到 GPU mesh 上一样。 + +下面的交互式演示把两个步骤放在一起展示:先紧凑 pack 到 32 个 TMEM lane 中,然后通过 `warpx4` +broadcast 到 128 个读取 lane。 + +```{raw} html + +``` +*交互:点击一个 scale factor `SFA[m, sf]`;它会 pack 到 TMEM 的 lane `m mod 32`、column `(m // 32)·4 + sf`, +然后沿 `TLane` 轴通过 `warpx4` broadcast 到四个 lane 副本(`l`、`l+32`、`l+64`、`l+96`),每个 warp 的 32-lane window 各一份。* + +每个 column 内部的 byte packing(`scale_vec` 的 1X/2X/4X 模式)以及 `cta_group::2` split +会在 {ref}`zh_chap_layout_generations` 中介绍。 + +已经熟悉 CuTe 的读者,可以把本章记法理解为它的一个 row-major 变体: +我们在其上扩展了显式的 hardware-named axes,以及专门的 replication 结构。 + +## Swizzle Layout + +本章最后一种 layout 是为了解决一个具体的硬件问题。GPU 上的 shared memory 被组织成多个 memory bank; +当不同 lane 落到不同 bank 上时,访问最快。相反,如果多个 lane 访问的是*同一个* bank 内的不同地址, +硬件别无选择,只能把它们串行化,于是我们就要付出 **bank conflict** 的代价。 + +在 tensor 程序中,这很难避免,因为内存访问并不是纯线性顺序。处理矩阵时,我们经常需要读取同一个 tile 的行切片和列切片, +这就产生了真实的张力:对按行访问高效的 layout,往往会让按列访问产生 bank conflict;偏向列的 layout 又会伤害行访问。 +**Swizzling** 正是为打破这种张力而设计的技术。 + +swizzle 背后的想法是置换地址映射,通常做法是把 column index 与 row 做 XOR, +让按行和按列访问最终都分散到多个 bank 上。它提供的 conflict-free 保证是有条件的: +只对匹配的元素宽度、swizzle mode 和访问模式(也就是某个引擎的 descriptor 所期望的模式)成立, +并不适用于任意元素宽度或对齐方式。 + +下面第一个交互式演示把这一点具体化。点击一个 column index,观察每个元素落到哪个 bank 中: +左侧朴素 row-major tile 中,一列会把全部八个元素汇入同一个 bank,因此 read 会串行化为八个 cycle; +右侧的 XOR-swizzled layout 中,同一列会分散到八个不同 bank,只需一个 cycle 即可读取。 + +```{raw} html + +``` +*交互:一个 8×8 tile;朴素 row-major 中按列访问会产生 bank conflict,XOR swizzle 后则 conflict-free。* + +这个小小的 8×8 例子抓住了核心思想,但真实 GPU 内存的 bank 数量远多于这个玩具图所暗示的数量。 +为了让 swizzling 在完整尺度上工作,我们不会把整个 tile 当成一个单体对象。相反,我们把内存切成小 segment, +并在每个 segment 内应用 swizzle pattern。实践中最常见的情况是 `SWIZZLE_128B`, +它围绕 128-byte segment 组织,使同样的 row/column-remapping 技巧能够自然适配 32-bank memory system。 + +下面的交互式演示展示一个具体的硬件 swizzle:`SWIZZLE_128B`。这样在推广到多种格式之前, +你可以先看到逐 segment 重复的 pattern。 + +```{raw} html + +``` +*交互:128-byte segment 内部的 `SWIZZLE_128B` pattern;逐步查看 read cycle,观察 `physical_sector = logical_sector XOR row` 如何把每一列分散到不同 bank。* + +同一个想法可以扩展到这个 128-byte 情况之外。为了简化可视化,接下来我们会用一个单色块表示一个 segment, +而不是画出每个 bank。一般来说,硬件会定义一个小的重复 **atom**,permutation 会应用在这个 atom 上; +不同 swizzle mode 会选择不同 atom 大小。`SWIZZLE_128B` 使用 8 × 128 B atom, +`SWIZZLE_64B` 使用 8 × 64 B atom,`SWIZZLE_32B` 使用 8 × 32 B atom; +随后整个 tile 会由当前使用的 atom 平铺而成。 + +最后一个交互式演示允许你在这些格式之间切换(包括 16 B interleaved mode)、选择数据类型, +并悬停任意单元格,直接检查一个 atom 内部的元素排列。对于推理某条 load/store 指令期望哪种 swizzle, +这正是合适的细节层级。 + +```{raw} html + +``` +*交互:选择一种 swizzle format(以及数据类型),查看它的 atom shape(8 × N B);悬停某个单元格,查看其中元素如何被置换。* + +应该选择哪种模式?经验法则是优先选择 tile 能填满的*最大* atom。一个 N-byte atom 要求 tile 的 contiguous dimension +至少为 N 字节,并且是 N 的倍数。因此,`SWIZZLE_128B` 只在一行跨度至少为 128 字节, +也就是 64 个 `float16` 元素时适用。如果能适配,它就是默认选择,因为它的 8 × 128 B atom 覆盖完整的 128-byte bank line, +从而一次把一列分散到全部 32 个 bank 上,在 fp16 中可以同时对 8 行和 8 列提供 conflict-free 访问。 +不过,当问题 shape 迫使 contiguous dimension 较小时,tile 就无法再填满 128 B atom; +此时你会降到 `SWIZZLE_64B` 或 `SWIZZLE_32B`,也就是该行仍然能覆盖的最大 atom。 + +你永远不需要手工算出这些置换后的地址;但有必要精确说明 swizzle 与 `S[...]` 记法之间的关系: +它*不是*那个 affine map 的一部分,而是叠加在其上的一个独立、非仿射层。`S[...]` layout 把元素放到线性内存 +(`@m`)地址上,随后 swizzle 置换该地址。在 TIRx layout API 中,这写作 +`ComposeLayout(swizzle, tile)`({ref}`zh_chap_tirx_layout_api`)。你的任务只是为每个会接触这个 tile 的 op +选择一种一致的模式,然后让 composed layout 完成其余工作。 + +硬件填充的也是这个 composed layout,这正是 swizzling 和 tiling 汇合的地方。TMA descriptor 是多维的, +所以单个三维 box 可以同时描述 tile 的 atom tiling 以及每个 atom 内的 swizzle; +一次 TMA load 随后会按 atom 布置 tile,并在写入 shared memory 时完成 swizzle({ref}`zh_chap_tma`), +不需要单独的 swizzling pass。每个引擎要求*哪一种* swizzle 是 generation-specific 的,这正是下一章的主题。 diff --git a/zh/chapter_flash_attention/index.md b/zh/chapter_flash_attention/index.md new file mode 100644 index 00000000..7956b79f --- /dev/null +++ b/zh/chapter_flash_attention/index.md @@ -0,0 +1,607 @@ +(zh_chap_flash_attention)= +# Flash Attention 4 + +:::{admonition} 概览 +:class: overview + +- Attention 会运行两个 MMA,并在它们之间插入 softmax,因此它不能像 GEMM 那样简单地重复同一个 MMA。 +- 这个 kernel 把 Part I 中的硬件原语(TMA、`tcgen05`、TMEM、barrier)和 Part III 中的 GEMM 技术组合起来:warp 角色分工、online-softmax rescaling、causal masking 和 GQA。 +::: + +Attention 是决定 transformer 能不能高效运行的核心 kernel,也是前面构建的所有机制终于汇合的地方。我们为 GEMM 组装过的每个组件都会延续到这里:TMA tile 搬运、`tcgen05` MMA、TMEM、warpgroup register tile,以及显式 barrier。 + +难点在于,attention 不是简单重复一个 MMA。它是两个 MMA,中间夹着真正的计算:online softmax、causal masking,以及把早期和后续 block 维持在同一尺度下的 rescaling。 + +新的复杂度正藏在这个中间阶段。普通矩阵乘只需要往 accumulator 里加;attention 则必须在新的 key 和 value 持续流入时,回头重访并重新缩放已经算过的结果。softmax 本身也运行在两个 Tensor Core MMA 之间的 CUDA core 上,因此指数运算和逐行规约直接落在关键路径上。 + +这就是为什么 attention 优化很大一部分其实是 softmax 优化:重写 `exp`,并把 softmax 与 MMA 重叠起来,而不是让 MMA 停下来等待它。 + +本章的目标不是从零重新推导 Flash Attention。我们会保留足够的算法视角,让 kernel 能读懂;然后把注意力放在真正新的部分:这个算法如何落到 TIRx 上。 + +最清晰的入口,是跟随一个 tile 在 kernel 中的流动。`Q`、`K` 和 `V` 作为输入 tile 进入 kernel,从 GMEM 加载到 SMEM。score MMA 将 `Q` 和 `K` 相乘,得到 TMEM 中的 score tile `S`。softmax 把 `S` 变成 numerator tile `P`,value MMA 再组合 `P` 和 `V` 来更新输出 accumulator `O`。 + +到这里为止,它看起来像是两个矩阵乘粘在一起。但它有一个 GEMM 不必处理的转折:每当运行中的 softmax 最大值发生变化,已经累计到 `O` 里的结果就突然处在了错误的尺度上。它必须先被重新缩放,下一次 value MMA 才能安全地加进去。下面几节会先追踪这条路径,然后再展示 TIRx 如何把每个阶段交给对应的 warpgroup,并把这些阶段串起来。 + +## 算法形状 + +在把 tile 放进内存之前,我们需要先看清这些 tile 服务的算法。对于一个 query block,Flash Attention 计算: + +$$O = \text{softmax}(QK^{\top} / \sqrt{d})V$$ + +按字面理解,这个公式会先形成完整的 score 矩阵 `S = QKᵀ`,对它做 softmax,然后再乘以 `V`。这恰恰是我们不能采用的做法,因为完整的 `S` 非常巨大。seq=4096 时,每个 head 大约有 16M 个元素,fp32 下约 64 MB,远远超过 SMEM 或单个 128×512 TMEM 区域的容量。片上根本没有地方放它。Flash Attention 的答案是完全不物化 `S`。它改为按 block 流式读取 `K/V`,并维护三个逐行运行状态,用来概括目前为止看过的全部内容: + +- `row_max`:到目前为止看到的最大 score。 +- `row_sum`:softmax 分母的运行和。 +- `O`:运行中的输出 accumulator。 + +流式更新负责让这些状态在新 block 到来时仍然正确。微妙之处在于,每处理一个 block,运行中的最大值都可能升高;一旦升高,所有在旧最大值尺度下计算出的内容都落在了错误尺度上。因此在加入新的贡献之前,我们先把旧状态拉回到新的尺度: + +```text +S = Q_block @ K_block.T +m_new = max(row_max, rowmax(S)) +scale = exp((row_max - m_new) / sqrt(d)) +P = exp((S - m_new) / sqrt(d)) +row_sum = row_sum * scale + rowsum(P) +O = O * scale + P @ V_block +row_max = m_new +``` + +单个 `scale` 因子在这里一鱼两吃:它同时重新缩放运行中的分母和运行中的输出,让早先 block 与后续 block 的贡献最终都落在同一个尺度上。 + +上面的伪代码使用自然 `exp`,并显式写出 `/sqrt(d)`,因为这样最好读;但 kernel 采用了更便宜的路径。它把 `1/sqrt(d)` 和 `log2(e)` 合并成一个常量 `scale_log2 = log2(e)/sqrt(d)`,然后用硬件 `exp2` 在原始 score 上计算所有指数,利用恒等式 `exp(x/sqrt(d)) = exp2(x · scale_log2)`。动机很简单:在这类硬件上,`exp2` 比自然 `exp` 更快。 + +继续往下之前,有一点值得钉牢:这里的 `P` 不是最终归一化后的 attention 矩阵。它只是当前 K/V block 的 softmax 分子。归一化被刻意推迟,只有最后一个 block 处理完之后,kernel 才写出 `O / row_sum`。 + +对 TIRx 来说,知道算法算什么只是一半;另一半是 kernel 运行时每个 tile 住在哪里,因为这决定了 layout 和 barrier 代码。`S`、`P` 和 `O` 都是 tile 值,而且各自有自己的家: + +- `S` 是 score tile。score MMA 将它写入 TMEM。 +- `P` 是 softmax numerator tile。softmax 从 TMEM 把 `S` 读入寄存器,计算 `P = exp((S - m_new) / sqrt(d))`,再把 `P` 写回 TMEM。 +- `O` 是输出 accumulator tile。value MMA 从 TMEM 读取 `P`、从 SMEM 读取 `V`,然后累计到 TMEM 中的 `O`。 + +前面提到的 rescale 也是一个 tile 操作,而不是一段标量记账:当 `row_max` 变化时,旧的 `O` 会从 TMEM 读出,在寄存器中相乘,再写回 TMEM,然后下一次 value MMA 才会继续累加。后续每一节都会沿着同样的结构展开:tile 的位置、硬件路径,以及证明下一个 consumer 可以运行的 barrier。 + +## Tile-Primitive 图 + +有了运行状态及其位置之后,我们可以把算法展开成一串具体的 tile 移动。对于一个 K/V block,kernel 从上到下走过这条 tile 路径: + +```text +Q, K, V in GMEM + -> Q, K, V in SMEM by TMA load + -> S in TMEM by score MMA: QK^T + -> P in TMEM by softmax numerator: TMEM -> RF -> TMEM + -> O in TMEM by value MMA: P V + -> O in GMEM by normalization, SMEM staging, and TMA store +``` + +它和 GEMM 的区别归结为一行。GEMM 是重复一条 MMA 链;FA4 有两个 MMA 阶段,中间坐着 softmax。后面几乎所有复杂度,都是这个额外阶段带来的后果。 + +如果把上面的短路径展开成显式的 producer-consumer 边,就得到完整图: + +| 阶段 | Tile 移动或计算 | TIRx primitive | 硬件路径 | +|-------|------------------|----------------|----------| +| 加载 Q/K/V | GMEM tile -> SMEM tile | `Tx.copy_async(..., dispatch="tma")` | TMA load | +| Score MMA | SMEM 中的 Q 与 K -> TMEM 中的 score tile `S` | `Tx.warp.gemm_async(..., dispatch="tcgen05")` | `tcgen05.mma` | +| Softmax 读取 | TMEM 中的 `S` -> warpgroup register tile | `Tx.wg.copy_async(reg, tmem)` | `tcgen05.ld` | +| Softmax 写入 | 寄存器中的 numerator tile `P` -> fp16 TMEM view | `Tx.copy_async(tmem_as_f16, reg)` | TMEM store,然后 `tcgen05.wait.st()` | +| Value MMA | TMEM 中的 `P` 与 SMEM 中的 V -> TMEM 中的输出 accumulator `O` | `Tx.warp.gemm_async(..., dispatch="tcgen05")` | 带 TMEM operand 的 `tcgen05.mma` | +| Correction | TMEM 中的 `O` -> 寄存器 -> TMEM 中的 `O` | TMEM readback、寄存器乘法、TMEM store | `tcgen05.ld` / TMEM store | +| Epilogue | TMEM 中的最终 `O` -> 寄存器 -> SMEM -> GMEM | TMEM readback、`Tx.copy`、TMA store | `tcgen05.ld` + TMA store | + +新增的行是 softmax 和 correction。二者都会增加 TMEM -> register -> TMEM 流量,也都会在 score MMA 与 value MMA 之间制造额外的交接。 + +**试着让你的 agent 做一遍**:让它只追踪上面的短路径。对每条箭头,指出 producer 阶段、consumer 阶段、源 tile、目标 tile 和硬件路径。然后再问哪些箭头在 GEMM 章节里并不存在。 + +## Warp 角色与 Scope + +数据路径理清之后,自然的下一个问题是:每个阶段到底由谁来跑。这里每个 CTA 有 4 个 warpgroup,总共 512 个线程;它们不是按接触的数据划分,而是按 warpgroup 执行的工作类型划分: + +- WG3 驱动硬件引擎:TMA load、MMA 和 TMA store。 +- WG0、WG1、WG2 执行这些引擎调用之间的寄存器重计算:softmax、correction 和 epilogue。 + +精确的角色表如下: + +| Owner | 角色 | 做什么 | +|-------|------|--------| +| WG3, warp 1 | TMA load | 从 GMEM 把 Q、K、V tile 加载到 SMEM | +| WG3, warp 0 | MMA | 发出 score MMA 和 value MMA | +| WG3, warp 2 | TMA store | 把最终 O tile 从 SMEM 存回 GMEM | +| WG0 | Q stage 0 的 softmax | 从 TMEM 读取 S,计算 P,把 P 写回 TMEM | +| WG1 | Q stage 1 的 softmax | 对第二个 Q pipeline stage 执行同样工作 | +| WG2 | Correction 与 epilogue | 重新缩放 TMEM 中的 O,做归一化,暂存输出 | + +很容易把“两个 Q stage”误读成两个 attention head,但它们不是。它们只是 Q pipeline 中的两个槽位:WG0 拥有一个,WG1 拥有另一个,因此两个 Q tile 可以同时在路上。这就是 softmax 工作出现两份的原因,一份在 WG0,一份在 WG1。 + +代码用符号坐标选出这些角色: + +```python +wg_id = T.warpgroup_id([4]) +warp_id = T.warp_id_in_wg([4]) +``` + +读 kernel 时,先找角色分支。它会告诉你分支内部每个 tile primitive 归哪个团队所有。 + +- WG3 warp 1 启动 TMA load 命令。一个被选出的 lane 发出 copy,TMA 引擎移动 tile。 +- WG3 warp 0 发出 `tcgen05.mma` 指令。 +- WG0 和 WG1 在完整 warpgroup scope 下运行 softmax。 +- WG2 在完整 warpgroup scope 下执行 correction 与 epilogue。 + +一个不对称性最终塑造了整个 barrier 图:每个 MMA,无论 score 还是 value,都只由 WG3 warp 0 发出。WG0 和 WG1 从不发出 MMA。它们只消费 score tile、运行 softmax,并把 `P` 写回 TMEM。 + +正是这种分离,让 softmax 周围必须有 barrier。`s_ready` 把 score tile 从 MMA warp 交给 softmax;`p_o_rescale` 则交付 `P`,以及一个对 value MMA 来说安全的 `O` 槽位:要么已经完成 rescale,要么因为不需要 rescale 而被释放。后面几节我们会反复回到这两个名字。 + +## 阅读代码片段 + +本章的代码片段摘自 [`flash_attention4.py`](https://github.com/mlc-ai/tirx-kernels/blob/main/tirx_kernels/attention/flash_attention4.py),所以它们不可避免地会引用一些我们没有完整复现的 kernel 内部名称。自解释的名称(`wg_id`、`warp_id`、`BLK_M`/`BLK_N`、`HEAD_DIM`、`kv_stage`、各个 `SMEM_PIPE_DEPTH_*` / `TMEM_PIPE_DEPTH` 深度、`should_accumulate`,以及这里为 1 的 `CTA_GROUP`)会在第一次相关时引入。其余名字先在下表给出一行释义,这样当代码片段突然把一个陌生名字放到你面前时,你有地方可查: + +| 名称 | 含义 | +|------|------| +| `q_stage`, `i_q` | Q pipeline stage,取 0 或 1,也就是哪个 Q tile 槽位(`SMEM_PIPE_DEPTH_Q = 2`)。在 WG0/WG1 softmax 内部,warpgroup 自己的 `wg_id`(0 或 1)就是同一个 stage 索引,因此 `S_region[q_stage]`、`P_region[wg_id]` 和 `O_region[i_q]` 都选择同一个 Q stage | +| `MMA_N` | TMEM 列中的 score/output tile 宽度(128) | +| `MMA_K` | `P`/`V` 列方向的 MMA inner-K 步长(16);`K_SPLIT = 6 * MMA_K = 96` | +| `K_SPLIT` | value-MMA 调度的切分点(见“两段 MMA 阶段”);第一段 value MMA 覆盖列 `0:K_SPLIT`(`6 * MMA_K = 96`) | +| `should_rescale` | WG2 的逐行标志:旧 `O` 是否需要在下一次 value MMA 前 rescale(通过 `any_sync` 在 warpgroup 内规约) | +| `rescale_threshold` | 跳过小幅 row-max 变化的阈值;当前 kernel 使用 `8.0`,跳过 rescale 时会把 `acc_scale` 精确设为 `1.0` | +| `scale_log2` | log2 单位下的 softmax scale,即 `log2(e)/√d`,因此 `P = exp2((S - m) · scale_log2)` | +| `acc_scale` | softmax 通过 SMEM mailbox 传给 WG2 的逐行 rescale 因子 | +| `chunk_start`/`chunk_end`, `p_start`/`p_end` | 正在读取/写入的 32 宽 softmax chunk 的列范围 | + +## 两段 MMA 阶段 + +对每个流式 K/V tile,Flash Attention 都会运行两个 MMA 阶段,并由 softmax 把它们桥接起来: + +```text +Q, K -> score MMA -> S +S -> softmax -> P +P, V -> value MMA -> O +``` + +可以把它看成三个 producer 串成的一条 pipeline。第一个 MMA 产生 attention score `S`,softmax 把 `S` 转成 numerator `P`,第二个 MMA 消费 `P` 来更新输出 accumulator `O`。按 `row_sum` 归一化会一直推迟到 epilogue,等每个 K/V tile 都贡献完之后再做。 + +下面每个 tile op 都会使用 GEMM 步骤中同样的 **scope / layout / dispatch** 卡片,只额外加一行 **handoff**,用来指出把 tile 交给下一个角色的 barrier。 + +计算代码从不直接使用裸 TMEM 列号。kernel 会把唯一的 TMEM 分配切成按 stage 索引的视图(`S_region`、`P_region`、`O_region`),然后用 pipeline stage 访问它们(`S_region[q_stage]`、`O_region[i_q]`、`P_region[i_q, 0:K_SPLIT]`)。这些视图由 [TMEM 布局与复用](#tmem-布局与复用) 一节中的 `T.TMEMStages` 定义;现在只要把每个 region 理解为同一块物理 TMEM 的一个具名切片就够了。 + +### Score MMA + +两个阶段中的第一个是 score MMA,也就是打开每个 K/V iteration 的矩阵乘。它计算: + +$$S = Q_{\text{block}}K_{\text{block}}^{\top}$$ + +并把 `128 x 128` score tile 写入 TMEM: + +```python +Tx.warp.gemm_async( + S_region[q_stage], + Q_smem[q_stage, 0:BLK_M, 0:HEAD_DIM], + K_smem[kv_stage, 0:BLK_N, 0:HEAD_DIM], + dispatch="tcgen05", + cta_group=CTA_GROUP, +) +if T.ptx.elect_sync(): + s_ready.arrive(q_stage) +``` + +我们可以问 GEMM 章节对每个 tile op 问过的同样四个问题:谁运行它、tile 住在哪里、如何 dispatch,以及如何交接: + +> **Tile-primitive 解读:Score MMA** +> - Scope:WG3 warp 0 发出它;一个 elected lane 到达 `s_ready`。 +> - Layout:Q、K 在 SMEM → TMEM 中的 `S`(`S_region[q_stage]`)。 +> - Dispatch:`tcgen05`。 +> - Handoff:`s_ready`(→ softmax)。 + +被选中的单个线程到达 `s_ready`,就是整个交接。它宣告这个 score tile 已经完成,softmax warpgroup 现在可以读取它了。 + +### 两个 MMA 之间的 Softmax + +两个 MMA 之间坐着 softmax,它把 score tile `S` 转成 numerator tile `P`。它的解读卡如下: + +> **Tile-primitive 解读:Softmax** +> - Scope:WG0(Q stage 0)/ WG1(Q stage 1),完整 warpgroup。 +> - Layout:TMEM 中的 `S` → 寄存器 → fp16 TMEM 中的 `P`(`P_region[wg_id]`)。 +> - Dispatch:用 `tcgen05.ld` 读取,用 TMEM store 写入;中间在寄存器中做逐行计算。 +> - Handoff:等待 `s_ready`;到达 `p_o_rescale`(前 96 列)和 `p_ready_2`(最后 32 列)。 + +这个阶段完全没有 GEMM 对应物。WG0/WG1 等待 `s_ready` 上的 score tile 到达,然后每次按寄存器大小的 chunk 从 TMEM 读出: + +```python +Tx.copy_async( + s_chunk[:, chunk_start : chunk_end], + S_region[wg_id, chunk_start : chunk_end], +) +``` + +这是 warpgroup scope 下的一次 TMEM-to-register tile 读取。score 进入寄存器后,softmax warpgroup 按顺序做三件事: + +1. 计算 row max 和 row sum; +2. 计算 softmax numerator tile `P`; +3. 以 fp16 把 `P` 写回 TMEM。 + +最后一步形如: + +```python +Tx.copy_async( + P_region[wg_id, p_start : p_end], + p_chunk[:, p_start : p_end], +) +``` + +为什么已经在寄存器里算完了,还要把 `P` 写回 TMEM?因为 value MMA 需要把 `P` 当作一个 *tile operand*,而 MMA 不能把分散在每个线程里的标量寄存器直接当成矩阵来读。在这个 kernel 中,MMA 可读的 `P` 形态就是 `P_region`,它是 fp16 TMEM alias `tmem_as_f16` 上的一个视图。所以这次写回不是多余搬运;它是在把 `P` 放进下一个 MMA 唯一能消费的形态。 + +### Value MMA + +第二个阶段,也是每个 K/V iteration 的收尾阶段,是 value MMA。它计算: + +$$O = O + P_{\text{block}}V_{\text{block}}$$ + +这个 MMA 运行时,`O` 已经被放进了当前 K/V block 需要的正确状态:第一个 block 上完成初始化,后续 block 上完成 rescale。因此 MMA 只需要累加。它和 GEMM 的区别在于 operand 的位置:A operand 是 TMEM 中的 `P`,B operand 是 SMEM 中的 `V`,accumulator `O` 也在 TMEM 中: + +```python +# 第一段 sub-MMA:列 0:K_SPLIT(P 的前 96 列 / V 的对应行)。 +Tx.warp.gemm_async( + O_region[i_q], + P_region[i_q, 0:K_SPLIT], + V_smem[kv_stage, 0:K_SPLIT, 0:HEAD_DIM], + transB=True, + accum=should_accumulate, + dispatch="tcgen05", + cta_group=CTA_GROUP, +) +# 第二段 sub-MMA 形式相同,accum=True,由 p_ready_2 gate 控制, +# 覆盖剩余列 K_SPLIT:BLK_N。 +``` + +> **Tile-primitive 解读:Value MMA** +> - Scope:WG3 warp 0。 +> - Layout:TMEM 中的 `P` + SMEM 中的 V → TMEM 中的 `O`(`O_region[i_q]`)。 +> - Dispatch:带 TMEM operand 的 `tcgen05`。 +> - Handoff:等待 `p_o_rescale`、`p_ready_2`、`kv_load.full`;到达 `o_ready`(→ epilogue)。 + +这种 operand 放置是两个 MMA 在硬件上的差异: + +- Score MMA 从 SMEM 读取两个 operand:Q 和 K。 +- Value MMA 从 TMEM 读取一个 operand:`P`。 +- Value MMA 从 SMEM 读取另一个 operand:V。 +- 结果累计到 TMEM 中的 `O`。 + +`accum=should_accumulate` 标志实现了算法中的“初始化还是相加”选择:query block 的第一个 K/V tile 上为 false,之后每个 tile 上为 true。 + +你可能还会注意到,value MMA 不是一次性跑完,而是切成 `96 + 32` 的调度: + +1. Softmax 以四个 32 列 chunk 写入 `P`。 +2. 前三个 chunk 一就绪,value MMA 就开始处理 `P` 的前 96 列和 `V` 的匹配行。 +3. 最后 32 列等待 `p_ready_2`。 +4. 第二个 MMA 消费最后这个 chunk 并完成 tile。 + +这样切分是为了让 Tensor Core 保持忙碌。如果 value MMA 作为单条指令运行,整个阶段都要等四个 32 列 `P` chunk 全部完成指数计算并写回后才能开始。先对前三个 chunk 发起 MMA,可以把最后一个 chunk 的 `exp` 和 TMEM 写入,与已经在飞行中的 96 宽 MMA 重叠起来,把本来会空转的时间变成有用工作。 + +## TMEM 布局与复用 + +`S`、`P` 和 `O` 都必须共享一个 `128 x 512` TMEM 分配;它们被打包进同一块空间的方式,正是这个 kernel 中 barrier 与 layout 不可分割的原因: + +下图直接展示了这种打包:score slot、numerator slot 和 output slot 全部共享同一块 TMEM 分配,因此 barrier 协议负责让这种复用合法。 + +![TMEM 布局](../img/tmem_layout_v3.png) + +可以把图读成一组 tile 槽位: + +- Score slot 保存 `S = QK^T`。 +- Numerator slot 保存 softmax 指数化后的 `P` tile。 +- Output slot 保存 fp32 `O` accumulator。 + +它们不是彼此独立的 buffer,而是同一块分配中的区域;这种共享不是风格选择,而是容量限制迫出来的。Q pipeline 深度为 2 时,两个 `S` slot(2 × MMA_N = 256 列)和两个 `O` slot(2 × MMA_N = 256 列)已经占满了全部 512 个 fp32 列。没有剩余空间给 `P`,所以 `P` 只能通过更窄的 fp16 view alias 到同一批字节上。安全性的唯一来源,是每个 region 都严格在前一个 consumer 完成之后才复用;这个时序正是 barrier 保证的。因此在 FA4 里,barrier 不只是调度机制;它们本身就是 layout 合法性的条件。 + +aliasing 技巧通过 `T.TMEMPool` 搭起来。kernel 先拿一个 fp32 view(`tmem`)用于 score 和 output accumulator,然后把 pool base 倒回 0,再在同一批物理字节上拿第二个 fp16 view(`tmem_as_f16`): + +```python +tmem_pool = T.TMEMPool(pool, total_cols=N_COLS_TMEM, cta_group=CTA_GROUP, tmem_addr=tmem_addr) +tmem = tmem_pool.alloc((128, N_COLS_TMEM), "float32") +tmem_pool.move_base_to(0) +tmem_as_f16 = tmem_pool.alloc((128, N_COLS_TMEM * 2), "float16") +tmem_pool.commit() +``` + +由于 fp16 元素宽度只有 fp32 的一半,fp16 view 会在同一批字节上暴露两倍数量的可索引列;`P` 正是住在这块空间里,而 fp32 layout 没有余量容纳它。拿到两个 view 后,kernel 使用 `T.TMEMStages` 把 `S`、`P` 和 `O` 槽位切成 staged region,这样计算代码就可以按 pipeline stage 索引,而不必直接操作裸列号: + +```python +S_region = T.TMEMStages(tmem, col_start=0, width=MMA_N, stages=SMEM_PIPE_DEPTH_Q, stride=MMA_N) +O_region = T.TMEMStages(tmem, col_start=MMA_N * SMEM_PIPE_DEPTH_Q, width=MMA_N, stages=SMEM_PIPE_DEPTH_Q, stride=MMA_N) +P_region = T.TMEMStages(tmem_as_f16, col_start=MMA_N, width=BLK_N, stages=SMEM_PIPE_DEPTH_Q, stride=MMA_N * 2) +``` + +`P_region` stride 里的 `* 2`,是 aliasing 在代码中显形的一个地方。`S_region` 和 `O_region` 用 fp32 `tmem` 列计数,而 `P_region` 用 fp16 `tmem_as_f16` 列计数;fp16 列只有一半宽,所以 stage 到 stage 的移动需要双倍 stride,才能落在相同的物理字节上。不过 region 一旦定义好,计算代码就保持干净:写 `S_region[q_stage]`,读 `S_region[wg_id, ...]`,写 `P_region[wg_id, ...]`,累计到 `O_region[i_q]`,完全不用碰裸列号。 + +**试着让你的 agent 做一遍**:让它解释这个 FA4 kernel 里的 fp32(`tmem`)和 fp16(`tmem_as_f16`)两个 view。哪些物理 TMEM 区域保存 `S`、`P` 和 `O`?为什么 `P_region` 的 stride 使用 `MMA_N * 2`?复用问题先留到下一节:看完 barrier 表之后,再检查每个 region 复用前必须等哪些 consumer 完成。 + +## Barrier 如何连接各个角色 + +这是整个 kernel 最难的部分,所以值得循序渐进。先从沿主计算路径移动数据的少数 barrier 入手,把其他部分都当作稍后可查的 bookkeeping。数据就绪交接包括: + +| Handoff | 含义 | +|---------|------| +| TMA load -> score/value MMA | Q、K 或 V 已经到达 SMEM,可以供 MMA 使用 | +| score MMA -> softmax | `S` 已经在 TMEM 中就绪 | +| softmax/correction -> value MMA | `P` 已经在 TMEM 中就绪,并且 `O` 可以安全累计 | +| value MMA -> epilogue | 最终 `O` 已经在 TMEM 中就绪 | +| epilogue -> TMA store | `O_smem` 已经可以存回 | + +不在这张表里的东西都是 pipeline bookkeeping:释放某个 SMEM、TMEM 或 staging buffer,让另一个角色可以复用它。有用的是,每个 barrier 不管携带的是数据还是 bookkeeping,都能用同一种方式阅读:一次 tile handoff。你问谁生产了数据、谁消费它,以及双方完成后哪个 buffer 变得可复用。 + +下一张图把这些交接压缩成两个 MMA 阶段的精确 readiness gate:score MMA 等什么,value MMA 累计前又必须等什么。 + +![Flash Attention 4 MMA 输入门控](../img/flash_attention_main_handoff.png) + +请把这张图读成一组正确性 gate,而不是调度表。它回答“这个 MMA 发射前必须满足什么”,但不说明具体时序。score MMA 等待 SMEM 中的 Q 和 K,然后产生 `S`。value MMA 同时等待三件事:SMEM 中的 V、softmax 产生的 `P` tile,以及一个由 WG2 释放或 rescale 完成的 `O` 槽位。softmax 到 value 的 gate 会分裂成两段,原因我们已经见过:`P` 的前 96 列就绪后 value MMA 就可以开始,`p_ready_2` 再释放最后 32 列。 + +有一个 handoff 不符合 tile-readiness 的模板:softmax 到 correction 的边。它不是传递 tile,而是通过一个单槽 SMEM mailbox,把一个标量(K/V loop 中的 `acc_scale`,或 epilogue 中的最终 `row_sum`)传给 WG2。由于这个槽位每次 iteration 都会复用,因此必须由一对 `full`/`empty` barrier 保护: + +下图放大了这个 mailbox handshake,因此这对 barrier 应该被读作一个标量 producer-consumer 通道,而不是 tile-ready gate。 + +![Flash Attention 4 softmax 缩放槽握手](../img/flash_attention_softmax_correction.png) + +把 `softmax_corr.full` 和 `softmax_corr.empty` 读成一对 producer-consumer barrier: + +1. Softmax 在复用 scale/sum 槽位前等待 `softmax_corr.empty`。 +2. Softmax 把 `acc_scale` 或最终 `row_sum` 写入这个槽位。 +3. Softmax 到达 `softmax_corr.full`。 +4. WG2 等待 `softmax_corr.full`,然后读取这个槽位。 +5. WG2 到达 `softmax_corr.empty`。 +6. softmax warpgroup 可以在下一阶段复用这个槽位。 + +要特别小心 `softmax_corr.empty` 表示什么、又不表示什么。它只表示 WG2 已经消费了 scale/sum 槽位。它不说明 `P` 是否就绪,更绝对不是允许 value MMA 开始的 gate。真正的 gate 是 `p_o_rescale`,它在 `P` 的前 96 列写好、且 `O` 槽位可以安全累计时触发。混淆这两者,是产生错误结果的经典来源。 + +掌握主路径后,完整 barrier 列表就可以作为参考: + +| Barrier | Producer -> consumer | 什么变得安全 | +|---------|----------------------|----------------| +| `q_load.full` | TMA load -> score MMA | Q SMEM tile 可以供 MMA 使用 | +| `q_load.empty` | 这个 Q stage 的所有 score MMA -> TMA load | Q SMEM stage 可以复用于下一个任务 | +| `kv_load.full` | TMA load -> score/value MMA | K 或 V SMEM tile 可以供 MMA 使用 | +| `kv_load.empty` | score/value MMA -> TMA load | K/V SMEM stage 可以复用 | +| `s_ready` | score MMA -> softmax | S TMEM tile 可以读取 | +| `p_o_rescale` | softmax + WG2 -> value MMA | P 的前 96 列已经在 TMEM 中,且 O 槽位可以供 value MMA 安全累计 | +| `p_ready_2` | softmax -> value MMA | P 的最后四分之一已经在 TMEM 中 | +| `o_ready` | value MMA -> epilogue | 最终 O accumulator 已经就绪 | +| `softmax_corr.full` | softmax -> WG2 | `acc_scale` 或最终 `row_sum` 已在 SMEM mailbox 中就绪 | +| `softmax_corr.empty` | WG2 -> softmax | WG2 读取后,同一个 SMEM mailbox 槽位可以复用 | +| `corr_epi.full` | epilogue -> TMA store | O_smem 已经可以存储 | +| `corr_epi.empty` | TMA store -> epilogue | O_smem stage 可以复用 | + +和 GEMM 一样,你可以从信号生产者预测 barrier 类型: + +- TMA load 使用 `TMABar`,因为 TMA 引擎会按字节数统计自己的完成。 +- MMA 完成使用 `TCGen05Bar`,因为 `tcgen05.commit` 会 signal completion group。 +- 纯线程到线程的 handoff 使用 `MBarrier`,参与线程显式 arrive。 + +softmax 到 value 的分裂式 handoff 值得仔细看。它使用两个 gate: + +- `p_o_rescale` 在 `P` 的前 96 列写好、且 `O` tile 可以安全累计后,允许 value MMA 开始。 +- `p_ready_2` 释放 `P` 的最后 32 列,对应上一节中的 `96 + 32` value-MMA 调度。 + +第一个 K/V block 是简单情况。WG2 会预先 arrive `p_o_rescale`,因为还没有旧的 `O` tile 需要 rescale。 + +后续 block 必须更谨慎。WG2 只有在跳过一次不必要的 rescale,或完成旧 `O` 的 rescale 之后,才会到达 `p_o_rescale`。跳过测试刻意保守:softmax 计算 log2 缩放后的 delta `(m_old - m_new) * scale_log2`;如果这个值仍然高于 `-rescale_threshold`,说明新的 max 变化还没大到值得 rescale,kernel 就保持旧 max,并把 `acc_scale` 精确设为 1.0。只有更大的 max 跳变才会走 `exp2` 路径,并要求 WG2 rescale `O`。 + +随后 WG2 用 `any_sync` 在 warpgroup 内规约 `should_rescale`。如果没有任何行需要更新,它就保持 `O` 不动。这个跳过很重要,因为 rescale `O` 是覆盖整个 accumulator 的一次 TMEM -> RF -> TMEM read-modify-write;当阈值逻辑已经把 `acc_scale` 维持为 1.0 时,做这件事就是纯浪费。 + +注意所有新增 barrier 都聚在同一个地方。`s_ready`、`p_o_rescale`、`p_ready_2`,以及 softmax/correction 这对 barrier,全都围绕 softmax。它们存在只有一个原因:score MMA 和 value MMA 不再相邻。寄存器计算、TMEM 重写和输出 rescale 现在插在两者之间,每一步都需要自己的 handoff。 + +**试着让你的 agent 做一遍**:让它追踪一个 K/V block 经过 `s_ready`、`p_o_rescale`、`p_ready_2` 和 `o_ready`。对每个 barrier,问谁等待、谁 arrive、哪个 tile 变得可读,以及之后哪个存储可以复用。 + +## Pipeline 结构 + +barrier 告诉我们某个角色消费 tile 之前什么必须 *就绪*。但它们没有告诉我们实际上哪些东西会 *并发* 运行;这正是现在要讨论的问题。两者确实不同:一个正确性 gate 可能在 producer 真正运行之前很久或之后很久才满足。 + +这里不存在单一的 pipeline 深度,因为不同 tile stream 以不同速率移动。因此 kernel 为每条 stream 保留独立的 ring: + +- Q pipeline 深度 2:一个 CTA 同时处理两个 Q stage。WG0 处理一个 stage,WG1 处理另一个。 +- KV pipeline 深度 3:K 和 V block 在内层循环中流动,同时复用同一批 Q stage。 +- TMEM pipeline 深度 2:每个 Q stage 都有自己的 S/P/O TMEM 槽位,并在匹配的 barrier 触发后复用。 + +下图从正确性 gate 切换到时间线视角,展示这些独立 ring 进入稳定状态后,哪些角色大致可以同时活跃。 + +![Flash Attention 4 流水线结构](../img/flash_attention_pipeline_v2.png) + +请把它读成时间线,而不是 barrier 图。它展示的是同一时刻大致有哪些角色处于活跃状态;前面的 barrier-flow 图才是检查精确 producer-consumer wait 的地方。两张图合起来,回答了本节开头提出的两个不同问题。 + +每一行对应代码中的一个角色分支: + +- WG3 warp 1 发出 TMA load。 +- WG3 warp 0 发出 score MMA 和 value MMA。 +- WG0 与 WG1 为两个 Q stage 运行 softmax。 +- WG2 释放或 rescale `O`,稍后再归一化最终输出。 +- WG3 warp 2 发出 TMA store。 + +沿着图从左到右,可以追踪一个有代表性的 pipeline wave。load warp 先从 `Q0`、`K[n-1]`、`Q1`、`V[n-1]` 开始,然后持续流式读取更低索引的 K/V block。MMA warp 发出最早的 score MMA,产生 `S0` 和 `S1`,WG0/WG1 再把它们转成 `P0` 和 `P1`。 + +重要的是,MMA warp 不会先跑完所有 score MMA,再跑所有 value MMA。两个 Q stage 预热好之后,它会交错两种 MMA:当前 `V` block 的一次 value MMA,下一次 `K` block 的一次 score MMA,如此继续: + +```text +score Q0*K[n-1] +score Q1*K[n-1] +value P0*V[n-1] +score Q0*K[n-2] +value P1*V[n-1] +score Q1*K[n-2] +value P0*V[n-2] +... +``` + +这种交错正是图中 score、softmax、correction 和 value 各行会重叠,而不是整齐依次执行的原因。 + +WG2 行标为 `release / rescale`,两半对应我们已经见过的两种情况。第一个 K/V block 上还没有旧 `O`,所以 WG2 只参与允许 value MMA 继续的 handoff;后续 block 上,它可能在 value MMA 累计之前先 rescale 旧的 `O`。归一化和 TMA store 只会发生一次,在 attention task 的最后一个 K/V block 之后。 + +没有一个 GEMM 风格的单 pipeline 可以描述 FA4,因为 Q、K/V 和 TMEM 槽位都在独立调度上前进。TIRx 把这些调度显式保留下来,用独立的 tile buffer、`PipelineState` cursor 和 barrier phase 表达,而不是把 kernel 藏进一个巨大的 monolithic primitive。代价是移动部件更多;收益是复杂度仍然可见、可检查。 + +## Rescaling 与 Writeback + +rescale 是必须的,不是可以丢掉的优化。online softmax 可能随着每个新 score tile 抬高逐行最大值;一旦发生,早先 block 累计到 `O` 中的内容就是按 *旧* 最大值缩放的。这样早先每一项都会大出一个 `exp(m_new - m_old)` 因子。跳过 correction 会让这些 block 权重过大,最终输出就是错的。修正方式是一次 TMEM → registers → TMEM tile 操作: + +$$O_{\text{old}} \leftarrow O_{\text{old}} \cdot e^{(m_{\text{old}} - m_{\text{new}}) / \sqrt{d}}$$ + +工作分给两个角色完成。softmax 计算逐行 scale,并把它投递到 SMEM mailbox;WG2 等待 `softmax_corr.full`,把当前 `O` 从 TMEM 读出,乘上该 scale,再把 `O` 写回: + +```python +RESCALE_TILE = T.meta_var(16) +o_row = T.wg_reg_tile(RESCALE_TILE) +Tx.copy_async(o_row, O_region[i_q, d_start : d_start + RESCALE_TILE]) +Tx.mul(o_row, o_row, acc_scale) +Tx.copy_async(O_region[i_q, d_start : d_start + RESCALE_TILE], o_row) +T.ptx.tcgen05.wait.st() +``` + +值得强调的是,这是覆盖整个 `O` accumulator 的一次完整 TMEM → registers → TMEM tile 操作,不是一点标量记账;它和其他阶段一样,也有自己的解读卡: + +> **Tile-primitive 解读:Correction(rescale)** +> - Scope:WG2,完整 warpgroup。 +> - Layout:TMEM 中的 `O` → 寄存器 → TMEM 中的 `O`(`O_region[i_q]`)。 +> - Dispatch:用 `tcgen05.ld` 读取,用 TMEM store 写入;中间做寄存器乘法。 +> - 交接:等待 `softmax_corr.full`;到达 `p_o_rescale`(→ value MMA)和 `softmax_corr.empty`(→ softmax)。 + +端到端追踪同步过程: + +1. Softmax 把 scale 值写入 SMEM。 +2. WG2 等待 `softmax_corr.full`。 +3. WG2 在 TMEM 中 rescale `O`。 +4. WG2 到达 `p_o_rescale`。 +5. WG3 的 value MMA 现在可以消费 `P`,并累计到 rescale 后的 `O` tile。 + +WG2 读取之后,`softmax_corr.empty` 会释放 SMEM 槽位,循环随之闭合,softmax 可以在下一次 iteration 复用 mailbox。 + +K/V loop 结束后,WG2 从 correction 切换到 epilogue。它等待最终的 `row_sum` 和 `o_ready`,从 TMEM 读取最终 `O`,乘以 `1 / row_sum`(也就是一开始推迟的归一化),转换成 fp16,并写入 `O_smem`。然后 WG3 的 TMA store warp 把 `O_smem` 搬回 GMEM。 + +如果你打算扩展这个 kernel,有一个限制值得标出。它只计算 forward output,而训练时的 forward pass 通常还要保存 backward pass 需要的 log-sum-exp(LSE)。加入 LSE 时有一个缩放细节要记住:这个 kernel 把 `row_max` 保留为 *未缩放* 的原始 `QK^T` score 最大值,而 `row_sum` 累计的是 `exp((S - row_max) / sqrt(d))`。因此形成自然对数 LSE 时,必须把 `1/\sqrt{d}` 因子重新应用到 `row_max` 上: + +$$\mathrm{LSE}_i = \log(\mathrm{row\_sum}_i) + \mathrm{row\_max}_i / \sqrt{d}$$ + +这个实现只输出 forward 结果,不写 LSE。 + +## Causal Masking + +causal attention 增加了一个约束:一个 query 只能 attend 到自身位置及之前的 key。kernel 用两种互补方式满足它,一种便宜,一种精确。 + +便宜的方式是直接跳过整块工作。很多 K/V block 完全位于对角线上方,对给定 Q block 没有任何贡献,因此 `get_n_block_max(...)` 会计算该 block 最多可能需要的最后一个 block,循环就根本不加载、不计算剩余部分。 + +精确的方式处理跨过对角线的 block,也就是一部分列有效、一部分无效的情况。这些 block 仍然运行 score MMA,但 softmax 会在指数化之前把无效列 mask 掉。对每一行,它根据该行 query 位置和 block offset 推导一个列上限,保留不超过该上限的列,并在寄存器中把之后每一列设为 `-inf`,让这些列既不贡献 row max,也不贡献 `exp2` numerator。 + +实现并不是逐元素分支,而是用 `mask_r2p(...)` 应用这个上限:它把上限转成整个 32 宽 score chunk 上的 bit mask,并一次性 mask 整个 chunk。完全位于对角线下方的 block 保留所有列,不需要 mask。 + +从 tile-primitive 视角看,causal mode 完全不改写数据路径。它只是缩短 K/V trip count,并把一个 masking 步骤插入寄存器驻留的 softmax 中,位于 score MMA 和 `P` writeback 之间。 + +## GQA 支持 + +Grouped Query Attention 允许多个 query head 共享一个 K/V head。这能节省内存带宽,但也提出一个打包问题:如何只保留一个 K/V tile,同时让多个 query head 都使用它?这个 kernel 的答案是:一次处理一整组 query head,让它们共同对应一个调度出来的 `kv_head_idx`: + +```python +GQA_RATIO = num_qo_heads // num_kv_heads +SEQ_Q_PER_TILE = BLK_M // GQA_RATIO +``` + +技巧在于重新解释 128 行 Q tile。对于 `GQA_RATIO=4`,它们不再表示 128 个序列位置,而是表示 32 个序列位置 × 4 个 query head;这些 query head 被打包在一起,共乘同一个 K/V tile。行解码如下: + +```text +seq_pos = row // GQA_RATIO +q_head = row % GQA_RATIO +``` + +Q load 用一个 3D view 表达这种打包。源数据是自然的 `Q[batch, seq, qo_head, dim]` 布局,目标则是 score MMA 随后会当作扁平 `128 x HEAD_DIM` operand 读取的同一个 SMEM tile。view 负责调和这两种形态,而且不需要任何额外 copy: + +```python +Q_smem_3d = Q_smem.view(SMEM_PIPE_DEPTH_Q, SEQ_Q_PER_TILE, GQA_RATIO, HEAD_DIM) +Tx.copy_async( + Q_smem_3d[i_q, :, :, :], + Q[batch_idx, + m_start : m_start + SEQ_Q_PER_TILE, + kv_head_idx * GQA_RATIO : (kv_head_idx + 1) * GQA_RATIO, + :], + **tma_copy_q, +) +``` + +K 和 V 从不在内存中展开,而这正是 GQA 的意义:`kv_head_idx` 对应的单个 K/V tile,会被打包进 Q 行里的全部 `GQA_RATIO` 个 query head 复用。输出侧与输入侧镜像对应,epilogue 之后用匹配的 3D view,把打包行存回 `O[batch, seq, qo_head, dim]`。 + +结果是,GQA 完全生活在 Q-load 和 O-store 边界上。在内部计算路径中,score MMA 仍然看到一个普通的 `128 x HEAD_DIM` Q tile,其余 tile-primitive 图完全不变。 + +## Tile 调度 + +scheduler 的工作是把每个 CTA 映射到一个 `(batch, kv_head, m_block)` attention task;合适的策略取决于 masking 是否让这些 task 代价相同: + +- 非 causal mode 使用 `FlashAttentionLinearScheduler`。每个 task 的工作量相同,因此一个固定 CTA 池按 `num_ctas` 前进,就足以把任务均匀摊开。 +- Causal mode 使用 `FlashAttentionLPTScheduler`,因为 causal masking 会让工作量极不均匀:靠近开头的 Q block 大约只 attend 一个 K/V block,而靠近结尾的 Q block 会 attend 所有 block。朴素切分会让某些 CTA 远晚于其他 CTA 完成,所以 longest-processing-time scheduler 会优先安排重任务以拉平完成时间,同时仍尽量保持相邻 batch/head task 聚在一起,利于 L2 locality。 + +尽管两种 scheduler 不同,它们暴露的循环接口完全相同: + +```python +while scheduler.valid(): + m_block_idx = scheduler.m_block_idx + batch_idx = scheduler.batch_idx + kv_head_idx = scheduler.head_idx + # 用对应 K/V block 范围处理一个 Q block + scheduler.next_tile() +``` + +唯一的行为差异在于 `next_tile()` 做什么:非 causal mode 下,它会让 CTA 前进到另一个 task;causal mode 下,它会在当前 task 后结束循环。无论哪种方式,这都只是调度决策:它选择 CTA 拥有 *哪个* attention tile,而不改变这个 tile 如何计算。循环内部仍然运行同样的本地 primitive:TMA load、score MMA、softmax、value MMA、correction、TMA store。 + +## 编译与验证 + +上面的内容都是摘录;要把所有东西合在一起并真正运行 kernel,我们会从 `tirx-kernels` 导入真实实现、编译它,并与 torch reference 对比。完整 kernel 位于 `tirx-kernels` 仓库中的 [`flash_attention4.py`](https://github.com/mlc-ai/tirx-kernels/blob/main/tirx_kernels/attention/flash_attention4.py),本章讲过的所有部件都组装在这个文件里。它和 GEMM 验证 cell 有两点不同:Flash Attention 的入口更丰富(`get_flash_attention4_kernel`),而且它为内建 profiler 多接收一个 `profiler_buf` 参数。整章只需要运行这一格: + +```python +import torch +import torch.nn.functional as F +import tvm +from tirx_kernels.attention.flash_attention4 import ( + get_flash_attention4_kernel, PROFILER_BUFFER_SIZE) + +B, S, Hq, Hkv, D = 1, 1024, 32, 8, 128 # GQA:32 个 query head 共享 8 个 KV head +Q = torch.randn(B, S, Hq, D, dtype=torch.float16, device="cuda") +K = torch.randn(B, S, Hkv, D, dtype=torch.float16, device="cuda") +V = torch.randn(B, S, Hkv, D, dtype=torch.float16, device="cuda") +O = torch.empty(B, S, Hq, D, dtype=torch.float16, device="cuda") +prof = torch.zeros(PROFILER_BUFFER_SIZE, dtype=torch.uint64, device="cuda") + +kernel = get_flash_attention4_kernel(B, S, S, Hq, Hkv, D, is_causal=False) +target = tvm.target.Target("cuda") +with target: + ex = tvm.compile(tvm.IRModule({"main": kernel}), target=target, tir_pipeline="tirx") +ex.mod(Q, K, V, O, prof) # 和其他章节一样,ex.mod 直接接收 torch tensor +torch.cuda.synchronize() + +# torch reference;enable_gqa 允许 32 个 query head 共享 8 个 KV head +qt, kt, vt = (x.transpose(1, 2).float() for x in (Q, K, V)) +ref = F.scaled_dot_product_attention(qt, kt, vt, enable_gqa=True).transpose(1, 2).half() +torch.testing.assert_close(O, ref, rtol=1e-2, atol=1e-2) +print(f"FA4: B={B} S={S} Hq={Hq} Hkv={Hkv} D={D}, non-causal -> PASS") +``` + +**预期输出**:`... -> PASS`。kernel 用 fp32 累计 online softmax,但它和高精度 reference 之间仍然存在几类近似:输入和 operand 的 fp16 存储与舍入;基于 `exp2` 的 softmax 重写(把每个指数改写成 `scale_log2 = log2(e)/√d` 形式);online-softmax 的重排和逐行 rescaling,它按运行尺度分 block 求和,而不是一次性求和;最后还有 writeback 时对 `O` 的 fp16 cast。这里选择的 `rtol`/`atol` 和源 kernel 自己的测试一致,是为了同时覆盖这些因素相对 torch reference 的差异,而不只是单独覆盖 fp16 舍入。因此如果你看到真正失败,而不是边界附近的小偏差,就应该把它当作指向 softmax 路径的路标:漏掉了 `s_ready` / `p_o_rescale` / `p_ready_2` wait,或者 `row_max` / `row_sum` 更新没有被 rescale 步骤正确应用。这些正是本章用 barrier 反复处理的 handoff。 + +## 与 GEMM 的差异 + +下表沿发生变化的轴比较 FA4 与 GEMM: + +| 方面 | GEMM | Flash Attention 4 | +|------|------|-------------------| +| MMA 阶段 | 一个重复的 MMA | score MMA 和 value MMA | +| MMA 之间的工作 | 除 pipeline handoff 外没有额外工作 | online softmax、masking 和 O rescaling | +| 运行状态 | 只有 accumulator | row max、row sum、O accumulator | +| 主要中间值 | accumulator TMEM tile | S、P 和 O TMEM tile region | +| Warp 角色 | TMA producer、MMA consumer、writeback | TMA load、MMA、softmax、correction、TMA store | +| Barrier | 主要是 load/compute/writeback handoff | 额外的 score/softmax/value/correction handoff | +| 调度单元 | 输出矩阵 tile | attention task:`(batch, kv_head, m_block)` | + +这些差异全部可以追溯到本章开头那条结构性变化:第二个 MMA,以及夹在两个 MMA 之间的 softmax。另一方面,底层 TIRx contract 完全没有改变: + +- tile primitive 说明哪个 tile 在移动或计算; +- 周围的 scope 说明哪些线程协作; +- layout 说明 tile 住在哪里; +- barrier 说明下一个角色什么时候可以消费它。 + +所以 FA4 比 GEMM 更难,并不是因为它依赖不同硬件,而是因为 tile 值更多、它们之间的 handoff 也更多。 + +## 练习 + +1. 和 GEMM 相比,FA4 在两个 MMA 阶段之间新增了什么 tile handoff?请说出 producer、TMEM tile 和 consumer。 +2. 为什么 softmax 要把 numerator tile `P` 写回 TMEM,而不是只把它留在寄存器中供 value MMA 使用? +3. 任选 `p_o_rescale` 或 `p_ready_2`。这个 barrier 精确证明了什么?如果 value MMA 跳过这次等待,可能出什么错? + +**试着让你的 agent 做一遍**:任选一个没有注释过的 tile primitive,例如 epilogue 里的 `Tx.copy_async`、fp32 -> fp16 的 `Tx.cast`,或第二段 `gemm_pv` sub-MMA。让它写出 scope / layout / dispatch / handoff 卡片,然后对照源码里的 guard、allocation 和 wait 检查答案。 diff --git a/zh/chapter_gemm_advanced/index.md b/zh/chapter_gemm_advanced/index.md new file mode 100644 index 00000000..3237131c --- /dev/null +++ b/zh/chapter_gemm_advanced/index.md @@ -0,0 +1,964 @@ +(zh_chap_gemm_advanced)= +# 用 Warp Specialization 和 Cluster 扩展 GEMM + +:::{admonition} 概览 +:class: overview + +- pipelined GEMM 仍然让一个 warpgroup 按顺序做 load、MMA 和 writeback;本章会移除这个瓶颈。 +- Step 7 把 warp 专门化为不同角色,Step 8 加入 2-CTA cluster,Step 9 加入多个 consumer。 +- 每一步都会移除一个串行瓶颈,最终接近 state-of-the-art 吞吐。 +::: + +上一章的 pipelined GEMM({ref}`zh_chap_gemm_async`)已经很快,但它仍然要求一个 warpgroup 做所有事情: +发射 load、运行 MMA,然后写回结果。即使用了 software pipeline,这一组 thread 仍然成为三个引擎的汇合点。 + +症状很容易看见。Tensor Core 运行时 TMA unit 安静下来;结果 drain 到内存时 Tensor Core 安静下来; +每个引擎都通过同一组 thread 等待其他引擎。越过这个问题的方法,是停止让一组 thread 做所有事情。 + +我们会通过三步逐渐扩大协作范围来追求这个想法。Step 7({ref}`zh_chap_warp_specialization`) +把 warp 专门化为 producer、consumer 和 writeback 角色。Step 8({ref}`zh_chap_cta_cluster`) +把两个 CTA 组成一个 cluster,并跨它们的 shared memory 共享 operand。Step 9({ref}`zh_chap_multi_consumer`) +加入第二个 MMA consumer,让一个 staged tile 喂给两倍数学工作。 + +把这三步看作同一种 pattern 在不同尺度上的展开,会很有帮助。Step 7 把完整 pipeline 保持在一个 CTA 内部: +TMA 和 MMA 共享一个 warpgroup,而 writeback 在另一个 warpgroup 中运行。 +Step 8 把协作扩大到 CTA 之间,产生一个跨越两个 CTA 的 256×256 tile。 +Step 9 进一步提高 compute density:cluster output 增长到 512×256,每个 staged B tile 被两个 consumer 复用, +我们也到达教程中最密集的变体。 + +贯穿这一切,有一件事保持不变。SMEM、TMEM 和 register layout 仍然遵守前两章建立的 contract; +变化的是*谁协作*,而不是数据如何布局。Step 8 是协作 scope 第一次扩展到单个 CTA 之外, +因此它的 operand tile 会切分到两个 CTA 的 shared memory 中,一个 layout 会沿 `cbx` cluster axis 跨越两个 CTA。 + + +(zh_chap_warp_specialization)= +## Step 7:Warp Specialization + Pipeline + +single-warpgroup kernel 留下性能的原因很简单:每个 thread 走同一条路径,先 load,再 compute,再 write。 +因此它在 loading 时,Tensor Core 无事可做;它在 computing 时,TMA engine 无事可做。 +修复方式是 *warp specialization*。我们不再让一组 thread 轮流做每项工作,而是把每项工作交给专门的 warp, +并让这些 warp 同时运行,再由 software pipeline 缝合起来。这是 GEMM 路径中最大的架构变化, +本章剩余内容都建立在它之上。这里的 benchmark 使用 M=N=K=4096。 + +> **这一步改变什么:Scope** +> - Scope:一个 warpgroup 按顺序走 load → MMA → writeback,变成三个并发角色(TMA producer、MMA consumer、writeback),由 full/empty barrier 连接。 +> - Layout:不变,与 Step 6 相同的 SMEM stage 和 TMEM accumulator。 +> - Dispatch:不变,TMA load、`tcgen05` MMA。 + +**主题。** + +- Warp specialization:把不同 warp/warpgroup 专门用于不同任务 + +- 高层 barrier 抽象:`TMABar`、`TCGen05Bar`、`MBarrier` + +- `PipelineState` 用于自动 stage/phase 管理 + +- `warpgroup_sync` barrier ID 用于按 warpgroup 同步 + +(multi-stage SMEM pipeline 和 persistent `ClusterPersistentScheduler2D` 从 Step 5–6 原样复用;这里只新增 scope split。) + +### 从顺序到并发 + +在介绍角色和 barrier 之前,先隔离 warp specialization 要移除的 scheduling bottleneck 会很有帮助。 +下图用 Step-4 风格的 sequential timeline 作为 Step 4-6 中 specialization 前 kernel 的紧凑参考, +并把它放在 Step 7 warp-specialized schedule 上方,让 engine utilization 的差异一眼可见。 + +![Warp 专门化时间线](../img/warp_specialization_timeline.png) + +上方是 specialization 前的 single-warpgroup pattern:同一个未专门化的 thread group 同时拥有 load path 和 MMA path, +因此一个引擎活跃时,另一个引擎很容易闲置。Step 5 和 Step 6 用 double buffering 和 persistent scheduling 改进了这个 baseline, +但它们还没有把 loading 和 compute 分成独立 producer/consumer 角色。 +下方的 specialization 打破了这种轮流执行。TMA producer 在 MMA consumer 忙于计算时 prefetch 下一个 tile, +writeback 则自行推进。producer warp 3 在 consumer warp 0 仍在处理当前 MMA 时发射下一次 load, +因此两个引擎都不必等待对方。load/MMA handoff 使用两个 barrier: + +- **`tma2mma`**(TMA → MMA):signal 已载入的 SMEM 数据已经 ready,可供 MMA 消费。 +- **`mma2tma`**(MMA → TMA):signal MMA 已经读完一个 buffer,因此 TMA 可以为下一次 load 复用它。 + +图中有个细节第一眼可能像错误:`mma2tma` 箭头会跨过一个 stage。原因是 ring buffer。 +`PIPE_DEPTH=2` 时有两个 SMEM buffer,stage 0 和 stage 1;TMA Load k=0 填充 buffer 0,TMA Load k=1 填充 buffer 1。 +当 MMA Compute k=0 读完 buffer 0 时,它 signal `mma2tma` 表示 buffer 空闲; +但真正想重新使用 buffer 0 的 load 是 TMA Load k=2,而不是 k=1(它使用 buffer 1)。 +这就是为什么 MMA Compute k=0 的 `mma2tma` 箭头一路指向 TMA Load k=2。 +release 跳过一个 stage,只是因为 ring 有两个 slot。 + +### Warp Roles + +timeline 展示了我们*为什么*拆分工作;下一个问题是*谁*做每一部分。 +specialization 把三个工作(load、compute、writeback)分配给特定 warp,让它们能同时运行。 +当 `WG_NUMBER=2` 时,kernel 使用两个 warpgroup(角色表中缩写为 WG): + +| Actor | Location | Job | +|-------|----------|-----| +| **TMA Producer** | Warpgroup 1, warp 3 | 通过 TMA 持续 load A 和 B tile | +| **MMA Consumer** | Warpgroup 1, warp 0 | 数据 ready 后立即运行 MMA | +| **Writeback** | Warpgroup 0(全部 warp) | 读取 TMEM 结果,写入 GMEM | + +### 4 个 Barrier + +三个并发 actor 需要四个 barrier,而这四个 barrier 正好分成两个相反方向。 +forward path(TMA → MMA → Writeback)signal 数据 *readiness*;它的信息是“你等的 tile 到了”。 +backward path(Writeback → MMA → TMA)signal buffer *release*:“你想要的 slot 又空了”。 +一旦知道命名约定,名字就能自己读懂:每个都是 `source2destination`,所以 `tma2mma` +就是 TMA signal MMA 的 barrier。 + +| Barrier | Type | Direction | Meaning | +|---------|------|-----------|---------| +| **tma2mma** | `TMABar` | TMA -> MMA | “SMEM data is ready” | +| **mma2tma** | `TCGen05Bar` | MMA -> TMA | “SMEM buffer can be reused” | +| **mma2ld** | `TCGen05Bar` | MMA -> Writeback | “TMEM results are ready” | +| **ld2mma** | `MBarrier` | Writeback -> MMA | “TMEM is free for next tile” | + +为什么每个 barrier 会有它自己的 *type*?type 来自 producer 如何宣布自己完成。 +**TMA Load** 使用 `TMABar`,即带 byte counting 的 mbarrier:当 transfer 的字节落地后, +TMA 硬件自己 arrive 到 barrier,因此 consumer 能知道数据 ready,而不需要任何 thread poll。 +**TMA Store** 不能使用这个机制(store 没有人需要通知),所以它们退回到 +`cp_async.bulk.commit_group()` + `wait_group(0)`,issuing thread 只是在等待自己的写入 drain。 +**MMA operation** 使用 `TCGen05Bar`,当 MMA 完成时,`tcgen05.commit()` 指令会 signal 这个 barrier。 + +这里有一个小细节会在 Step 8 产生回报。`arrive` 调用传入 `cta_mask=0`, +因为在 single-CTA kernel 中没有其他 CTA 需要 signal。当 Step 8 形成 cluster 时, +这个参数会变成非零,并成为唤醒协作 CTA 的机制。 + +### PipelineState + +四个 barrier 会告诉角色 buffer *何时* ready;但还需要有东西追踪 pipeline 循环时每个角色位于*哪个* buffer。 +这正是 `PipelineState` 管理的 bookkeeping。ring buffer 同时携带两份 bookkeeping: +当前位于哪个 slot,以及正在等待这个 slot 的 barrier 的哪个 “phase”。 +在 pipelined loop 中手动追踪二者,正是容易滋生 off-by-one 错误的事情; +这里的 off-by-one 会让整个 kernel deadlock。`PipelineState` 存在的目的就是把二者绑在一起,免得你手动管理: + +```python +tma_ps = PipelineState(PIPE_DEPTH, phase=1) # Producer starts ready (phase=1) +# tma_ps.stage = current stage index +# tma_ps.phase = current phase (0 or 1) +tma_ps.advance() # Advance to next stage +``` + +initial `phase` 会决定某个角色的第一次 `wait` 是让它运行,还是让它阻塞。 +pipe 两端的正确答案正好相反,这就是容易绊倒人的地方: +- `phase=1`(producer)-> 第一次 `wait(phase=1)` 看到 barrier 仍在 phase 0;由于 0 != 1,它会**立即通过**。 + 这正是我们想要的,因为 buffer 一开始是空的,producer 应该可以立刻开始填充。 + +- `phase=0`(consumer)-> 第一次 `wait(phase=0)` 看到 barrier 位于 phase 0;由于 0 == 0,它会**阻塞**。 + 这同样是我们想要的,因为还没有数据,consumer 在 producer arrive 前没有东西可读。 + +如果给两端相同的 starting phase,你会得到 deadlock,或者更糟,silent corruption。 +所以这个选择值得认真做对。 + +### `warpgroup_sync` Barrier IDs + +specialization 引入了一个很容易踩到的同步危险。一旦每个 warpgroup 运行不同代码路径, +熟悉的 `cta_sync()` 就会 deadlock:它使用硬件 barrier #0,并要求*每个* CTA thread arrive; +但在 warpgroup branch 内,只有一部分 thread 存在。我们需要的是作用域为单个 warpgroup 的 barrier。 +GPU 给了我们 16 个 named barrier(ID 0–15),所以 kernel 会使用 `warpgroup_sync(10)`, +它只同步一个 warpgroup 内的 thread。当多个 warpgroup 都需要各自同步时(multi-consumer Step 9 中就会这样), +它们通过 `warpgroup_sync(wg_id + 10)` 使用不同 ID,避免在同一个硬件 barrier 上碰撞。 + +**实现。** + +这里使用 `PIPE_DEPTH=2`,这是仍然能让 load 和 compute overlap 的最小深度。 +更深的 pipeline 可以隐藏更多内存延迟,直到 SMEM 预算限制为止;下面的 *When Step 7 misbehaves* 会详细讨论这个取舍。 +现在所有部件都已具备(角色、四个 barrier、`PipelineState` 和 warpgroup-scoped sync),我们可以组装完整 kernel: + +```python +import tvm +from tvm.script import tirx as T +from tvm.script.tirx import tile as Tx +from tvm.tirx.layout import TileLayout, S, TLane, TCol, tid_in_wg +from tvm.tirx.cuda.operator.tile_primitive.tma_utils import tma_shared_layout, SwizzleMode +from tvm.tirx.lang.pipeline import TMABar, TCGen05Bar, MBarrier, PipelineState +from tvm.tirx.lang.tile_scheduler import ClusterPersistentScheduler2D + +SM_COUNT = 148 # Number of SMs on NVIDIA B200 GPU +F16_SIZE = 2 + +def hgemm_v7(M, N, K): + a_type = tvm.DataType("float16") + b_type = tvm.DataType("float16") + d_type = tvm.DataType("float16") + acc_type = tvm.DataType("float32") + + BLK_M, BLK_N, BLK_K = 128, 128, 64 + K_TILES = K // BLK_K + PIPE_DEPTH = 2 + WG_NUMBER = 2 + + A_layout = tma_shared_layout(a_type, SwizzleMode.SWIZZLE_128B_ATOM, (PIPE_DEPTH, BLK_M, BLK_K)) + B_layout = tma_shared_layout(b_type, SwizzleMode.SWIZZLE_128B_ATOM, (PIPE_DEPTH, BLK_N, BLK_K)) + D_layout = tma_shared_layout(d_type, SwizzleMode.SWIZZLE_128B_ATOM, (BLK_M, BLK_N)) + + @T.prim_func + def kernel( + A: T.Buffer((M, K), a_type), + B: T.Buffer((N, K), b_type), + D: T.Buffer((M, N), d_type), + ): + T.device_entry() + bx = T.cta_id([SM_COUNT]) + wg_id = T.warpgroup_id([WG_NUMBER]) + warp_id = T.warp_id_in_wg([4]) + lane_id = T.lane_id([32]) + + # --- Allocation --- + pool = T.SMEMPool() + tmem_addr = pool.alloc((1,), "uint32") + tma2mma = TMABar(pool, PIPE_DEPTH) + mma2tma = TCGen05Bar(pool, PIPE_DEPTH) + mma2ld = TCGen05Bar(pool, 1) + ld2mma = MBarrier(pool, 1) + pool.move_base_to(1024) + Asmem = pool.alloc((PIPE_DEPTH, BLK_M, BLK_K), a_type, layout=A_layout) + Bsmem = pool.alloc((PIPE_DEPTH, BLK_N, BLK_K), b_type, layout=B_layout) + Dsmem = pool.alloc((BLK_M, BLK_N), d_type, layout=D_layout) + + # --- Barrier init --- + tma2mma.init(1) + mma2tma.init(1) + mma2ld.init(1) + ld2mma.init(128) # all 128 Warpgroup 0 threads arrive + pool.commit() + + # --- TMEM alloc + fence --- + if wg_id == 0: + if warp_id == 0: + T.ptx.tcgen05.alloc(T.address_of(tmem_addr), n_cols=512, cta_group=1) + T.ptx.fence.proxy_async("shared::cta") + T.ptx.fence.mbarrier_init() + T.cuda.cta_sync() + + tmem = T.decl_buffer( + (128, 512), acc_type, scope="tmem", allocated_addr=tmem_addr[0], + layout=TileLayout(S[(128, 512) : (1@TLane, 1@TCol)])) + + # --- Tile scheduler --- + tile_scheduler = ClusterPersistentScheduler2D( + "ts", num_m_tiles=M // BLK_M, num_n_tiles=N // BLK_N, + l2_group_size=8, num_clusters=SM_COUNT) + tile_scheduler.init(bx) + m_st = T.meta_var(tile_scheduler.m_idx * BLK_M) + n_st = T.meta_var(tile_scheduler.n_idx * BLK_N) + + # ============================================= + # Warpgroup 1: TMA Producer (warp 3) + MMA Consumer (warp 0) + # ============================================= + if wg_id == 1: + if warp_id == 3: + # === TMA Producer === + tma_ps = PipelineState(PIPE_DEPTH, phase=1) + + @T.inline + def tma_load(k_offset): + Tx.copy_async(Asmem[tma_ps.stage, :, :], + A[m_st:m_st+BLK_M, k_offset:k_offset+BLK_K], + dispatch="tma", cta_group=1, + mbar=tma2mma.ptr_to([tma_ps.stage])) + Tx.copy_async(Bsmem[tma_ps.stage, :, :], + B[n_st:n_st+BLK_N, k_offset:k_offset+BLK_K], + dispatch="tma", cta_group=1, + mbar=tma2mma.ptr_to([tma_ps.stage])) + + if T.filter(lane_id, T.ptx.elect_sync()): + while tile_scheduler.valid(): + for k in range(K_TILES): + mma2tma.wait(tma_ps.stage, tma_ps.phase) + tma_load(k * BLK_K) + tma2mma.arrive(tma_ps.stage, + (BLK_M * BLK_K + BLK_N * BLK_K) * F16_SIZE) + tma_ps.advance() + tile_scheduler.next_tile() + + elif warp_id == 0: + # === MMA Consumer === + mma_ps = PipelineState(PIPE_DEPTH, phase=0) + ld_ps = PipelineState(1, phase=1) + + if T.filter(lane_id, T.ptx.elect_sync()): + while tile_scheduler.valid(): + # Wait for TMEM to be free from previous tile's writeback + ld2mma.wait(ld_ps.stage, ld_ps.phase) + ld_ps.advance() + + for k in range(K_TILES): + tma2mma.wait(mma_ps.stage, mma_ps.phase) + Tx.gemm_async( + tmem[:, :BLK_N], + Asmem[mma_ps.stage, :, :], + Bsmem[mma_ps.stage, :, :], + accum=(k != 0), dispatch="tcgen05", cta_group=1) + mma2tma.arrive(mma_ps.stage, cta_group=1, cta_mask=0) + mma_ps.advance() + + # Signal results ready for writeback + mma2ld.arrive(0, cta_group=1, cta_mask=0) + tile_scheduler.next_tile() + + # ============================================= + # Warpgroup 0: Writeback + # ============================================= + elif wg_id == 0: + wb_ps = PipelineState(1, phase=0) + reg_f16 = T.alloc_local((BLK_N,), d_type) + + while tile_scheduler.valid(): + # Wait for MMA results + mma2ld.wait(wb_ps.stage, wb_ps.phase) + wb_ps.advance() + + # Read TMEM -> registers (warpgroup scope) + reg = T.alloc_local((BLK_N,), acc_type) + reg_wg = reg.view(128, BLK_N, + layout=TileLayout(S[(128, BLK_N) : (1@tid_in_wg, 1)])) + Tx.wg.copy_async(reg_wg[:], tmem[:, :BLK_N]) + T.ptx.tcgen05.wait.ld() + + # Signal TMEM free (all 128 threads arrive) + ld2mma.arrive(0, cta_id=0, pred=True) + + # Cast fp32 -> fp16 + Tx.cast(reg_f16[:], reg[:]) + + # Write to Dsmem + TMA store + Tx.copy(Dsmem[warp_id * 32 + lane_id, :], reg_f16[:]) + T.ptx.fence.proxy_async("shared::cta") + T.cuda.warpgroup_sync(10) + if warp_id == 0: + if lane_id == 0: + Tx.copy_async(D[m_st:m_st+BLK_M, n_st:n_st+BLK_N], + Dsmem[:, :], dispatch="tma") + T.ptx.cp_async.bulk.commit_group() + T.ptx.cp_async.bulk.wait_group(0) + T.cuda.warpgroup_sync(10) + + tile_scheduler.next_tile() + + # --- Cleanup --- + T.cuda.cta_sync() + if warp_id == 0: + T.ptx.tcgen05.relinquish_alloc_permit(cta_group=1) + T.ptx.tcgen05.dealloc(tmem_addr[0], n_cols=512, cta_group=1) + + return kernel +``` + +要运行这些 kernel 中的任意一个,可以复用我们在 Step 1({ref}`zh_chap_gemm_basics`)中展示过的 compile / run / check harness:把 `hgemm_v1` 换成 `hgemm_v7`、`hgemm_v8` 或 `hgemm_v9`,并选择例如 `M=N=K=4096` 的问题规模。注意,cluster 版本要求 `M` 和 `N` 是 cluster tile 的倍数(Step 8 为 `256×256`,Step 9 为 `512×256`),因此很小的 `128×128` 规模根本不会产生 tile。每个 step 请在全新的 Python session 中单独编译,切换 step 前重启 kernel,因为这些 kernel 会复用内部名字,而编译器会保留 session 内状态。各 step 的计时汇总在下面的 *End-to-End Result* 中。 + +### Epilogue(Writeback)细节 + +Step 7 的 epilogue 可以相当简单。因为只有 `BLK_N=128` 列,writeback warpgroup 能一次性把整个 TMEM tile 读入寄存器,然后发起一次 TMA store。Step 8 和 Step 9 就没有这个余裕了,所以后面会引入 chunking;但现在流程是: + +1. 等待 MMA:`mma2ld.wait(phase)`。本教程中的 Step 8 和 Step 9 会在这里额外加一个保守的 `fence.after_thread_sync()`;MMA-completion mbarrier 已经覆盖了顺序保证,大多数 kernel(包括 CUTLASS)都会省略它,所以 Step 7 也省略。 +2. 读取 TMEM -> registers(每个线程 128 个 fp32;warpgroup scope 下通过 `Tx.copy_async(reg_wg, tmem[:, :BLK_N])`,随后 `T.ptx.tcgen05.wait.ld()`)。 +3. 通知 MMA:`ld2mma.arrive(0, cta_id=0, pred=True)`(全部 128 个线程 arrive);此时 TMEM 可以被下一个 tile 复用。这两个 `arrive` kwargs 在 cluster 版本中会再次出现:`cta_id` 表示要 signal *哪个 CTA 的* barrier 副本(`0` = 本 CTA,也就是 local barrier;Step 8 的 cooperative arrive 会改用 `cta_mask` 指向 CTA-0),`pred` 是逐线程谓词,用来决定该线程是否真的 arrive(这里是 `True`,所以每个 writeback 线程都会计入 arrival 总数)。 +4. 在寄存器中把 fp32 转成 fp16。 +5. 写 registers -> Dsmem,然后用 `fence.proxy_async("shared::cta") + warpgroup_sync(10)` 刷新。 +6. 通过 `cp_async.bulk.commit_group() + wait_group(0)` 做 TMA store,把 Dsmem 写回 GMEM。 + +Step 8(`BLK_N=256`)和 Step 9(每个 consumer 的 `MMA_N=256`)不能继续保持这种一次性形式,原因是寄存器压力。每个线程读取 256 个 fp32 值,意味着 256 × 4 = 1024 字节必须同时驻留在该线程寄存器中,这有溢出到 local memory 的风险;同时还会迫使 Dsmem buffer 变大。因此这些 step 会把 writeback 拆成 `EPI_N` 列的 chunk(`EPI_N=64`):每次 iteration 只保留 `EPI_N` 个 fp32 寄存器值,并发起一个相应更小的 TMA store,用少量额外 store 指令换取更舒服的寄存器预算。 + +**实现说明。** + +- **Persistent kernel**:`bx = T.cta_id([SM_COUNT])` --- 每个 SM 一个 CTA,在 tile 上循环 + +- **L2-friendly scheduling**:`ClusterPersistentScheduler2D` 按有利于 cache locality 的顺序安排 tile + +- 这种模式 --- warp specialization 加 software pipelining --- 在高性能 GEMM kernel 中很常见,包括 CUTLASS 风格的设计。 + +### Step 7 行为异常时 + +Step 7 是第一个让 TMA load、`tcgen05` MMA 和 writeback 同时在路上的 GEMM kernel。Step 8 和 Step 9 会反复遇到同样的失败模式:barrier 计数不匹配、role guard 放错位置、缺少 fence,或 TMA store 还没 drain 就复用了 staging buffer。这类问题的调试清单汇总在 {ref}`zh_chap_warp_spec_debug`。 + +**Pipeline depth 调优。** Step 7 kernel 使用最小的 `PIPE_DEPTH=2`。把它推到 4 或 6,可以让 TMA producer 领先 MMA consumer 更远,从而隐藏更多内存延迟;但代价是消耗更多 SMEM,而 SMEM 是有限的。B200 每个 SM 提供 228 KB(见 {ref}`zh_chap_background` 中的 *Numbers to Keep in Mind*)。在 `BLK_M=BLK_N=128, BLK_K=64, fp16` 下,每个 pipeline stage 中 A 和 B 合计消耗 `(128*64 + 128*64) * 2 = 32 KB`,`Dsmem` writeback staging buffer 还要再加 32 KB。因此 `PIPE_DEPTH=4` 大约是 160 KB,`PIPE_DEPTH=6` 大约是 224 KB,已经贴近预算上限。想再深入,就必须重新设计 writeback staging 策略。 + +--- + +warp specialization 让一个 CTA 内的线程协作起来。下一步会把这种协作扩展到 CTA 边界之外,让两个 CTA 共同处理一个更大的 tile。 + + +(zh_chap_cta_cluster)= +## Step 8: 2-CTA Cluster + +Step 7 让各个引擎开始重叠,但每个 CTA 仍然孤立地计算自己的 128×128 tile,重新加载邻居无法借用的 operand。Step 8 打破这种隔离。两个 CTA 组成一个 cluster,并获得访问彼此 shared memory 的能力;于是单个 cooperative `tcgen05` MMA 可以产生一个横跨两者的 256×256 tile,而一次 B 加载现在能喂给两倍的 MMA 工作。和前面一样,M=N=K=4096。 + +> **这个 step 改变了什么:Scope + Layout + Dispatch** +> - Scope:协作 scope 现在跨越 cluster 中的两个 CTA,而不是一个。 +> - Layout:operand tile 被拆分到两个 CTA 的 SMEM 中;CTA 0 拥有共享的 completion barrier(`remote_view`)。 +> - Dispatch:MMA 增加 `cta_group` / `cta_mask`,让 `tcgen05` 以 2-CTA cooperative op 运行。 + +**主题。** + +- CTA cluster:多个 CTA 在一个更大的 tile 上协作 + +- 通过 `map_shared_rank` 进行 cross-CTA SMEM 访问 + +- 在 256x256 cluster tile 上使用 `cta_group=2` 执行 cooperative MMA + +- 使用 `cta_mask` 做 cross-CTA barrier signaling + + +### Cluster Tile 形状 + +整个优化建立在一个硬件能力上:使用 `cta_group=2` 时,MMA 可以读取 *两个* CTA staged 的 operand tile,而不仅是自己所在 CTA 的 tile。每个 CTA 加载 stored B 的一个 128 行切片;转置后,它会变成 128 个逻辑输出列;cooperative MMA 再把两个切片缝合回一个 operand。下图追踪两个 CTA 的 A/B 切片如何合并成单个 256×256 cluster tile: + +```{raw} html +
+ +
+``` +*交互图:每个 CTA 拥有一个 A 行切片和一个 stored-B 行切片,然后通过 cluster(DSMEM)读取另一个 CTA 的 stored-B 切片。经过 `B.T` 后,两个 stored-B 切片覆盖完整的输出列范围,因此这对 CTA 产生一个 256×256 输出 tile。* + +**为什么 A 和 B 要跨 cluster 拆分**:要看清 256×256 tile 如何分区,先回忆本教程把 GEMM 写成 `D = A @ B.T`,其中 stored B 的形状是 `N x K`。有两个 CTA 在一个 cluster 中时,拆分方式非常自然: + +- **A 竖向拆分**:CTA-0 持有 A0(行 0-127),CTA-1 持有 A1(行 128-255)。堆叠后是 `[A0; A1]`(256 行)。 +- **Stored B 按行拆分**:CTA-0 加载 B 行 0-127,CTA-1 加载 B 行 128-255。因为数学上使用 `B.T`,这两个 stored row slice 会变成逻辑右操作数的两个 128 列切片。 +- 使用 `cta_group=2` 时,MMA 硬件通过 cross-CTA shared memory access 从 **两个** CTA 的 SMEM 中读取 B,因此它能看到完整的逻辑输出列范围。 +- 结果:两个 CTA 协作处理一个 256x256 输出 tile。每个 CTA 写出这个 tile 的一个 128x256 行条带。 + +这里值得停一下,看看为什么这是真正的收益,而不只是重新洗牌。每个 CTA 仍然只加载 128×K 的 A 和 128×K 的 B,因此整个 cluster staged operand 约为单个 CTA 的 2×;但它产生的是 256×256 tile,输出 FLOP 大约是 128×128 tile 的 4×。因此每个 staged-operand byte 对应的 MMA 工作量约翻倍,因为每个 CTA 的 B 切片会通过 cooperative MMA 与另一个 CTA 的 A 切片复用。换句话说,arithmetic intensity 大约翻倍,而这正是仍偏 memory-bound 的 kernel 所需要的杠杆:End-to-End 表中约 2.2× 的加速来自让同一批字节服务更多数学计算。 + +### Tile 地址计算 + +现在 cluster 成了工作单元,tile scheduler 也必须按 cluster tile 计数。它返回的每个 `(m_idx, n_idx)` 都表示一个完整的 256×256 区域,cluster 内的两个 CTA 会共同拆分这个区域。把 cluster 坐标转换成每个 CTA 实际加载的 per-CTA slice,形式如下: + +```python +m_st = (m_idx * CTA_GROUP + cbx) * BLK_M +n_st = (n_idx * CTA_GROUP + cbx) * BLK_N +``` + +两个 CTA 处理的是 *同一个* 256×256 cluster tile;单个坐标 `cbx`(该 CTA 在 cluster 内的位置,0 或 1)会在两个轴上选出这个 CTA 的贡献。`m_st` 选择该 CTA 拥有的输出行条带,`n_st` 选择它喂给 cooperative MMA 的 stored-B 切片,writeback 随后会写出 256 列输出范围的两个 128 列半块。还要注意,`num_m_tiles = M // 256` 和 `num_n_tiles = N // 256` 计数的是 cluster tile,而不是单个 CTA tile。 + +乍看之下,`cbx` 同时出现在 `m_st` 和 `n_st` 中,好像一个行偏移泄漏到了列上;但两个用法都是正确的,值得拆开看。在 writeback 路径上,`cbx` 只属于 M 轴:每个 CTA 拥有不同的 128 行条带(`m_st = (m_idx * CTA_GROUP + cbx) * BLK_M`,因此 CTA-0 写 `m_idx*256 .. +128` 行,CTA-1 写接下来的 128 行),但两个 CTA 都会写 cluster tile 的 *完整* 256 个输出列。这也正是 store 的列坐标来自 cluster 的 `n_idx`(`n_st_epi = n_idx * 256 + no * 128`,完全没有 `cbx`),而不是 per-CTA `n_st` 的原因。`n_st` 之所以带着 `cbx`,是因为每个 CTA 会把不同的 stored-B 行切片加载进 MMA:在那里,`cbx` 是一个 *load* offset,而不是该 CTA 的输出列偏移。 + +### 相比 Step 7 的代码变化 + +相对 Step 7 的 diff 有六处改动,每一处都编码了刚才描述的 cluster contract 中的一个部分: + +```python +# 1. Cluster launch +cbx, cby = T.cta_id_in_cluster([CTA_GROUP, 1]) # cbx = CTA index within cluster (0 or 1) + +# 2. Cooperative MMA (was cta_group=1) +Tx.gemm_async(..., cta_group=2) + +# 3. Cross-CTA shared memory access +B_remote = T.ptx.map_shared_rank(Bsmem, cta_id=1) + +# 4. Cross-CTA barrier +tma2mma_cta0 = T.decl_buffer( + [CTA_GROUP], "uint64", + data=T.ptx.map_shared_rank(tma2mma.ptr_to([0]), 0), + scope="shared" +) + +# 5. mma2tma / mma2ld arrives go from cta_mask=0 (single CTA, Step 7) +# to cta_mask=3 (signal both CTAs in the cluster) +mma2tma.arrive(mma_ps.stage, cta_group=CTA_GROUP, cta_mask=3) +mma2ld.arrive(0, cta_group=CTA_GROUP, cta_mask=3) + +# 6. Cluster sync replaces cta_sync at the end +T.cuda.cluster_sync() +``` + + +### Cluster-Scope 变化 + +这六处改动都源自同一个转变:协作 scope 现在是 cluster,而不是单个 CTA。下面几点说明这种扩展在实践中意味着什么:每个 CTA 如何找到自己的位置、cluster 以谁的 barrier 作为协调点,以及究竟哪个 CTA 发出 cooperative MMA。 + +- **Cluster CTA ID**:`cbx` 告诉每个 CTA 它在 cluster 中的位置(0 或 1)。CTA-0 处理 A 行 0-127,CTA-1 处理行 128-255。 + +- **Remote barrier view**:在 cluster 中,每个 CTA 都有自己的 SMEM 和自己的 barrier,这带来一个自然问题:如果 CTA-1 需要等待 CTA-0 产生的东西,它实际应该碰谁的 barrier?答案是指定 CTA-0 的 barrier 作为唯一协调点,并允许 cluster 中任意 CTA 访问它们。`map_shared_rank(tma2mma.ptr_to([0]), 0)` 会返回指向 CTA-0 barrier 的 cluster-wide pointer;TIRx wrapper 是 `tma2mma.remote_view(0)`。从那以后,每次 arrive 和 wait 都指向 CTA-0 的副本。 + +- **MMA 只从 CTA-0 dispatch**:很容易把 `cta_group=2` 理解成并行发射两个引擎,但事实不是这样。CTA-0 只发出一个 `tcgen05.mma`,然后硬件驱动一个跨越两个 CTA 的 *单个 cooperative* MMA:它从两个 SM 的 SMEM 中读取 operand,并把 accumulator 写到两个 SM 的 TMEM 中。CTA-1 完全不发出 MMA。(每个 SM 只有一个 `tcgen05` 引擎,所以 `cta_group=2` 是一次 cross-SM MMA,不是两个引擎并排运行。)这就是代码用 `if cbx == 0:` guard MMA 的原因。 + +- **Multicast arrive**:`tcgen05.commit(..., cta_group=2, cta_mask=3)` 只由 CTA-0 发出,但会 signal 两个 CTA 的 barrier。`cta_mask=3`(二进制 `11`)表示目标包含 CTA-0 和 CTA-1。 + +- **ld2mma init count**:`init(128 * CTA_GROUP)` --- 两个 CTA 的 writeback warpgroup(各 128 个线程)都会 arrive。 + + +**实现。** + +```python +def hgemm_v8(M, N, K): + a_type = tvm.DataType("float16") + b_type = tvm.DataType("float16") + d_type = tvm.DataType("float16") + acc_type = tvm.DataType("float32") + + CTA_GROUP = 2 + BLK_M, BLK_N, BLK_K = 128, 128, 64 + MMA_M, MMA_N = 256, 256 + K_TILES = K // BLK_K + PIPE_DEPTH = 4 + WG_NUMBER = 2 + F16_SIZE = 2 # fp16 + + A_layout = tma_shared_layout(a_type, SwizzleMode.SWIZZLE_128B_ATOM, (PIPE_DEPTH, BLK_M, BLK_K)) + B_layout = tma_shared_layout(b_type, SwizzleMode.SWIZZLE_128B_ATOM, (PIPE_DEPTH, BLK_N, BLK_K)) + D_layout = tma_shared_layout(d_type, SwizzleMode.SWIZZLE_128B_ATOM, (BLK_M, 128)) + + @T.prim_func + def kernel( + A: T.Buffer((M, K), a_type), + B: T.Buffer((N, K), b_type), + D: T.Buffer((M, N), d_type), + ): + T.device_entry() + bx = T.cta_id([SM_COUNT]) + cbx, cby = T.cta_id_in_cluster([CTA_GROUP, 1]) + wg_id = T.warpgroup_id([WG_NUMBER]) + warp_id = T.warp_id_in_wg([4]) + lane_id = T.lane_id([32]) + + # --- Allocation --- + pool = T.SMEMPool() + tmem_addr = pool.alloc((1,), "uint32") + tma2mma = TMABar(pool, PIPE_DEPTH) + mma2tma = TCGen05Bar(pool, PIPE_DEPTH) + mma2ld = TCGen05Bar(pool, 1) + ld2mma = MBarrier(pool, 1) + pool.move_base_to(1024) + Asmem = pool.alloc((PIPE_DEPTH, BLK_M, BLK_K), a_type, layout=A_layout) + Bsmem = pool.alloc((PIPE_DEPTH, BLK_N, BLK_K), b_type, layout=B_layout) + Dsmem = pool.alloc((BLK_M, 128), d_type, layout=D_layout) + + # --- Barrier init --- + tma2mma.init(1) + mma2tma.init(1) + mma2ld.init(1) + ld2mma.init(128 * CTA_GROUP) # both CTAs' writeback threads + pool.commit() + + # --- TMEM alloc (cooperative) --- + if wg_id == 0: + if warp_id == 0: + T.ptx.tcgen05.alloc(T.address_of(tmem_addr), n_cols=512, cta_group=CTA_GROUP) + T.ptx.fence.proxy_async("shared::cta") + T.ptx.fence.mbarrier_init() + T.cuda.cta_sync() + + tmem = T.decl_buffer( + (128, 512), acc_type, scope="tmem", allocated_addr=tmem_addr[0], + layout=TileLayout(S[(128, 512) : (1@TLane, 1@TCol)])) + + # --- Tile scheduler (cluster tiles) --- + tile_scheduler = ClusterPersistentScheduler2D( + "ts", num_m_tiles=M // 256, num_n_tiles=N // 256, + l2_group_size=8, num_clusters=SM_COUNT // CTA_GROUP) + tile_scheduler.init(bx // CTA_GROUP) + m_idx = T.meta_var(tile_scheduler.m_idx) + n_idx = T.meta_var(tile_scheduler.n_idx) + m_st = T.meta_var((m_idx * CTA_GROUP + cbx) * BLK_M) + n_st = T.meta_var((n_idx * CTA_GROUP + cbx) * BLK_N) + + # --- Cross-CTA barrier view --- + tma2mma_cta0 = tma2mma.remote_view(0) + + # ============================================= + # Warpgroup 1: TMA Producer (warp 3) + MMA Consumer (warp 0) + # ============================================= + if wg_id == 1: + if warp_id == 3: + tma_ps = PipelineState(PIPE_DEPTH, phase=1) + + @T.inline + def tma_load(k_offset): + Tx.copy_async(Asmem[tma_ps.stage, :, :], + A[m_st:m_st+BLK_M, k_offset:k_offset+BLK_K], + dispatch="tma", cta_group=CTA_GROUP, + mbar=tma2mma_cta0.ptr_to([tma_ps.stage])) + Tx.copy_async(Bsmem[tma_ps.stage, :, :], + B[n_st:n_st+BLK_N, k_offset:k_offset+BLK_K], + dispatch="tma", cta_group=CTA_GROUP, + mbar=tma2mma_cta0.ptr_to([tma_ps.stage])) + + if T.filter(lane_id, T.ptx.elect_sync()): + while tile_scheduler.valid(): + for k in range(K_TILES): + mma2tma.wait(tma_ps.stage, tma_ps.phase) + tma_load(k * BLK_K) + if cbx == 0: + tma2mma_cta0.arrive(tma_ps.stage, + CTA_GROUP * (BLK_M * BLK_K + BLK_N * BLK_K) * F16_SIZE) + tma_ps.advance() + tile_scheduler.next_tile() + + elif warp_id == 0: + mma_ps = PipelineState(PIPE_DEPTH, phase=0) + ld_ps = PipelineState(1, phase=1) + + if cbx == 0: + if T.filter(lane_id, T.ptx.elect_sync()): + while tile_scheduler.valid(): + ld2mma.wait(ld_ps.stage, ld_ps.phase) + ld_ps.advance() + + for k in range(K_TILES): + tma2mma.wait(mma_ps.stage, mma_ps.phase) + Tx.gemm_async( + tmem[:, :MMA_N], + Asmem[mma_ps.stage, :, :], + Bsmem[mma_ps.stage, :, :], + accum=(k != 0), dispatch="tcgen05", cta_group=CTA_GROUP) + mma2tma.arrive(mma_ps.stage, cta_group=CTA_GROUP, cta_mask=3) + mma_ps.advance() + + mma2ld.arrive(0, cta_group=CTA_GROUP, cta_mask=3) + tile_scheduler.next_tile() + + # ============================================= + # Warpgroup 0: Writeback (256 columns in 2 x 128-column chunks) + # ============================================= + elif wg_id == 0: + wb_ps = PipelineState(1, phase=0) + reg_f16 = T.alloc_local((128,), d_type) + + while tile_scheduler.valid(): + mma2ld.wait(wb_ps.stage, wb_ps.phase) + wb_ps.advance() + T.ptx.tcgen05.fence.after_thread_sync() + + for no in T.unroll(2): # 2 chunks of 128 columns = 256 total + reg = T.alloc_local((128,), acc_type) + reg_wg = reg.view(128, 128, + layout=TileLayout(S[(128, 128) : (1@tid_in_wg, 1)])) + Tx.wg.copy_async(reg_wg[:], tmem[:, no * 128:(no + 1) * 128]) + T.ptx.tcgen05.wait.ld() + Tx.cast(reg_f16[:], reg[:]) + Tx.copy(Dsmem[warp_id * 32 + lane_id, :], reg_f16[:]) + T.ptx.fence.proxy_async("shared::cta") + T.cuda.warpgroup_sync(10) + if warp_id == 0: + if lane_id == 0: + n_st_epi = T.meta_var(n_idx * 256 + no * 128) + Tx.copy_async(D[m_st:m_st+BLK_M, n_st_epi:n_st_epi+128], + Dsmem[:, :], dispatch="tma") + T.ptx.cp_async.bulk.commit_group() + T.ptx.cp_async.bulk.wait_group(0) + T.cuda.warpgroup_sync(10) + + ld2mma.arrive(0, cta_id=0, pred=True) + tile_scheduler.next_tile() + + # --- Cleanup --- + T.cuda.cluster_sync() + if warp_id == 0: + T.ptx.tcgen05.relinquish_alloc_permit(cta_group=CTA_GROUP) + T.ptx.tcgen05.dealloc(tmem_addr[0], n_cols=512, cta_group=CTA_GROUP) + + return kernel +``` + +**2 个 CTA 带来的变化。** + +- `CTA_GROUP = 2`, `MMA_N = BLK_N * CTA_GROUP = 256` + +- `ld2mma.init(128 * CTA_GROUP)` --- 两个 CTA 的 writeback WG 都会 arrive + +- TMA arrive 字节数包含两个 CTA:`CTA_GROUP * (BLK_M * BLK_K + BLK_N * BLK_K) * F16_SIZE` + +- `tcgen05.alloc` 和 `tcgen05.dealloc` 必须使用 `cta_group=2` + +- Writeback 会把 256 个输出列拆成两个 128 列 chunk --- 一次读取全部 256 个 TMEM 列会超过寄存器容量。Step 9 会进一步把 chunk 缩小到 `EPI_N=64` + +- 末尾用 `cluster_sync()` 替换 `cta_sync()`(确保 TMEM dealloc 前所有 CTA 都已完成) + +额外的 arithmetic intensity 会直接体现在墙钟时间上:Step 8 在 4096³ 下达到 **0.104 ms**,相比相同规模下 70 ms 的 Step-1 算法约快 676×(见 End-to-End 表)。这个 kernel 现在已经开始偏向 compute-bound,这正好为 Step 9 铺路:我们会加入第二个 MMA consumer,让更多 Tensor Core 工作保持在飞行中。 + +如果 Step 8 反而比 Step 7 *更慢*,问题几乎总是某个新的 cluster contract 写偏了。优先检查三件事:TMA arrive byte count 是否为 `CTA_GROUP * (BLK_M*BLK_K + BLK_N*BLK_K) * F16_SIZE`;256×256 cluster tile 对应的 scheduler 维度是否是 `num_m_tiles=M//256, num_n_tiles=N//256`;writeback 是否确实发起两次 TMA store(每个 128 列 chunk 一次),且每次都在 Dsmem 复用前 drain 完。 + +--- + +Cluster 提升的是 CTA *之间* 的复用。最后一步转向内部:给 producer 再配一个 MMA consumer,让每个 CTA *内部* 的计算密度更高。 + + +(zh_chap_multi_consumer)= +## Step 9: Multi-Consumer Warp Specialization + +到 Step 8,MMA 已经真正忙起来了;但单个 consumer warp 消化 staged B tile 的速度毕竟有限,而这块 B tile 一直待在 SMEM 中,任何愿意读取它的角色都能复用。最后一个优化正是利用这一点:加入第二个 MMA consumer,用 *不同的* A block 乘同一个 B tile。每个 CTA 的计算密度翻倍,cluster 输出从 256×256 增长到 512×256。和前面一样,M=N=K=4096。 + +> **这个 step 改变了什么:Scope + Layout** +> - Scope:一个 MMA consumer 变成两个,由 `warp_id` 选择。 +> - Layout:同一个 staged B tile 被两个 consumer 复用;A 增加一个 consumer 轴。 +> - Dispatch:不变。 + +**主题。** + +- 多个 MMA warp(consumer)以获得更高吞吐 + +- 多个 writeback warpgroup,各自拥有独立 barrier slot + +- 本教程中最高优化 GEMM 变体使用的结构 + + +### Multi-Consumer 结构 + +加入第二个 consumer 意味着 kernel 现在需要安排更多独立角色:两个 MMA warp,而不是一个;再配一个第二 writeback warpgroup,用来 drain 额外的 accumulator。在 `NUM_CONSUMER=2` 且 `WG_NUMBER=3` 时,kernel 现在横跨三个 warpgroup(角色表中缩写为 WG): + +| Warpgroup | Warp | 角色 | +|-----------|------|------| +| **WG 2** | warp 0 | MMA consumer 0:`Asmem[..., 0] x B` -> TMEM cols `[0:256]` | +| **WG 2** | warp 1 | MMA consumer 1:`Asmem[..., 1] x B` -> TMEM cols `[256:512]` | +| **WG 2** | warp 3 | TMA producer:每个 stage 加载 2x A block + 1x B block | +| **WG 0** | all | consumer 0 的 writeback:读取 TMEM `[0:256]` | +| **WG 1** | all | consumer 1 的 writeback:读取 TMEM `[256:512]` | + +整个安排依赖一个不对称性。每个 consumer 都用自己的 A block 去乘 *同一个* staged B tile,因此一次 B 加载现在能喂给 2× 的 MMA 工作,B 在每个有效 FLOP 上的加载成本等效减半。我们共享 B 而不是 A,是因为两个 consumer 覆盖不同的 M 行条带:它们的 A block 确实是不同数据,而 B 对两者完全相同。练习 3 会让你说服自己:这是唯一可行的共享方式。 + +### 相比 Step 8 的变化 + +具体来说,支持第二个 consumer 会触碰 kernel 中的几个地方,而每处变化都可以追溯到同一个事实:每个 stage 现在要喂给并 drain 两个 A block 和两个 TMEM range,而 B 保持共享。下面这些修改会额外 stage 一个 A block,给每个 consumer 自己的 barrier slot,并为更高的 512×256 cluster tile 调整 tile addressing。 + +- `Asmem = pool.alloc((PIPE_DEPTH, NUM_CONSUMER, BLK_M, BLK_K), ...)` --- 每个 stage 有 2 个 A block,每个 consumer 一个 + +- TMA 同时加载 `Asmem[stage, 0]` 和 `Asmem[stage, 1]`,TMA arrive bytes 现在是 `CTA_GROUP * (NUM_CONSUMER * BLK_M * BLK_K + BLK_N * BLK_K) * F16_SIZE`(多了一个 A block) + +- MMA warp 用 `warp_id` 选择哪个 A block 和哪个 TMEM range + +- `mma2tma.init(NUM_CONSUMER)` --- 每个 stage 中两个 consumer 都会 signal TMA + +- `mma2ld` 和 `ld2mma` 都有 `depth=NUM_CONSUMER` --- 每个 consumer 使用自己的 barrier slot(MMA 侧用 `warp_id`,writeback 侧用 `wg_id`) + +- Tile 地址:`m_st = (m_idx * NUM_CONSUMER * CTA_GROUP + cbx) * BLK_M` --- M 方向多了一个 `NUM_CONSUMER` 因子,因为每个 cluster tile 现在在 M 方向跨越 `NUM_CONSUMER` 个 consumer。Tile scheduler 使用 `num_m_tiles = M // 256 // NUM_CONSUMER`(cluster tile 为 512x256) + +- Writeback 使用分块的 `EPI_N`,让每次 iteration 中活跃在寄存器里的 TMEM-readback 值更少 + + +**实现。** + +```python +def hgemm_v9(M, N, K): + a_type = tvm.DataType("float16") + b_type = tvm.DataType("float16") + d_type = tvm.DataType("float16") + acc_type = tvm.DataType("float32") + + CTA_GROUP = 2 + NUM_CONSUMER = 2 + BLK_M, BLK_N, BLK_K = 128, 128, 64 + MMA_N = BLK_N * CTA_GROUP # 256 + K_TILES = K // BLK_K + PIPE_DEPTH = 4 + EPI_N = 64 + WG_NUMBER = 3 + F16_SIZE = 2 # fp16 + + A_layout = tma_shared_layout(a_type, SwizzleMode.SWIZZLE_128B_ATOM, + (PIPE_DEPTH, NUM_CONSUMER, BLK_M, BLK_K)) + B_layout = tma_shared_layout(b_type, SwizzleMode.SWIZZLE_128B_ATOM, + (PIPE_DEPTH, BLK_N, BLK_K)) + D_layout = tma_shared_layout(d_type, SwizzleMode.SWIZZLE_128B_ATOM, + (NUM_CONSUMER, BLK_M, EPI_N)) + + @T.prim_func + def kernel( + A: T.Buffer((M, K), a_type), + B: T.Buffer((N, K), b_type), + D: T.Buffer((M, N), d_type), + ): + T.device_entry() + bx = T.cta_id([SM_COUNT]) + cbx, cby = T.cta_id_in_cluster([CTA_GROUP, 1]) + wg_id = T.warpgroup_id([WG_NUMBER]) + warp_id = T.warp_id_in_wg([4]) + lane_id = T.lane_id([32]) + + # --- Allocation --- + pool = T.SMEMPool() + tmem_addr = pool.alloc((1,), "uint32") + tma2mma = TMABar(pool, PIPE_DEPTH) + mma2tma = TCGen05Bar(pool, PIPE_DEPTH) + mma2ld = TCGen05Bar(pool, NUM_CONSUMER) # depth=2, one slot per consumer + ld2mma = MBarrier(pool, NUM_CONSUMER) # depth=2, one slot per consumer + pool.move_base_to(1024) + Asmem = pool.alloc((PIPE_DEPTH, NUM_CONSUMER, BLK_M, BLK_K), a_type, layout=A_layout) + Bsmem = pool.alloc((PIPE_DEPTH, BLK_N, BLK_K), b_type, layout=B_layout) + Dsmem = pool.alloc((NUM_CONSUMER, BLK_M, EPI_N), d_type, layout=D_layout) + + # --- Barrier init --- + tma2mma.init(1) + mma2tma.init(NUM_CONSUMER) # each stage expects 2 arrivals + mma2ld.init(1) # each slot gets 1 arrival + ld2mma.init(128 * CTA_GROUP) # both CTAs' writeback threads + pool.commit() + + # --- TMEM alloc (cooperative) --- + if wg_id == 0: + if warp_id == 0: + T.ptx.tcgen05.alloc(T.address_of(tmem_addr), n_cols=512, cta_group=CTA_GROUP) + T.ptx.fence.proxy_async("shared::cta") + T.ptx.fence.mbarrier_init() + T.cuda.cta_sync() + + tmem = T.decl_buffer( + (128, 512), acc_type, scope="tmem", allocated_addr=tmem_addr[0], + layout=TileLayout(S[(128, 512) : (1@TLane, 1@TCol)])) + + # --- Tile scheduler (512x256 cluster tiles) --- + tile_scheduler = ClusterPersistentScheduler2D( + "ts", num_m_tiles=M // 256 // NUM_CONSUMER, num_n_tiles=N // 256, + l2_group_size=8, num_clusters=SM_COUNT // CTA_GROUP) + tile_scheduler.init(bx // CTA_GROUP) + m_idx = T.meta_var(tile_scheduler.m_idx) + n_idx = T.meta_var(tile_scheduler.n_idx) + m_st = T.meta_var((m_idx * NUM_CONSUMER * CTA_GROUP + cbx) * BLK_M) + n_st = T.meta_var((n_idx * CTA_GROUP + cbx) * BLK_N) + + tma2mma_cta0 = tma2mma.remote_view(0) + + # ============================================= + # Warpgroup 2: TMA Producer (warp 3) + 2 MMA Consumers (warp 0, 1) + # ============================================= + if wg_id == 2: + if warp_id == 3: + # === TMA Producer: loads 2 A blocks + 1 B block per stage === + tma_ps = PipelineState(PIPE_DEPTH, phase=1) + + @T.inline + def tma_load(k_offset): + m_st_c1 = T.meta_var(m_st + CTA_GROUP * BLK_M) + Tx.copy_async(Asmem[tma_ps.stage, 0, :, :], + A[m_st:m_st+BLK_M, k_offset:k_offset+BLK_K], + dispatch="tma", cta_group=CTA_GROUP, + mbar=tma2mma_cta0.ptr_to([tma_ps.stage])) + Tx.copy_async(Asmem[tma_ps.stage, 1, :, :], + A[m_st_c1:m_st_c1+BLK_M, k_offset:k_offset+BLK_K], + dispatch="tma", cta_group=CTA_GROUP, + mbar=tma2mma_cta0.ptr_to([tma_ps.stage])) + Tx.copy_async(Bsmem[tma_ps.stage, :, :], + B[n_st:n_st+BLK_N, k_offset:k_offset+BLK_K], + dispatch="tma", cta_group=CTA_GROUP, + mbar=tma2mma_cta0.ptr_to([tma_ps.stage])) + + if T.filter(lane_id, T.ptx.elect_sync()): + while tile_scheduler.valid(): + for k in range(K_TILES): + mma2tma.wait(tma_ps.stage, tma_ps.phase) + tma_load(k * BLK_K) + if cbx == 0: + tma2mma_cta0.arrive(tma_ps.stage, + CTA_GROUP * (NUM_CONSUMER * BLK_M * BLK_K + BLK_N * BLK_K) * F16_SIZE) + tma_ps.advance() + tile_scheduler.next_tile() + + elif warp_id < NUM_CONSUMER: + # === MMA Consumer: warp_id selects A block and TMEM range === + mma_ps = PipelineState(PIPE_DEPTH, phase=0) + ld_ps = PipelineState(1, phase=1) + + if cbx == 0: + if T.filter(lane_id, T.ptx.elect_sync()): + while tile_scheduler.valid(): + ld2mma.wait(warp_id, ld_ps.phase) + ld_ps.advance() + + for k in range(K_TILES): + tma2mma.wait(mma_ps.stage, mma_ps.phase) + Tx.gemm_async( + tmem[:, warp_id * MMA_N:warp_id * MMA_N + MMA_N], + Asmem[mma_ps.stage, warp_id, :, :], + Bsmem[mma_ps.stage, :, :], + accum=(k != 0), dispatch="tcgen05", cta_group=CTA_GROUP) + mma2tma.arrive(mma_ps.stage, cta_group=CTA_GROUP, cta_mask=3) + mma_ps.advance() + + mma2ld.arrive(warp_id, cta_group=CTA_GROUP, cta_mask=3) + tile_scheduler.next_tile() + + # ============================================= + # Warpgroup 0/1: Writeback (each reads its consumer's TMEM range) + # ============================================= + elif wg_id < NUM_CONSUMER: + wb_ps = PipelineState(1, phase=0) + reg_f16 = T.alloc_local((EPI_N,), d_type) + + while tile_scheduler.valid(): + mma2ld.wait(wg_id, wb_ps.phase) # wait for THIS consumer + wb_ps.advance() + T.ptx.tcgen05.fence.after_thread_sync() + + # Read TMEM in EPI_N=64 column chunks (4 iterations for 256 cols) + for i in T.unroll(MMA_N // EPI_N): + reg = T.alloc_local((EPI_N,), acc_type) + reg_wg = reg.view(128, EPI_N, + layout=TileLayout(S[(128, EPI_N) : (1@tid_in_wg, 1)])) + col_st = T.meta_var(wg_id * MMA_N + i * EPI_N) + col_end = T.meta_var(wg_id * MMA_N + i * EPI_N + EPI_N) + Tx.wg.copy_async(reg_wg[:], tmem[:, col_st:col_end]) + T.ptx.tcgen05.wait.ld() + Tx.cast(reg_f16[:], reg[:]) + Tx.copy(Dsmem[wg_id, warp_id * 32 + lane_id, :], reg_f16[:]) + T.ptx.fence.proxy_async("shared::cta") + T.cuda.warpgroup_sync(wg_id + 10) + if warp_id == 0: + if lane_id == 0: + m_st_epi = T.meta_var( + (m_idx * NUM_CONSUMER * CTA_GROUP + wg_id * CTA_GROUP + cbx) * BLK_M) + n_st_epi = T.meta_var(n_idx * MMA_N + i * EPI_N) + Tx.copy_async( + D[m_st_epi:m_st_epi+BLK_M, n_st_epi:n_st_epi+EPI_N], + Dsmem[wg_id, :, :], dispatch="tma") + T.ptx.cp_async.bulk.commit_group() + T.ptx.cp_async.bulk.wait_group(0) + T.cuda.warpgroup_sync(wg_id + 10) + + ld2mma.arrive(wg_id, cta_id=0, pred=True) + tile_scheduler.next_tile() + + # --- Cleanup --- + T.cuda.cluster_sync() + if warp_id == 0: + T.ptx.tcgen05.relinquish_alloc_permit(cta_group=CTA_GROUP) + T.ptx.tcgen05.dealloc(tmem_addr[0], n_cols=512, cta_group=CTA_GROUP) + + return kernel +``` + +**实现说明。** + +- 在这个 Step 9 设计中,`mma2ld` 和 `ld2mma` 各自都是一个带 `depth=NUM_CONSUMER` 的共享对象,而不是分开的 per-consumer 对象。slot 0 连接 MMA warp 0 和 Warpgroup 0,slot 1 连接 MMA warp 1 和 Warpgroup 1;MMA 侧用 `warp_id` 索引,writeback 侧用 `wg_id` 索引。 + +## End-to-End 结果 + +下表给出了从 naive baseline 到 warp-specialized cluster kernel 的实测里程碑,并列出 cuBLAS reference。参考数字来自 NVIDIA B200,M=N=K=4096,fp16,锁频,1000 次 iteration 计时 benchmark: + +| Step | 技术 | 时间 | 加速比 | +|------|------|------|--------| +| 1 | 同步加载 + MMA | 70 ms | 1× | +| 2 | K-loop accumulation | --- | 处理大于单 tile 的 K | +| 3 | Spatial tiling | 53.6 ms | ~1.3× | +| 4 | TMA async load | 0.49 ms | ~142× | +| 5 | Software pipeline | --- | 重叠加载与计算 | +| 6 | Persistent kernel | --- | L2 cache locality | +| 7 | Warp specialization | 0.23 ms | ~309× | +| 8 | 2-CTA cluster | 0.104 ms | ~676× | +| 9 | Multi-consumer | 0.094 ms | ~744× | +| --- | cuBLAS(reference) | 0.094 ms | ~744× | + +表中的所有时间,包括 70 ms 的 Step 1 baseline,都是在同一个 M=N=K=4096 规模下测得的,所以整条加速链可以端到端比较。这里有必要精确说明 70 ms 指什么,因为它很容易被误读。它 *不是* {ref}`zh_chap_gemm_basics` 中那个单 tile Step-1 kernel 在 4096³ 上运行的结果;那个 kernel 只会计算一个 128×128 tile,也只在小规模下运行。这里的 70 ms 指的是一个 naive full-size baseline:它采用同样的顺序、单 tile 思路,并把它扩展到完整 4096³ 问题。{ref}`zh_chap_gemm_basics` 中的 Steps 1–3 用小规模(128×128 和 256³)引入,是为了让前几段讲解保持简单;这里的 Step 1 和 Step 3 行是它们对应的 full-size benchmark。其余破折号(Steps 2、5、6)表示这些 step 用于展示结构,但没有单独计时。 + +请把这些数字理解为一次受控条件下的 B200 reference run,而不是 leaderboard 成绩。每个 step 中嵌入的 `{.python .input}` benchmark cell 是 smoke benchmark:适合观察趋势,不适合宣称峰值性能。 + +几乎所有收益都来自四项技术: + +1. **TMA Async Data Movement**:硬件 copy engine 替代 software copy(Step 1 → Step 4 约 142×)。这个 142× 要正确理解:它反映的是从单个 128×128-tile kernel(grid 1×1)一路变成带 K-loop、spatial tiling 和大量 CTA 的完整 tiled-and-parallel kernel,*同时* 引入 TMA;它不是 TMA 单独贡献。要隔离 TMA,就需要比较两个 full-size kernel,且它们只在 copy 机制上不同。 +2. **Software Pipelining + Warp Specialization**:通过给加载和计算各自专用角色来重叠二者(Step 4 → Step 7 约 2.2×)。 +3. **CTA Clusters**:2-SM cooperative MMA 提升跨 CTA 的 B-tile 复用(本 benchmark 中 Step 7 → Step 8 约 2.2×)。 +4. **Multi-Consumer**:两个 MMA warp 带来更高计算密度(Step 8 → Step 9 约 10%)。 + +如果把这些里程碑画出来,同样四项贡献就形成了从同步 tiled kernel 逐步逼近 cuBLAS reference 的下降轨迹。下图展示了选取的实测点: + +![GEMM 优化历程](../img/gemm_perf.png) + +注意,越往后收益越小,这背后有结构性原因,不是优化力度变弱。早期 step 处理的是 *memory* 瓶颈(TMA 替代 software copy,cluster 提升 arithmetic intensity),而 70 ms 中的大部分时间确实花在那里,所以这些 step 收益最大。到 Step 8 时,kernel 已经进入 cuBLAS 约 10% 范围内(0.104 vs 0.094 ms),并接近 *compute-bound*,这意味着剩下可隐藏的 memory stall 很少;Step 9 的 multi-consumer overlap 回收了剩余空间中的大部分。接近计算上限时,最终约 10% 的收益正是合理预期:这是一个几乎已经解决的问题所呈现的 diminishing return,而不是优化乏力的信号。 + +本章构建的所有内容(TMA load、`tcgen05` MMA、TMEM readback,以及 warp-specialized barrier)都会直接进入下一章。Flash Attention 会复用它们,然后通过在两个 MMA 阶段之间插入 online-softmax,而不是简单重复同一个 MMA,把难度再抬高一层。 + + +## 练习 + +1. 如果把 Step 7 中 TMA 和 MMA `PipelineState` 的初始 `phase` 都设为 `0`,会发生什么?画出 deadlock 场景。 +2. Step 8 使用 `cta_group=2` 时,TMA arrive byte count 是 `CTA_GROUP * (BLK_M*BLK_K + BLK_N*BLK_K) * F16_SIZE`。既然每个 CTA 加载自己的数据,为什么还要乘以 `CTA_GROUP`? +3. Step 9 中,每个 consumer 处理不同的 M 行,但使用同一个 B tile。为什么共享 B(而不是 A)才是正确选择? + +**试着让你的 agent 做一遍**:粘贴 Step 7 kernel,让它追踪一个 K-tile 如何经过四个 barrier(`tma2mma`、`mma2tma`、`mma2ld`、`ld2mma`)。对每个 barrier,问谁 wait、谁 arrive、哪个 tile 变得可读,以及之后哪个 buffer 可以复用。 diff --git a/zh/chapter_gemm_async/index.md b/zh/chapter_gemm_async/index.md new file mode 100644 index 00000000..34d63266 --- /dev/null +++ b/zh/chapter_gemm_async/index.md @@ -0,0 +1,765 @@ +(zh_chap_gemm_async)= +# 用 TMA 对 GEMM 做 Pipelining + +:::{admonition} 概览 +:class: overview + +- basic GEMM 会轮流执行(copy 一个 tile、compute、copy 下一个 tile),而这些事情本可以同时运行,因此浪费时间。 +- Step 4 切换到 TMA async load,Step 5 对 SMEM 做 double-buffer 并 prefetch(PIPE_DEPTH=2);完整 load/compute overlap 会在 Step 7 通过 warp specialization 到来,Step 6 则用 tile scheduler 把 kernel 变成 persistent。 +- 目标是在 Tensor Core 咀嚼当前 tile 的同时,load 下一个 tile。 +::: + +Tensor Core 是芯片上最昂贵的单元,而上一章中正确的 tiled GEMM 会让它们在大部分时钟周期里闲置。 +kernel 轮流工作:thread 把一个 tile copy 到 shared memory,Tensor Core 处理它,thread copy 下一个 tile,Tensor Core 等待。 +每个 stage 都卡在前一个 stage 上,尽管 load 下一个 tile 和 compute 当前 tile 使用的是完全不同的硬件,本可以同时运行。 +缩小这个差距不需要新的数据路径;tile、layout 和数学都已经正确。需要改变的是工作*何时*发生,以及由*谁*调度。 +本章保持 tile 数据路径完全不变,直接攻击闲置时间。 + +我们会通过三个增量步骤到达那里,而且在开始前知道目的地会很有帮助。 +Step 4 把 bulk GMEM <-> SMEM transfer 交给 TMA,让专用 copy 硬件移动 tile,而不是 thread。 +Step 5 添加 two-stage software pipeline,让下一个 K tile 在当前 tile 仍在相乘时有地方落脚。 +Step 6 把 launch 重塑成由 tile scheduler 驱动的 persistent kernel,从而摊销 per-tile setup, +并允许我们选择能让 operand 保持 hot 的 tile 顺序。整个过程中,SMEM、TMEM 和 register layout 都保持上一章留下的样子。 +唯一真正的新思想,是硬件单元之间的异步 handoff:让一个引擎跑在另一个前面,而不是 lockstep 前进。 + +(zh_chap_tma_async)= +## Step 4:TMA Async Load + +第一步是把 copy 本身移出 critical path。回想 Step 1-3 中 CTA 在做什么: +它的每个 thread 都在计算地址并发出 load 指令,唯一目的只是把 tile 搬进 SMEM。 +这把 instruction bandwidth 花在管线活上,而不是数学上。Step 4 用 TMA 替换同步 `Tx.copy`: +单个 thread 发出一条命令,TMA engine 自己完成整个 tile transfer。 +从这里开始,示例运行在完整 M=N=K=4096 尺寸上,而不是 Step 1-3 的小尺寸; +它们的端到端时间会出现在 {ref}`zh_chap_gemm_advanced` 末尾的 *End-to-End Result* 表中。 + +> **这一步改变什么:Dispatch** +> - Scope:不变,一个 warpgroup。 +> - Layout:不变,同样的 SMEM/TMEM/register tile。 +> - Dispatch:GMEM → SMEM load 从同步 `Tx.copy` 移到 TMA engine。 + +### TMA 发射模式 + +Step 4 的唯一变化,是用 TMA load 替换同步 tile copy,因此值得仔细看这个 load 如何发射。 +源码改动只有几行,但这些行背后的执行模型在性质上不同。同步 `Tx.copy` 是 CTA thread 用自己的指令亲自做的工作; +TMA copy 是一个 thread 发出的命令,之后所有移动由 TMA 硬件完成。把二者放在一起看很有价值。 + +**之前(Step 3)**:全部 128 个 thread 参与 copy,随后 `cta_sync` 让 shared-memory 写入可见: +```python +Tx.cta.copy(Asmem[:, :], A[m_st:m_st+BLK_M, i*BLK_K:(i+1)*BLK_K]) # all 128 threads +Tx.cta.copy(Bsmem[:, :], B[n_st:n_st+BLK_N, i*BLK_K:(i+1)*BLK_K]) +T.cuda.cta_sync() +``` + +**之后(Step 4)**:一个 thread 发射 TMA load,mbarrier 追踪硬件 transfer 何时完成: +```python +tid = warp_id * 32 + lane_id # 0..127 within the warpgroup +if tid == 0: # exactly one thread starts TMA + Tx.copy_async(Asmem, A[...], dispatch="tma") + Tx.copy_async(Bsmem, B[...], dispatch="tma") + T.ptx.mbarrier.arrive.expect_tx(tma_bar, byte_count) # bytes expected from TMA +T.ptx.mbarrier.try_wait(tma_bar, phase) # wait before MMA reads SMEM +``` + +注意,load 由 `tid == 0` gate,而不是由 `elect_sync()` gate,这个区别比看上去更重要。 +`elect.sync` 会*每个 warp* 选出一个 active lane,而一个 warpgroup 有四个 warp, +所以 `elect_sync()` 实际会让四个 thread 进入 load protocol。 +问题在于,这个协议会向 mbarrier 宣布 expected byte count,而且必须恰好宣布一次; +四次宣布会破坏 count,wait 将永远无法正确 release。通过 warpgroup-wide id 精确选择一个 thread,是避免这个问题的干净方式。 + +需要诚实说明 speedup 来自哪里。Step 4 仍然在每次 TMA load 后等待,所以还没有让 load 与 compute overlap; +那是 Step 5 的工作。这里的收益纯粹来自数据移动路径的改变: + +- `Tx.copy` 使用 CTA thread 计算地址并发出 load/store 指令。 +- TMA 使用一条发出的命令启动硬件 tile transfer。address generation、coalescing 和 swizzling 由 TMA descriptor 描述,并由 TMA engine 执行。 + +因此,即使 Step 4 仍然在每次 load 上阻塞,它最终仍然更快。TMA 吸收了 bulk transfer, +让 CTA thread 不必花 instruction bandwidth 来搬运 tile;仅这项节省就足以改变性能。 + +### TMA Load 与 Store 同步 + +我们已经看到 TMA copy 如何发射;故事的另一半是知道它何时完成。切换到 TMA 会同时改变两件事: +谁启动 copy,以及代码如何知道 copy 已完成。第一点从代码中很明显;第二点容易忽略,搞错后得到的是静默 correctness bug,而不是崩溃。 +使用 `Tx.cta.copy` 时,CTA thread 一起做 copy,后面的 `cta_sync()` 足以说明它完成。 +使用 TMA 时,一个被选中的 thread 发射 `Tx.copy_async(..., dispatch="tma")`, +engine 按自己的调度执行 transfer,并通过 mbarrier signal completion。 + +这正是 `cta_sync()` 不再足够的原因。`cta_sync()` 只等待 CTA 自己的 thread, +也只排序它们的 shared-memory 写入;它对 in-flight TMA transfer 一无所知,所以即使 tile 仍在到达,它也会高兴地返回。 +修复方式是显式化 completion:对于 TMA load,被选中的 thread 先告诉 mbarrier 应期待多少字节, +然后 CTA 在任何 MMA 触碰 SMEM tile 前等待*那个* mbarrier。下图端到端追踪这个 handshake。 + +![TMA 异步加载:同步流程](../img/tma_sync_flow.png) + +上图隔离了 load 侧 handshake:一个 selected thread launch TMA,mbarrier +统计 expected bytes,MMA 在读取 SMEM 前等待 release。图中写着 +“Elected Thread”的地方,意思是启动 TMA 的 selected thread;在我们的代码里是 `tid == 0` +thread,而不是 `elect_sync()` lane。 + +把 load path 合起来看:selected thread 发出两个 `copy_async` 调用,然后执行 `arrive.expect_tx(total_bytes)`, +其中 byte count 精确表示 mbarrier 应该等待多少数据。当 engine 移动了这么多字节后, +匹配的 `mbarrier.try_wait(phase)` 才会 release;只有这时,SMEM tile 才能安全喂给 MMA。 + +store 侧经过同样硬件,但等待方式不同,所以需要在脑中清楚区分两种协议: +load 用 mbarrier 和 byte count 追踪 completion,而 store 用 commit group 和 wait group 追踪。 +thread 把 fp16 结果写入 `Dsmem` 并同步后,一个 selected thread 启动 +`Tx.copy_async(D[...], Dsmem, dispatch="tma")`,随后 `cp_async.bulk.commit_group()` +和 `cp_async.bulk.wait_group(0)` 会阻塞到 store drain。这个 wait 不是可选的: +在前一次 store 离开之前,`Dsmem` 不能被下一个 tile 复用。 + +**可以让你的 agent 试试**:追踪一个 K tile 上 Step 4 的 load 和 store 同步。 +识别哪个 thread 启动每个 TMA command,哪个 mbarrier 或 commit group 追踪 completion, +哪个 wait 保护 MMA 对 `Asmem` 和 `Bsmem` 的读取,哪个 wait 保护 `Dsmem` 的复用。 +为什么这里用 `elect_sync()` 选择 TMA load protocol 的 thread 是错误的? + +### 完整 Kernel + +完整 kernel 把 TMA load 和 store 折进 Step 3 结构中,并保持该结构其余部分不变。import 与之前相同: + +```python + +import tvm +from tvm.script import tirx as T +from tvm.script.tirx import tile as Tx +from tvm.tirx.layout import TileLayout, S, TLane, TCol, tid_in_wg +from tvm.tirx.cuda.operator.tile_primitive.tma_utils import tma_shared_layout, SwizzleMode +``` + +它被包在 `hgemm_v4(M, N, K)` 中,这是我们贯穿使用的模式: +wrapper 把 shape-dependent constant 和 layout 放在使用它们的 kernel 旁边。 + +```python +def hgemm_v4(M, N, K): + a_type = tvm.DataType("float16") + b_type = tvm.DataType("float16") + d_type = tvm.DataType("float16") + acc_type = tvm.DataType("float32") + + BLK_M, BLK_N, BLK_K = 128, 128, 64 + K_TILES = K // BLK_K + F16_SIZE = 2 + + A_layout = tma_shared_layout(a_type, SwizzleMode.SWIZZLE_128B_ATOM, (BLK_M, BLK_K)) + B_layout = tma_shared_layout(b_type, SwizzleMode.SWIZZLE_128B_ATOM, (BLK_N, BLK_K)) + D_layout = tma_shared_layout(d_type, SwizzleMode.SWIZZLE_128B_ATOM, (BLK_M, BLK_N)) + + @T.prim_func + def kernel( + A: T.Buffer((M, K), a_type), + B: T.Buffer((N, K), b_type), + D: T.Buffer((M, N), d_type), + ): + T.device_entry() + bx, by = T.cta_id([M // BLK_M, N // BLK_N]) + wg_id = T.warpgroup_id([1]) + warp_id = T.warp_id_in_wg([4]) + lane_id = T.lane_id([32]) + + # --- SMEM allocation (now includes Dsmem for TMA store) --- + pool = T.SMEMPool() + tmem_addr = pool.alloc((1,), "uint32") + tma_bar = pool.alloc((1,), "uint64", align=8) + mma_bar = pool.alloc((1,), "uint64", align=8) + pool.move_base_to(1024) + Asmem = pool.alloc((BLK_M, BLK_K), a_type, layout=A_layout) + Bsmem = pool.alloc((BLK_N, BLK_K), b_type, layout=B_layout) + Dsmem = pool.alloc((BLK_M, BLK_N), d_type, layout=D_layout) + pool.commit() + + # --- Barrier + TMEM init --- + if warp_id == 0 and lane_id == 0: + T.ptx.mbarrier.init(mma_bar.ptr_to([0]), 1) + T.ptx.mbarrier.init(tma_bar.ptr_to([0]), 1) + if warp_id == 0: + T.ptx.tcgen05.alloc(T.address_of(tmem_addr), n_cols=512, cta_group=1) + + T.ptx.fence.proxy_async("shared::cta") + T.ptx.fence.mbarrier_init() + T.cuda.cta_sync() + + tmem = T.decl_buffer( + (128, 512), "float32", scope="tmem", allocated_addr=tmem_addr[0], + layout=TileLayout(S[(128, 512) : (1@TLane, 1@TCol)]) + ) + + m_st = T.meta_var(bx * BLK_M) + n_st = T.meta_var(by * BLK_N) + phase_tma: T.int32 = 0 + phase_mma: T.int32 = 0 + + # --- Inline helpers --- + @T.inline + def tma_load(k_st): + tma_config = T.meta_var({ + "dispatch": "tma", "cta_group": 1, + "mbar": tma_bar.ptr_to([0]) + }) + Tx.copy_async(Asmem[:, :], + A[m_st : m_st + BLK_M, k_st : k_st + BLK_K], + **tma_config) + Tx.copy_async(Bsmem[:, :], + B[n_st : n_st + BLK_N, k_st : k_st + BLK_K], + **tma_config) + T.ptx.mbarrier.arrive.expect_tx( + tma_bar.ptr_to([0]), + (BLK_M * BLK_K + BLK_N * BLK_K) * F16_SIZE + ) + + @T.inline + def mma(accum): + Tx.gemm_async( + tmem[:, :BLK_N], Asmem[:, :], Bsmem[:, :], + accum=accum, dispatch="tcgen05", cta_group=1 + ) + T.ptx.tcgen05.commit(mma_bar.ptr_to([0]), cta_group=1) + + # --- K-loop with TMA async --- + tid = T.meta_var(warp_id * 32 + lane_id) + for k in range(K_TILES): + k_st = T.meta_var(k * BLK_K) + + # Single thread issues TMA load + if tid == 0: + tma_load(k_st) + + # Wait for TMA to finish; the mbarrier release carries SMEM + # visibility to the subsequent MMA, so no extra fence is needed. + T.ptx.mbarrier.try_wait(tma_bar.ptr_to([0]), phase_tma) + + # Single thread issues MMA + if tid == 0: + mma(accum=k != 0) + + # Wait for MMA to finish + T.ptx.mbarrier.try_wait(mma_bar.ptr_to([0]), phase_mma) + phase_tma ^= 1 + phase_mma ^= 1 + + # --- TMA Store Writeback --- + Dreg = T.alloc_local((BLK_N,), acc_type) + Dreg_f16 = T.alloc_local((BLK_N,), d_type) + Dreg_wg = Dreg.view(128, BLK_N, + layout=TileLayout(S[(128, BLK_N) : (1@tid_in_wg, 1)])) + + # Read TMEM -> registers (async; wait.ld then cta_sync to ensure read completes) + Tx.wg.copy_async(Dreg_wg[:, :], tmem[:, :BLK_N]) + T.ptx.tcgen05.wait.ld() + T.cuda.cta_sync() + # Cast fp32 -> fp16 + Tx.cast(Dreg_f16[:], Dreg[:]) + # Write registers -> Dsmem, flush, then sync + Tx.copy(Dsmem[warp_id * 32 + lane_id, 0:BLK_N], Dreg_f16[:]) + T.ptx.fence.proxy_async("shared::cta") + T.cuda.warpgroup_sync(10) + # TMA store: Dsmem -> GMEM. One selected thread starts the store and drains the + # store group before Dsmem is reused. + if tid == 0: + Tx.copy_async(D[m_st : m_st + BLK_M, n_st : n_st + BLK_N], + Dsmem[:, :], dispatch="tma") + T.ptx.cp_async.bulk.commit_group() + T.ptx.cp_async.bulk.wait_group(0) + T.cuda.warpgroup_sync(10) + + # --- Deallocate TMEM --- + T.cuda.cta_sync() + if warp_id == 0: + T.ptx.tcgen05.relinquish_alloc_permit(cta_group=1) + T.ptx.tcgen05.dealloc(tmem_addr[0], n_cols=512, cta_group=1) + + return kernel +``` + +### Kernel 中的 TMA 配置 + +这个 kernel 中几乎所有内容都继承自 Step 3。真正承载 TMA 语义的只有五个配置点,值得逐一认识: + +- **TMA config**:`{"dispatch": "tma", "cta_group": 1, "mbar": tma_bar.ptr_to([0])}` 告诉 `Tx.copy_async` 使用 TMA,并通过 `tma_bar` 报告 load completion。 + +- **Byte count**:`(BLK_M * BLK_K + BLK_N * BLK_K) * 2` 是两个 fp16 operand tile 载入的字节数。`arrive.expect_tx(...)` 把这个 count 交给 mbarrier。 + +- **mbarrier 初始化**:`init(tma_bar.ptr_to([0]), 1)` 创建 TMA load 使用的 completion barrier。 + +- **`@T.inline`**:`tma_load(...)` 和 `mma(...)` 是 helper function。它们会在编译期展开到 kernel body 中,并且可以使用周围 kernel 的变量。 + +- **TMA store 同步**:epilogue 先把 fp16 row 写入 `Dsmem`。`fence.proxy_async` 和 `warpgroup_sync` + 让这些由 thread 写入的 SMEM 值对 TMA store 路径 ready。随后 store 使用 `commit_group()` 和 `wait_group(0)` + 等待 SMEM-to-GMEM transfer 完成。 + +到这里,我们有了正确部件,但节奏仍然错误。Step 4 仍然在启动匹配 MMA 前完成每次 load, +所以 load 和 multiply 从未真正同时运行;我们费力分开的两个引擎仍在轮流工作。 +下一步会保持 TMA load 和 store 路径完全不变,只重新安排 schedule,让一个 K tile 的 load 可以在另一个 K tile 上的 compute 运行时进行。 + +(zh_chap_software_pipeline)= +## Step 5:Software Pipeline(PIPE_DEPTH=2) + +既然两个引擎显然是独立的,为什么 Step 4 仍不能让 load 与 compute overlap? +障碍原来是 storage。只有一对 SMEM tile 时,下一个 load 没地方去: +它必须等当前 MMA 读完这一对 tile 后才能开始,因为提前开始会覆写仍在使用的数据。 +Step 5 通过 double-buffer shared memory 移除这个 storage conflict。 +single-warpgroup loop 仍然会在 launch 下一次 TMA load 前等待每个 MMA, +但现在它有不同 stage 可以 prefetch 和 reuse。我们仍然使用完整 M=N=K=4096 尺寸。 + +> **这一步改变什么:Layout** +> - Scope:不变,一个 warpgroup。 +> - Layout:单个 SMEM tile pair 变成 `PIPE_DEPTH`-stage ring buffer。 +> - Dispatch:不变,仍是 TMA load 和 `tcgen05` MMA;这一步加入 prefetch 和 stage reuse,完整 load/compute overlap 会在 Step 7 到来。 + +### Pipeline Walkthrough + +当 `PIPE_DEPTH=2` 时,kernel 会分配两个 SMEM stage,让 load path 和 MMA path 拥有不同 slot 可用。 + +请把下图读成 two-stage buffer 旨在启用的 pipeline 结构,而不是这个 single-warpgroup kernel 的精确执行 trace。 +Step 5 构建 ring buffer,并 prefetch 后续 stage,但主 loop 仍然在发射下一次 TMA load 前等待当前 MMA。 +完整 load/compute overlap 会在 Step 7 到来,届时 warp specialization 会给 TMA 和 MMA 分配不同角色。 + +![*PIPE_DEPTH=2 的流水线目标调度;这个 single-warpgroup 步骤只做预取,完整重叠会在步骤 7 随 warp 专门化到来*](../img/pipe_depth2.png) + +primed 之后,loop 会在两个 stage 之间交替。两次 TMA load 会预先填满两个 stage; +之后,loop 等待当前 stage,在其上运行 MMA,等待该 MMA 读完这个 stage, +然后把 `k + PIPE_DEPTH` 的 load launch 到刚刚变得可复用的 stage 中。 +这还不是 concurrent TMA/MMA schedule,但它建立了 Step 7 将拆分到 producer 和 consumer 角色上的 ring-buffer 结构。 + +具体来说,代码与 Step 4 有四处不同: + +1. `Asmem` 和 `Bsmem` 增加一个 leading `PIPE_DEPTH` 维度,因此每个 stage 有自己的 SMEM storage。 +2. `tma_bar` 变成数组,每个 stage 一个 mbarrier。 +3. 在主 K loop 之前,kernel prefetch 前两个 stage。 +4. K loop 使用 `stage = k % PIPE_DEPTH`:等待当前 stage,在其上运行 MMA,然后为 `k + PIPE_DEPTH` 复用该 stage。 + +### Pipeline 机制 + +**1. Prefetch**:在主 loop 运行前,我们 load 前 `PIPE_DEPTH` 个 stage, +让 loop 在第一次 iteration 时就总能发现已有数据在等它: +```python +for s in range(min(PIPE_DEPTH, K_TILES)): + tma_load(s, s * BLK_K) +``` + +**2. Main loop**:对每个 K tile,我们等待它的 stage ready,在其上运行 MMA, +然后立即通过 launch 提前 `PIPE_DEPTH` 个 tile 的 load,让这个现在空闲的 stage 重新工作: +```python +stage = k % PIPE_DEPTH +wait(tma_bar[stage], phase_tma) +mma(stage, accum) +wait(mma_bar[0], phase_mma) +phase_mma ^= 1 +tma_load(stage, next_k * BLK_K) +``` + +**3. Phase management**:这是容易绊倒人的部分,但规则比第一眼看上去更简单。 +每个 barrier 的 phase-flip 规则直接来自该 barrier 有多少个 slot,这就是两个 barrier 以不同节奏翻转的原因。 +MMA accumulator 位于一个 TMEM slot 中,所以 `mma_bar` 是单个 barrier(`mma_bar.ptr_to([0])`),每个 iteration 都会重新访问; +每个 iteration 都重新访问的 barrier,必须每个 iteration 翻转 phase。 +TMA barrier 的故事不同:它们形成一个 `PIPE_DEPTH` 元素数组,每个 stage 一个 barrier; +任意给定 stage 的 barrier 只有在 ring 中绕一圈后才会再次出现。因此,`phase_tma` 只在 stage index wrap 回 0 时翻转: +```python +if stage == PIPE_DEPTH - 1: + phase_tma ^= 1 +``` + +**可以让你的 agent 试试**:在 `PIPE_DEPTH=2` 且 `K_TILES=5` 时,让它追踪主 loop。 +对每个 `k`,列出 `stage`、传给 wait 的 `phase_tma` 和 `phase_mma` 值,以及是否发射新的 prefetch。 +`phase_tma` 究竟在哪里翻转?为什么最后两个 iteration 没有 prefetch? + +### 完整 Kernel + +完整 kernel 原样保留 Step 4 的 TMA load 和 store 路径,然后用刚才描述的 staged buffer 和 phase logic 包住它。 +import 不变: + +```python + +import tvm +from tvm.script import tirx as T +from tvm.script.tirx import tile as Tx +from tvm.tirx.layout import TileLayout, S, TLane, TCol, tid_in_wg +from tvm.tirx.cuda.operator.tile_primitive.tma_utils import tma_shared_layout, SwizzleMode +``` + +它被包在 `hgemm_v5(M, N, K)` 中。`PIPE_DEPTH=2` 常量设置 pipeline stage 数量 +(这里是两个,正好是 double buffering): + +```python +PIPE_DEPTH = 2 + +def hgemm_v5(M, N, K): + a_type = tvm.DataType("float16") + b_type = tvm.DataType("float16") + d_type = tvm.DataType("float16") + acc_type = tvm.DataType("float32") + F16_SIZE = 2 + BLK_M, BLK_N, BLK_K = 128, 128, 64 + K_TILES = K // BLK_K + + # Double-buffered layouts: first dimension is pipeline stage + A_layout = tma_shared_layout(a_type, SwizzleMode.SWIZZLE_128B_ATOM, + (PIPE_DEPTH, BLK_M, BLK_K)) + B_layout = tma_shared_layout(b_type, SwizzleMode.SWIZZLE_128B_ATOM, + (PIPE_DEPTH, BLK_N, BLK_K)) + D_layout = tma_shared_layout(d_type, SwizzleMode.SWIZZLE_128B_ATOM, + (BLK_M, BLK_N)) + + @T.prim_func + def kernel( + A: T.Buffer((M, K), a_type), + B: T.Buffer((N, K), b_type), + D: T.Buffer((M, N), d_type), + ): + T.device_entry() + bx, by = T.cta_id([M // BLK_M, N // BLK_N]) + wg_id = T.warpgroup_id([1]) + warp_id = T.warp_id_in_wg([4]) + lane_id = T.lane_id([32]) + + # --- SMEM allocation --- + pool = T.SMEMPool() + tmem_addr = pool.alloc((1,), "uint32") + # Double-buffered TMA barriers (one per stage), single MMA barrier + tma_bar = pool.alloc((PIPE_DEPTH,), "uint64", align=8) + mma_bar = pool.alloc((1,), "uint64", align=8) + pool.move_base_to(1024) + Asmem = pool.alloc((PIPE_DEPTH, BLK_M, BLK_K), a_type, layout=A_layout) + Bsmem = pool.alloc((PIPE_DEPTH, BLK_N, BLK_K), b_type, layout=B_layout) + Dsmem = pool.alloc((BLK_M, BLK_N), d_type, layout=D_layout) + pool.commit() + + # Initialize barriers: PIPE_DEPTH for TMA, 1 for MMA + if warp_id == 0: + if lane_id == 0: + T.ptx.mbarrier.init(mma_bar.ptr_to([0]), 1) + for s in range(PIPE_DEPTH): + T.ptx.mbarrier.init(tma_bar.ptr_to([s]), 1) + if warp_id == 0: + T.ptx.tcgen05.alloc(T.address_of(tmem_addr), n_cols=512, cta_group=1) + + T.ptx.fence.proxy_async("shared::cta") + T.ptx.fence.mbarrier_init() + T.cuda.cta_sync() + + tmem = T.decl_buffer( + (128, 512), acc_type, scope="tmem", allocated_addr=tmem_addr[0], + layout=TileLayout(S[(128, 512) : (1@TLane, 1@TCol)]) + ) + + m_st = T.meta_var(bx * BLK_M) + n_st = T.meta_var(by * BLK_N) + phase_tma: T.int32 = 0 + phase_mma: T.int32 = 0 + + @T.inline + def tma_load(stage, k_offset): + tma_config = T.meta_var({ + "dispatch": "tma", "cta_group": 1, + "mbar": tma_bar.ptr_to([stage]) + }) + Tx.copy_async(Asmem[stage, :, :], + A[m_st:m_st+BLK_M, k_offset:k_offset+BLK_K], + **tma_config) + Tx.copy_async(Bsmem[stage, :, :], + B[n_st:n_st+BLK_N, k_offset:k_offset+BLK_K], + **tma_config) + T.ptx.mbarrier.arrive.expect_tx( + tma_bar.ptr_to([stage]), + (BLK_M * BLK_K + BLK_N * BLK_K) * F16_SIZE) + + @T.inline + def mma(stage, accum): + Tx.gemm_async(tmem[:, :BLK_N], Asmem[stage, :, :], Bsmem[stage, :, :], + accum=accum, dispatch="tcgen05", cta_group=1) + T.ptx.tcgen05.commit(mma_bar.ptr_to([0]), cta_group=1) + + tid = T.meta_var(warp_id * 32 + lane_id) + + # === Prefetch: load first PIPE_DEPTH stages === + if tid == 0: + for s in range(min(PIPE_DEPTH, K_TILES)): + tma_load(s, s * BLK_K) + + # === Main loop === + for k in range(K_TILES): + stage = k % PIPE_DEPTH + + # Wait for TMA to finish loading this stage + T.ptx.mbarrier.try_wait(tma_bar.ptr_to([stage]), phase_tma) + + # MMA on this stage's data + if tid == 0: + mma(stage, accum=(k != 0)) + + T.ptx.mbarrier.try_wait(mma_bar.ptr_to([0]), phase_mma) + phase_mma ^= 1 + + # Issue next prefetch load (k + PIPE_DEPTH) + next_k = k + PIPE_DEPTH + if next_k < K_TILES: + if tid == 0: + tma_load(stage, next_k * BLK_K) + + # TMA phase flips when stage wraps around + if stage == PIPE_DEPTH - 1: + phase_tma ^= 1 + + # === TMA Store Writeback: TMEM -> RF -> Dsmem -> TMA -> GMEM === + Dreg = T.alloc_local((BLK_N,), acc_type) + Dreg_f16 = T.alloc_local((BLK_N,), d_type) + Dreg_wg = Dreg.view(128, BLK_N, + layout=TileLayout(S[(128, BLK_N) : (1@tid_in_wg, 1)])) + Tx.wg.copy_async(Dreg_wg[:, :], tmem[:, :BLK_N]) + T.ptx.tcgen05.wait.ld() + T.cuda.cta_sync() + Tx.cast(Dreg_f16[:], Dreg[:]) + Tx.copy(Dsmem[warp_id * 32 + lane_id, 0:BLK_N], Dreg_f16[:]) + T.ptx.fence.proxy_async("shared::cta") + T.cuda.warpgroup_sync(10) + if tid == 0: + Tx.copy_async(D[m_st : m_st + BLK_M, n_st : n_st + BLK_N], + Dsmem[:, :], dispatch="tma") + T.ptx.cp_async.bulk.commit_group() + T.ptx.cp_async.bulk.wait_group(0) + T.cuda.warpgroup_sync(10) + + # Deallocate TMEM + T.cuda.cta_sync() + if warp_id == 0: + T.ptx.tcgen05.relinquish_alloc_permit(cta_group=1) + T.ptx.tcgen05.dealloc(tmem_addr[0], n_cols=512, cta_group=1) + + return kernel +``` + +(zh_chap_persistent_kernel)= +## Step 6:Persistent Kernel + Tile Scheduler + +到目前为止,一切都在优化单个 tile 内部的工作。Step 6 改变问题的尺度,开始跨 tile 优化。 + +Step 5 为每个 128 x 128 output tile 启动一个 CTA。对于 4096 x 4096 输出, +这意味着 1024 个独立 CTA,每个 CTA 都支付自己的 setup cost,并在自己的 tile 完成后立即消失。 + +Step 6 改为启动固定 CTA 池,然后让每个 CTA 依次处理多个 tile。 +这带来两点收益:setup work 被摊销到多个 tile 上;tile assignment 移入 kernel 内部, +在那里 scheduler 可以选择一种能复用 operand 的顺序。我们仍保持完整 M=N=K=4096 尺寸。 + +> **这一步改变什么:Scope** +> - Scope:固定的 persistent CTA 池,每个 CTA 通过 scheduler 循环处理多个 output tile。 +> - Layout:不变,同样的 per-tile SMEM/TMEM/register 路径。 +> - Dispatch:不变。 + +### Persistent Scheduling + +persistent kernel 的定义性想法是:按硬件规模,而不是按问题规模来设置 grid。 +它启动 `SM_COUNT` 个 CTA,大致每个 SM 一个,不管实际有多少 output tile,目标是让每个 SM 持续保持占用。 +我们有意说“大致”:精确 1:1 residency 并不保证,因为它取决于 occupancy,也取决于硬件如何调度 CTA。 + +在这里目标的 B200 上,`SM_COUNT=148`。这 148 个 CTA 中的每一个,都会循环处理 +`ClusterPersistentScheduler2D` 分配给它的 tile。 + +第一项收益是摊销。TMEM allocation、barrier initialization 和 scheduler state 现在每个 CTA 只发生一次, +并在该 CTA 处理的大约 7 个 tile 间复用,而不是在一次性 CTA 上重复 1024 次。 + +第二项收益来自 scheduler 选择的顺序。设置 `l2_group_size=8` 会把相邻 tile 分组, +因此共享同一 row band 的 tile 会复用相同 A row-tile,共享同一 column band 的 tile 会复用相同 B tile。 +背靠背运行这些 tile,可以让 operand 在 L2 中保持 hot,而不是从 HBM 重新获取。 +这正是 Step 3 留在桌面上的复用。 + +```python +bx = T.cta_id([SM_COUNT]) # 1D grid, one CTA per SM + +tile_scheduler = ClusterPersistentScheduler2D( + "ts", + num_m_tiles=M // BLK_M, + num_n_tiles=N // BLK_N, + l2_group_size=8, # Group 8 nearby tiles together + num_clusters=SM_COUNT +) +tile_scheduler.init(bx) +``` + +跨 tile 循环带来一个容易漏掉的 correctness 后果。每个 tile 都运行自己的全新 K-loop, +这意味着它的 barrier phase 必须从已知状态开始。Step 5 中,一个 CTA 恰好处理一个 tile, +所以只初始化一次 `phase_tma` 和 `phase_mma` 完全没问题。 +Step 6 中,这些 initializer 必须移到 `while tile_scheduler.valid()` loop *内部*, +让每个 tile 都以匹配自己 TMA 和 MMA 工作的 phase state 开始,而不是继承前一个 tile 偶然留下的状态: + +```python +while tile_scheduler.valid(): + phase_tma: T.int32 = 0 + phase_mma: T.int32 = 0 + ... +``` + +### 完整 Kernel + +从结构上说,这个 kernel 只是把 Step 5 的 pipeline 包在 tile-level outer loop 里。 +唯一新的依赖是 scheduler 本身,我们把它和其他依赖一起 import: + +```python + +import tvm +from tvm.script import tirx as T +from tvm.script.tirx import tile as Tx +from tvm.tirx.layout import TileLayout, S, TLane, TCol, tid_in_wg +from tvm.tirx.cuda.operator.tile_primitive.tma_utils import tma_shared_layout, SwizzleMode +from tvm.tirx.lang.tile_scheduler import ClusterPersistentScheduler2D +``` + +grid dimension 现在只是 `SM_COUNT`,而不是 `(M//BLK_M, N//BLK_N)`; +`ClusterPersistentScheduler2D` 接管了给每个 CTA 分配 tile 的工作: + +```python +SM_COUNT = 148 # Number of SMs on NVIDIA B200 GPU +PIPE_DEPTH = 2 + +def hgemm_v6(M, N, K): + a_type = tvm.DataType("float16") + b_type = tvm.DataType("float16") + d_type = tvm.DataType("float16") + acc_type = tvm.DataType("float32") + F16_SIZE = 2 + BLK_M, BLK_N, BLK_K = 128, 128, 64 + K_TILES = K // BLK_K + + A_layout = tma_shared_layout(a_type, SwizzleMode.SWIZZLE_128B_ATOM, + (PIPE_DEPTH, BLK_M, BLK_K)) + B_layout = tma_shared_layout(b_type, SwizzleMode.SWIZZLE_128B_ATOM, + (PIPE_DEPTH, BLK_N, BLK_K)) + D_layout = tma_shared_layout(d_type, SwizzleMode.SWIZZLE_128B_ATOM, + (BLK_M, BLK_N)) + + @T.prim_func + def kernel( + A: T.Buffer((M, K), a_type), + B: T.Buffer((N, K), b_type), + D: T.Buffer((M, N), d_type), + ): + T.device_entry() + # 1D grid: one CTA per SM (not a 2D grid anymore!) + bx = T.cta_id([SM_COUNT]) + wg_id = T.warpgroup_id([1]) + warp_id = T.warp_id_in_wg([4]) + lane_id = T.lane_id([32]) + + # --- SMEM allocation (same as Step 5) --- + pool = T.SMEMPool() + tmem_addr = pool.alloc((1,), "uint32") + tma_bar = pool.alloc((PIPE_DEPTH,), "uint64", align=8) + mma_bar = pool.alloc((1,), "uint64", align=8) + pool.move_base_to(1024) + Asmem = pool.alloc((PIPE_DEPTH, BLK_M, BLK_K), a_type, layout=A_layout) + Bsmem = pool.alloc((PIPE_DEPTH, BLK_N, BLK_K), b_type, layout=B_layout) + Dsmem = pool.alloc((BLK_M, BLK_N), d_type, layout=D_layout) + pool.commit() + + # --- Barrier + TMEM init (same as Step 5) --- + if warp_id == 0 and lane_id == 0: + T.ptx.mbarrier.init(mma_bar.ptr_to([0]), 1) + for s in range(PIPE_DEPTH): + T.ptx.mbarrier.init(tma_bar.ptr_to([s]), 1) + if warp_id == 0: + T.ptx.tcgen05.alloc(T.address_of(tmem_addr), n_cols=512, cta_group=1) + T.ptx.fence.proxy_async("shared::cta") + T.ptx.fence.mbarrier_init() + T.cuda.cta_sync() + + tmem = T.decl_buffer( + (128, 512), acc_type, scope="tmem", allocated_addr=tmem_addr[0], + layout=TileLayout(S[(128, 512) : (1@TLane, 1@TCol)]) + ) + + # Tile scheduler: assigns tiles to CTAs in L2-friendly order + tile_scheduler = ClusterPersistentScheduler2D( + "ts", + num_m_tiles=M // BLK_M, + num_n_tiles=N // BLK_N, + l2_group_size=8, + num_clusters=SM_COUNT + ) + tile_scheduler.init(bx) + + tid = T.meta_var(warp_id * 32 + lane_id) + + @T.inline + def tma_load(stage, k_offset, m_st, n_st): + tma_config = T.meta_var({ + "dispatch": "tma", "cta_group": 1, + "mbar": tma_bar.ptr_to([stage]) + }) + Tx.copy_async(Asmem[stage, :, :], + A[m_st:m_st+BLK_M, k_offset:k_offset+BLK_K], + **tma_config) + Tx.copy_async(Bsmem[stage, :, :], + B[n_st:n_st+BLK_N, k_offset:k_offset+BLK_K], + **tma_config) + T.ptx.mbarrier.arrive.expect_tx( + tma_bar.ptr_to([stage]), + (BLK_M * BLK_K + BLK_N * BLK_K) * F16_SIZE) + + @T.inline + def mma(stage, accum): + Tx.gemm_async(tmem[:, :BLK_N], Asmem[stage, :, :], Bsmem[stage, :, :], + accum=accum, dispatch="tcgen05", cta_group=1) + T.ptx.tcgen05.commit(mma_bar.ptr_to([0]), cta_group=1) + + # === Outer loop: iterate over tiles === + while tile_scheduler.valid(): + # Get current tile position from scheduler + m_st = T.meta_var(tile_scheduler.m_idx * BLK_M) + n_st = T.meta_var(tile_scheduler.n_idx * BLK_N) + + # === Inner loop: same pipeline as Step 5 === + phase_tma: T.int32 = 0 + phase_mma: T.int32 = 0 + + # Prefetch first PIPE_DEPTH stages + if tid == 0: + for s in range(min(PIPE_DEPTH, K_TILES)): + tma_load(s, s * BLK_K, m_st, n_st) + + # Main K-loop + for k in range(K_TILES): + stage = k % PIPE_DEPTH + T.ptx.mbarrier.try_wait(tma_bar.ptr_to([stage]), phase_tma) + if tid == 0: + mma(stage, accum=(k != 0)) + T.ptx.mbarrier.try_wait(mma_bar.ptr_to([0]), phase_mma) + phase_mma ^= 1 + next_k = k + PIPE_DEPTH + if next_k < K_TILES: + if tid == 0: + tma_load(stage, next_k * BLK_K, m_st, n_st) + if stage == PIPE_DEPTH - 1: + phase_tma ^= 1 + + # === TMA Store Writeback: TMEM -> RF -> Dsmem -> TMA -> GMEM === + Dreg = T.alloc_local((BLK_N,), acc_type) + Dreg_f16 = T.alloc_local((BLK_N,), d_type) + Dreg_wg = Dreg.view(128, BLK_N, + layout=TileLayout(S[(128, BLK_N) : (1@tid_in_wg, 1)])) + Tx.wg.copy_async(Dreg_wg[:, :], tmem[:, :BLK_N]) + T.ptx.tcgen05.wait.ld() + T.cuda.cta_sync() + Tx.cast(Dreg_f16[:], Dreg[:]) + Tx.copy(Dsmem[warp_id * 32 + lane_id, 0:BLK_N], Dreg_f16[:]) + T.ptx.fence.proxy_async("shared::cta") + T.cuda.warpgroup_sync(10) + if tid == 0: + Tx.copy_async(D[m_st : m_st + BLK_M, n_st : n_st + BLK_N], + Dsmem[:, :], dispatch="tma") + T.ptx.cp_async.bulk.commit_group() + T.ptx.cp_async.bulk.wait_group(0) + T.cuda.warpgroup_sync(10) + + T.cuda.cta_sync() + tile_scheduler.next_tile() # Move to next tile + + # Deallocate TMEM + T.cuda.cta_sync() + if warp_id == 0: + T.ptx.tcgen05.relinquish_alloc_permit(cta_group=1) + T.ptx.tcgen05.dealloc(tmem_addr[0], n_cols=512, cta_group=1) + + return kernel +``` + +## 练习 + +1. 在 Step 4 中,`arrive.expect_tx` 使用 `(BLK_M * BLK_K + BLK_N * BLK_K) * 2` 字节。如果这个 byte count 太小或太大,mbarrier 会等待什么? +2. 在 Step 5 中,为什么每个 SMEM stage 都需要自己的 TMA barrier,而不是两个 stage 共享一个 `tma_bar`? +3. 在 Step 6 中,`BLK_M=BLK_N=128` 时,一个 4096 x 4096 输出有多少个 output tile?当 `SM_COUNT=148` 时,每个 persistent CTA 平均处理多少个 tile? diff --git a/zh/chapter_gemm_basics/index.md b/zh/chapter_gemm_basics/index.md new file mode 100644 index 00000000..39d2e8b2 --- /dev/null +++ b/zh/chapter_gemm_basics/index.md @@ -0,0 +1,693 @@ +(zh_chap_gemm_basics)= +# 构建 Tiled GEMM + +:::{admonition} 概览 +:class: overview + +- 从单个 output tile 开始,用 TIRx tile primitives 构建一个正确的 tiled GEMM。 +- Step 1 是 single-tile GEMM,Step 2 添加 K-loop accumulation,Step 3 针对完整矩阵跨 CTA 做 spatial tiling。 +- 正确性优先;性能是后两章的任务。 +::: + +GEMM 是整本书围绕的工作负载。它位于 linear layer、attention projection 和 convolution 之下, +而这些操作主导着 GPU 时间。因此,正确 GEMM 和快速 GEMM 之间的差距, +就是让芯片大部分闲置和把芯片打满之间的差距。 + +这个差距太大,无法一步跨过。一个能打满硬件的 kernel 会让你同时 debug memory movement、accumulation、tiling 和 Tensor Core scheduling, +而且没有可信对象可供比较。更安全的路径是从能产生正确答案的最小 kernel 开始,然后一次增加一个决策。 + +本章会写出第一个正确的 tiled GEMM。前面章节从抽象层面介绍了 TIRx 的 scope / layout / dispatch 模型; +这里我们把它应用到真实 kernel。我们从一个 128 x 128 output tile 开始, +逐步把它扩展成能处理完整矩阵的 kernel:先加入 K 维度 accumulation,再跨多个 CTA 加入 spatial tiling。 + +这是三章 GEMM 优化路径中的第一章,三章会端到端走完同一条路径。本章构建一个正确的 tiled kernel,并到此为止。 +下一章({ref}`zh_chap_gemm_async`)会用 TMA 替换 thread copy,并通过 pipelining 让数据移动和计算 overlap; +{ref}`zh_chap_gemm_advanced` 则进一步加入 warp specialization 和 CTA cluster。 +每章都建立在前一章之上,所以 kernel 会逐步积累功能,而不是从头再来。 + +把每一步读成对同一个三项 contract 的修改会很有帮助:哪个 **scope** 运行操作,operand tile 使用哪个 **layout**, +以及由哪条 **dispatch** 路径执行。大多数步骤都有一个主要变化,所以我们会用一个小卡片开头,点明这个变化, +并指出为了安全复用而需要的同步细节。Step 1 建立后续路径要不断修改的 baseline。 + +## GEMM + +GEMM 是 dense matrix multiply,位于 linear layer、attention projection 和许多 convolution 实现之下; +因此,快速 GEMM kernel 几乎处处都有回报。本教程中的例子使用 $D = A B^{\top}$: + +- $A$ 的 shape 是 $M \times K$。 +- $B$ 的 shape 是 $N \times K$。 +- $D$ 的 shape 是 $M \times N$。 +- $D[m,n] = \sum_k A[m,k] \cdot B[n,k]$. + +transpose 不是我们选择额外执行的操作;它来自数据的存储方式。 +这些例子把 $B$ 保持为 $N$ 行、每行长度 $K$,这通常也是 linear-layer weight 的 layout。 +因此,沿 $K$ contract 会自然读取 $B^{\top}$,不需要任何重排。 + +整个教程中,我们用 TFLOPS 吞吐来衡量 kernel:把每次 multiply-add 计为两个 floating-point operation, +再除以 wall-clock time: + +$$\text{TFLOPS} = \frac{2 \times M \times N \times K}{t_{\text{seconds}} \times 10^{12}}$$ + +### GEMM 数据路径 + +本教程中的每个优化最终都落到数据住在哪里、如何移动,所以在写代码前值得先把这条路径画出来。 +从核心上说,Blackwell GEMM kernel 围绕两类活动组织:在不同内存之间移动 tile,以及在 tile 上计算。 +下图追踪一个 tile 从输入到输出过程中接触的每个内存空间: + +![*内存数据流*](../img/memory_dataflow.png) + +上图展示了 baseline 路径:后续每个优化都会修改它,但不会替换它。 +从左到右读:operand tile 先从 GMEM 移到 SMEM;随后 `tcgen05.mma` 消费 SMEM operand, +并把 accumulator 写入 TMEM;最后 epilogue 先把 TMEM 读回寄存器,再把结果存到 GMEM。 +请记住这条链路,因为下面每一步只会改变某一跳*如何*发生,而不会改变这些跳本身。 + +## 优化路径 + +上面这条朴素数据路径足以得到正确答案,但会让大部分硬件闲置。 +教程剩余部分会一次加入一个 Blackwell 特性来缩小这个差距,而每个特性都通过 TIRx tile primitive 表达。 +我们将依次经过这些特性: + +- **TMA async movement** 通过 Blackwell 的硬件 copy path 移动 GMEM <-> SMEM tile,并用 barrier 追踪 completion。 +- **Software pipelining** 使用多个 SMEM stage,让下一个 K tile 的数据移动可以与当前 tile 上的 Tensor Core 计算 overlap。 +- **Persistent scheduling** 保持固定 CTA 池,每个 CTA 通过 tile scheduler 处理许多 output tile,而不是每个 tile 启动一个 CTA。 +- **Warp specialization** 把 producer、MMA consumer 和 writeback 角色拆到独立 warpgroup 上。 +- **CTA clusters** 让两个 CTA 协作处理一个更大的 Blackwell MMA tile。 +- **Multi-consumer execution** 使用多个 consumer warpgroup 同时计算 tile 的不同部分,提高 compute density。 + +--- + +(zh_chap_single_tile)= +## Step 1:顺序 Single-Tile GEMM + +仍然能走完整硬件路径的最简单 GEMM,是计算单个 output tile 的 GEMM。所以我们从这里开始。 +Step 1 计算一个 128 x 128 output tile,K = 64;它足够小,不需要任何 loop, +而数据路径的每个部分都恰好出现一次。由于没有重复,我们可以在需要推理 loop 之前,先孤立地观察每一跳。 + +> **这一步建立什么:baseline** +> - Scope:一个包含 128 个 thread 的单个 warpgroup 按顺序走完整条路径,一个 stage 接一个 stage。 +> - Layout:A 和 B tile 位于 SMEM,accumulator 位于 TMEM,结果通过寄存器 stage 出去。 +> - Dispatch:同步 `Tx.copy` 执行 load,`tcgen05` 执行 MMA。 + +### Single-Tile Dataflow + +baseline contract 固定后,接下来要确定的是一个 tile 穿过它的顺序。 +第一个 kernel 会精确走一次核心 GEMM 数据路径,也就是数据流图中的同一条 GMEM -> SMEM -> TMEM -> registers -> GMEM 链, +外面没有任何 loop。它分配工作内存、载入 operand、计算乘积、写回结果,并清理自身: + +1. **分配**:SMEM(pool allocator)、TMEM(`tcgen05.alloc`)、mbarrier +2. **加载**:全部 128 个 thread 协作地把 A 和 B tile 从 GMEM copy 到 SMEM(同步 `Tx.copy`) +3. **计算**:单个 elected thread 发射 `Tx.gemm_async` + `tcgen05.commit`;所有 thread 等待 mbarrier +4. **写回**:warpgroup 读取 TMEM → registers;每个 thread 把 fp32 cast 为 fp16 并写到 GMEM +5. **释放**:释放 TMEM + +### 第一个 Kernel 的四个部分 + +完整 kernel 只有几十行,但分块阅读更容易消化。我们会分四部分阅读它: +memory allocation、synchronous load、MMA dispatch 和 writeback,之后再把它们组装成一个 kernel。 +过程中出现的 API 名称,是第二部分介绍的 TIRx tile-primitive 词汇({ref}`zh_chap_tirx_primer`,{ref}`zh_chap_tirx_layout_api`)。 + +**Memory allocation。** kernel 首先为 operand 切出 shared memory,同时为 TMEM address 和 mbarrier 留出 slot: + +```python +pool = T.SMEMPool() +tmem_addr = pool.alloc((1,), "uint32") # TMEM address (4 bytes) +mma_bar = pool.alloc((1,), "uint64", align=8) # mbarrier (8 bytes) +pool.move_base_to(1024) # Skip to offset 1024 +Asmem = pool.alloc((BLK_M, BLK_K), a_type, layout=A_layout) # 128×64 fp16 +Bsmem = pool.alloc((BLK_N, BLK_K), b_type, layout=B_layout) # 128×64 fp16 +pool.commit() +``` + +这里有两个细节值得停一下。`pool.move_base_to(1024)` 把 Asmem 和 Bsmem 推到 offset 1024, +把低地址留给前面那些小 metadata,让体积较大的 operand tile 落在干净边界上。 +另外,`layout=A_layout` 会向 `tma_shared_layout` 请求一个 swizzled SMEM placement, +它能被 TMA 和 `tcgen05.mma` 直接读取,正是第二部分描述的那种 layout-as-contract 义务。 + +**Synchronous load。** buffer 到位后,operand 仍然必须到达 SMEM。在第一个版本中,我们让 CTA 自己的 thread 完成 copy: + +```python +Tx.cta.copy(Asmem[:, :], A[:, :]) +Tx.cta.copy(Bsmem[:, :], B[:, :]) +T.cuda.cta_sync() +``` + +因为这里只存在一个 tile(M=N=128,K=64),copy 整个 A 和 B 就是全部 load。 +`Tx.cta.copy(...)` 让 CTA 协作完成这次 copy,每个 thread 负责自己的数据切片。 +后面的 `T.cuda.cta_sync()` 一举两得:它等待每个 thread 完成,同时发布它们的 shared-memory 写入; +这样后续 MMA 读取 `Asmem` 和 `Bsmem` 时,看到的是完整 tile,而不是半填充 buffer。 +这种 thread-driven copy 也是我们首先要替换的东西;下一章({ref}`zh_chap_gemm_async`)会把它换成 TMA。 + +**MMA dispatch。** operand 现在位于 SMEM 中,我们可以发射 MMA,并且从单个 elected thread 发射: + +```python +if warp_id == 0: + if T.ptx.elect_sync(): + Tx.gemm_async(tmem[:, :BLK_N], Asmem[:, :], Bsmem[:, :], + accum=False, dispatch="tcgen05", cta_group=1) + T.ptx.tcgen05.commit(mma_bar.ptr_to([0]), cta_group=1) +``` + +两个嵌套 guard 分两步缩小 issuer。外层 `if warp_id == 0` 只保留 warpgroup 中的 warp 0; +内层 `if T.ptx.elect_sync():` 随后在该 warp 中选出一个 active lane。 +二者合起来只留下一个 thread 来运行 `Tx.gemm_async` 和 `tcgen05.commit`。 + +这里值得说清楚这个单个 thread 意味着什么、不意味着什么,因为自然读法很容易误导。 +单个 issuing thread *并不*意味着单线程乘法。计算仍然是完整 tile-level MMA: +硬件会为 SMEM operand layout 和 TMEM accumulator layout 所描述的 tile 执行 cooperative multiply。 +关键在于 `Tx.gemm_async` 是一个 *tile operation*,不是一条硬件指令。 +K = 64 的 tile 比硬件 MMA K-atom(`MMA_K = 16`)更宽,因此这个 tile op 会 lower 成沿 K 方向前进的一小段 raw `tcgen05.mma` 指令, +warpgroup 会协作驱动其中每一条。只有一个 thread 发射 tile op 的原因是,每个底层 `tcgen05.mma` +本身就是一个 *single-instruction* cooperative op:一次 launch 驱动 tile MMA 的那个 K-atom。 +如果全部 128 个 thread 都发射这个序列,相同工作只会被重复 launch 128 次。 +最后,`accum=False` flag 告诉 MMA 覆写 TMEM destination,而不是加到其中; +这正是我们这里想要的,因为没有先前 partial sum 需要扩展。 + +**Writeback。** 乘积现在位于 TMEM 中,但 caller 想要它以 fp16 回到 GMEM。 +因此 epilogue 必须通过寄存器把结果带下来,并在途中 cast: + +```python +Dreg = T.alloc_local((BLK_N,), acc_type) # per-thread fp32 register row +Dreg_f16 = T.alloc_local((BLK_N,), d_type) # same row, cast to fp16 +Dreg_wg = Dreg.view(128, BLK_N, layout=TileLayout(S[(128, BLK_N) : (1@tid_in_wg, 1)])) +Tx.wg.copy_async(Dreg_wg[:, :], tmem[:, :BLK_N]) +T.ptx.tcgen05.wait.ld() +Tx.cast(Dreg_f16[:], Dreg[:]) +m_thr = T.meta_var(m_st + warp_id * 32 + lane_id) +Tx.copy(D[m_thr, n_st : n_st + BLK_N], Dreg_f16[:]) +``` + +MMA 会在 TMEM 中留下一个 128 x 128 fp32 accumulator tile。fp32 是有意选择的: +GEMM 会沿 K 累加许多乘积,用更高精度保存 running sum 可以压低本来会积累的舍入误差。 +但 `D` 是 fp16,所以这些值不能直接写出。它们先落入寄存器,在那里缩窄为 fp16,然后才到达 GMEM。 + +两个 register buffer 扮演不同角色。`Dreg` 是每个 thread 的 `BLK_N` 元素 buffer, +而 `Dreg_wg` 是同一批寄存器在选定 layout 下的 warpgroup-wide *view*: + +```python +TileLayout(S[(128, BLK_N) : (1@tid_in_wg, 1)]) +``` + +这个 layout 把 tile 的第一维映射到 warpgroup 的 thread:thread 0 拥有 row 0,thread 1 拥有 row 1, +依此类推直到 row 127。第二维保留在每个 thread 自己的 register buffer 中, +所以一个 thread 持有自己那一行的所有 column。warpgroup 中有 128 个 thread,tile 中有 128 行, +因此 128 x 128 输出正好分成每个 thread 一行。 + +在这个 view 下读出 accumulator,正是 `Tx.wg.copy_async(Dreg_wg, tmem)` 所做的事; +它会 lower 到 Blackwell TMEM load path,即 `tcgen05.ld`。因为这个 load 是异步的, +`T.ptx.tcgen05.wait.ld()` 必须在任何 thread 触碰 `Dreg` 前完成;否则 thread 可能读取 load 还没有填好的寄存器。 + +wait 返回后,每个 thread 私有的 `Dreg[:]` 都持有自己那一条逻辑 output row 的 fp32 值。 +thread 在 `Dreg_f16` 中把这些值缩窄为 fp16,并算出自己负责哪个 global row: + +```python +m_thr = T.meta_var(m_st + warp_id * 32 + lane_id) +``` + +然后写入 `D[m_thr, n_st:n_st + BLK_N]`。这些 row 干净地分布在四个 warp 上: +warp 0 写 row 0-31,warp 1 写 row 32-63,warp 2 写 row 64-95,warp 3 写 row 96-127。 + +### 完整 Kernel + +现在把四个部分重新拼成一个可运行 kernel(M=N=128,K=64)。先是 import: + +```python + +import tvm +from tvm.script import tirx as T +from tvm.script.tirx import tile as Tx +from tvm.tirx.cuda.operator.tile_primitive.tma_utils import tma_shared_layout, SwizzleMode +from tvm.tirx.layout import TileLayout, S, TLane, TCol, tid_in_wg +``` + +kernel 包在后续步骤也会使用的 `hgemm_vX(M, N, K)` 风格中。 +Step 1 使用 `M=N=128, K=64` 运行,因此 launch 恰好包含一个 output tile: + +```python +def hgemm_v1(M, N, K): + a_type = tvm.DataType("float16") + b_type = tvm.DataType("float16") + d_type = tvm.DataType("float16") + acc_type = tvm.DataType("float32") + + BLK_M, BLK_N, BLK_K = 128, 128, 64 + # MMA_M/MMA_N/MMA_K document the underlying hardware MMA tile; they are not + # passed to gemm_async (which derives the MMA shape from the operand and + # accumulator tiles), so the later steps omit them. + MMA_M, MMA_N, MMA_K = 128, 128, 16 + + A_layout = tma_shared_layout(a_type, SwizzleMode.SWIZZLE_128B_ATOM, (BLK_M, BLK_K)) + B_layout = tma_shared_layout(b_type, SwizzleMode.SWIZZLE_128B_ATOM, (BLK_N, BLK_K)) + + @T.prim_func + def kernel( + A: T.Buffer((M, K), a_type), + B: T.Buffer((N, K), b_type), + D: T.Buffer((M, N), d_type), + ): + T.device_entry() + # Step 1 is a single-tile kernel: M = BLK_M and N = BLK_N, so the grid + # is 1x1. Starting with a 1x1 grid keeps the per-CTA tile offsets + # (m_st, n_st) trivially zero; Steps 3+ generalise this to larger M / N. + bx, by = T.cta_id([M // BLK_M, N // BLK_N]) + wg_id = T.warpgroup_id([1]) # single warpgroup, so wg_id is always 0 (unused below) + warp_id = T.warp_id_in_wg([4]) + lane_id = T.lane_id([32]) + + # --- SMEM allocation --- + pool = T.SMEMPool() + tmem_addr = pool.alloc((1,), "uint32") + mma_bar = pool.alloc((1,), "uint64", align=8) + pool.move_base_to(1024) + Asmem = pool.alloc((BLK_M, BLK_K), a_type, layout=A_layout) + Bsmem = pool.alloc((BLK_N, BLK_K), b_type, layout=B_layout) + pool.commit() + + # --- Barrier + TMEM init (warp 0 only) --- + if warp_id == 0: + if lane_id == 0: + T.ptx.mbarrier.init(mma_bar.ptr_to([0]), 1) + T.ptx.tcgen05.alloc(T.address_of(tmem_addr), n_cols=512, cta_group=1) + + T.ptx.fence.proxy_async("shared::cta") + T.ptx.fence.mbarrier_init() + T.cuda.cta_sync() + + tmem = T.decl_buffer( + (128, 512), "float32", scope="tmem", allocated_addr=tmem_addr[0], + layout=TileLayout(S[(128, 512) : (1@TLane, 1@TCol)]) + ) + + m_st = T.meta_var(bx * BLK_M) + n_st = T.meta_var(by * BLK_N) + phase_mma: T.int32 = 0 + + # --- Load: all threads copy global -> shared (synchronous). + # With M=BLK_M and N=BLK_N the slices below cover the full matrices; + # the slice form is kept so the diff to Step 3 (multi-tile) is minimal. + Tx.cta.copy(Asmem[:, :], A[m_st:m_st + BLK_M, :]) + Tx.cta.copy(Bsmem[:, :], B[n_st:n_st + BLK_N, :]) + T.cuda.cta_sync() + + # --- Compute: single elected thread issues MMA --- + if warp_id == 0: + if T.ptx.elect_sync(): + Tx.gemm_async( + tmem[:, :BLK_N], Asmem[:, :], Bsmem[:, :], + accum=False, dispatch="tcgen05", cta_group=1 + ) + T.ptx.tcgen05.commit(mma_bar.ptr_to([0]), cta_group=1) + + T.ptx.mbarrier.try_wait(mma_bar.ptr_to([0]), phase_mma) + + # --- Writeback: TMEM -> RF -> GMEM --- + Dreg = T.alloc_local((BLK_N,), acc_type) + Dreg_f16 = T.alloc_local((BLK_N,), d_type) + Dreg_wg = Dreg.view(128, BLK_N, + layout=TileLayout(S[(128, BLK_N) : (1@tid_in_wg, 1)])) + Tx.wg.copy_async(Dreg_wg[:, :], tmem[:, :BLK_N]) + T.ptx.tcgen05.wait.ld() + Tx.cast(Dreg_f16[:], Dreg[:]) + m_thr = T.meta_var(m_st + warp_id * 32 + lane_id) + Tx.copy(D[m_thr, n_st : n_st + BLK_N], Dreg_f16[:]) + + # --- Deallocate TMEM --- + T.cuda.cta_sync() + if warp_id == 0: + T.ptx.tcgen05.relinquish_alloc_permit(cta_group=1) + T.ptx.tcgen05.dealloc(tmem_addr[0], n_cols=512, cta_group=1) + + return kernel +``` + +后续每个 GEMM step 都会用同样方式编译、运行和检查自己,所以我们只在这里把这套 scaffolding 完整写一次, +之后只展示 kernel。要运行后续 step,把下面的 `hgemm_vX` 和对应 problem size 换掉即可。 +有一点需要记住:每个全新的 Python session 只编译一个 step,尝试另一个 step 前请重启, +因为这些例子会复用内部名称,而编译器持有 per-session state。 + +```python +import torch + +target = tvm.target.Target("cuda") +device = torch.device('cuda') # gpu(0) + +M, N, K = 128, 128, 64 +kernel = hgemm_v1(M, N, K) +with target: + ex = tvm.compile(tvm.IRModule({"main": kernel}), target=target, tir_pipeline="tirx") + +torch.cuda.empty_cache() +torch.cuda.synchronize() +A_tensor = torch.randn(M, K, dtype=torch.float16, device=device) +B_tensor = torch.randn(N, K, dtype=torch.float16, device=device) +D_tensor = torch.zeros(M, N, dtype=torch.float16, device=device) + +# ex.mod(...) takes torch tensors directly, the same call form used in every chapter. +ex.mod(A_tensor, B_tensor, D_tensor) + +D_ref = (A_tensor.float() @ B_tensor.float().T).half() +max_err = float((D_tensor - D_ref).abs().max()) +print(f"Max error vs torch reference: {max_err:.6f}") +# Relative tolerance, like the warp-specialization and Flash Attention cells: +# output magnitude grows with K, so a fixed absolute bound would fail at larger K. +torch.testing.assert_close(D_tensor, D_ref, rtol=2e-2, atol=1e-2) +print("PASS") + +# Optional timing for larger kernels. +ITERS = 10 +for _ in range(3): + ex.mod(A_tensor, B_tensor, D_tensor) +torch.cuda.synchronize() +start = torch.cuda.Event(enable_timing=True) +end = torch.cuda.Event(enable_timing=True) +start.record() +for _ in range(ITERS): + ex.mod(A_tensor, B_tensor, D_tensor) +end.record() +torch.cuda.synchronize() +ms = start.elapsed_time(end) / ITERS +tflops = 2 * M * N * K / ms / 1e9 +print(f"Performance: {ms:.3f} ms, {tflops:.1f} TFLOPS") +``` + +Step 1 到 Step 3 会刻意用较小尺寸运行(这里是 128×128,Step 3 是 256³),让最初的 walkthrough 容易跟随。 +{ref}`zh_chap_gemm_advanced` 末尾的跨 step *End-to-End Result* 表格采取相反做法: +它在统一的 M=N=K=4096 尺寸下测量每个 step,包括这个 Step 1 算法,从而让 speedup ratio 可以直接比较。 + +### Single-Tile Kernel 的限制 + +这个 kernel 是正确的,而这正是 Step 1 的全部目的;但它只在非常狭窄的设置中正确。 +我们有意内置了四个限制,优化路径剩余部分会一次解除一个: + +- 它只处理单个 K tile,因此无法在大 K 上 contract。 +- 它只处理单个 output tile,因此 M 和 N 被固定为 128。 +- 它使用同步 GMEM -> SMEM copy,而不是 TMA。 +- 它不会让数据移动和计算 overlap,因此二者从不同时运行。 + +--- + +(zh_chap_k_loop)= +## Step 2:K-Loop Accumulation + +要移除的第一个限制是最小的那个。Step 1 只处理单个宽度为 64 的 K tile,但真实矩阵会在远大于此的 K 上 contract。 +在 Step 2 中,我们保留单个 output tile,但让 K 跨越许多宽度为 64 的 chunk。 + +想法很直接:每个 chunk 重复一次 load -> MMA -> wait 序列,并让每次 MMA 都累加到同一个 TMEM slot。 +真正需要费心的是同步。跨 iteration 复用一个 mbarrier,会引入本章第一个真正的 correctness hazard。 +如果代码追踪了错误 phase,wait 可能在对应 MMA 实际完成*之前*返回,从而静默破坏结果。 +下面的机制会精确说明它如何出错,以及如何避免。 + +> **这一步改变什么:Layout reuse** +> - Scope:不变,仍然是单个 warpgroup。 +> - Layout/reuse:同一对 SMEM tile 和同一个 TMEM accumulator slot 跨 K-loop 复用。不会分配新 storage;operand tile 流经一对固定 buffer,accumulator state 保留在一个 TMEM slot 中。 +> - Synchronization:复用的 MMA barrier 必须在每个 K chunk 上推进到正确 phase,否则后续 wait 可能观察到更早的 completion。 +> - Dispatch:不变。 + +### K-Loop 机制 + +Step 1 只在单个宽度为 64 的 K tile 上 contract;这里我们保留它的单个 output tile,但让 K 按矩阵需求延伸。 +为了覆盖大于 64 的 K,我们以 `BLK_K=64` 为 chunk 遍历 K。每次 iteration 把下一个 A 和 B 的 K-slice load 到 SMEM, +并发射 `Tx.gemm_async`。`accum` flag 把这些 chunk 缝合成一个 dot product: +第一个 chunk 上,`accum=False` 初始化 TMEM accumulator;后续每个 chunk 上, +`accum=True` 把该 chunk 的乘积加到已经位于 TMEM 中的 running sum。 + +同步是需要谨慎的地方。每次 MMA completion 都复用同一个 mbarrier,而安全复用归结为追踪我们正在等待哪个 barrier phase。 +mbarrier 携带 1-bit phase,值为 0 或 1;每当预期 arrival 落地,它就翻转到另一个值。 +微妙之处在于 wait condition 本身:`try_wait(bar, phase)` 会阻塞到 barrier 内部 phase *不同于* `phase` 参数。 +所以我们传入的参数必须命名“我们期望离开的 phase”,而不是“我们等待抵达的 phase”: + +| K iteration | wait 前的本地 `phase_mma` | `try_wait` 等待什么 | wait 后的本地更新 | +|---|---:|---|---:| +| 0 | 0 | barrier flips to 1 | `phase_mma = 1` | +| 1 | 1 | barrier flips to 0 | `phase_mma = 0` | +| 2 | 0 | barrier flips to 1 | `phase_mma = 1` | + +单行 `phase_mma ^= 1` 正是让这张表保持正确的东西。去掉它,第二次 iteration 仍会调用 `try_wait(bar, 0)`, +但 barrier 在第一次 MMA 后已经翻转到 phase 1,因此 wait 看到 mismatch 后会立刻返回, +早于第二次 MMA 完成。kernel 随后会读取半计算的 accumulator,并在没有任何错误的情况下报告错误答案。 +这是一个能够完美编译和运行的 bug,也正是 phase flip 值得如此关注的原因。 + +### 完整 Kernel + +下面完整 kernel 只是把 K-loop 和 phase flip 折进 Step 1。import 与之前相同: + +```python + +import tvm +from tvm.script import tirx as T +from tvm.script.tirx import tile as Tx +from tvm.tirx.cuda.operator.tile_primitive.tma_utils import tma_shared_layout, SwizzleMode +from tvm.tirx.layout import TileLayout, S, TLane, TCol, tid_in_wg +``` + +它被包在 `hgemm_v2(M, N, K)` 中。grid 仍然是 `[1, 1]`,因为我们仍在计算单个 output tile; +增长的只有它的 K extent: + +```python +def hgemm_v2(M, N, K): + a_type = tvm.DataType("float16") + b_type = tvm.DataType("float16") + d_type = tvm.DataType("float16") + acc_type = tvm.DataType("float32") + + BLK_M, BLK_N, BLK_K = 128, 128, 64 + K_TILES = K // BLK_K + + A_layout = tma_shared_layout(a_type, SwizzleMode.SWIZZLE_128B_ATOM, (BLK_M, BLK_K)) + B_layout = tma_shared_layout(b_type, SwizzleMode.SWIZZLE_128B_ATOM, (BLK_N, BLK_K)) + + @T.prim_func + def kernel( + A: T.Buffer((M, K), a_type), + B: T.Buffer((N, K), b_type), + D: T.Buffer((M, N), d_type), + ): + T.device_entry() + bx, by = T.cta_id([M // BLK_M, N // BLK_N]) # still one output tile (M=N=128) + wg_id = T.warpgroup_id([1]) + warp_id = T.warp_id_in_wg([4]) + lane_id = T.lane_id([32]) + + pool = T.SMEMPool() + tmem_addr = pool.alloc((1,), "uint32") + mma_bar = pool.alloc((1,), "uint64", align=8) + pool.move_base_to(1024) + Asmem = pool.alloc((BLK_M, BLK_K), a_type, layout=A_layout) + Bsmem = pool.alloc((BLK_N, BLK_K), b_type, layout=B_layout) + pool.commit() + + if warp_id == 0: + if lane_id == 0: + T.ptx.mbarrier.init(mma_bar.ptr_to([0]), 1) + T.ptx.tcgen05.alloc(T.address_of(tmem_addr), n_cols=512, cta_group=1) + + T.ptx.fence.proxy_async("shared::cta") + T.ptx.fence.mbarrier_init() + T.cuda.cta_sync() + + tmem = T.decl_buffer( + (128, 512), "float32", scope="tmem", allocated_addr=tmem_addr[0], + layout=TileLayout(S[(128, 512) : (1@TLane, 1@TCol)])) + + phase_mma: T.int32 = 0 + m_st = T.meta_var(bx * BLK_M) + n_st = T.meta_var(by * BLK_N) + + # === K-loop: iterate over K in chunks of BLK_K === + for i in T.serial(K_TILES): # serial device loop (keeps the full-K A/B parameters correctly shaped) + # Load the i-th K chunk + Tx.cta.copy(Asmem[:, :], A[:, i*BLK_K:(i+1)*BLK_K]) + Tx.cta.copy(Bsmem[:, :], B[:, i*BLK_K:(i+1)*BLK_K]) + + T.cuda.cta_sync() + + # MMA: accum=False for first tile, True for rest + if warp_id == 0: + if T.ptx.elect_sync(): + Tx.gemm_async(tmem[:, :BLK_N], Asmem[:, :], Bsmem[:, :], + accum=(i != 0), dispatch="tcgen05", cta_group=1) + T.ptx.tcgen05.commit(mma_bar.ptr_to([0]), cta_group=1) + + # Wait for MMA, then flip phase + T.ptx.mbarrier.try_wait(mma_bar.ptr_to([0]), phase_mma) + phase_mma ^= 1 + + # === Writeback (same as Step 1) === + Dreg = T.alloc_local((BLK_N,), acc_type) + Dreg_f16 = T.alloc_local((BLK_N,), d_type) + Dreg_wg = Dreg.view(128, BLK_N, + layout=TileLayout(S[(128, BLK_N) : (1@tid_in_wg, 1)])) + + Tx.wg.copy_async(Dreg_wg[:, :], tmem[:, :BLK_N]) + T.ptx.tcgen05.wait.ld() + + Tx.cast(Dreg_f16[:], Dreg[:]) + m_thr = T.meta_var(m_st + warp_id * 32 + lane_id) + Tx.copy(D[m_thr, n_st : n_st + BLK_N], Dreg_f16[:]) + + T.cuda.cta_sync() + if warp_id == 0: + T.ptx.tcgen05.relinquish_alloc_permit(cta_group=1) + T.ptx.tcgen05.dealloc(tmem_addr[0], n_cols=512, cta_group=1) + + return kernel +``` + +--- + +(zh_chap_spatial_tiling)= +## Step 3:Spatial Tiling(Multi-CTA) + +K-loop 处理了 contraction dimension,但 M 和 N 仍然固定在单个 128 x 128 tile 上。 +真实输出远大于一个 tile,因此 basic kernel 的最后一块,是一次用许多 tile 覆盖 M 和 N。 +Step 3 启动一个 2D CTA grid,每个 output tile 一个 CTA,并让 GPU 并行计算所有 tile。 +例子使用 M=N=K=256,会得到一个 2x2 tile grid,足以让 indexing 不再平凡,同时又不会被细节淹没。 + +> **这一步改变什么:Scope** +> - Scope:一个 2D CTA grid,每个 CTA 拥有一个 128 x 128 output tile。 +> - Layout:不变;在 CTA 内部,这与 Step 2 是同一条 SMEM/TMEM/register 路径。 +> - Dispatch:不变。 + +### Grid Mapping + +grid shape 直接来自 tiling:每个 128 x 128 output tile 一个 CTA,因此总共需要 `[M // BLK_M, N // BLK_N]` 个 CTA。 +与 Step 2 相比,唯一真正的新工作是告诉每个 CTA,矩阵的哪一片是*它*要计算的片段。 + +CTA `(bx, by)` 拥有这个 output region: + +```text +D[bx * BLK_M : (bx + 1) * BLK_M, + by * BLK_N : (by + 1) * BLK_N] +``` + +为了产生它,这个 CTA 的 K-loop 会反复 load 自己的 A row band 和 B column band 中匹配的 K-slice: + +```text +A[bx * BLK_M : (bx + 1) * BLK_M, k : k + BLK_K] +B[by * BLK_N : (by + 1) * BLK_N, k : k + BLK_K] +``` + +indexing 直接来自 `D = A @ B.T` 约定:`bx` 选择 A 和 D 的 row, +而 `by` 选择 B 的 row;一旦应用 transpose,这些 B row 会变成 D 的 column。 + +每个 CTA 一个 tile 是能工作的最简单映射,但它也很浪费。同一行中的每个 CTA 都会从 GMEM 重新 load 相同 A tile, +同一列中的每个 CTA 都会重新 load 相同 B tile,因此没有复用相邻 CTA 已经拉进来的数据。 +我们暂时保留这种浪费;persistent scheduling({ref}`zh_chap_gemm_async` 中的 Step 6)会回到这个问题, +并让这些共享 operand 在 L2 中保持 hot。 + +**可以让你的 agent 试试**:在 `M=N=K=256`、`BLK_M=BLK_N=128`、`BLK_K=64` 时, +让它追踪 CTA `(1, 0)` 和 CTA `(0, 1)`。对每个 CTA,列出 `m_st`、`n_st`、 +每个 K iteration 载入的 A/B slice,以及写入的 D region。 +由于 kernel 计算 `D = A @ B.T`,哪些 B row 会变成 D column? + +### 完整 Kernel + +这个 kernel 再一次基于 Step 2,这次只有两个变化:grid shape 和 per-CTA offset。 +内部 K-loop 和 writeback 不变。import 仍然相同: + +```python + +import tvm +from tvm.script import tirx as T +from tvm.script.tirx import tile as Tx +from tvm.tirx.cuda.operator.tile_primitive.tma_utils import tma_shared_layout, SwizzleMode +from tvm.tirx.layout import TileLayout, S, TLane, TCol, tid_in_wg +``` + +grid 从 `[1, 1]` 变成 `[M // BLK_M, N // BLK_N]`, +load 和 store 现在会根据 CTA 自己的 `m_st` 和 `n_st` 加 offset: + +```python +def hgemm_v3(M, N, K): + a_type = tvm.DataType("float16") + b_type = tvm.DataType("float16") + d_type = tvm.DataType("float16") + acc_type = tvm.DataType("float32") + + BLK_M, BLK_N, BLK_K = 128, 128, 64 + K_TILES = K // BLK_K + + A_layout = tma_shared_layout(a_type, SwizzleMode.SWIZZLE_128B_ATOM, (BLK_M, BLK_K)) + B_layout = tma_shared_layout(b_type, SwizzleMode.SWIZZLE_128B_ATOM, (BLK_N, BLK_K)) + + @T.prim_func + def kernel( + A: T.Buffer((M, K), a_type), + B: T.Buffer((N, K), b_type), + D: T.Buffer((M, N), d_type), + ): + T.device_entry() + # 2D grid: one CTA per 128x128 output tile + bx, by = T.cta_id([M // BLK_M, N // BLK_N]) + wg_id = T.warpgroup_id([1]) + warp_id = T.warp_id_in_wg([4]) + lane_id = T.lane_id([32]) + + pool = T.SMEMPool() + tmem_addr = pool.alloc((1,), "uint32") + mma_bar = pool.alloc((1,), "uint64", align=8) + pool.move_base_to(1024) + Asmem = pool.alloc((BLK_M, BLK_K), a_type, layout=A_layout) + Bsmem = pool.alloc((BLK_N, BLK_K), b_type, layout=B_layout) + pool.commit() + + if warp_id == 0: + if lane_id == 0: + T.ptx.mbarrier.init(mma_bar.ptr_to([0]), 1) + T.ptx.tcgen05.alloc(T.address_of(tmem_addr), n_cols=512, cta_group=1) + + T.ptx.fence.proxy_async("shared::cta") + T.ptx.fence.mbarrier_init() + T.cuda.cta_sync() + + tmem = T.decl_buffer( + (128, 512), "float32", scope="tmem", allocated_addr=tmem_addr[0], + layout=TileLayout(S[(128, 512) : (1@TLane, 1@TCol)])) + + phase_mma: T.int32 = 0 + + # Per-CTA tile offsets + m_st = T.meta_var(bx * BLK_M) + n_st = T.meta_var(by * BLK_N) + + # K-loop with offset A and B slices + for i in T.serial(K_TILES): # serial device loop (keeps the full-K A/B parameters correctly shaped) + Tx.cta.copy(Asmem[:, :], A[m_st:m_st+BLK_M, i*BLK_K:(i+1)*BLK_K]) + Tx.cta.copy(Bsmem[:, :], B[n_st:n_st+BLK_N, i*BLK_K:(i+1)*BLK_K]) + + T.cuda.cta_sync() + + if warp_id == 0: + if T.ptx.elect_sync(): + Tx.gemm_async(tmem[:, :BLK_N], Asmem[:, :], Bsmem[:, :], + accum=(i != 0), dispatch="tcgen05", cta_group=1) + T.ptx.tcgen05.commit(mma_bar.ptr_to([0]), cta_group=1) + + T.ptx.mbarrier.try_wait(mma_bar.ptr_to([0]), phase_mma) + phase_mma ^= 1 + + # Writeback to the correct output tile + Dreg = T.alloc_local((BLK_N,), acc_type) + Dreg_f16 = T.alloc_local((BLK_N,), d_type) + Dreg_wg = Dreg.view(128, BLK_N, + layout=TileLayout(S[(128, BLK_N) : (1@tid_in_wg, 1)])) + + Tx.wg.copy_async(Dreg_wg[:, :], tmem[:, :BLK_N]) + T.ptx.tcgen05.wait.ld() + + Tx.cast(Dreg_f16[:], Dreg[:]) + m_thr = T.meta_var(m_st + warp_id * 32 + lane_id) + Tx.copy(D[m_thr, n_st:n_st+BLK_N], Dreg_f16[:]) + + T.cuda.cta_sync() + if warp_id == 0: + T.ptx.tcgen05.relinquish_alloc_permit(cta_group=1) + T.ptx.tcgen05.dealloc(tmem_addr[0], n_cols=512, cta_group=1) + + return kernel +``` + +## 练习 + +1. 在 Step 1-3 中,`Tx.copy` 会在 MMA 之前把 A 和 B tile 移入 SMEM。为什么 kernel 需要在 `Tx.gemm_async` 读取这些 SMEM tile 前执行 `T.cuda.cta_sync()`? +2. 在 Step 2 中,如果从 K-loop 中移除 `phase_mma ^= 1`,会发生什么?kernel 会等待每个 MMA,还是后续 wait 可能过早通过? +3. 对于 M=N=4096 且 BLK_M=BLK_N=128,Step 3 会启动多少个 CTA?哪些 operand tile 在逻辑上会被相邻 CTA 复用?Step 3 是否利用了这种复用? diff --git a/zh/chapter_intro_tirx/index.md b/zh/chapter_intro_tirx/index.md new file mode 100644 index 00000000..dac9ba95 --- /dev/null +++ b/zh/chapter_intro_tirx/index.md @@ -0,0 +1,261 @@ +(zh_chap_tirx_primer)= +# TIRx 简介 + +:::{admonition} 概览 +:class: overview + +- TIRx 是一个用于在 IR 层级编写 GPU kernel 的 Python DSL:你会直接命名硬件,但通过结构化 IR 来表达。 +- 每个 tile operation 都由三个设计元素控制:*scope*(哪些 thread)、*layout*(tile 位于哪里)和 *dispatch*(哪条硬件路径)。 +- 一个可运行的 single-MMA GEMM 会展示三者;本书其余内容就是把这些设计元素扩展到更大规模。 +::: + +:::{admonition} 运行示例 +:class: note + +这些示例需要 Blackwell GPU(`sm_100a`,例如 B200)。TIRx compiler 随 Apache TVM wheel 的 +`tvm.tirx` 模块发布;请将它与 CUDA build 的 PyTorch 一起安装: + +```bash +pip install apache-tvm==0.25.0 +``` + +用 `python -c "import tvm, tvm.tirx; print(tvm.__version__)"` 确认它能 import。 +同样的设置可以运行本书中每个可运行示例。 +::: + +第一部分解释了硬件是什么。要让它计算任何东西,我们还需要一种编程方式。 + +我们可以直接写 CUDA 或 PTX,许多高速 kernel 也正是这样写的。问题在于,真正决定 kernel 行为的决策在那里很难看清: +哪些 thread 运行某个操作、每个 data tile 位于哪里,以及由哪条硬件路径执行它。 +这些选择被埋在 intrinsic 参数、地址算术和约定之中。 + +TIRx(Tensor IR neXt)是一个 Python DSL,它把这三个决策显式提到台面上: +**scope**(哪些 thread 运行操作)、**layout**(operand tile 位于哪里)和 **dispatch**(哪条硬件路径执行它)。 +它仍然直接命名硬件概念,包括 thread、shared/tensor memory、barrier 和 `tcgen05` MMA。 +不同之处在于,这些选择现在是结构化 IR,编译器可以 lower、check 和 schedule。 + +我们不会抽象地介绍这些思想,而是从一个完整 kernel 出发:一个最小 single-MMA GEMM。 +我们先让它跑起来,然后再逐行读回去,观察 scope、layout 和 dispatch 各自如何塑造它,以及 kernel 如何被编译。 +这个 kernel 依赖的 tensor layout model 会在 {ref}`zh_chap_tirx_layout_api` 中独立展开, +完整语言特性集见 {ref}`zh_chap_language_reference`;这里我们聚焦于一个 kernel 和三个设计元素。 + +## 第一个 Kernel:Single-MMA GEMM + +我们承诺的 kernel 是一个最小 GEMM,缩减到仍然能使用 Tensor Core 的最小版本。它在 K = 64 时计算 +`D = A B^T` 的单个 128 x 128 output tile。整个计算从头到尾表达为一个 `Tx.gemm_async` tile operation。 +(这个 tile operation 并不映射到单条硬件指令:因为硬件 MMA 的 K-atom 是 16,K=64 的 tile 会 lower 成沿 K 方向前进的一小段 +`tcgen05.mma` 指令序列。DSL 的意义恰恰在于我们写 tile,而不是写序列。) +围绕这个操作,kernel 做常规杂务:分配 shared memory(SMEM)和 tensor memory(TMEM),把 A 和 B 从 global copy 到 shared memory, +把 tile MMA 发射到 TMEM accumulator 中,通过寄存器把 accumulator 读回,并存储结果。 +虽然它很小,这个 kernel 正是 {ref}`zh_chap_gemm_basics` 中 GEMM 阶梯的 Step 1,那里会完整走读它。 + +每个 TIRx kernel 都从同一组 import 开始,所以值得先看一次: + +```python + +import tvm +from tvm.script import tirx as T +from tvm.script.tirx import tile as Tx +from tvm.tirx.cuda.operator.tile_primitive.tma_utils import tma_shared_layout, SwizzleMode +from tvm.tirx.layout import TileLayout, S, TLane, TCol, tid_in_wg +``` + +我们把 kernel 包在一个小 builder `hgemm_v1(M, N, K)` 中,它接收 problem shape 并返回一个 `PrimFunc`。 +对于我们选择的 shape `M=N=128, K=64`,launch 恰好只包含一个 output tile, +这让第一个版本足够简单,可以一次读完: + +```python +def hgemm_v1(M, N, K): + a_type = tvm.DataType("float16") + b_type = tvm.DataType("float16") + d_type = tvm.DataType("float16") + acc_type = tvm.DataType("float32") + + BLK_M, BLK_N, BLK_K = 128, 128, 64 + # MMA_M/MMA_N/MMA_K document the underlying hardware MMA tile; they are not + # passed to gemm_async (which derives the MMA shape from the operand and + # accumulator tiles), so the later steps omit them. + MMA_M, MMA_N, MMA_K = 128, 128, 16 + + A_layout = tma_shared_layout(a_type, SwizzleMode.SWIZZLE_128B_ATOM, (BLK_M, BLK_K)) + B_layout = tma_shared_layout(b_type, SwizzleMode.SWIZZLE_128B_ATOM, (BLK_N, BLK_K)) + + @T.prim_func + def kernel( + A: T.Buffer((M, K), a_type), + B: T.Buffer((N, K), b_type), + D: T.Buffer((M, N), d_type), + ): + T.device_entry() + # Step 1 is a single-tile kernel: M = BLK_M and N = BLK_N, so the grid + # is 1x1. Starting with a 1x1 grid keeps the per-CTA tile offsets + # (m_st, n_st) trivially zero; Steps 3+ generalise this to larger M / N. + bx, by = T.cta_id([M // BLK_M, N // BLK_N]) + wg_id = T.warpgroup_id([1]) # single warpgroup, so wg_id is always 0 (unused below) + warp_id = T.warp_id_in_wg([4]) + lane_id = T.lane_id([32]) + + # --- SMEM allocation --- + pool = T.SMEMPool() + tmem_addr = pool.alloc((1,), "uint32") + mma_bar = pool.alloc((1,), "uint64", align=8) + pool.move_base_to(1024) + Asmem = pool.alloc((BLK_M, BLK_K), a_type, layout=A_layout) + Bsmem = pool.alloc((BLK_N, BLK_K), b_type, layout=B_layout) + pool.commit() + + # --- Barrier + TMEM init (warp 0 only) --- + if warp_id == 0: + if lane_id == 0: + T.ptx.mbarrier.init(mma_bar.ptr_to([0]), 1) + T.ptx.tcgen05.alloc(T.address_of(tmem_addr), n_cols=512, cta_group=1) + + T.ptx.fence.proxy_async("shared::cta") + T.ptx.fence.mbarrier_init() + T.cuda.cta_sync() + + tmem = T.decl_buffer( + (128, 512), "float32", scope="tmem", allocated_addr=tmem_addr[0], + layout=TileLayout(S[(128, 512) : (1@TLane, 1@TCol)]) + ) + + m_st = T.meta_var(bx * BLK_M) + n_st = T.meta_var(by * BLK_N) + phase_mma: T.int32 = 0 + + # --- Load: all threads copy global -> shared (synchronous). + # With M=BLK_M and N=BLK_N the slices below cover the full matrices; + # the slice form is kept so the diff to Step 3 (multi-tile) is minimal. + Tx.cta.copy(Asmem[:, :], A[m_st:m_st + BLK_M, :]) + Tx.cta.copy(Bsmem[:, :], B[n_st:n_st + BLK_N, :]) + T.cuda.cta_sync() + + # --- Compute: single elected thread issues MMA --- + if warp_id == 0: + if T.ptx.elect_sync(): + Tx.gemm_async( + tmem[:, :BLK_N], Asmem[:, :], Bsmem[:, :], + accum=False, dispatch="tcgen05", cta_group=1 + ) + T.ptx.tcgen05.commit(mma_bar.ptr_to([0]), cta_group=1) + + T.ptx.mbarrier.try_wait(mma_bar.ptr_to([0]), phase_mma) + + # --- Writeback: TMEM -> RF -> GMEM --- + Dreg = T.alloc_local((BLK_N,), acc_type) + Dreg_f16 = T.alloc_local((BLK_N,), d_type) + Dreg_wg = Dreg.view(128, BLK_N, + layout=TileLayout(S[(128, BLK_N) : (1@tid_in_wg, 1)])) + Tx.wg.copy_async(Dreg_wg[:, :], tmem[:, :BLK_N]) + T.ptx.tcgen05.wait.ld() + Tx.cast(Dreg_f16[:], Dreg[:]) + m_thr = T.meta_var(m_st + warp_id * 32 + lane_id) + Tx.copy(D[m_thr, n_st : n_st + BLK_N], Dreg_f16[:]) + + # --- Deallocate TMEM --- + T.cuda.cta_sync() + if warp_id == 0: + T.ptx.tcgen05.relinquish_alloc_permit(cta_group=1) + T.ptx.tcgen05.dealloc(tmem_addr[0], n_cols=512, cta_group=1) + + return kernel +``` + +在阅读 kernel 之前,先确保它能工作。我们编译它,并用 torch reference 检查输出。 +我们不必写出精确架构:arch(例如 `sm_100a`)会从 device 自动检测,因此 target `"cuda"` 就足够; +`tir_pipeline="tirx"` 用来选择 TIRx lowering pipeline。编译完成后,`ex.mod(...)` 可以直接接收 torch tensor, +中间不需要手动转换。 + +```python +import torch + +target = tvm.target.Target("cuda") +device = torch.device('cuda') # gpu(0) + +M, N, K = 128, 128, 64 +kernel = hgemm_v1(M, N, K) +with target: + ex = tvm.compile(tvm.IRModule({"main": kernel}), target=target, tir_pipeline="tirx") + +torch.cuda.empty_cache() +torch.cuda.synchronize() +A_tensor = torch.randn(M, K, dtype=torch.float16, device=device) +B_tensor = torch.randn(N, K, dtype=torch.float16, device=device) +D_tensor = torch.zeros(M, N, dtype=torch.float16, device=device) + +# ex.mod(...) takes torch tensors directly, the same call form used in every chapter. +ex.mod(A_tensor, B_tensor, D_tensor) + +D_ref = (A_tensor.float() @ B_tensor.float().T).half() +max_err = float((D_tensor - D_ref).abs().max()) +print(f"Max error vs torch reference: {max_err:.6f}") +torch.testing.assert_close(D_tensor, D_ref, rtol=2e-2, atol=1e-2) +print("PASS") +``` + +## Scope、Layout、Dispatch + +现在 kernel 已经能运行,我们可以读回它,并询问每一行实际上决定了什么。 +这样看,整个 kernel 就是围绕三个设计元素作出的一组选择。其中每个操作都回答同三个问题: +*谁*运行它,数据*位于哪里*,以及它*如何*执行;这三个答案正是 scope、layout 和 dispatch。 +本节剩余部分会逐一讨论这些设计元素;下面的交互式演示让你看到每个设计元素控制哪些代码行。 + +```{raw} html + +``` +*交互:点击 Scope / Layout / Dispatch,高亮 kernel 中由该设计元素控制的代码行。* + +使用这个演示时,关注三个问题: + +- **Scope:谁运行这个操作?** `Tx.cta.copy(...)` 是 CTA-scoped,因此全部 128 个 thread 都会帮助完成 GMEM -> SMEM copy。 + `Tx.gemm_async(...)` 由一个被选出的 thread 发射一次,因为每条 lowered `tcgen05.mma` 指令已经是一次 cooperative MMA launch。 + `Tx.wg.copy_async(...)` 是 warpgroup-scoped,因此 warpgroup 的 128 个 thread 会逐行切分 TMEM readback。 +- **Layout:每个 tile 位于哪里?** A 和 B 使用 `tcgen05.mma` 期望的 swizzled SMEM layout。 + accumulator 在 `TLane`/`TCol` layout 下位于 TMEM。register readback view 把 row 映射到 `tid_in_wg`, + 因此每个 warpgroup thread 拥有一个 row fragment。 +- **Dispatch:哪条硬件路径执行它?** `Tx.gemm_async(..., dispatch="tcgen05", ...)` 选择 Blackwell Tensor Core 路径。 + copy 操作也有 dispatch 选择:第一个 kernel 使用普通 thread copy,后续 GEMM step 会把这些 copy 换成 TMA, + 而不改变周围的 scope 或 layout。 + +**可以让你的 agent 试试**:从第一个 kernel 中挑三行:一个 copy、一个 MMA 和一个 TMEM readback。 +让它为每行标注 scope、layout 和 dispatch,然后检查答案是否匹配代码中的 guard、buffer layout 和 `dispatch=` 参数。 + +## 编译如何工作 + +我们上面已经编译过 kernel 来测试它;现在稍微仔细看一下这一步做了什么。 +流程很短:把 `PrimFunc` 包进 `IRModule`,并交给 `tvm.compile(mod, target=..., tir_pipeline="tirx")`。 +这会运行 TIRx lowering pipeline,并返回一个可以直接调用的 `Executable`。 + +```python +target = tvm.target.Target("cuda") +ex = tvm.compile(tvm.IRModule({"main": kernel}), target=target, tir_pipeline="tirx") +``` + +至少从轮廓上了解 `tir_pipeline="tirx"` 启动了什么,是很有价值的。pipeline 的核心 pass `LowerTIRx` +会根据每个 tile primitive 的 scope / layout / dispatch contract 来解析它: +我们刚刚讨论的三个设计元素正是在这里兑现成指令。之后,常规 host/device split 和 finalize 步骤会产生可 launch 的 module。 +如果你愿意,也可以在 `with target:` block 内编译,这让 kernel 能继承外层 target context。 + +这个流程的一个好性质是,没有什么对你隐藏:结果可以在两个层级检查。 +你可以用 `.show()` 或 `.script()` 阅读 IR 本身,也可以直接从 compiled module 读取编译器最终生成的 CUDA C。 + +```python +kernel.show() # pretty-print the TIRx (TVMScript) +print(kernel.script()) # ... the same, as a string + +# the generated CUDA C source, from the compiled Executable: +print(ex.mod.imports[0].inspect_source()) +``` + +这只是一个概览。完整 lowering 故事,包括所有 pass、tile-primitive dispatch 如何解析,以及 host/device split 如何完成, +见 {ref}`zh_chap_arch`。 + +## 接下来读什么 + +一个 kernel 已经足够让我们认识 scope、layout 和 dispatch,并看到它们被编译和运行。 +三个设计元素中的每一个,以及这个 kernel 本身,都会通向进一步展开的章节: + +- {ref}`zh_chap_tirx_layout_api`:tensor layout model(`TileLayout`、named axes、swizzle),上面的 operand 和 accumulator placement 都建立在它之上。如果 layout 这个设计元素在三者中最神秘,请从这里开始。 +- {ref}`zh_chap_language_reference`:完整语言特性集,覆盖 parser utilities、data types、buffers and memory、control flow 和 thread synchronization;当你想要完整词汇表,而不只是导览时,可以读这里。 +- {ref}`zh_chap_gemm_basics`:把这个 kernel 作为 GEMM 优化路径的 Step 1,并通过 K-loop accumulation、spatial tiling、TMA 和 warp specialization 逐步扩展。如果你想看同样三个设计元素如何扩展到真实 kernel,这是自然的下一站。 diff --git a/zh/chapter_layout_generations/index.md b/zh/chapter_layout_generations/index.md new file mode 100644 index 00000000..25505a74 --- /dev/null +++ b/zh/chapter_layout_generations/index.md @@ -0,0 +1,345 @@ +(zh_chap_layout_generations)= +# 跨 GPU 世代的 Tensor Core Operand Layout + +:::{admonition} 概览 +:class: overview + +- 在 Ampere、Hopper 和 Blackwell 中,Tensor Core 执行的高层操作仍然相同:`D = A B + C`。 +- 代际之间变化的是 operand 如何到达 Tensor Core、支持哪些 tile shape 和 dtype,以及 accumulator 位于哪里。 +- Ampere 使用 warp 级 register fragment。shared memory tile 通过 `ldmatrix` 载入 fragment,accumulator 保留在寄存器中。 +- Hopper 允许 `wgmma` 通过 matrix descriptor 直接从 shared memory 读取 operand。descriptor 会指定 Tensor Core 所期望的 shared-memory swizzle format。 +- Blackwell 保留 shared-memory operand 路径,但把 accumulator 移入 TMEM。Block-scaled MMA 也通过 TMEM 暂存 scale factor。 +- 有两个内存约束贯穿所有世代:global memory coalescing 和 shared memory bank conflict。 +::: + +从远处看,Tensor Core 操作似乎很稳定。它把 A 和 B 的 tile 相乘,加上 accumulator C,并产生 D。 +从 Volta 开始,这个形式就没有变过。 + +但围绕这个操作的细节并没有固定不变。某一代上很快的 kernel,到了下一代可能会变慢。 +使用错误 layout 的 kernel 也可能算出错误答案,即使逻辑数学仍然写作 `D = A B + C`。 +原因在于 Tensor Core 消费的不是抽象矩阵,而是以非常具体的硬件 layout 排列的 operand。 + +本章沿着三代 GPU 追踪这个 layout contract。Ampere 通过 warp-level register fragment 暴露 Tensor Core。 +Hopper 把输入 operand 移到 shared memory descriptor。Blackwell 保留 shared memory operand, +但把 accumulator 移入 TMEM。操作仍然是 matrix-multiply-accumulate,但进入和离开 Tensor Core 的路径每一代都在改变。 + +{ref}`Data Layout ` 章节中的 layout 记法,是我们描述这些 contract 的语言。 +Blackwell 的 TMEM 细节会在 {ref}`zh_chap_tmem` 中单独介绍。 + +## 两个从未消失的约束 + +在 Tensor Core 参与之前,两个普通内存约束就已经在塑造 GPU kernel 的 layout。 + +第一个是 global memory coalescing。当一个 warp 的 32 个 lane 发射 global memory load 时, +内存系统希望这些地址落入少量连续且对齐的 memory segment。如果地址分散,warp load 就会变成多次 memory transaction。 +同样的逻辑数据移动会消耗更多带宽和更多时间。 + +第二个是 shared memory bank conflict。shared memory 被划分成 32 个 bank。 +如果 warp 中的多个 lane 访问不同地址,但这些地址映射到同一个 bank,这些访问就无法同时被服务,硬件会把它们串行化。 +因此,一个看起来只是平坦 shared memory array、似乎无害的 layout,可能会因为 bank pattern 而变慢。 + +swizzling 通常是修复 shared memory 侧问题的方法。逻辑 tile 保持不变,但物理地址映射会被置换, +让访问 pattern 分散到多个 bank 上,而不是堆叠到同一个 bank。 + +这两个约束甚至适用于完全不使用 Tensor Core 的 kernel。Tensor Core kernel 还会增加第三个约束: +operand 必须按 Tensor Core 指令本身期望的 layout 排列。本章剩余部分讨论这个第三约束如何在 Ampere、Hopper 和 Blackwell 间变化。 + +## Ampere:跨 Warp Lane 的 Register Fragment + +在 Ampere 级 GPU 上,主要 Tensor Core 指令是 warp-level 的 `mma.sync.aligned.m16n8k*` 系列。 +关键事实是这条指令从哪里读写数据:寄存器。 + +A、B,以及 C 或 D accumulator,都是分布在一个 warp 的 32 个 lane 上的 per-thread register fragment。 +shared memory 只是 staging area。在 MMA 运行之前,operand tile 必须从 shared memory 移入该指令所期望的精确 register fragment layout。 + +数据路径如下: + +```text +SMEM to registers with ldmatrix +registers to registers with mma.sync +registers back to SMEM with ordinary stores +``` + +Ampere 的大部分 layout 故事都来自这条路径。kernel 必须以一种能高效载入的形式把 tile 存进 shared memory, +然后使用 `ldmatrix` 产生 `mma.sync` 所需的 register fragment。 + +## Ampere Tensor Core 期望什么 + +Ampere Tensor Core 读取由 8×8 subtile unit 构成的 register fragment。这些 unit 是 `ldmatrix` 载入、MMA 消费的单位。 + +以 fp16 或 bf16 输入、fp32 accumulate 的 `mma.m16n8k16` 作为具体例子。accumulator tile 的 shape 是 `16 by 8`。 +它按固定 pattern 分布在 32 个 lane 上。 + +对于 C 或 D accumulator,lane `l` 持有的 row 是: + +```text +l / 4 +l / 4 + 8 +``` + +column 是: + +```text +2 * (l % 4) +2 * (l % 4) + 1 +``` + +因此每个 lane 拥有四个 fp32 accumulator 值:来自两个 8-row half 的两行,交叉上两个相邻列。 +四个连续 lane 覆盖一行的八个 column。 + +A operand 使用同样的 M 侧 row carve。K 维度分布在 `l % 4` 以及该 lane 持有的寄存器上。 +对于 fp16 或 bf16,每个 32-bit 寄存器会 pack 两个 K 值。 + +B operand 使用匹配的 K placement,并把 N 侧分散到 lane group 和寄存器上。 + +精确细节会随 instruction shape 和 dtype 变化,但原则固定:Tensor Core 期望某种特定的 per-lane register fragment。 +如果值不在这些寄存器的这个 pattern 中,指令就会把错误元素相乘。 + +在 layout 记法中,m8n8 fragment 就是那种用 named lane axes 写出的 pattern,例如: + +```text +S[(8, 4, 2) : (4@laneid, 1@laneid, 1@m)] +``` + +两个 `laneid` iter 一起描述 row 和 column 片段如何散布到 lane 上,而最后的 `m` 分量描述 per-lane register slot。 + +## `ldmatrix`:从 Shared Memory 到 Register Fragment + +`ldmatrix` 是 Ampere 中连接 shared memory 和 Tensor Core register fragment 的指令。它是一个 warp-collective load。 +一条指令会把一个或多个 8×8 的 16-bit matrix 从 shared memory 移入 `mma.sync` 期望的分布式 register layout。 + +指令形式是: + +```text +ldmatrix.sync.aligned.m8n8.x1.shared.b16 +ldmatrix.sync.aligned.m8n8.x2.shared.b16 +ldmatrix.sync.aligned.m8n8.x4.shared.b16 +``` + +并且可以带一个可选的 `.trans` qualifier。 + +`.x1`、`.x2` 和 `.x4` 形式分别载入一个、两个或四个 8×8 matrix。row base address 由 lane 提供。 +对于 matrix `m` 和 row `r`,base address 来自 lane `m * 8 + r`。 +这意味着 `.x1` 使用 lane 0 到 7 提供 row address,`.x2` 使用 lane 0 到 15,`.x4` 使用 lane 0 到 31。 + +结果会直接落入 MMA fragment。对于基本的 8×8 情况,lane `l` 会收到 Tensor Core 所期望的 row 和 column pair。 +如果用普通的 per-lane `ld.shared` 指令循环,就必须手工复现这种 scatter。 +`ldmatrix` 则把 shared-memory-to-fragment 的重排作为一条 warp-collective 指令完成。 + +`.trans` 形式会在 load 时转置每个 8×8 matrix。当 operand 的存储方向与 MMA 指令期望的方向相反时,就会使用它。 + +![ldmatrix 将一个 8x8 共享内存 tile 载入 warp 寄存器 fragment;Ampere 上的反向路径使用普通存储,专用 stmatrix 指令稍后才在 Hopper 出现](../img/ldstmatrix.svg) + +## 把 Ampere Fragment 写回 + +`mma.sync` 完成后,accumulator 仍然是 register fragment。epilogue 必须把这个 fragment 移出去。 + +在 Ampere 上,没有 `ldmatrix` 的专用反向指令。kernel 使用普通 per-thread store, +有时在 store 之前配合 warp shuffle 或本地重排,把 accumulator 以有用 layout 写入 shared memory 或 global memory。 + +这让 Ampere 模型保持简单,但也把许多 layout 工作暴露给 kernel。输入侧使用 `ldmatrix` 创建 fragment。 +计算指令读写 register fragment。输出侧则由从这些 fragment 发出的普通 store 处理。 + +## Ampere 上的 Swizzle + +Ampere kernel 已经需要 shared memory swizzle。原因是 shared memory tile 通常以一种访问 pattern 写入,却以另一种 pattern 读取。 + +假设一个 tile 是从 global memory 按行填充的。row-major layout 会让这种写入 coalesced 且 bank-friendly。 +但 `ldmatrix` 后面可能以一种实际沿列或跨 8×8 subtile 行走的 pattern 读取该 tile。 +如果使用朴素 row-major layout,这些读取可能堆叠到同一个 shared memory bank 上。 + +对于一个简单的 `(8, 64)` float16 tile,一行是: + +```text +64 * 2 bytes = 128 bytes +``` + +这刚好是一整条 shared memory bank line。沿固定 column 向下走时,每一行前进 128 字节,所以 bank index 会重复。 +八行可能坍缩到同一个 bank 上,造成 8-way conflict。 + +改成朴素 column-major layout 并不能完整解决问题。它通常只是把 conflict 移到另一种访问上: +row write 变差,而 column-style read 变好。 + +XOR swizzle 通过让 physical column 依赖 row 来修复这个问题。一个简单版本是: + +```text +physical_col = logical_col xor row +``` + +逻辑 tile 不变。shared memory 中的物理 placement 被置换,使 row-style write 和 Tensor Core read pattern 都能避免 bank conflict。 + +在 Ampere 上,这种 swizzle 通常通过手写 shared memory index math 表达。后续世代则把它变成硬件引擎使用的 descriptor format 的一部分。 + +![在朴素 row-major tile 上,行写入会分散到多个 bank,而列读取会在一个 bank 上碰撞;XOR swizzle 在不牺牲合并行写入的情况下,把列读取分散到多个 bank](../img/swizzle_conflict.svg) + +## Hopper:`wgmma`、Shared Memory Descriptor 与 Swizzle 格式 + +Hopper 改变了 Tensor Core 路径的输入侧。它不再要求每个 operand 都用 `ldmatrix` 载入寄存器; +Hopper 的 `wgmma` 可以直接从 shared memory 读取 operand。 + +B operand 从 shared memory matrix descriptor 读取。A operand 可以从 shared memory descriptor 或寄存器读取, +对应 `.ss` 和 `.rs` 两种形式。 + +这移除了 SMEM-sourced operand 的显式 `ldmatrix` 步骤,但没有移除 layout requirement。 +Tensor Core 仍然期望 operand 以精确的 shared memory format 存储。区别在于,这个 format 现在通过 matrix descriptor 描述给硬件。 + +## Hopper Tensor Core 期望什么 + +Hopper shared memory matrix descriptor 是 shared memory 中 matrix tile 的一种紧凑描述。 +它告诉 `wgmma` 如何把逻辑 operand coordinate 转成 shared memory address。 + +descriptor 包含如下字段: + +```text +start address +leading dimension offset +stride dimension offset +swizzle mode +base offset +``` + +精确解释取决于 operand major mode。对于 K-major tile,一个 stride 沿 K 前进,另一个沿 M 前进。 +对于 MN-major tile,二者角色互换。 + +swizzle mode 是 shared memory descriptor format 之一,例如: + +```text +SWIZZLE_NONE +SWIZZLE_32B +SWIZZLE_64B +SWIZZLE_128B +``` + +swizzle mode 决定两件事。它决定 descriptor 使用的 atom shape,也决定应用在该 atom 内部的 XOR permutation。 +例如,128-byte swizzle mode 会把 operand 看作由 8-row × 128-byte atom 组成的网格,并在每个 atom 内应用 swizzle。 + +kernel 仍然必须正确放置字节。TMA 通常负责填充 shared memory tile,而 TMA descriptor 必须使用后续 `wgmma` descriptor 所指定的同一种 swizzle format。 +如果 TMA 写入的是 128-byte swizzled tile,那么 `wgmma` descriptor 就必须把它作为 128-byte swizzled tile 来读取。 +如果 descriptor 和数据不一致,Tensor Core 就会读到错乱的 operand。 + +这是相对于 Ampere 的主要变化。swizzle 不再只是藏在手写 shared memory indexing 中。 +Hopper 把它提升为 first-class descriptor format。写入 tile 的 TMA load 和读取 tile 的 `wgmma` 指令, +都可以命名同一种 format。 + +![Hopper 共享内存 matrix descriptor 把 operand 坐标映射到 swizzled 共享内存 atom:descriptor stride 选择 atom,swizzle 选择 atom 内部的 byte 位置](../img/smem_descriptor.svg) + +## Hopper 输出仍然使用寄存器 + +Hopper 改变了输入路径,但 accumulator 仍然位于寄存器中。 + +`wgmma` 指令把 accumulator 写入 per-thread register fragment。精确的 fragment 大小和寄存器数量取决于 instruction shape, +例如 `m64nNk16`,其中 N 会改变 accumulator register 数量。但基本思想和 Ampere 一样:epilogue 消费一个 register fragment。 + +因此 Hopper 有一个 mixed layout model。输入 operand 可以直接来自 shared memory descriptor,swizzle 由硬件描述。 +输出 accumulator 仍然是 register layout 问题。 + +Blackwell 改变了输出侧。 + +## Blackwell:`tcgen05` 与 TMEM + +Blackwell 为数据 operand 保留 shared memory descriptor 这一思想。A 和 B 仍然在 shared memory 中按 Tensor Core 期望的 layout 准备。 +某些模式也可以从 TMEM 读取 A operand。 + +主要变化在 accumulator。`tcgen05.mma` 会把 accumulator 写入 Tensor Memory,也就是 TMEM, +而不是把它保留为长期存在的 register fragment。在 compute phase 中,accumulator 留在 TMEM。 +epilogue 随后使用 `tcgen05.ld` 把它载回寄存器。 + +这把输出 layout 问题从寄存器移动到了 TMEM。kernel 必须分配 TMEM、选择正确的 TMEM layout、等待 MMA 完成, +然后使用匹配的 `tcgen05.ld` 路径,为 epilogue 恢复 accumulator fragment。 + +`cta_group::1` 和 `cta_group::2` 如何把 accumulator 分配到一个或两个 CTA 上,细节见 {ref}`zh_chap_tensor_cores`。 +与早期世代差异最大的 layout,是 block-scaled scale-factor layout。 + +## TMEM 中的 Scale Factor Layout + +block-scaled MMA mode(如 `mxfp8` 和 `nvfp4`)会加入 scale-factor operand。除了 A 和 B,MMA 还会读取: + +```text +SFA(M, SFK) +SFB(N, SFK) +``` + +其中 `SFK` 是 K scale block 的数量。 + +数据 operand A 和 B 位于 shared memory。scale factor 位于 TMEM。因此它们有不同的数据移动路径。 + +TMA 从 global memory load 到 shared memory,并不会直接 load 到 TMEM。因此 scale factor 通常分两步移动: + +```text +global memory to shared memory with TMA +shared memory to TMEM with tcgen05.cp +``` + +只有在这次 copy 之后,scale factor 才进入 `tcgen05.mma` 期望读取它们的内存空间。 + +TMEM scale-factor layout 使用 TMEM 的硬件坐标 Lane 和 Col。在 TIRx layout 记法中,这些轴写作 `TLane` 和 `TCol`。 + +一个 128-row scale vector 会被压缩到 32-lane group 中,然后复制到 TMEM 的四个 32-lane window 上。 +在 layout 记法中,核心 pattern 是: + +```text +S[(32, sf_per_mma) : (1@TLane, 1@TCol)] + R[4 : 32@TLane] +``` + +shard 放置 base 32-row group: + +```text +TLane = r +TCol = s +``` + +replica 项会在 lane offset 0、32、64 和 96 处添加副本: + +```text +TLane = r + 32 * q, where q in {0, 1, 2, 3} +TCol = s +``` + +这就是 `warpx4` broadcast pattern。同一个紧凑 scale-factor group 会在完整的 128-lane TMEM 空间中变得可见。 + +32-bit `TCol` cell 内部还存在 byte packing。packing 取决于 `scale_vec` mode: + +```text +1X: one scale value is broadcast across the 32-bit cell +2X: two scale values are packed, each duplicated +4X: four K-block scale values are packed +``` + +![scale_vec byte 打包:1X 在 4-byte cell 中广播一个缩放因子;2X 打包两个缩放因子且各复制一份;4X 打包四个 K-block 缩放因子](../img/sf_scale_vec.svg) + +这种 packing 在 Ampere 或 Hopper 中没有直接对应物,因为那些世代没有供 `tcgen05` block-scaled MMA 使用的 TMEM scale-factor operand。 + +在 `cta_group::2` 中,scale factor 会跟随它所缩放的数据。SFA 缩放 A,因此它按 M 在两个 CTA 之间切分, +匹配每个 CTA 拥有的 A row。SFB 缩放 B,而 B 被计算中的两个 CTA half 共享,因此 SFB 会 multicast 到两个 CTA +({ref}`zh_chap_tensor_cores`)。 + +## 反复出现的 Fragment + +尽管周围的内存路径在变化,一个结构会不断回归:m8n8 风格的 register fragment。 + +在 Ampere 上,`ldmatrix` 构建这个 fragment,让 `mma.sync` 能读取它。 + +在 Hopper 上,`wgmma` 把它的 accumulator 写成 register fragment,供 epilogue 使用。 + +在 Blackwell 上,accumulator 在 compute 期间位于 TMEM,但在 epilogue 处理并存储它之前, +`tcgen05.ld` 会把它载回 register fragment({ref}`zh_chap_tmem`)。 + +因此 fragment 并没有消失,只是角色改变了。早期世代会在整个 compute phase 中把 accumulator 保留在那里。 +Blackwell 则主要在 TMEM 和 epilogue 的边界处使用它。 + +## 贯穿主线 + +在 Ampere 上,kernel 显式构建 Tensor Core register fragment。shared memory swizzle 主要由 kernel 通过 index math 负责。 + +在 Hopper 上,Tensor Core 可以通过 matrix descriptor 直接从 shared memory 读取 operand。 +swizzle 变成 TMA 和 `wgmma` 共享的 named descriptor format。 + +在 Blackwell 上,输入侧仍然使用 shared memory operand,但 accumulator 移到 TMEM。 +block-scaled MMA 还增加了必须 stage 到 TMEM 中的 scale-factor operand。 + +descriptor 并不会消除 layout 工作。它们只是把 contract 显式化。kernel 仍然必须确保数据移动路径、memory layout +和 Tensor Core 指令全部一致。写入 swizzled SMEM tile 的 TMA descriptor、读取该 tile 的 MMA descriptor, +以及附着在 buffer 上的 layout,都必须描述同一种物理排列。 + +如果其中任何一部分不一致,硬件仍然会运行。它只是会读到错误字节,或者读取得很慢。 +这就是为什么 layout 不是 Tensor Core kernel 周围的装饰,而是 instruction interface 的一部分。 diff --git a/zh/chapter_performance/index.md b/zh/chapter_performance/index.md new file mode 100644 index 00000000..0c86187d --- /dev/null +++ b/zh/chapter_performance/index.md @@ -0,0 +1,308 @@ +(zh_chap_performance)= +# 什么让 Kernel 变快 + +:::{admonition} 概览 +:class: overview + +- Roofline 模型给出 kernel 的性能上限。这个上限由内存带宽或计算吞吐决定。 +- 算术强度决定适用哪一个上限。它表示每搬运一个字节所完成的有用算术工作量。 +- 低算术强度意味着 kernel 是 memory-bound。主要出路是搬运更少字节、更多复用数据、融合操作,或使用更小的 dtype。 +- 高算术强度意味着 kernel 可能是 compute-bound。此时主要任务就是让 Tensor Core 保持忙碌。 +- 在现代 GPU kernel 中,最主要的杠杆是 overlap。只要依赖图允许,TMA、Tensor Core、epilogue 和 store 就应该同时运行。 +::: + +kernel 的快慢只有相对于某个上限才有意义。像 330 TFLOP/s 这样的数字本身看起来很大, +但如果放到一个 dense fp16 或 bf16 Tensor Core 工作能维持约 2 PFLOP/s 的 GPU 上,它的含义就完全不同了。 +如果没有上限作为参照,就很难判断一个 kernel 是已经接近硬件极限,还是仍然让芯片的大部分能力闲着。 + +Roofline 模型给出的正是这个上限。它把 kernel 拆成两类基本活动:搬运字节,以及执行算术。 +如果 kernel 不能足够快地移动数据,内存带宽就会设定上限。如果 kernel 有足够的数据复用和足够多的算术工作, +计算吞吐就会设定上限。 + +本章的数字以 NVIDIA B200 作为贯穿示例。沿用 {ref}`zh_chap_background` 中的约定,我们使用便于推理的整数上限: +dense fp16 或 bf16 Tensor Core 吞吐约为 2 PFLOP/s,HBM3e 带宽约为 8 TB/s。 +精确值取决于具体设备、时钟、功耗限制和测量设置,因此这里应把它们理解为数量级上限,而不是 datasheet 常数。 + +## Roofline 模型 + +每个 kernel 都会移动数据并执行算术。Roofline 模型用这两条路径中更慢的一条来约束 kernel。 + +compute ceiling 是硬件的最大算术吞吐。对于 B200 上的 Tensor Core GEMM,相关上限就是 Tensor Core 吞吐。 +对于标量或 elementwise kernel,相关上限可能是 CUDA core 吞吐,或另一个功能单元。 + +memory ceiling 是带宽乘以算术强度。如果一个 kernel 每搬运一个字节只做很少算术,内存带宽就会限制性能。 +如果它每字节执行很多操作,内存就不太可能是限制因素。 + +基本的 roofline bound 是: + +```text +attainable FLOP/s <= min(peak FLOP/s, memory bandwidth * arithmetic intensity) +``` + +算术强度是: + +```text +arithmetic intensity = useful FLOPs / bytes moved +``` + +必须指定内存层级。对于 HBM roofline,这里的字节是 HBM 字节。对于 L2 roofline,它们是 L2 字节。 +对于 SMEM roofline,它们是 shared memory 字节。在本章中,默认 roofline 是 HBM roofline。 + +在 roofline 图中,x 轴是算术强度,单位是 FLOP/byte。y 轴是可达到的性能。memory roof 是一条斜线: + +```text +performance = bandwidth * arithmetic intensity +``` + +compute roof 是一条水平线: + +```text +performance = peak FLOP/s +``` + +二者在 ridge point 处相交: + +```text +ridge point = peak FLOP/s / bandwidth +``` + +对于这里使用的 B200 近似数字: + +```text +ridge point ≈ 2000 TFLOP/s / 8 TB/s + ≈ 250 FLOP/byte +``` + +算术强度低于这个值的 kernel,在 HBM roofline 下是 memory-bound。它无法达到 Tensor Core 峰值吞吐, +因为它无法每秒提供足够多的字节来喂饱这么多算术。 + +算术强度高于这个值的 kernel 可能是 compute-bound。此时,内存流量不再是一阶限制。 +剩下的工作,是足够好地驱动计算单元,以接近那条水平 roof。 + +Roofline 模型真正有用的部分不是图本身,而是它告诉程序员哪个资源正在成为约束。 +memory-bound kernel 不会因为数学指令稍微更好就变快。compute-bound kernel 也不会因为省下几个无关紧要的字节就变快。 +第一步,是知道 kernel 位于 ridge 的哪一侧。 + +![包含示例工作负载的 B200 roofline,展示内存上限、计算上限和 ridge 点](../img/roofline.png) + +## 常见工作负载的算术强度 + +算术强度通常首先是算法属性,其次才是实现细节。在编写 kernel 之前,通常就能做一个粗略估计。 + +### Elementwise 与 Reduction + +elementwise kernel(如 GELU)和 reduction 风格的 kernel(如 RMSNorm)会读写大 tensor, +但每个元素只执行少量 FLOP。 + +它们的算术强度很低,位于 ridge point 的很左侧。这类 kernel 的最佳版本通常试图接近内存带宽 roof, +而不是 Tensor Core compute roof。 + +对于这些 kernel,重要问题很机械: + +```text +Are the loads and stores coalesced? +Are bytes moved only once? +Can the operation be fused with a producer or consumer? +Can the dtype be smaller? +Can TMA or vectorized accesses help? +``` + +如果没有复用,也没有 fusion 机会,memory roof 就是真正的上限。 + +### GEMM + +GEMM 是相反的情况。它的算术强度会随问题规模增长,因为每个载入的 tile 都可以被复用到许多 multiply-accumulate 操作中。 + +对于 `M = N = K` 的方阵 fp16 matmul,理想算术强度大约是: + +```text +AI ≈ 2N^3 / (3 * 2N^2) + = N / 3 FLOP/byte +``` + +这个估计假设 A 和 B 各读一次,C 写一次,beta 为零,片上复用完美,并且没有额外 metadata、padding 或冗余流量。 +真实 kernel 搬运的数据会比这个理想模型更多。但这个估计仍然有用。 + +当 `N = 4096` 时: + +```text +AI ≈ 4096 / 3 + ≈ 1365 FLOP/byte +``` + +这个值远在 B200 约 250 FLOP/byte 的 ridge point 右侧。因此,大型 GEMM 在 HBM roofline 下是 compute-bound。 +目标不只是减少 HBM traffic。目标是使用 Tensor Core、持续喂饱它们,并把数据移动与计算 overlap 起来, +从而让 compute roof 变得可达。 + +这就是为什么 GEMM 虽然有高算术强度,朴素 GEMM 仍然可能很慢。算法允许高性能,但实现可能让 Tensor Core 闲置。 + +### 注意力 + +Attention 位于这两个极端之间。它的算术强度取决于序列长度、head dimension、tiling、masking, +以及中间 tensor 是否被 materialize。 + +标准 attention 的关键问题是 score matrix。如果 kernel 把 score matrix 写入 HBM,随后又读回来, +它就通过内存移动了一个大型中间结果。Flash Attention({ref}`zh_chap_flash_attention`)通过把相关 tile 留在片上, +避免这次 HBM 往返,从而提高算术强度。 + +因此,attention 优化一部分是 roofline 问题,一部分是调度问题。算法被改写,让更少字节进入 HBM。 +随后调度 kernel,让剩余的数据移动和计算 overlap。 + +## 当算术强度较低时 + +如果一个 kernel 位于 ridge 左侧,它就是 memory-bound。Tensor Core 或 CUDA core 可能闲置, +因为瓶颈是字节,而不是算术指令。 + +有两类应对方式。 + +第一类是提高算术强度。这条路径杠杆更高,因为它可以把 kernel 推向 compute-bound 区域。 + +最重要的技术是 fusion。低算术强度的常见来源,是把中间 tensor 写入 HBM,并在下一个操作中立刻读回。 +融合 producer 和 consumer 可以把这个中间结果留在寄存器、SMEM 或 TMEM 中。HBM 往返就消失了。 + +例子包括: + +```text +GEMM plus elementwise epilogue +normalization folded into a neighboring op +attention computed without materializing the full score matrix +``` + +第二种技术是为了复用而 blocking。如果一个 tile 载入一次,并在被逐出之前使用很多次,每个字节就支撑了更多算术工作。 +GEMM 的高算术强度正是来自这种复用。其他工作负载只要存在对 tile 的重复使用,也可以采用同样思想。 + +第三种技术是减少每个值占用的字节数。从 fp32 换成 fp16、fp8 或 fp4 会减少 traffic,并提高每字节 FLOP。 +当格式需要 metadata、scale factor 或额外转换工作时,真实收益会小于原始 dtype 比例。block-scaled fp8 和 fp4 就是这样的例子。 +即便如此,更小的 dtype 仍然常常是让 kernel 在 roofline 上向右移动的最直接方式之一。 + +第二类应对方式,是接受 memory roof,并试图抵达它。有些 kernel 没有足够工作可以 fusion,也没有足够复用可以利用。 +纯 copy、简单 elementwise 操作,或对大 tensor 的单遍 reduction,可能在本质上就是 memory-bound。 + +在这种情况下,目标不是超过 roof,而是饱和它。 + +这意味着: + +```text +move each byte once +avoid redundant reads +use coalesced or vectorized accesses +use TMA for regular bulk tiles +keep enough memory requests in flight +use smaller storage dtypes when the algorithm allows it +``` + +一旦 memory-bound kernel 达到 memory roof,进一步优化计算就没有帮助。想更快,唯一办法是改变算法,让它搬运更少字节。 + +## 优化阶梯 + +roofline 说明什么是可能的,但并不说明达到那个上限有多容易。 + +大型 fp16 GEMM 理论上可能是 compute-bound。这只意味着 HBM roof 不是主要限制, +并不意味着任何实现都能达到 Tensor Core roof。要缩小差距,需要正确的指令、layout、staging、同步和调度。 + +第三部分的 GEMM kernel 会在 B200 上把这一点展示为一系列步骤({ref}`zh_chap_gemm_advanced`)。 +每一步都保留相同的基本算法,但改变 tile 的计算方式或调度方式。 + +GEMM 阶梯中第一次测得的大幅跃升,是从 thread-copy tiled 路径移动到 TMA-backed 路径。 +TMA 把规则的 GMEM -> SMEM tile 移动从 CTA thread 手中拿走,让 kernel 通过硬件管理的 bulk copy 喂给 Tensor Core。 + +在第一次跃升之后,主要改进来自 overlap 和调度。TMA 把未来的 tile 带入 shared memory。`tcgen05.mma` 异步运行。 +epilogue 排空先前结果。software pipelining 和 warp specialization 安排这些部件,让硬件引擎同时活跃。 + +也没有规则要求每个中间步骤本身都必须更快。像 warp specialization 这样的步骤,可能会暂时把资源花在一种结构上, +而这种结构不会立刻改善数字。但如果它能启用更简单结构无法表达的后续 overlap,它仍然可能是正确的一步。 + +![B200 上的 GEMM 优化旅程:从同步分块 baseline,到 TMA、warp 专门化、CTA 集群和多消费者执行的测量点](../img/gemm_perf.png) + +## Overlap 是主要杠杆 + +一旦 GEMM 已经是 compute-bound,并且已经使用 Tensor Core,剩下的差距通常来自 idle time。 + +一个简单 kernel 可能这样做: + +```text +load tile k +compute tile k +store tile k +load tile k + 1 +compute tile k + 1 +store tile k + 1 +``` + +这种 schedule 会让硬件闲置。load 运行时,Tensor Core 在等待。Tensor Core 运行时,copy engine 可能闲置。 +store 排空时,两者都可能在等待。 + +pipelined kernel 则试图把彼此独立的阶段一起运行: + +```text +load tile k + 1 +compute tile k +store tile k - 1 +``` + +这就是本书后面使用的 Blackwell kernel 结构背后的核心思想。TMA 处理异步数据移动。`tcgen05.mma` 处理异步 Tensor Core 工作。 +epilogue 和 store 处理输出侧。`mbarrier` 对象连接各个阶段,让每个 consumer 只在真正需要数据时等待。 + +重点不是移除依赖,而是围绕依赖进行调度。tile `k` 的 MMA 必须等 tile `k` 载入后才能开始。 +tile `k` 的 epilogue 必须等 tile `k` 的 MMA 完成后才能读取 accumulator。 +但 tile `k + 1` 的 load 通常可以在 tile `k` 的 MMA 正在进行时运行,而 tile `k - 1` 的 store 通常也可以同时排空。 + +这就是为什么后面许多章节会聚焦异步机制: + +```text +TMA for global memory to shared memory movement +mbarriers for load completion and resource handoff +tcgen05 for asynchronous Tensor Core compute +TMEM for long-lived accumulators +warp specialization to separate producer and consumer roles +clusters for larger cooperative tiles and multicast +``` + +它们是不同机制,但服务于同一个调度目标:让有用工作同时运行在不止一条硬件路径上。 + +## Occupancy 与资源压力 + +overlap 并不是唯一的 latency hiding 机制。更老也更通用的机制是 occupancy。 + +occupancy 是驻留在一个 SM 上的工作量。如果一个 warp stall,scheduler 可以运行另一个已经 ready 的 warp。 +它通过保持一池可用的独立 warp 来隐藏延迟。 + +occupancy 受每个 SM 的资源限制。主要限制包括寄存器、shared memory、warp slot 和 CTA slot。 +如果一个 kernel 每个 thread 使用很多寄存器,或每个 CTA 使用大量 shared memory,它可能 occupancy 很低, +因为 SM 上只能放下少量 CTA 或 warp。 + +许多现代 Tensor Core kernel 会有意以降低 occupancy 的方式消耗资源。multi-stage shared memory pipeline 会消耗 SMEM。 +大型 register fragment 会消耗寄存器。TMEM 分配会消耗 Tensor Memory 容量。warp specialization 可能会为 producer +或 consumer 角色保留整个 warp。 + +这种取舍是刻意的。与其通过让许多无关 warp 驻留来隐藏延迟,这些 kernel 会在较少数量的驻留 CTA 内部通过显式 overlap +来隐藏延迟。如果 pipeline 能让 TMA、Tensor Core 和 store 保持忙碌,低 occupancy 的 kernel 仍然可以很快。 + +没有哪种方式总是更好。有些 kernel 需要高 occupancy,因为它们具有不规则内存访问,或显式 overlap 很有限。 +另一些 kernel 需要深度 staging 和 specialization,因为那是高效喂饱 Tensor Core 的唯一方式。 +正确的问题不是 occupancy 是否很高,而是活跃的硬件单元是否保持忙碌。 + +## 这对后续章节有什么帮助 + +本书后续会不断回到同一套诊断问题: + +```text +Which roof is this kernel under? +What resource is binding? +What change moves the kernel closer to that roof? +``` + +对于 memory-bound kernel,答案通常是更少字节和更好的带宽使用。这意味着 fusion、coalescing、vectorized access、 +适用时使用 TMA,以及更小的 dtype。 + +对于 compute-bound GEMM,答案是先使用 Tensor Core,然后做 overlap。kernel 必须 stage operand、发射异步 MMA 工作、 +保持 pipeline 充满,并在不阻塞计算路径的情况下排空结果。 + +对于 Flash Attention,第一步是通过把 score 和 probability tile 留在片上来提高算术强度。 +之后,它使用与 GEMM 相同的 overlap 工具:tiled data movement、shared memory staging、异步计算,以及谨慎的资源交接。 + +这给出了一个实用的优化流程:估计算术强度,定位 roof,判断 kernel 是 memory-bound 还是 compute-bound, +然后优化真正设定上限的资源。 + +如果没有这一步,kernel 优化就会变成猜谜。有了它,每一次修改都有理由:要么提高算术强度, +要么让内存路径更接近带宽峰值,要么减少 compute roof 下的 idle time。 diff --git a/zh/chapter_tensor_cores/index.md b/zh/chapter_tensor_cores/index.md new file mode 100644 index 00000000..f6598eae --- /dev/null +++ b/zh/chapter_tensor_cores/index.md @@ -0,0 +1,247 @@ +(zh_chap_tensor_cores)= +# Tensor Core:`tcgen05` + +:::{admonition} 概览 +:class: overview + +- `tcgen05` 是 Blackwell 的 Tensor Core 指令家族。它的 MMA 指令以协作方式执行 tile matrix-multiply-accumulate 工作,并由一个被选出的 thread commit。 +- accumulator 位于 TMEM 中,而不是寄存器中。epilogue 稍后用 `tcgen05.ld` 把它带回寄存器。 +- `cta_group::1` 和 `cta_group::2` 控制是一个 CTA 还是两个 CTA 协作完成 MMA。这个选择也会改变 M 维度如何映射到 TMEM。 +- block-scaled MMA mode(如 `mxfp8` 和 `nvfp4`)会添加 scale-factor operand。数据 operand 位于 SMEM,而 scale factor 会通过 TMEM stage。 +::: + +dense linear algebra 是现代 GPU 花费大部分有用工作的地方。普通 CUDA-core matrix multiply 无法接近芯片标称峰值 +({ref}`zh_chap_background`)。快速 GEMM 和 attention kernel 通过以正确的 tile shape、layout 和 synchronization +喂给 Tensor Core,来接近这个峰值。 + +从 Volta 开始,基本操作在精神上没有改变。Tensor Core 消费 matrix tile,把它们相乘,并累加结果。 +代际之间变化的是操作如何发射、operand 如何布局,以及 accumulator 位于哪里。 + +Blackwell 对最后一点做了重大改变。`tcgen05` 的 accumulator 不再作为长期存在的 register fragment 保存。 +它被写入 Tensor Memory,也就是 TMEM({ref}`zh_chap_tmem`)。这一个变化会影响整个 kernel: +MMA 写入 TMEM,completion 被异步追踪,epilogue 稍后从 TMEM 中 load accumulator, +并把它变回自己用于转换和 store 的 register fragment。 + +本章聚焦计算指令本身。TMA({ref}`zh_chap_tma`)负责把 operand 移入 SMEM。 +TMEM 负责保存 accumulator 以及某些 scale-factor operand。`tcgen05.mma` 是位于这两次内存移动之间的 Tensor Core 操作。 + +```{raw} html +
+ +
+``` +*交互:`tcgen05` accumulator 行为。切换 A 或 B 的 transpose,选择输出宽度 `N`,并逐步走过 `K` 次迭代,观察 partial sum 如何在 TMEM 中累加。* + +## `tcgen05` MMA + +`tcgen05` MMA 是 Blackwell Tensor Core 的 matrix-multiply-accumulate 指令。它是一条协作指令: +工作面向一个 warpgroup 执行,在某些模式下还可以涉及同一个 cluster 中的两个 CTA。 +这条指令不是由每个 thread 独立发射的;而是由一个被选出的 thread 代表参与组 commit 这个操作。 + +把 MMA 拆成三个问题会更清楚。 + +第一个问题是谁协作。普通模式使用一个 CTA,写作 `cta_group::1`。更大的模式使用 cluster 中的两个 CTA,写作 `cta_group::2`。 +两种情况下,这条指令都表示对一个 tile 的一次 Tensor Core 操作,而不是一个 thread 的标量操作。 + +第二个问题是 operand 和结果住在哪里。数据 operand 通常位于 SMEM。某些变体也可以从 TMEM 读取 A operand。 +accumulator 写入 TMEM。operand layout 必须匹配 Tensor Core 的期望,包括数据 operand 使用的 swizzled shared-memory layout +({ref}`zh_chap_data_layout`)。 + +第三个问题是如何观察 completion。`tcgen05.mma` 是异步的。发射 MMA 并不意味着 multiply-accumulate 已经完成。 +指令会在操作 commit 后返回,而 Tensor Core 继续运行。kernel 使用 commit group 和 `mbarrier` 来得知结果何时 ready +({ref}`zh_chap_async_barriers`)。 + +正是这种异步行为让 overlap 成为可能。快速 kernel 不会发射 MMA 后立刻 stall 到它结束。 +它可以发射 MMA,开始准备后续 tile,并且只在真正需要结果时等待。代价是每一次 handoff 都必须显式。 +如果 epilogue 在 MMA completion barrier 触发之前读取 TMEM,那就是读得太早。 + +## Accumulator 位于 TMEM + +在 Ampere 和 Hopper 上,accumulator 以寄存器形式暴露给程序。MMA 产生 per-lane register fragment, +epilogue 直接消费这个 fragment。这很简单,但它把 accumulator 大小绑定到了每个 thread 的寄存器预算上。 + +Blackwell 打破了这个链接。`tcgen05.mma` 把 accumulator 写入 TMEM,这是 Blackwell 上一个 CTA 作用域的内存空间。 +accumulator 可以在整个 compute phase 中留在 TMEM,epilogue 稍后使用 `tcgen05.ld` 把它载回寄存器。 + +这改变了 kernel 的形态。register fragment 在边界处仍然重要。epilogue 仍然需要寄存器,以便转换、应用 elementwise work, +并存储结果。但长期存在的 accumulator state 不再是 register allocation 问题,而是 TMEM allocation 和 layout 问题 +({ref}`zh_chap_tmem`)。 + +这就是为什么 `tcgen05` 和 TMEM 必须放在一起理解。MMA 指令决定计算哪个 tile。 +TMEM 决定 accumulator 落在哪里。epilogue 必须使用匹配的 load 路径,以自己期望的 register layout 恢复 accumulator。 + +## `cta_group::1` and `cta_group::2` + +`tcgen05` MMA 可以运行在 `cta_group::1` 或 `cta_group::2` 模式。 + +在 `cta_group::1` 中,一个 CTA 拥有这次 MMA。它的 operand 位于该 CTA 的 SMEM 中,accumulator 写入该 CTA 的 TMEM。 + +在 `cta_group::2` 中,cluster 中的两个 CTA 协作处理一个 MMA tile。每个 CTA 都有自己的 SMEM 和 TMEM。 +accumulator 并不是存储在一个跨越两个 CTA 的物理 TMEM 区域中,而是切分到两个 CTA 上,每个 CTA 持有自己的部分。 +偶数 CTA 发射指令,并为这一对 CTA commit completion barrier。 + +这个选择很重要,因为它改变逻辑 accumulator tile `C(M, N)` 如何映射到 TMEM。 +TMEM 有 128 个硬件 Lane row,以及最多 512 个硬件 Col column。在 TIRx layout 记法中,这些轴写作 `TLane` 和 `TCol`。 +MMA mode 决定 `C` 的 row 和 column 如何放到这些 TMEM 轴上。 + +有四种有用情况值得记住。 + +下图沿用演示中的颜色约定:紫色表示 SMEM operand,橙色表示 TMEM accumulator state,绿色表示 Tensor Core MMA 路径。 +CTA 身份通过标签和位置表示,而不是通过改变这些硬件颜色表示。 + +### `cta_group::1`, `M = 128` + +这是最简单的情况。一个 CTA 计算 128-row tile。TMEM 也有 128 个 Lane row。 +因此映射是直接的:accumulator 的 row `m` 映射到 Lane `m`,N 维度映射到 TMEM column。 + +结果填满 128 个 Lane row 和 N 个 Col column。这是 baseline 图景。CTA 在 SMEM 中拥有 A 和 B, +并在自己的 TMEM 中拥有完整 accumulator tile。 + +![cta_group::1, M=128:行 m 直接映射到 TMEM lane m](../img/mma_cg1_m128.svg) + +### `cta_group::1`, `M = 64` + +当 `M = 64` 时,accumulator 只有 64 行,但 TMEM 仍然有 128 个 Lane row。 +硬件并不会简单地把 row 0 到 63 pack 到 lane 0 到 63。相反,它会把它们以四段 16-row run 的形式分散到 128 个 lane 中。 + +row 0 到 15 去 lane 0 到 15。row 16 到 31 去 lane 32 到 47。 +row 32 到 47 去 lane 64 到 79。row 48 到 63 去 lane 96 到 111。 + +这会在 lane 16 到 31、48 到 63、80 到 95、112 到 127 留下空隙。这些空隙是有意的。 +通过不同的 lane alignment,另一个独立的 `M = 64` MMA 可以占用互补 lane。 +这让两个较小的 M tile 能共享 128-lane TMEM 结构,而不会彼此踩踏。 + +N 维度仍然映射到 TMEM column。不寻常的部分只在于 M row 在 Lane 上的 placement。 + +![cta_group::1, M=64:四段 16 行 run,lane stride 为 32,为另一个对齐的 M=64 tile 留出空间](../img/mma_cg1_m64.svg) + +### `cta_group::2`, `M = 256` + +当 M 维度大到一个 CTA 无法自然持有时,MMA 可以使用 `cta_group::2`。对于 `M = 256`,切分很直接: +CTA 0 持有 row 0 到 127,CTA 1 持有 row 128 到 255。 + +每个 CTA 使用自己的 TMEM Lane row 0 到 127,以及完整 N column。物理上,这是两个独立的 128-row TMEM region, +每个 CTA 一个。逻辑上,它们形成一个 256×N accumulator tile。 + +每个 CTA 也提供 A 中对应自己 M row 的部分。B 按该模式的要求对两个 CTA 可用。 +偶数 CTA 负责发射 MMA,并为这对 CTA commit completion barrier。 + +这是 {ref}`zh_chap_gemm_advanced` 中 two-CTA cluster GEMM 使用的模式。 + +![cta_group::2, M=256:M 连续切分到两个 CTA 上,每个 CTA 128 行](../img/mma_cg2_m256.svg) + +### `cta_group::2`, `M = 128` + +`cta_group::2`、`M = 128` 模式仍然使用两个 CTA,但 M 维度更短。由于总共只有 128 行, +每个 CTA 接收 64 个 M row。 + +剩余的 lane 容量用于 pack N 维度。在每个 CTA 内,N 的一半占据 lane 0 到 63, +另一半占据 lane 64 到 127。这样即使每个 CTA 只拥有 64 个 M row,也能使用全部 128 个 Lane row。 + +因此这个切分有两部分。M 在 CTA pair 之间切分,每个 CTA 64 行。 +随后 N 在每个 CTA 内部跨 TMEM Lane row 的 lower half 和 upper half 切分。 + +![cta_group::2, M=128:每个 CTA 64 个 M 行,N 的两半堆叠在下/上半 lane 上](../img/mma_cg2_m128.svg) + +在这些模式中,原则相同。`tcgen05.mma` 计算一个逻辑 accumulator tile,但这个 tile 必须放入物理的 +128 Lane × 最多 512 Col 的 TMEM 空间。mode 和 M shape 决定这种 placement。 +kernel 后续在把 accumulator 读回时,必须使用同一种映射。 + +对于这里的 kernel,TMEM 中的 accumulator 通常是 f32。这是常见的高精度路径。 +它不是唯一可能的 accumulator type。`.kind::f16` 路径可以用 f16 accumulate。 + +## Operand Placement + +对于 dense MMA mode,A 和 B 会在 MMA 运行前准备在 SMEM 中。TMA 负责把 global memory tile 移入 SMEM。 +kernel 会把这些 SMEM tile 安排成 Tensor Core 期望的 layout,包括任何必需的 swizzle。 + +accumulator C 写入 TMEM。这是与早期世代的主要区别。epilogue 不会直接把 accumulator 作为 MMA 指令输出接收。 +它必须用 `tcgen05.ld` 从 TMEM 显式 load。 + +在 `cta_group::1` 中,一个 CTA 提供 operand 并拥有 accumulator。在 `cta_group::2` 中, +每个 CTA 从自己的 SMEM 提供自己一侧的 operand,并拥有 accumulator 中属于自己的 TMEM 部分。 +当 A 按 M 切分时,每个 CTA 保留自己 M slice 的 A row。B 按 mode 共享,因为两个 M slice 都要乘以同一个 N×K tile。 + +阅读 kernel 时,这种分离很重要。SMEM placement 回答 Tensor Core 如何读取 A 和 B。 +TMEM placement 回答 accumulator 去哪里。这两个 layout 由 MMA mode 联系起来,但它们不是同一个内存空间,不能互换看待。 + +## Block-Scaled MMA + +dense mode 直接从 SMEM 读取数据 operand,并累加到 TMEM。Block-scaled MMA 增加两个 operand:A 和 B 的 scale-factor tensor。 + +这用于 `mxfp8` 和 `nvfp4` 这样的极低精度格式。低精度格式很高效,但动态范围很小。 +单个 global scale 通常过于粗糙。如果 scale 按最大值选择,小值会损失精度;如果 scale 按小值选择,大值可能 clip。 + +block scaling 通过给小 K block 分配 scale factor 来修复这个问题。一组连续 K 元素共享一个 scale。 +MMA 在概念上用对应 scale 对每个 block 做 dequantize,然后用 accumulator type 累加乘积。 + +对于 A 和 B,这会引入两个 scale-factor tensor: + +```text +SFA(M, SFK) +SFB(N, SFK) +``` + +其中 `SFK = K / B`,而 `B` 是沿 K 的 block size。 + +精确 block size 取决于格式。重要的是,scale axis 以更粗粒度跟随 K。 +每个 scale factor 描述的是一块 K 值,而不是单个元素,也不是整个矩阵。 + +数学形式是: + +```text +acc += (Aq * scale_a) * (Bq * scale_b) +``` + +其中 `Aq` 和 `Bq` 是 quantized low-precision value,scale 在 accumulate 前恢复它们的近似幅度。 + +scale dtype 也很重要。使用 `e8m0` scale 时,每个 scale 实际上是 2 的幂。 +使用 `nvfp4` 所采用的 `e4m3` scale 时,scale 是一个小浮点值,可以表示 2 的幂之间的值。 + +## Scale Factor 位于哪里 + +block-scaled `tcgen05.mma` 与 dense MMA 有一条重要 placement rule 不同:scale factor 从 TMEM 读取。 + +数据 operand A 和 B 仍然 stage 在 SMEM 中。scale factor SFA 和 SFB 通过 TMEM stage。 +由于 TMA load 到 SMEM,scale factor 通常需要额外一步。kernel 先把它们 load 到 SMEM, +再用 `tcgen05.cp` 从 SMEM copy 到 TMEM。只有当 scale factor 位于 TMEM 中时,block-scaled MMA 才能读取它们。 + +这给 scale factor 带来了不同于数据 operand 的移动路径: + +```text +A, B: global memory to SMEM, then MMA reads SMEM +SFA, SFB: global memory to SMEM, then tcgen05.cp copies SMEM to TMEM, then MMA reads TMEM +``` + +scale factor 的 TMEM layout 很紧凑。一个 128-row scale vector 可以 pack 到 32 个 Lane row 中: +lane position 基于 `r % 32`,column 方向基于 `r / 32`。 +数据随后可以 broadcast 到读取完整 128 Lane 空间的四个 warp 上({ref}`zh_chap_layout_generations`)。 + +这是为什么 TMEM layout 必须显式的好例子。accumulator layout 和 scale-factor layout 都在 TMEM 中, +但它们不是同一个 layout。accumulator 使用 MMA output mapping,scale factor 使用 block-scaled MMA 期望的 compact layout。 + +## `cta_group::2` 中的 Scale Factor + +在 two-CTA 情况下,scale factor 跟随它缩放的数据。 + +SFA 缩放 A。由于 A 按 M 在 CTA pair 之间切分,SFA 也按 M 切分。每个 CTA 持有与自己 A row 对应的 SFA row。 + +SFB 缩放 B。由于两个 CTA 都乘以同一个 B tile,SFB 必须对两个 CTA 可见。实践中,这意味着 SFB 会 multicast 到 CTA pair。 + +这就是 block-scaled cluster GEMM 中常见 load pattern 的来源。SFA 按 CTA load,使用该 CTA 自己 M slice 的 mask。 +SFB 会 broadcast 到这一对 CTA,因为两个 CTA 都需要同一组 N-side scale factor。 + +![块缩放 MMA 放置:A 和 B 在 SMEM 中打包;SFA、SFB 和 C 位于 TMEM,其中 SFA 按 M 跨 CTA 切分,SFB 多播到 CTA 对](../img/mma_block_scaled.svg) + +## 保持 MMA Contract 匹配 + +一个 Blackwell GEMM tile 会经过几条专门化路径。 + +TMA 把 A 和 B 从 global memory 带入 SMEM。对于 block-scaled mode,它也会把 scale factor 带入 SMEM。 +需要时,`tcgen05.cp` 把这些 scale factor 移入 TMEM。`tcgen05.mma` 读取 operand,在 Tensor Core 上异步运行, +并累加到 TMEM 中。completion barrier 告诉 kernel 这个 accumulator 何时 ready。 +epilogue 随后用 `tcgen05.ld` 把 accumulator 从 TMEM 载回寄存器,并存储最终输出。 + +跨越这些路径,kernel 必须保持三个 contract 匹配:SMEM operand layout、TMEM accumulator 或 scale-factor layout, +以及让下一个 consumer 可以安全运行的异步 completion signal。 diff --git a/zh/chapter_tirx_layout_api/index.md b/zh/chapter_tirx_layout_api/index.md new file mode 100644 index 00000000..7f97e5c3 --- /dev/null +++ b/zh/chapter_tirx_layout_api/index.md @@ -0,0 +1,783 @@ +(zh_chap_tirx_layout_api)= +# TIRx Layout API + +:::{admonition} 概览 +:class: overview + +- TIRx layout API 会把 {ref}`zh_chap_data_layout` 中的 layout 记法变成编译器对象。主要对象是 `TileLayout`、`SwizzleLayout` 和 `ComposeLayout`。 +- `TileLayout` 描述 named hardware axes 上的仿射 placement。它由 shard spec `S[...]`、replica spec `R[...]` 和可选 offset 构成。 +- 一个 layout 会把一个逻辑坐标映射到一个或多个物理坐标。`layout.apply()` 会求值这个映射。 +- `SwizzleLayout` 描述用于避免 bank conflict 的、基于 XOR 的 shared-memory swizzle。`ComposeLayout` 会把 swizzle 叠加到 tile layout 上。 +- `tmem_datapath_layout`、`tcgen05_atom_layout` 和 `wg_local_layout` 等现成 constructor 覆盖了 kernel 中反复出现的硬件 layout。 +::: + +{ref}`zh_chap_data_layout` 引入了本书通用的记法:一个 tile shape、一组位于 named axes 上的 stride, +以及一个可选 replication term,用来表示被复制而不是被 partition 的值。本章会把这个记法转成编译器使用的 API。 + +目标是让页面上的记法和 kernel 中的代码看起来几乎一样。当你写下这样的 layout: + +```python +S[(128, 256) : (1@TLane, 1@TCol)] +``` + +你不只是在写解释。你正在构造一个可以附着到 buffer 上的 `TileLayout` 对象。 +之后,每个接触这个 buffer 的 tile operation 都可以从 layout 中读取它的 placement。 +placement 写一次、检查一次,然后由编译器复用。 + +layout 可以在从 pool 分配时附着,也可以在声明 buffer 时附着: + +```python +pool.alloc(shape, dtype, layout=layout) + +T.decl_buffer(shape, dtype, scope=scope, layout=layout) +``` + +从那一刻起,buffer 就携带自己的物理 placement。tile operation 不需要重复说明每个元素住在哪里。 + +layout object 位于同一个模块中: + +```python +from tvm.tirx.layout import ( + TileLayout, + SwizzleLayout, + ComposeLayout, + S, + R, + laneid, + warpid, + tid_in_wg, + TLane, + TCol, + m, + tcgen05_atom_layout, + tmem_datapath_layout, +) +``` + +这个 API 背后有一个核心思想:layout 不必把逻辑索引映射到单个物理地址。 +它会把逻辑索引映射到 named axes 上的一组物理坐标。通常情况下,这个集合只有一个元素。 +当存在 replication 时,同一个逻辑元素会有多个物理 placement。 + +这就是为什么 layout model 有三部分:shard、replica 和 offset。shard 放置元素。 +replica 把它复制到额外坐标。offset 平移整个 placement。 + +## 通过例子理解 Layout + +下面的例子展示了 API 的基本形状。 + +TMEM 中的 accumulator 可以写成 TMEM axes 上的直接 placement: + +```python +acc = TileLayout(S[(128, 256) : (1@TLane, 1@TCol)]) +``` + +这里,逻辑 row 映射到 `TLane`,逻辑 column 映射到 `TCol`。 +在 {ref}`zh_chap_tmem` 中,硬件坐标称为 Lane 和 Col。在 TIRx layout 记法中,这些硬件轴写作 `TLane` 和 `TCol`。 + +block-scaled MMA 的 scale-factor layout 使用 replication: + +```python +scale_factor_layout = TileLayout( + S[(32, sf_per_mma) : (1@TLane, 1@TCol)] + R[4 : 32@TLane] +) +``` + +shard 会在 TMEM 中放置一个 32-row group。replica 以 32 lane 的 stride 把这个 group 重复四次, +因此这个 32-row group 在完整 128-lane TMEM 空间中可见。 + +tensor-core register fragment 可以分布在 lane 和 warp 上: + +```python +frag = TileLayout( + S[(8, 2, 4, 2) : (4@laneid, 1@warpid, 1@laneid, 1)] +) +``` + +同一个物理轴可以出现多次。在这个例子中,两个不同 iter 都贡献到 `laneid`。 +没有显式轴的 stride 会使用默认 memory axis `m`。 + +在真实 kernel 中,常见硬件 layout 通常来自 constructor: + +```python +acc = tmem_datapath_layout("D", 128, 256) + +ld = tcgen05_atom_layout("32x32b", (128, 64), "float32") +``` + +这些 constructor 返回普通 `TileLayout` 对象。它们只是便利函数,不是另一套机制。 +你可以检查返回的 layout,把它与其他 layout compose,或者在 shape 比较特殊时手写底层 `S[...]` 和 `R[...]` 形式。 + +## 交互式演示 + +进入机制之前,有一个能动手戳的具体对象会很有帮助。下面的演示允许你选择 preset layout, +编辑 logical shape 和 `S` 或 `R` 项,选择 dtype 和 swizzle mode,并点击一个元素,查看哪个或哪些物理坐标拥有它。 + +```{raw} html +

+ ▶ Open the demo full screen ↗ +

+ + +``` + +这个演示很有用,因为 API 的大部分内容就是演示所展示过程的精确版本。 +一个逻辑元素进入 layout。layout 把它 flatten,跨自己的 iter split,在 named axes 上累加坐标, +然后在需要时应用 replication。 + +## TileLayout + +`TileLayout` 是主要的 affine layout object。它通常用正文中相同的记法书写: + +```python +TileLayout(S[shape : strides]) +``` + +`S` 项是 shard spec。你可以这样读它:取一个这种 shape 的逻辑 tile,并用这些 named axes 上的 strides 放置它。 + +当一个值需要出现在多个位置时,shard spec 会用 replica spec 扩展: + +```python +TileLayout(S[shape : strides] + R[replica_shape : replica_stride]) +``` + +也可以加入可选 offset: + +```python +TileLayout(S[shape : strides] + R[replica_shape : replica_stride] + offset) +``` + +在表面之下,这些部分由 iter 表示。一个 iter 是三元组: + +```text +(extent, stride, axis) +``` + +它描述了在一个 named axis 上的 strided walk。extent 表示这个 iter 有多少个位置。 +stride 表示每一步移动多远。axis 表示哪个硬件坐标正在改变。 + +一个 layout 有三部分。 + +### Shard + +shard,也就是 `D`,是由 `S[...]` 构建的部分。它把逻辑索引 partition 到一个或多个 iter 上,并产生 base physical coordinate。 + +For example: + +```python +S[(8, 2, 4, 2) : (4@laneid, 1@warpid, 1@laneid, 1)] +``` + +有四个 shard iter。它们的 extent 是 `8`、`2`、`4` 和 `2`。 +它们的 stride 分别把数据放到 `laneid`、`warpid`、再次 `laneid`,以及默认 memory axis `m` 上。 + +这推广了普通 shape-and-stride 规则。区别在于,stride 附着到 named hardware axes 上,而不是附着到单个 flat address 上。 + +### Replica + +replica,也就是 `R`,描述同一个逻辑元素的额外物理副本。replica iter 与逻辑索引无关。 +它们枚举硬件空间中的额外 offset。 + +For example: + +```python +R[2 : 4@warpid] +``` + +会在 `warpid` 轴上创建两个相隔四个 warp 的副本。 + +replication 不是为了方便而设的技巧,它描述的是真实硬件行为。有些数据会跨 warp、lane 或 memory region broadcast。 +logical-to-physical mapping 自然支持这一点,因为一个逻辑元素可以映射到一组物理坐标。 + +### Offset + +offset,也就是 `O`,是加到每个结果上的固定坐标。 + +For example: + +```python +5@warpid +``` + +会把整个 placement 在 `warpid` 轴上平移五个单位。 + +offset 用于把 tile 放到选定 base coordinate、为独占使用保留一段区域, +或描述同一资源中位于另一个 tile 之后开始的 tile。 + +### 把这些部分组合起来 + +layout 会按顺序应用这三部分。 + +首先,shard 计算 base coordinate。然后,replica 把这个 coordinate fan out 成零个或多个额外副本。 +最后,offset 平移每个 coordinate。 + +对于逻辑坐标 `x`,结果是: + +```text +L(x) = { D(x) + r + O | r in R } +``` + +如果没有 replica,`R` 只包含 zero offset,因此结果是 singleton set。如果存在 replica, +结果会为每个 replica position 包含一个 coordinate。 + +在 TIRx 语法中,一个完整 layout 可以这样写: + +```python +layout = TileLayout( + S[(8, 2, 4, 2) : (4@laneid, 1@warpid, 1@laneid, 1)] + + R[2 : 4@warpid] + + 5@warpid +) +``` + +从左到右读,shard 放置逻辑 tile,replica 在相隔四个 warp ID 的地方创建第二份副本, +offset 把整个 placement 平移到从 `warpid = 5` 开始。 + +如果 iter 已经被构造成对象,同一个 layout 可以直接构造: + +```python +TileLayout.from_iters(shard, replica, offset) +``` + +大多数用户代码使用 `S[...]` 和 `R[...]` 记法,因为它更接近数学形式。 + +## Named Axes + +layout 中的 axis 不是匿名维度。每个 axis 都命名一个真实硬件坐标,或 compiler-level placement coordinate。 + +Examples include: + +```text +bx, by, bz +cbx, cby, cbz +tx +warpid +laneid +wgid +tid_in_wg +wid_in_wg +m +P, F +Bank +TLane, TCol +``` + +`bx`、`by` 和 `bz` 等 grid axes 会把工作放置到 CTA 之间。 +`cbx`、`cby` 和 `cbz` 等 cluster axes 会把工作放置在 CTA cluster 内部。 +`tx`、`warpid`、`laneid`、`tid_in_wg` 和 `wid_in_wg` 等 thread axes 描述 CTA 或 warpgroup 内部的 ownership。 +`m` 轴是默认 linear memory axis。`P` 和 `F` 用于二维 scratchpad-style placement。 +`Bank` 命名 shared memory bank。`TLane` 和 `TCol` 是 TMEM Lane 和 Col 坐标在 TIRx layout 中的名字。 + +axis name 是 layout 的一部分。这很重要,因为整数值相同的两个坐标可能表示不同硬件事物。 +`1@tx` 不等于 `1@tid_in_wg`。`1@laneid` 不等于 `1@TLane`。layout 会让这些含义保持显式。 + +## Forward Mapping + +求值一个 layout,就是拿一个逻辑坐标并计算它物理上落在哪里。API 方法是: + +```python +layout.apply(*coord) +``` + +对于没有 replication 的 layout,结果是一个 coordinate dictionary。带 replication 时,结果是一组 coordinate dictionary。 +coordinate dictionary 会把 axis name 映射到整数位置,例如: + +```python +{"laneid": 7, "warpid": 2, "m": 1} +``` + +求值规则有四步。 + +首先,按 row-major 顺序 flatten 逻辑坐标。对于逻辑坐标: + +```text +x = (x0, x1, ..., xr-1) +``` + +inside a logical shape: + +```text +(S0, S1, ..., Sr-1) +``` + +flat index 是: + +```text +flat = x0 * S1 * S2 * ... * Sr-1 + + x1 * S2 * ... * Sr-1 + + ... + + xr-2 * Sr-1 + + xr-1 +``` + +第二,把这个 flat index 跨 shard extents split。如果 shard extents 是: + +```text +(e0, e1, ..., en-1) +``` + +那么 split 会产生 components: + +```text +c0, c1, ..., cn-1 +``` + +使用 shard extents 上相同的 row-major 顺序。 + +第三,使用 stride 把每个 component 累加到它的 axis 上。如果 shard iter `k` 的 extent 为 `ek`、 +stride 为 `sk`、axis 为 `ak`,那么 component `ck` 贡献: + +```text +ck * sk @ ak +``` + +同一个 axis 上的所有贡献会加在一起。随后再加上 offset。 + +第四,应用 replica iter。每个 replica iter 都贡献一个与逻辑坐标无关的额外 offset。 +如果有多个 replica iter,layout 会枚举所有组合。 + +这条规则的一个有用后果是,layout 不需要 hard-code 输入 shape。它需要的是逻辑 tile 的总元素数等于 shard extents 的乘积。 +一旦满足这一点,flatten 和 splitting 就定义了映射。 + +## 案例研究:Tensor Core Register Tile + +考虑一个逻辑 `(8, 16)` tile,它分布在两个 warp 上,每个 warp 有 32 个 lane。 +每个 lane 拥有一个小 register fragment。register slot 由默认 memory axis `m` 表示。 + +```python +layout = TileLayout( + S[(8, 2, 4, 2) : (4@laneid, 1@warpid, 1@laneid, 1)] + + R[2 : 4@warpid] + + 5@warpid +) +``` + +取 `(8, 16)` tile 中的一个逻辑元素 `(i, j)`。 + +row-major flat index 是: + +```text +flat = 16 * i + j +``` + +按 shard extents `(8, 2, 4, 2)` split 得到: + +```text +c0 = i +c1 = floor(j / 8) +c2 = floor(j / 2) mod 4 +c3 = j mod 2 +``` + +shard contribution 是: + +```text +laneid = 4 * c0 + c2 +warpid = c1 +m = c3 +``` + +加上 offset `5@warpid` 后,它变成: + +```text +laneid = 4 * i + floor(j / 2) mod 4 +warpid = floor(j / 8) + 5 +m = j mod 2 +``` + +replica 项: + +```python +R[2 : 4@warpid] +``` + +会给 `warpid` 加上 `0` 或 `4`。因此完整映射是: + +```text +laneid = 4 * i + floor(j / 2) mod 4 +warpid = floor(j / 8) + 5 + 4 * r, where r in {0, 1} +m = j mod 2 +``` + +shard 把 tile 放到 warp 5 和 6 上。replica 随后把它复制到 warp 9 和 10。 +因此,同一个逻辑元素会出现在两个 warp 位置。 + +这个例子说明了为什么模型使用一组物理坐标。replication 并不适合自然地表示为从物理坐标到逻辑坐标的函数; +它更自然地表示为从一个逻辑坐标到多个物理坐标的函数。 + +## 案例研究:Blackwell Tensor Memory + +同一个 layout model 也适用于 memory placement。axis 不必是 thread axis,也可以是 memory axis。 + +TMEM 通过硬件 Lane 和 Col 坐标寻址。在 TIRx layout 记法中,这些轴写作 `TLane` 和 `TCol`。 + +考虑这个 layout: + +```python +layout = TileLayout( + S[(2, 128, 112) : (112@TCol, 1@TLane, 1@TCol)] +) +``` + +如果逻辑 tile shape 是 `(2, 128, 112)`,split components 就是逻辑坐标本身。 +对于元素 `(a, l, c)`,映射是: + +```text +TLane = l +TCol = 112 * a + c +``` + +extent-128 iter 以 stride `1@TLane` 填满 128 个 TMEM Lane row。 +extent-2 iter 以 stride `112@TCol`、extent-112 iter 以 stride `1@TCol`,二者共同覆盖 224 个 column: + +```text +TCol in [0, 224) +``` + +224-column span 是有意的。TMEM layout 不必是 2 的幂。block-scaled FP8 GEMM 可能会选择 224-column accumulator, +因为完整 256-column tile 将无法为两个 accumulator stage 加 scale factor 留出足够 TMEM 容量。 +layout API 可以直接表达这个 shape。 + +## Scale Factor Layout + +上面的 accumulator layout 是纯 placement。每个逻辑 accumulator 元素映射到一个 TMEM coordinate。 +block-scaled MMA 的 scale factor 不同,因为同一个物理 group 可能需要在多个 warp window 中可见。 +这正是 replication 变得有用的地方。 + +一个紧凑 scale-factor layout 可以写作: + +```python +scale = TileLayout( + S[(32, sf_per_mma) : (1@TLane, 1@TCol)] + + R[4 : 32@TLane] +) +``` + +shard 会在 TMEM 中放置一个 32-row scale-factor group: + +```text +TLane = r +TCol = s +``` + +对于逻辑 scale coordinate `(r, s)`。 + +replica 项创建四个相隔 32 lane 的副本: + +```text +TLane = r + 32 * q, where q in {0, 1, 2, 3} +TCol = s +``` + +因此,这个 32-row group 在 TMEM lane 0 到 31、32 到 63、64 到 95、96 到 127 上都可见。 +这就是 `warpx4` 广播模式({ref}`zh_chap_layout_generations`)。 +四个 warp-sized TMEM lane window 中的每一个都会看到同一个 scale-factor group。 + +在完整 block-scaled MMA layout 中,这个 atom 会与 M row 和 K scale-factor group 上的 outer iter 结合。 +根据 scale-factor dtype,多个 scale factor 还可能被 pack 到一个 32-bit `TCol` cell 中。 +例如,fp8 scale factor 可以把四个值 pack 到一个 32-bit column cell 中。 +可选的 stride-zero reuse 和 pipeline-depth iter 随后可以描述跨多个 MMA 的 scale reuse 以及 double buffering。 + +重要的是,同一个 `TileLayout` model 描述了这两种情况。accumulator 是 TMEM 中的单一 placement。 +scale factor 是同一 TMEM address space 中的复制式 placement。 + +## 现成 Layout + +大多数 kernel 不会手写每一种硬件 layout。TIRx 为经常出现的 layout 提供 constructor。 + +```python +tmem_datapath_layout(datapath, rows, cols) +``` + +返回由 `tcgen05.mma` 写入的 TMEM accumulator layout。`datapath` 参数选择 row placement pattern。 +例如,`"D"` 对应 `M = 128` 的 identity-style placement,而 `"F"` 对应 `M = 64` 的 scattered placement。 + +```python +tcgen05_atom_layout(instr_shape, tensor_shape, dtype) +``` + +返回由 `tcgen05.ld` 或 `tcgen05.st` atom 移动的 register tile layout。 +instruction shape 的例子包括 `.32x32b`、`.16x64b`、`.16x128b` 以及相关形式。 +在 DSL 层面,这是一个 warpgroup-distributed tile。lowering 期间,它会变成四条 warp-collective `tcgen05.ld` +或 `tcgen05.st` 指令,每个 warp 一条,每个 warp 处理自己的 32 个 TMEM lane。 + +```python +wg_local_layout(cols, rows=128) +``` + +返回 warpgroup-local register tile,通常在 `tid_in_wg` 上每个 thread 一行。 + +这些 helper 用来避免手写常见硬件映射。它们并不隐藏模型。 +每个 helper 都返回普通 `TileLayout`,由上面描述的同一组 `S` 和 `R` 部分构成。 + +## SwizzleLayout and ComposeLayout + +`TileLayout` 是 affine 的。它可以表达 named axes 上的 stride、replication 和 offset。 +这足以覆盖许多 placement,包括 thread fragment、TMEM tile 和 compact scale-factor layout。 + +shared memory swizzle 需要别的东西。用于避免 bank conflict 的 swizzle 不是 affine stride pattern, +而是对线性 shared-memory address 做基于 XOR 的 permutation。 + +因此,TIRx 把 swizzling 保留为单独的 layout object: + +```python +SwizzleLayout(...) +``` + +并把它与 tile layout compose: + +```python +ComposeLayout(swizzle, tile) +``` + +tile layout 先产生一个 linear memory address。随后 swizzle 对这个地址做 permutation。 +把这两层分开,比强行把 XOR permutation 塞进 affine layout model 更清晰。 + +## 为什么需要 Swizzle + +shared memory 被划分成 32 个 bank,每个 bank word 持有 4 字节。 +当一次访问中的多个 lane 触及同一个 bank 中的不同地址时,该访问会因为 bank conflict 被串行化。 + +朴素 row-major tile 会结构性地产生这种 conflict。考虑一个具有 row-major layout 的 `(8, 64)` float16 tile: + +```python +TileLayout(S[(8, 64) : (64@m, 1@m)]) +``` + +逻辑元素 `(i, j)` 的 linear element address 是: + +```text +m = 64 * i + j +``` + +每行是 64 个 float16 值,也就是 128 字节。这正好是一整条 shared memory bank line。 +如果一个 warp 以固定 `j` 向下读一列,每一步 row 都会前进一整条 128-byte line。 +bank index 会重复,因此 column read 会跨多个 row 坍缩到同一个 bank 上。 + +swizzle 通过让低地址位依赖更高的 row bit 来改变这一点。 +原本会反复落在同一个 bank 上的一列,会被分散到不同 bank 上。 + +## Swizzle Transform + +`SwizzleLayout` 由三个整数参数控制: + +```text +per_element = M +swizzle_len = B +atom_len = S +``` + +输入是一个 linear element address `m`。 + +`m` 的低 `M` 位保持不变。这会保留一个小的 contiguous element group。 +更高位会右移到一个临时值中: + +```text +x = m >> M +``` + +然后,`x` 中位置 `[S, S + B)` 的 bit group 会 XOR 到 `x` 中位置 `[0, B)` 的 bit group 上。 +swizzled address 随后通过把未改变的低 `M` 位放回去形成。 + +等价地: + +```text +mask = (1 << B) - 1 + +low = m & ((1 << M) - 1) +x = m >> M +x2 = x ^ ((x >> S) & mask) + +addr = (x2 << M) | low +``` + +为了让 layout well formed,`S` 必须至少为 `B`。 + +这个 transform 的目的不是改变 tile 中有哪些逻辑元素,而是改变这些元素在 shared memory 中落在哪里。 +MMA 仍然读取同一个逻辑 tile。swizzle 让物理 bank pattern 更好。 + +## 选择 Swizzle 参数 + +正常使用中,swizzle 参数由 dtype 和 shared-memory swizzle mode 选择。 +常见 mode 是 32-byte、64-byte 和 128-byte swizzle。 + +`per_element` 参数的选择会让一个小的 vector-sized group 保持 contiguous。对于 float16,一个 16-byte vector 包含 8 个元素,因此: + +```text +M = log2(8) = 3 +``` + +使用 128-byte swizzle 时,layout 使用: + +```python +SwizzleLayout(per_element=3, swizzle_len=3, atom_len=3) +``` + +这会保持 16-byte vector group 完整,同时仍然足够置换更大的 shared-memory address pattern,以打破 column bank conflict。 + +大多数代码不应该手工推导这些参数。dtype 和 descriptor mode 通常会决定它们。 +对程序员来说,重要的是 TIRx layout 中的 swizzle、TMA descriptor 和 MMA expectation 三者匹配。 + +因此,一个 swizzled shared memory allocation 看起来像这样: + +```python +tile = TileLayout(S[(8, 64) : (64@m, 1@m)]) +swizzle = SwizzleLayout(per_element=3, swizzle_len=3, atom_len=3) + +layout = ComposeLayout(swizzle, tile) +``` + +composed layout 会被附着到 shared memory buffer 上。 + +## 元素的 Bank 与 Line + +要判断 swizzle 是否有帮助,可以把 swizzled element address 转回 shared memory bank。 + +令 `addr` 为 swizzled element address,`b` 为元素大小(字节)。byte address 是: + +```text +byte = addr * b +``` + +bank 是: + +```text +bank = floor(byte / 4) mod 32 +``` + +128-byte bank line 是: + +```text +line = floor(byte / 128) +``` + +对于 float16,`b = 2`,因此 bank 公式变成: + +```text +bank = floor(addr / 2) mod 32 +``` + +这是下面 worked example 中使用的公式。 + +## Worked Example:`(8, 64)` float16 Tile 上的 128B Swizzle + +回到 row-major float16 tile: + +```text +m = 64 * i + j +``` + +使用: + +```python +SwizzleLayout(per_element=3, swizzle_len=3, atom_len=3) +``` + +transform 变成: + +```text +x = m >> 3 +addr = ((x ^ ((x >> 3) & 7)) << 3) | (m & 7) +``` + +由于: + +```text +m = 64 * i + j +``` + +我们可以写成: + +```text +q = floor(j / 8) +r = j mod 8 +``` + +swizzled address 是: + +```text +addr = 64 * i + 8 * (q xor i) + r +``` + +现在看 column `j = 0`。此时 `q = 0` 且 `r = 0`,所以: + +```text +addr = 72 * i +``` + +对于 float16,bank 是: + +```text +bank = floor(addr / 2) mod 32 +``` + +因此八个 row 映射到: + +```text +i = 0: bank 0 +i = 1: bank 4 +i = 2: bank 8 +i = 3: bank 12 +i = 4: bank 16 +i = 5: bank 20 +i = 6: bank 24 +i = 7: bank 28 +``` + +这一列现在触及八个不同 bank。conflict 消失了。 + +如果没有 swizzling,同一列的 address 是: + +```text +m = 64 * i +``` + +因此: + +```text +bank = floor(64 * i / 2) mod 32 = 0 +``` + +每一行都落在 bank 0 上,因此访问会被串行化。swizzle 只改变物理 placement, +但这已经足够把 column access 变成 conflict-free。 + +这个保证依赖于按设计方式使用 swizzle。dtype、swizzle width 和 access shape 必须匹配 TMA 与 MMA descriptor mode。 +128-byte float16 swizzle 是围绕相关 16-byte row chunk 和 Tensor Core access pattern 设计的。 +它并不承诺任意 shared memory access 都会变成 conflict-free。 +本章开头的演示会让这一点可见:选择 dtype 和 swizzle mode,观察没有 swizzle 时一列如何坍缩到一个 bank 上, +再观察应用匹配 swizzle 后它如何散布到 bank 视图中。 + +## 设计理由 + +layout API 遵循三项设计选择。 + +第一,它支持一般 shape。硬件 tile 不总是 2 的幂。global tensor、shared memory stage、TMEM accumulator +和 scale-factor buffer 的 shape,往往来自容量限制或算法选择。layout model 把这些 shape 视为普通情况。 + +第二,映射方向是从逻辑坐标到物理坐标。这个方向很重要,因为 replication 很常见。 +一个逻辑元素可能住在多个物理位置。logical-to-physical map 会直接把它表示为一组坐标。 + +第三,hardware axes 是显式的。layout 不使用匿名维度,也不依赖稍后的上下文来解释它们。 +`tx`、`tid_in_wg`、`laneid`、`warpid`、`TLane` 和 `TCol` 之间的差异,会写进 layout 本身。 + +legality 和 feasibility check 并不只是 layout object 的职责。layout 可以说明数据放在哪里。 +更高层的 tile primitive 会决定某个给定操作能否合法且高效地使用这个 placement。 +这种分离让 layout API 保持小巧,同时仍然给编译器足够信息来 dispatch 真实硬件操作。 diff --git a/zh/chapter_tma/index.md b/zh/chapter_tma/index.md new file mode 100644 index 00000000..48e85767 --- /dev/null +++ b/zh/chapter_tma/index.md @@ -0,0 +1,192 @@ +(zh_chap_tma)= +# 异步数据移动:TMA + +:::{admonition} 概览 +:class: overview + +- TMA 是一个硬件引擎,用于在 global memory 和 shared memory 之间异步复制 tile。一个 thread 发射 copy,引擎负责移动字节。 +- TMA copy 由 tensor-map descriptor 描述。descriptor 会告诉引擎 global tensor 的 shape、strides、tile coordinates,以及 shared-memory swizzle mode。 +- 在 load 路径上,TMA 可以在写入 shared memory 时对 tile 做 swizzle,让 tile 直接落到 Tensor Core 所期望的 layout 中。 +- TMA load 通过带 byte-count tracking 的 `mbarrier` 完成。TMA store 使用 commit group 和 wait group。 +::: + +只有当 Tensor Core 有准备好的数据可消费时,它才有帮助。在 GEMM 或 attention kernel 中,一旦 pipeline 填满, +数学部分可能是 compute-bound({ref}`zh_chap_performance`),但只有下一个 operand tile 按时到达,pipeline 才能保持填满。 + +移动 tile 的旧方法是让 thread 自己复制。每个 thread 计算地址,从 global memory 发出 load,并把值存进 shared memory。 +这可行,但它会把 warp 指令花在地址算术和 copy bookkeeping 上,而不是计算上。 +它还会让 copy 路径出现在同一批本应喂给 Tensor Core 的 warp 的指令流中。 + +Tensor Memory Accelerator,即 TMA,会把这项工作移入硬件 copy engine。一个 thread 发射一次 tile copy。 +随后 copy engine 在 global memory 和 shared memory 之间异步移动一个矩形 tile。 +当引擎正在搬运字节时,CTA 的其余部分可以继续做其他工作。 + +TMA 也处理一部分 layout 问题。Tensor Core 不只是需要 shared memory 中有正确的值; +它还需要这些值处在正确的 shared-memory layout 中。在 load 路径上,TMA 可以在写入 tile 时应用 shared-memory swizzle。 +这让 tile 可以直接落到后续 MMA 期望的 layout 中。 + +```{raw} html +
+ +
+``` +*交互:TMA 将 tile 从 global memory 复制到 shared memory。切换 swizzle mode,并悬停 source cell,查看它落到 shared memory 中的哪里。* + +## 一个 Thread 发射,硬件移动 Tile + +TMA copy 从一个 issuing thread 开始。这个 thread 不会循环遍历 tile 中的所有元素。 +它把 copy 的描述交给硬件,然后由 TMA engine 执行传输。 + +主要输入是 tensor-map descriptor。descriptor 描述 global tensor,以及应如何从中读取一个 tile。 +它记录 tensor shape、strides、element size、tile shape 和 swizzle mode 等信息。 +issuing thread 还会提供 tile 应该落到的 shared-memory address。 + +指令发射后,copy 会异步运行。issuing thread 可以继续执行,CTA 中的其他 thread 也可以继续执行。 +传输现在由 TMA engine 负责,而不是由普通 load/store 指令循环负责。 + +这给了 kernel 两种不同方式来表达同一个逻辑操作:“复制这个 tile”。 + +一种路径是 thread copy。thread 协作地从 global memory load,并 store 到 shared memory。 +这让 kernel 能直接控制每一次访问,但会消耗 thread 指令和用于地址计算的寄存器。 + +另一种路径是 TMA copy。一个 thread 发射传输,由硬件 copy engine 执行矩形 copy。 +对于大型规则 tile,尤其是 Tensor Core kernel 使用的 operand tile,这是自然的路径。 + +这两条路径有不同的同步规则和性能行为。在二者之间选择,是一个 dispatch decision。 +layout 告诉 kernel 它想要哪种内存排列。scope 告诉它哪些 thread 或 CTA 参与其中。 +dispatch 则决定这个 copy 是由普通 thread code 实现,还是由 TMA 实现。 + +## Swizzled Layout + +移动 tile 还不够。tile 还必须以 Tensor Core 能高效读取的 layout 放入 shared memory。 + +这正是 TMA swizzling 的用武之地。当 TMA 把 tile 写入 shared memory 时,它可以置换 shared-memory address pattern。 +global memory tile 仍然是一个逻辑矩形,但 shared memory 中的 destination layout 可以是 swizzled 的。 + +swizzle mode 是 TMA descriptor 的一部分。一旦 descriptor 设置好,issuing thread 就不必手工应用 swizzle。 +引擎会在字节落入 shared memory 时应用它。 + +重要要求是一致性。TMA descriptor、shared-memory tile layout 和后续 MMA 指令必须都描述同一个 layout({ref}`zh_chap_data_layout`)。 +如果 TMA 用一种 swizzle 写入 tile,而 MMA 却按另一种 swizzle 去读,硬件仍然会精确执行它被要求做的事; +只是这些字节对计算来说会排列错误。 + +在这一点上,layout 记法就不再只是 bookkeeping device。DSL 使用的 layout 必须匹配 TMA descriptor 和 Tensor Core 指令使用的硬件 layout。 +例如,如果 kernel 说某个 operand tile 存储在 128-byte swizzled layout 中,TMA descriptor 就必须使用匹配的 swizzle mode, +而 MMA dispatch 也必须期望同一个 shared-memory arrangement。上面的演示允许你在 no swizzle 和 128-byte swizzle 之间切换; +悬停某个 source element,可以查看应用 swizzle 后它落在哪里。 + +理解 swizzle 的一种有用方式是:TMA 并没有改变逻辑 tile。它改变的是逻辑元素在 shared memory 中的物理落点。 +后续 MMA 消费的仍然是同一个逻辑 A 或 B tile。swizzle 只决定这个 tile 如何排列在 shared memory bank 上。 + +## 用于 Tiling 和 Swizzling 的 3D TMA + +普通 TMA copy 移动的是平坦 2D tile,但 Tensor Core 想要的 shared-memory layout 通常会被 *tiled* 成 swizzle atom +(来自 {ref}`zh_chap_data_layout` 的 8 x 128-byte atom)。TMA 用额外的 descriptor 维度来处理这一点。 +**3D TMA** 把 shared-memory box 描述为 `(group, row, col)`,其中 group 维度跨 atom 行走,内部两个维度则在一个 atom 内寻址。 +一次 3D copy 随后既会按 atom 布置 tile(tiling),又会在每个 atom 内应用 swizzle, +因此数据到达时已经处在 MMA 期望的 layout 中,不需要单独的 tiling 或 swizzling pass。 + +```{raw} html +
+ +
+``` +*交互:一个 3D TMA copy,以 (group, row, col) 寻址,并 tiled 到 swizzled shared memory 中。* + +选择 swizzle *format* 与这种 tiling 绑定在一起。更宽的 swizzle 会把一列分散到更多 bank 上, +所以能适配时默认选择 128-byte swizzle;但一个 N-byte atom 需要 tile 的 contiguous dimension 能填满它。 +因此,如果某个 tile 因 shape 约束而较小,就不能使用 128-byte swizzle,必须降到 64-byte 或 32-byte: +经验法则是选择 tile 能填满的最大 swizzle({ref}`zh_chap_data_layout`)。下面的演示直接展示了这个约束: +16 x 16 tile 上的 128-byte swizzle,只有当 tile 被切成匹配 atom 的 16 x 8 group 后,才会 conflict-free。 + +```{raw} html +
+ +
+ +``` +*交互:16 x 16 tile 上的 128-byte swizzle;一旦 tiled 成 16 x 8 group,就会 conflict-free。* + +## Completion:Load + +copy 是异步的,所以仅仅发射还不够。consumer 不能只因为 TMA 指令已经发射,就去读取 shared-memory tile。 +只有当引擎已经完成字节写入后,tile 才能安全读取。 + +对于 TMA load,完成信号是一个 `mbarrier`({ref}`zh_chap_async_barriers`)。 + +通常序列如下: + +1. 为 pipeline stage 初始化或复用一个 `mbarrier`; +2. 告诉 barrier 这次 TMA transfer 预计写入多少字节; +3. 发射 TMA load; +4. 让 TMA engine 在字节到达时更新 barrier; +5. 在读取 shared-memory tile 之前,让 consumer 等待对应 barrier phase。 + +byte count 通过如下操作设置: + +```text +mbarrier.arrive.expect_tx(bytes) +``` + +这做了两件事。它记录预期 transfer size,同时也执行 issuing thread 在 barrier 上的 arrival。 +barrier 不会仅仅因为这个调用发生就完成。它仍然等待 TMA engine 报告预期字节已经到达。 + +随着 transfer 进行,引擎会对 barrier 执行 complete-tx update。只有两个条件都满足时,barrier phase 才会翻转: +arrival count 已满足,并且 pending byte count 到达零。 + +consumer 随后等待这个 barrier。一旦对预期 phase 的 wait 完成,shared-memory tile 就 ready 了。 +此时 MMA 路径可以安全读取它。 + +![TMA 加载同步流程](../img/tma_sync_flow.png) + +这是其他异步 producer-consumer handoff 使用的同一个 barrier 模型。producer 是 TMA engine。 +consumer 是 MMA 路径,或任何读取 shared-memory tile 的其他代码。barrier 是二者之间的显式 handoff。 + +## Completion:Store + +TMA store 按相反方向移动数据:从 shared memory 到 global memory。它们同样是异步的,但 completion mechanism 不同。 + +TMA load 通常会喂给同一个 kernel 内部的 consumer。MMA 路径需要知道 shared-memory tile 何时 ready。 +这就是 load 路径使用 `mbarrier` 的原因。 + +TMA store 通常把最终数据写出到 global memory。通常没有立即的 in-kernel consumer 在等待被存储的结果。 +kernel 主要需要知道的是:什么时候可以安全复用 shared-memory buffer,或结束 store sequence。 + +为此,TMA store 使用 commit group 和 wait group。kernel 发射一个或多个 store,commit 这个 group, +稍后等待这个 group drain。wait 完成后,从 kernel 的角度看,该 group 中的 store 已经完成, +store 使用的 shared-memory region 可以安全复用。 + +所以规则很简单: + +```text +TMA load: wait through an mbarrier with byte-count tracking +TMA store: wait through a commit group and wait group +``` + +这两种机制在不同 handoff point 服务于同一个目的。load 需要让 shared-memory tile 对后续 consumer 可见。 +store 需要确保 outgoing transfer 已完成,然后 kernel 才能复用 source storage,或依赖 store 已经 drain。 + +## 为什么 TMA 对 Pipelining 很重要 + +当 TMA 成为 pipeline 的一部分时,它最有用。kernel 可以在 Tensor Core 计算当前 tile 的同时,发射未来 tile 的 load。 +load 在后台运行,compute 在前台运行。当未来 tile 变成当前 tile 时,barrier 把二者连接起来。 + +典型 GEMM loop 会反复使用这种结构。shared memory 的一个 stage 保存当前被 MMA 消费的 tile。 +另一个 stage 正在被 TMA 填充。随着 loop 前进,这些角色会轮换。MMA 读取某个 stage 之前,会等待该 stage 的 load barrier。 +TMA 覆写某个 stage 之前,kernel 会确保前一个 consumer 已经用完它。 + +这就是为什么 TMA 和 `mbarrier` 通常一起出现在 Blackwell 和 Hopper 风格的 kernel 中。 +TMA 给 kernel 一个异步 copy engine;barrier 给 kernel 一种精确方式,知道复制的字节何时 ready。 diff --git a/zh/chapter_tmem/index.md b/zh/chapter_tmem/index.md new file mode 100644 index 00000000..204a1f83 --- /dev/null +++ b/zh/chapter_tmem/index.md @@ -0,0 +1,115 @@ +(zh_chap_tmem)= +# 特殊内存:TMEM + +:::{admonition} 概览 +:class: overview + +- TMEM 是 Blackwell 专有、供 `tcgen05` 使用的内存空间。它是每个 SM 上的二维 scratchpad,拥有 128 个 Lane row 和最多 512 个 Col column。 +- `tcgen05.mma` 把 accumulator 写入 TMEM。block-scaled MMA 也使用 TMEM 存放 scale factor。 +- TMEM 通过 Lane 和 Col 寻址。在 TIRx layout 记法中,这两个硬件轴写作 `TLane` 和 `TCol`。 +- TMEM 不像寄存器那样自动分配。kernel 必须以 32 column 为单位显式分配并释放它。 +- 普通 shared-memory load/store 不能访问 TMEM。数据通过专用异步 `tcgen05` 指令在 TMEM、寄存器和 shared memory 之间移动。 +::: + +在 Hopper 及更早 GPU 上,Tensor Core({ref}`zh_chap_tensor_cores`)accumulator 位于寄存器中。 +这个模型很容易推理:MMA 指令产生一个 register fragment,kernel 在 compute phase 中保持这个 fragment live, +epilogue 稍后读取它、转换它,并存储结果。 + +问题在于 register pressure。寄存器是固定的 per-thread 资源。随着 MMA tile 变大,accumulator fragment 也会变大。 +到某个点,accumulator 会开始挤占 thread 还需要保存的其他值。更大的 tile 有利于 Tensor Core 吞吐, +但把整个 accumulator 保存在寄存器中,会让这些更大 tile 更难使用。 + +Blackwell 改变了数据路径的这一部分。`tcgen05` 的 accumulator 不必在整个 compute phase 中停留在寄存器里。 +相反,`tcgen05.mma` 会把 accumulator 写入 Tensor Memory,也就是 TMEM。 +TMEM 是早期 NVIDIA GPU 没有的内存空间。它是 SM 上的二维 scratchpad,形状为 128 个 Lane row × 最多 512 个 Col column, +作用域是使用它的 CTA。 + +这个额外内存空间让 Blackwell 能支持更大的 Tensor Core tile,而不必强迫整个 accumulator 进入 per-thread register。 +但 TMEM 并不像寄存器那样自动。编译器不会把它当作普通 register storage 简单发放。 +kernel 必须分配 TMEM,用正确 layout 寻址它,用正确指令把数据移入移出,并在 CTA 完成后释放它。 + +## 二维地址空间 + +TMEM 不是平坦 byte array,而是一个二维地址空间。硬件把它的两个坐标命名为 Lane 和 Col。 +它有 128 个 Lane row,以及最多 512 个 Col column。每个 Col 是一个 32-bit column。 + +这个形状很重要,因为 `tcgen05.mma` 会使用这个二维结构把 accumulator 写入 TMEM。 +一个 TMEM location 由 Lane coordinate 和 Col coordinate 描述,而不是由单个 shared-memory-style byte offset 描述。 + +当 kernel 在 TIRx 中声明 TMEM buffer 时,它会给这个 buffer 一个覆盖这两个硬件坐标的 layout。 +在 layout 记法({ref}`zh_chap_data_layout`)中,我们把 TMEM Lane 轴写作 `TLane`,把 TMEM Col 轴写作 `TCol`。 +这些名字并不是为了替代官方硬件术语,而是 layout axis name,用来在 DSL 中显式标出 TMEM 维度。 + +例如,一个 accumulator tile 可以写成: + +```text +S[(128, N) : (1@TLane, 1@TCol)] +``` + +这表示 tile 沿硬件 Lane 维度有 128 行,沿硬件 Col 维度有 `N` 列。 +在 layout 记法中,这两个维度表现为 `TLane` 和 `TCol`。这个 layout 是直接映射: +相邻 row 沿 `TLane` 移动,相邻 column 沿 `TCol` 移动。下图展示了这个网格: +hardware Lane 沿 128 行向下,hardware Col 跨 column 横向展开。 + +![作为二维网格的 TMEM:TLane 行 × TCol 列](../img/tmem_grid.png) + +重点是:TMEM 是 tile layout 故事的一部分。它不只是 Tensor Core 背后的隐藏 backing store。 +kernel 必须命名这块内存,从中分配 column,并使用匹配 `tcgen05` 指令读写方式的 layout。 + +## 分配 + +kernel 使用 TMEM 之前,必须先在其中预留空间。这不同于寄存器。寄存器由编译器分配,而 TMEM 由 kernel 显式分配。 + +分配按 CTA 完成。CTA 中的一个 warp 请求一段 TMEM column。请求以 32 column 为单位, +请求的 column 数会根据硬件分配规则向上取整。分配后,CTA 收到一个 base TMEM address。 +后续 `tcgen05` 指令使用这个 base address 访问预留区域。 + +把 TMEM 看作一种有预算的 CTA 资源很有用,类似 shared memory。CTA 拥有自己分配到的 TMEM column。 +kernel 决定 accumulator、scale factor 或 temporary staging 需要多少 column。CTA 完成后,必须释放这次分配。 + +这让 TMEM 成为 kernel resource planning 的一部分。更大的 accumulator tile 可能提升 Tensor Core 吞吐, +但它会消耗更多 TMEM column。block-scaled MMA 可能需要额外 TMEM 空间来存放 scale factor。 +kernel 必须让这些用途适配可用 TMEM 预算,就像它必须让 shared-memory buffer 适配 SMEM 预算一样。 + +## 读写 TMEM + +普通 `ld.shared` 和 `st.shared` 指令不能访问 TMEM。TMEM 是独立地址空间,因此数据通过专用 `tcgen05` 指令移动。 + +主要有三条路径。 + +第一条路径是 `tcgen05.ld`,它把数据从 TMEM load 到寄存器。这是 epilogue 在 MMA phase 之后使用的路径。 +accumulator 已经在 TMEM 中产生,但 epilogue 通常需要一个 register fragment,以便 cast、应用 elementwise operation, +并存储最终结果。 + +在 DSL 层面,TMEM load 分布在一个 warpgroup 上。它 lower 成四个 warp-level `tcgen05.ld` 操作,每个 warp 一个。 +每个 warp 处理 128 个 TMEM Lane row 中的 32 个,因此四个 warp 合起来覆盖完整 Lane 维度。 +在 layout 记法中,这个完整维度就是 `TLane` 轴。 + +这条指令本身来自一组 load shape,例如 `.16x64b`、`.16x128b`、`.16x256b`、`.32x32b` 和 `.16x32bx2`, +repeat factor 从 `.x1` 到 `.x128`。所选 shape 决定读取多少 TMEM column,以及每个 thread 接收多少寄存器。 + +重要结果是 register fragment layout。对于常见 epilogue 路径,lane `l` 会接收来自 TMEM row `l / 4` 和两列的值。 +这产生了与早期世代直接从 MMA 暴露出的 per-lane accumulator fragment 同类的结构({ref}`zh_chap_layout_generations`)。 +这种连续性很重要。它意味着即使 accumulator 在 compute phase 中位于 TMEM,Blackwell epilogue 仍然可以复用 +Ampere `mma` 或 Hopper `wgmma` 已经使用过的同一种 register-level cast 和 store 结构。 + +![tcgen05.ld / st 以 m8n8 fragment 形式在 TMEM 累加器和寄存器之间移动数据(lane l → row l/4,两列)](../img/tcgen05_ldst.svg) + +第二条路径是 `tcgen05.st`,它把数据从寄存器 store 回 TMEM。这是 `tcgen05.ld` 的反方向。 +当 thread 已经持有 register fragment,并且需要把它放入 TMEM 时会使用它。 +例如,某些 operand 或 intermediate value 可能会先通过寄存器 stage,然后写入 TMEM,供后续 `tcgen05` 操作使用。 + +第三条路径是 `tcgen05.cp`,它把数据从 shared memory copy 到 TMEM。这是一条 bulk copy 路径, +常用于 block-scaled MMA 中的 scale factor。在这种情况下,TMA 或普通 thread code 先在 shared memory 中准备 scale data, +`tcgen05.cp` 再把它移入 Tensor Core 期望的 TMEM layout。 + +三条路径都是异步的。`tcgen05.ld`、`tcgen05.st` 或 `tcgen05.cp` 指令都可能在数据移动完成前返回。 +因此,kernel 必须在消费结果或复用 storage 前使用正确的 completion mechanism({ref}`zh_chap_async_barriers`)。 + +wait path 取决于指令。`tcgen05.ld` 通过 `tcgen05.wait::ld` 完成。`tcgen05.st` 通过 `tcgen05.wait::st` 完成。 +`tcgen05.cp` 像 `tcgen05.mma` 一样,通过 commit group 和 `mbarrier` 完成。 +如果数据从一组 thread 交给另一组 thread,kernel 可能还需要 fence,确保接收方 thread 按预期顺序看到已经完成的写入。 + +TMEM 位于 Blackwell Tensor Core 数据路径的中间。TMA 把 operand stage 到 shared memory。 +`tcgen05.mma` 读取 operand,并累加到 TMEM 中。对于 block-scaled MMA,scale factor 也可以 stage 到 TMEM 中。 +compute phase 之后,`tcgen05.ld` 把 accumulator 带回寄存器,epilogue 转换并存储最终输出。 diff --git a/zh/img/flash_attention_main_handoff.png b/zh/img/flash_attention_main_handoff.png new file mode 100644 index 0000000000000000000000000000000000000000..471795fff011661d5bceccfc1aa6c8558fbe4d40 GIT binary patch literal 155084 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�XV1D^6$Hcz18->qL8do2%7TAFa+vWL*l<9zW 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≥iIM$7b$*SzTwwU4|0HiPko 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 COOa^+ literal 0 HcmV?d00001 diff --git a/zh/img/flash_attention_pipeline_v2.png b/zh/img/flash_attention_pipeline_v2.png new file mode 100644 index 0000000000000000000000000000000000000000..056f78ed342cc1b302346a52fcc1a91c0e585467 GIT binary patch literal 136538 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 z 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%0AvR9!KB2hPiAGLp`n3N)HSCdCo}Vv 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%0D3oL*Q6 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

u<{RX4i6fNbN}$Y@`R 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 z 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 Ot%i@bI6QRfn*RfJ-V*2l literal 0 HcmV?d00001 diff --git a/zh/img/ldstmatrix.svg b/zh/img/ldstmatrix.svg new file mode 100644 index 00000000..9dae1d8f --- /dev/null +++ b/zh/img/ldstmatrix.svg @@ -0,0 +1,3643 @@ + + + + + + + + 2026-06-25T13:24:06.033932 + image/svg+xml + + + Matplotlib v3.8.3, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/zh/img/memory_dataflow.png b/zh/img/memory_dataflow.png new file mode 100644 index 0000000000000000000000000000000000000000..2570f30198b773be632afd562f039015f2b9439f GIT binary patch literal 60455 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 literal 0 HcmV?d00001 diff --git a/zh/img/mma_block_scaled.svg b/zh/img/mma_block_scaled.svg new file mode 100644 index 00000000..a27d9228 --- /dev/null +++ b/zh/img/mma_block_scaled.svg @@ -0,0 +1,2907 @@ + + + + + + + + 2026-06-25T13:24:06.586642 + image/svg+xml + + + Matplotlib v3.8.3, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/zh/img/mma_cg1_m128.svg b/zh/img/mma_cg1_m128.svg new file mode 100644 index 00000000..ceef1d01 --- /dev/null +++ b/zh/img/mma_cg1_m128.svg @@ -0,0 +1,1065 @@ + + + + + + + + 2026-06-25T13:24:06.196203 + image/svg+xml + + + Matplotlib v3.8.3, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/zh/img/mma_cg1_m64.svg b/zh/img/mma_cg1_m64.svg new file mode 100644 index 00000000..f0ad7484 --- /dev/null +++ b/zh/img/mma_cg1_m64.svg @@ -0,0 +1,1804 @@ + + + + + + + + 2026-06-25T13:24:06.263085 + image/svg+xml + + + Matplotlib v3.8.3, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/zh/img/mma_cg2_m128.svg b/zh/img/mma_cg2_m128.svg new file mode 100644 index 00000000..343a2cf2 --- /dev/null +++ b/zh/img/mma_cg2_m128.svg @@ -0,0 +1,2013 @@ + + + + + + + + 2026-06-25T13:24:06.463635 + image/svg+xml + + + Matplotlib v3.8.3, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/zh/img/mma_cg2_m256.svg b/zh/img/mma_cg2_m256.svg new file mode 100644 index 00000000..8ac6083a --- /dev/null +++ b/zh/img/mma_cg2_m256.svg @@ -0,0 +1,2228 @@ + + + + + + + + 2026-06-25T13:24:06.350390 + image/svg+xml + + + Matplotlib v3.8.3, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/zh/img/pipe_depth2.png b/zh/img/pipe_depth2.png new file mode 100644 index 0000000000000000000000000000000000000000..af015f59f0a8f75a933225366477e58084157546 GIT binary patch literal 21362 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 literal 0 HcmV?d00001 diff --git a/zh/img/roofline.png b/zh/img/roofline.png new file mode 100644 index 0000000000000000000000000000000000000000..930a75f51a86699ecae9e48a8a2a1bd8c50380a5 GIT binary patch literal 129790 zcmdqJc|4YD+dY13KvJnx$dEK35h?SK3Mn&@BttTkc}m7oN~TODk*QFLBvYBkP$VKl zD03o1rcB>;?!DjVd7tm_$M5~~xA$k)Hr)4pUFUTk$FYvJ)^Yl&sVJYqwQrI$IBMRJDg4J9V~3D z5AuuhALQF%?&xUiATA(a^{-#xx3M=9sOs0%#G9zy^bh`a2*v+z*<&b<}MrCKBpWp86l#Gh4 zZY^J4&RoB9`wrXj)fP1R54t!OtczG(XmqA?O9!STC2L0Bo0$zbI|t{rGEM*5%j7XWIL2+`4t?tJe#?te4hb#eHT%wyDHQ2jXXP{P!PT<_HiJ zHvdTRS{T38mR)vhL!x@3{OoXgQ9x%sz7q8K;}{WCIy-wM-*b^=XlO{jO6Tg*f|zwj zZoIwnNkzrt)=aZ?X;lFM^Z`tQD>^$nBgLJbshp=MKGAR-`m{Qb|fwlG7vhQ>^?#Qy8Uq9E|cind5#XnPq0pETVEz27lCm4*o{QPpQ zrz+T_T9N1_?(`#kxbT7yv)*g-Yj{jtTwF)f z?SJ$%zc@>aCsh|C@j1HyuNYxrFE0gFCTxbQCr(!d?n6F&kY$qOAPQ?!9}tgoHLdIeFhVIXOAc-$a|N zC98}lt7g)vBYvB9e=PFyiWq50KVOxo5X`W7vrkG2cSpYKW_5LSHEu@zsE;4j=sBcW zJ?5uBTf|~jS5aPDe`N^?3Ar5@SfO*?W3{TP>M;d{#8VH1EM0f*+&R|ewah6kZSc!P z>k$VP6&1Jc%ecsyiUJw4xg zdv9RnE}d%0wmQpq=GBe+9+n5KJ46?z+ifBbnyn9FmwGnt-gE(rNbw&1`u5>t{nd1g z-oe2eX54V=z4l@&R<6uzk@j4;tr{yGZ{Cn#>*7LlS4?RNA1pr7^WmY$-P%5GjmNan z(b2O~-h4r964Vs)u0oHXA(d#+Yj|8`A3m&mc-Ts=Du~Ug^OjtEF|LQIxI0MRgj=Gq z!Z@Qu@Qu^3FE&=9>tz3zH%|NRY}w~~-gEBw{&N}{o374`29k)mGX7oE`6tuYwQD%b zPnqu`Iqmt~c5Y@jH@7RUuAIWcjA46Ko88#=YlbL2L45EoEG~W<9Hh0ev3VbLXzjs^ z@4aPr$R^4MYJJ)lT*VmdA5}BB)lrNeQ><)aDtDU7Jc88#jM`u2a?YRP#{K zLX9PMxB2I1Tj;j&(~}Q!b4xU-3d)oIb9L&6HVHk%B6i5J2STO?oPX+ODfnbc;3D<1 zFZ;>eq$_D{WiBZxi4-)U*3i^+lJJ%@*tevYO&9qXAu>^XuwkWvZrzTgFFnx=Kq*I9nDg%FDYu3*2bw=;Y=m`Z5el zRtQ^nFp1c7mcI+(Qcu$tJN59e@~@tEelam@Z=6T&Sbu%f5FLC~Lt3aK{k+U**4UVB zKB8x7X^D2t8o{f`Oz!g|Ik{KHcT!|`hIEhjRIzw{|Nh0S|7DK7li@b}iG~t+=+5hC-2Yn|?2N&VTFvm!6APA3u2# zf2k$y%UhT9x_MF01yO@ScR%cq(yp%a1MaGiB&)~u+EUcH!UfJtw}{rv`{v~2)Xg{V z+O=yH&3abv#6+&G0tNwG3PCBCy~e+|$;`)#N(xu2iEGMFPc&tYKao;}o_o}Odl zFI|W50Kbrg^FGpOjJp6K9WnDtFUu0)Q5CpdGDr!qnet5V7ndi``Lt~P1%Gn(L>CvxiLlkcy7)WHz;;E}W z)!1ELUT*##k64nViM=Y(ve#CuR(s=UA?Z4?>Y!QOF%$qTcAjSKzM6>f$$A;C-MeoN z@2a*&J`{BsW$i5V@OSyuX@tEz`|TEo+A}Slf@$OlUP_dN$e-UsKG>>8(?44yg-q{s zR>cQm1uxb=3d9>5;tlgF4&9P)86BG#oCsh(X#ceZNhjk{3%{tSXdK?PV;IkB^~^ltCeg^_ni9e5|yG z?a-&)F+qJfU7jl`^z4$l$-gOMON(y87N1sWKhyfge!reyT%0ACL#FP~y@@3b28OuF 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⁣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 + + + + + + + 2026-06-25T13:27:09.026671 + image/svg+xml + + + Matplotlib v3.8.3, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/zh/img/smem_descriptor.svg b/zh/img/smem_descriptor.svg new file mode 100644 index 00000000..62aaf0a9 --- /dev/null +++ b/zh/img/smem_descriptor.svg @@ -0,0 +1,4405 @@ + + + + + + + + 2026-06-25T13:24:58.635220 + image/svg+xml + + + Matplotlib v3.8.3, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/zh/img/swizzle_conflict.svg b/zh/img/swizzle_conflict.svg new file mode 100644 index 00000000..e8ebd2c3 --- /dev/null +++ b/zh/img/swizzle_conflict.svg @@ -0,0 +1,4324 @@ + + + + + + + + 2026-06-25T13:24:07.039615 + image/svg+xml + + + Matplotlib v3.8.3, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/zh/img/tcgen05_ldst.svg b/zh/img/tcgen05_ldst.svg new file mode 100644 index 00000000..cb849402 --- /dev/null +++ b/zh/img/tcgen05_ldst.svg @@ -0,0 +1,3847 @@ + + + + + + + + 2026-06-25T13:24:07.223393 + image/svg+xml + + + Matplotlib v3.8.3, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/zh/img/tma_sync_flow.png b/zh/img/tma_sync_flow.png new file mode 100644 index 0000000000000000000000000000000000000000..4e2f7ba06375f27810e2043c85191fb571e77bfe GIT binary patch literal 126882 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 Fb5d1D4P2y&w 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

    X}(t6{3yB2Im~=Pk$!46(6BD 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 literal 0 HcmV?d00001 diff --git a/zh/img/tmem_layout_v3.png b/zh/img/tmem_layout_v3.png new file mode 100644 index 0000000000000000000000000000000000000000..fad86331f7fcc56201eae2dd46ce99ed02c03d1d GIT binary patch literal 109974 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≧gQ9DoI02_Ql)%LS6pZNk2G4-4( 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 Ii_@% literal 0 HcmV?d00001 diff --git a/zh/img/warp_specialization_timeline.png b/zh/img/warp_specialization_timeline.png new file mode 100644 index 0000000000000000000000000000000000000000..99c11853ab4d3c005defcbb80753d2e9b9be59fe GIT binary patch literal 94127 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"default"`` = dense + row-major + * - ``elem_offset`` / ``allocated_addr`` + - ``elem_offset``(或 ``byte_offset``)把一个 *view* 放到 ``data`` 内部的 + 某个偏移;``allocated_addr`` 携带预先分配的地址(tensor memory) + * - ``align`` + - data pointer 的对齐字节数 + +``scope`` 参数选择内存空间: + +.. list-table:: + :header-rows: 1 + :widths: 26 22 52 + + * - Scope + - 简写 + - 内存 + * - ``"global"`` + - (default) + - device global memory + * - ``"shared"`` + - ``T.alloc_shared`` + - static shared memory(``__shared__``) + * - ``"shared.dyn"`` + - (pool) + - dynamic shared memory(pooled,见下文) + * - ``"local"`` + - ``T.alloc_local`` + - per-thread register + * - ``"tmem"`` + - (TMEM pool) + - Blackwell tensor memory(见下文) + +.. code-block:: python + + A = T.match_buffer(A_ptr, (M, K), "float16", align=16) # parameter buffer + As = T.alloc_shared((BM, BK), "float16") # new shared tile + acc = T.alloc_local((4,), "float32") # register accumulator + view = T.decl_buffer((BM, BK), "float16", data=As.data) # a view over As + +**基于 pointer 的 buffer 本质上只是 pointer 上的一层 metadata。** 对任何 +非 tmem buffer,声明都只是一个 pointer 加一个 layout;索引会解析成地址: + + addr(buffer[coord]) = buffer.data + elem_offset + layout.apply(coord, shape=shape)["m"] + +(``layout.apply`` 返回每个轴的映射;其中 ``"m"`` 分量是元素偏移。)因此 +*同一个* 逻辑访问会完全根据 buffer metadata 编译成不同的地址算术。对一个 +4×8 区域写 ``B[i, j] = A[i, j] + 1``,并用四种方式声明 ``B``: + +.. code-block:: python + + from tvm.tirx.layout import TileLayout, S + + B = T.match_buffer(p, (4, 8), "float32") # row-major + B = T.match_buffer(p, (4, 8), "float32", layout=TileLayout(S[(4, 8):(1, 4)])) # column-major + B = T.match_buffer(p, (4, 8), "float32", elem_offset=64) # shifted view + B = T.match_buffer(p, (4, 8), "float32", layout=TileLayout(S[(4, 8):(16, 1)])) # row stride 16 + +每种声明都会让 ``B[i, j]`` 在生成的 CUDA 中 lower 成不同索引(``A[i, j]`` +load 仍是 ``i*8 + j``,只有 ``B`` 的 metadata 改了): + +.. code-block:: c++ + + B_ptr[((i * 8) + j)] = ...; // row-major: i*8 + j + B_ptr[((j * 4) + i)] = ...; // column-major: j*4 + i + B_ptr[(((i * 8) + j) + 64)] = ...; // elem_offset=64: i*8 + j + 64 + B_ptr[((i * 16) + j)] = ...; // row stride 16: i*16 + j + +Shared memory +------------- + +shared memory 有两种形式:**static** (编译期固定大小)和 **dynamic** (launch +时确定大小);此外还有一个 pool helper 用来管理 dynamic 情况。 + +Static +~~~~~~ + +最简单的 shared buffer 是 **static** 形式:``T.alloc_shared``(也就是 +``scope="shared"``),大小在编译期确定。把数据 stage 进去,调用 +``cta_sync`` 让整个 block 都看到这些写入,然后再读出: + +.. code-block:: python + + @T.prim_func + def smem_demo(A_ptr: T.handle, B_ptr: T.handle): + A = T.match_buffer(A_ptr, (128,), "float32") + B = T.match_buffer(B_ptr, (128,), "float32") + T.device_entry() + bx = T.cta_id([1]) + tx = T.thread_id([128]) + sm = T.alloc_shared((128,), "float32") # static shared memory + sm[tx] = A[tx] + T.cuda.cta_sync() + B[tx] = sm[tx] * T.float32(2.0) + +它会 lower 成普通 ``__shared__`` array(省略生成 CUDA 的样板部分): + +.. code-block:: c++ + + extern "C" __global__ void __launch_bounds__(128) + smem_demo_kernel(float* __restrict__ A_ptr, float* __restrict__ B_ptr) { + int tx = ((int)threadIdx.x); + __shared__ alignas(64) float sm_ptr[128]; // T.alloc_shared + sm_ptr[tx] = A_ptr[tx]; + __syncthreads(); // T.cuda.cta_sync() + B_ptr[tx] = sm_ptr[tx] * 2.0f; + } + +Dynamic +~~~~~~~ + +**Dynamic** shared memory(``scope="shared.dyn"``)的大小按 launch 确定(即 +``sharedMemBytes`` launch 参数),不是编译期确定。一个 kernel **只能有一个** +dynamic-shared allocation,也就是 *arena*。因此你只分配一次 arena,再用 +``T.decl_buffer`` 把每个 buffer 声明成它内部的一个 view:``data=`` 传 arena +pointer,并设置 ``elem_offset``: + +.. code-block:: python + + arena = T.alloc_buffer((128,), "float32", scope="shared.dyn") # the one arena + As = T.decl_buffer((64,), "float32", data=arena.data, scope="shared.dyn") # offset 0 + Bs = T.decl_buffer((64,), "float32", data=arena.data, elem_offset=64, scope="shared.dyn") # offset 64 + As[tx] = A[tx] + Bs[tx] = B[tx] + T.cuda.cta_sync() + C[tx] = As[tx] + Bs[tx] + +两个 view 共享同一个 ``extern __shared__`` arena(省略生成 CUDA 的样板部分; +为了清楚起见,arena 命名为 ``smem``): + +.. code-block:: c++ + + extern __shared__ __align__(64) float smem[]; // the one dynamic-shared arena + smem[tx] = A_ptr[tx]; // As — view at offset 0 + smem[tx + 64] = B_ptr[tx]; // Bs — view at offset 64 + __syncthreads(); + C_ptr[tx] = smem[tx] + smem[tx + 64]; + +(两次单独调用 ``alloc_buffer(scope="shared.dyn")`` 是错误的——*只允许一个 +dynamic shared memory allocation*。)因此 static shared memory 在编译期定大小 +(``__shared__ T x[N];``);dynamic shared memory 则是这个 launch-sized arena, +其内部不同偏移处声明多个 view。 + +.. note:: + + **TVM 如何标注 dynamic-shared 大小。** arena 的大小在编译期已知(这里 + ``128`` 个 float = ``512`` bytes)。lowering 期间,TVM 会向 device kernel 的 + ``tirx.kernel_launch_params`` 追加一个 ``"tirx.use_dyn_shared_memory"`` tag; + host launcher 会计算总字节数,并把它作为最后一个 launch 参数传入: + + .. code-block:: python + + # device kernel attribute: + "tirx.kernel_launch_params": ["blockIdx.x", "threadIdx.x", "tirx.use_dyn_shared_memory"] + + # host-side launch call (..., gridDim.x, blockDim.x, dyn_shared_bytes): + T.call_packed("dyn_kernel", A.data, B.data, C.data, 1, 64, 512) + + 运行时,这个 ``512`` 会成为 ``cuLaunchKernelEx`` 调用中的 + ``config.sharedMemBytes``。你不需要手动设置它;它由 ``shared.dyn`` + allocation 的大小推导而来。 + +Pool sugar +~~~~~~~~~~ + +``T.SMEMPool`` 会自动处理 arena bookkeeping:它用 bump allocator 分配偏移, +因此你不用手写 ``decl`` view。除了 ``alloc`` / ``commit`` 之外,它还提供 +per-buffer ``align=``、一个为你构建 MMA-compatible swizzle layout 的 +``alloc_mma`` helper,以及用于回退 cursor、复用空间的 ``move_base_to``: + +.. code-block:: python + + pool = T.SMEMPool() # bump allocator over shared.dyn + As = pool.alloc((BM, BK), "float16", align=128) # carve a tile + Bs = pool.alloc((BK, BN), "float16", align=128) + Cs = pool.alloc_mma((BM, BN), "float16") # MMA-compatible, swizzle inferred + pool.commit() # finalize the pool's size + # pool.move_base_to(offset) rewinds the cursor to reuse space + +TMEM pool(见下文 `Tensor memory`_)构建在 ``SMEMPool`` 之上。 + +Registers +--------- + +per-thread scratch 存在 register 中。用 ``T.alloc_local(shape, dtype)`` +(也就是 ``scope="local"``)分配:它对每个线程私有,并 lower 成保存在 +register 中的 local array。 + +.. code-block:: python + + r = T.alloc_local((4,), "float32") # per-thread register array + for k in T.unroll(4): + r[k] = A[tx, k] + # ... compute on r[0..3] ... + +.. code-block:: c++ + + alignas(64) float r_ptr[4]; // per-thread, register-resident + r_ptr[0] = A_ptr[tx * 4 + 0]; + r_ptr[1] = A_ptr[tx * 4 + 1]; + // ... + +.. note:: + + ``alignas(64)`` 是 *默认* buffer alignment:buffer 的 ``data_alignment`` + 默认是 ``runtime::kAllocAlignment``(64 bytes),CUDA codegen 会把它印到每个 + allocation 上,包括这种对齐没有意义的 per-thread ``local`` array。对于这些 + register-resident array,它 **没有性能影响**:带静态可解析索引的 thread-local + array 会被 nvcc/ptxas 提升到 register(scalar replacement of aggregates,SROA), + 因此它从不进入可寻址 local memory,对齐就是 no-op。(如果动态索引 array + spill 到 local memory,它确实会带上这种过度对齐,但那是不常见情况。)这种 + register local 的过度对齐是一个已知粗糙边角,我们计划修掉(对 ``local`` + scope 使用 dtype 的自然对齐)。 + +Scalar +~~~~~~ + +scalar 只是一个 **单元素** register array;严格来说,不需要单独概念。你可以 +分配一个 size-1 的 ``local`` buffer,并用 ``[0]`` 索引: + +.. code-block:: python + + phase = T.alloc_local((1,), "int32") # 1-element register array + phase[0] = 0 + while phase[0] < 4: + acc = acc + A[tx, phase[0]] + phase[0] += 1 + +但到处写 ``phase[0]`` 很笨重,所以 **scalar** 正是这件事的语法糖:一个可以 +**按名字** 读写的单元素 register buffer: + +.. code-block:: python + + phase: T.int32 = 0 # mutable scalar (sugar for the above) + while phase < 4: + acc = acc + A[tx, phase] + phase += 1 + + s = T.local_scalar("int32") # explicit form; assign by name (s = ..., not s[0]) + acc: T.float32 = 0.0 # a type-annotated assignment also makes one + +二者不只是相似,而是会 parse 成 **结构完全相同的 TIRx**。这个语法糖完全在 +parser 中消解:``phase: T.int32`` *就是* 那个单元素 ``local`` buffer, +``phase`` / ``phase += 1`` *就是* ``phase[0]`` / ``phase[0] += 1``。两个 +kernel 上的 ``tvm.ir.assert_structural_equal`` 会通过,printer 甚至会把显式 +``alloc_local`` + ``[0]`` 形式 **重新打印回** scalar 形式;因此 parsing 完成 +后没有任何差别。二者都会 lower 成同一个 +``alignas(64) int phase_ptr[1];``;scalar 只是让你省掉 ``[0]``。 +(``T.local_scalar`` / ``T.shared_scalar`` / ``T.alloc_scalar`` 可以显式选择 scope。) + +.. note:: + + **为什么不用** ``Var``\ **?** TIRx ``Var`` 是 *immutable* 的:它是一个单次 + static binding(也就是下面的 ``T.let`` 产生的东西)。scalar 需要是 + *mutable* 的,因为你会在循环和 accumulator 中反复给它赋值;所以它必须 + 由一个可重复 store 的单元素 buffer 支撑,而不是 ``Var``。 + +``let`` +~~~~~~~ + +``T.let`` binding 是 **immutable** 的:一个单独的 ``LetStmt`` (有名字的值, +不是 buffer)。它适合派生常量: + +.. code-block:: python + + n: T.let = M * K # immutable binding (LetStmt) + half: T.let[T.int32] = N // 2 # ... with an explicit type + +它会 lower 成 **普通 scalar C 变量**,不是 buffer(没有 array,没有 ``[0]``)。 +对于 ``half: T.let = m * 2``(其中 ``m`` 是运行时值): + +.. code-block:: c++ + + int half = m * 2; // the `let` -> a const-like local + +因为值是 immutable 的,simplifier 可以自由传播并对它做 CSE,所以在使用点你 +经常会直接看到 ``m * 2`` 被替换进去(或通过 common-subexpression 临时变量 +共享),而不是引用 ``half``。 + +.. note:: + + **为什么还需要 immutable binding?** 因为值不会变化,arithmetic analyzer 可以 + 把 var 绑定到这个值上(化简 ``LetStmt`` 时调用 + ``analyzer.Bind(var, value)``),所以关于这个值证明出的事实——常量边界、 + modular set(可整除性 / 对齐)、范围——都会 **传播到每次使用**。这会反过来 + 支持 index simplification、bounds-check elimination,以及 alignment/vectorization + 决策。*mutable* scalar 是一次 memory load(``buf[0]``):analyzer 不能假设它 + 保持不变,所以这些性质不会传递。``let`` 也是一个纯值:没有 allocation, + 可以自由 inline / substitute / CSE;而 scalar 是一个带 load/store 语义的 + 单元素 buffer。 + +Tensor memory +------------- + +Blackwell *tensor memory* 不是普通 scratch scope:它必须用 warp-uniform 的 +``T.ptx.tcgen05.alloc`` / ``tcgen05.dealloc`` intrinsic 显式 reserve 和 free; +每个 tensor 都是其中的一个 view,通过 +``T.decl_buffer(..., scope="tmem", allocated_addr=, layout=)`` +声明。``allocated_addr``(列偏移)是必需的,tensor-core dispatch 会 assert 它; +因此 ``T.alloc_buffer(scope="tmem")``(不会设置它)不能工作。不同于 shared +memory,tensor memory 不能直接寻址:只能通过 ``tcgen05`` 的 ``mma`` / ``ld`` / +``st`` / ``cp`` 读写。 + +手写时,一个 warp 会把 allocation 发到一个 shared slot 中;你再把每个 tensor +``decl`` 成某个列偏移处的 view;最后由一个 warp 释放它: + +.. code-block:: python + + addr = T.alloc_shared((1,), "uint32") # slot for the allocated base + if warp_id == alloc_warp: # tcgen05.alloc is warp-uniform + T.ptx.tcgen05.alloc(T.address_of(addr), n_cols=512, cta_group=cta_group) + acc = T.decl_buffer((CTA_M, 512), "float32", scope="tmem", + allocated_addr=0, layout=tmem_layout) # view at column 0 + # ... use acc as a gemm_async / copy_async operand ... + if warp_id == alloc_warp: + T.ptx.tcgen05.relinquish_alloc_permit(cta_group=cta_group) + T.ptx.tcgen05.dealloc(addr, n_cols=512, cta_group=cta_group) + +列偏移和 ``tmem_layout`` (datapath D/F layout)由你自己管理。下面的 pool 发出 +的正是这套序列。 + +Pool +~~~~ + +``T.TMEMPool`` 把这些全部封装起来:warp-uniform alloc/dealloc、列方向 +bump-allocation,以及 datapath layout: + +.. code-block:: python + + tmem_addr = pool.alloc((1,), "uint32") # pool = the kernel's smem pool + tmem_pool = T.TMEMPool(pool, total_cols=512, cta_group=cta_group, + tmem_addr=tmem_addr) + acc = tmem_pool.alloc((CTA_M, 512), "float32") # allocated_addr set for you + tmem_pool.commit() # emits tcgen05.alloc (one warp) + # ... use acc ... + tmem_pool.dealloc() # emits tcgen05.dealloc (one warp) + +完整示例见 Part III 的 GEMM kernel。 + +Buffer API +---------- + +``Buffer`` 是 pointer 上的 metadata(见上文 *声明 buffer*),因此它的大部分 +方法都是 *compile-time* reshape/reinterpret:要么改变索引算术,要么把指针交给 +你;它们本身不会发出 runtime op。常见方法如下: + +.. list-table:: + :header-rows: 1 + :widths: 34 66 + + * - 方法 + - 含义 + * - ``B.data`` + - 原始 data pointer(一个 ``Var``);打印为 ``B_ptr`` + * - ``B.ptr_to([i, j])`` + - 指向某个元素的 typed pointer(``address_of``);打印为 ``&B_ptr[…]`` + * - ``B.vload([i], dtype="float32x4")`` / ``B.vstore([i], v)`` + - vectorized load / store;打印为 ``*(float4*)(B_ptr + …)`` + * - ``B.view(*shape, layout=…)`` + - 以新的 shape/layout reinterpret 同一份存储(不 copy) + * - ``B.local(*shape, layout=…)`` + - 调用线程在 ``local`` buffer 中的私有 register slice + * - ``B.permute(*dims)`` + - 轴被 permute 后的 view(转置 layout) + * - ``B.access_ptr(mask, …)`` + - masked access pointer(``tvm_access_ptr`` builtin),用于把 region 传给 + intrinsic + +**Pointer — ``ptr_to`` / ``data``。** ``ptr_to`` 用来把元素地址交给 intrinsic +或 inline function;``data`` 是 base pointer: + +.. code-block:: python + + B[tx] = T.cuda.func_call("ld", A.ptr_to([tx]), source_code=SRC, return_type="float32") + +.. code-block:: c++ + + B_ptr[tx] = ld(&A_ptr[tx]); // ptr_to([tx]) -> &A_ptr[tx]; A.data -> A_ptr + +**Vectorized access — ``vload`` / ``vstore``。** 把多个元素作为一次宽传输来 +移动(另见 :doc:`data_types`): + +.. code-block:: python + + B.vstore([tx * 4], A.vload([tx * 4], dtype="float32x4")) + +.. code-block:: c++ + + *(float4*)(B_ptr + tx * 4) = *(float4*)(A_ptr + tx * 4); + +**Reshape / reinterpret — ``view`` / ``permute``。** 二者都是纯 metadata; +data pointer 不变,只有索引算术不同。``A.view(64, 4)`` 会把 256 元素 buffer +看成 ``64×4``;``A.permute(1, 0)`` 会转置轴: + +.. code-block:: python + + A2 = A.view(64, 4); y = A2[tx, 0] + A2[tx, 3] # A2[tx, j] -> A_ptr[tx*4 + j] + At = A.permute(1, 0); z = At[i, j] # At[i, j] -> A_ptr[j*4 + i] + +.. code-block:: c++ + + A2_ptr[tx * 4] /* +3 */ // view: row-major 64x4 index + At_ptr[(j * 4) + i] // permute: swapped strides + +**Register — ``local``。** 把 thread-axis ``local`` layout 分解成调用线程的 +flat register bundle(tile primitive 中大量使用): + +.. code-block:: python + + R = T.alloc_buffer((32, 8), "float32", scope="local", layout=TileLayout(S[(32, 8) : (1 @ laneid, 1)])) + Rl = R.local(8) # this lane's 8 registers + +.. code-block:: c++ + + alignas(64) float Rl_ptr[8]; // the lane's private registers diff --git a/zh/tirx_guide/language_reference/cuda/control_flow.rst b/zh/tirx_guide/language_reference/cuda/control_flow.rst new file mode 100644 index 00000000..e5e360df --- /dev/null +++ b/zh/tirx_guide/language_reference/cuda/control_flow.rst @@ -0,0 +1,122 @@ +.. Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + +.. http://www.apache.org/licenses/LICENSE-2.0 + +.. Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + +控制流 +====== + +控制流包括 ``if``、循环家族和 ``while``;它们都会映射到直观对应的 +CUDA 结构。 + +if +-- + +Python 的 ``if`` / ``else`` 会变成 CUDA 的 ``if`` / ``else``。可以用 +thread/lane 比较来保护某段工作,也可以用 ``T.ptx.elect_sync()`` 选出 +一个发出指令的线程: + +.. code-block:: python + + if tx < 128: + A[tx] = A[tx] * T.float32(2.0) + else: + A[tx] = A[tx] + T.float32(1.0) + + if T.ptx.elect_sync(): + ... # one elected lane (e.g. to issue TMA/MMA) + +.. code-block:: c++ + + if (((int)threadIdx.x) < 128) { + A_ptr[tx] = A_ptr[tx] * 2.0f; + } else { + A_ptr[tx] = A_ptr[tx] + 1.0f; + } + +如果只是表达式级选择(不产生分支),使用 ``T.if_then_else(cond, a, b)``。 +它会 lower 成三元表达式,因此不会引入 control-flow divergence: + +.. code-block:: c++ + + O_ptr[tx] = (A_ptr[tx] > 0.0f) ? A_ptr[tx] : 0.0f; + +Uniform 与 divergent 控制流 +--------------------------- + +像 ``if tx < 128`` 这样的 per-thread guard 对普通工作没有问题,但 +**collective** 操作必须被它要同步的所有线程 *一致地* 到达。 + +例如,``T.cuda.cta_sync()`` 会映射到 ``__syncthreads()``,它要求 thread block +中的所有线程都到达。它绝不能放在 thread-divergent 或 warpgroup-divergent +分支里:如果放进 ``if wg_id == 0:``,其他 warpgroup 永远不会到达,kernel +就会 deadlock。若只需要同步一个 warpgroup,请使用 warpgroup-scoped +``T.cuda.warpgroup_sync(id)`` (见 :ref:`zh_chap_gemm_advanced` 和 +:doc:`threads_sync`)。 + +barrier 初始化也要同样小心。``mbarrier`` 的 ``.init()`` 会 lower 成一个 +single-thread guard(``if (threadIdx.x < 1)``)。如果再把它嵌进另一个 +divergent 分支,barrier 可能保持未初始化,导致未定义的 launch failure。 + +loop +---- + +循环有四种形式;普通 Python ``range`` 会变成 ``T.serial``: + +- ``T.serial(n)`` — 顺序循环(ptxas 仍可能 unroll 它)。 +- ``T.unroll(n)`` — 完全 unroll(展开成直线语句)。 +- ``T.vectorized(n)`` — vectorized loop。 +- ``T.grid(*extents)`` — 嵌套循环。 + +循环内部可以使用 ``break`` / ``continue``。 + +.. code-block:: python + + for i, j in T.grid(8, 8): + B[i, j] = T.max(A[i, j], T.float32(0.0)) + +.. code-block:: c++ + + for (int i = 0; i < 8; ++i) + for (int j = 0; j < 8; ++j) + B_ptr[i * 8 + j] = max(A_ptr[i * 8 + j], 0.0f); + +``T.unroll(4)`` 则会展开成四条直线语句,不再保留循环。 + +while +----- + +``while`` 循环会一直运行到条件为 false。请使用 mutable scalar counter +(见 :doc:`buffers`): + +.. code-block:: python + + i: T.int32 = 0 + while i < 64: + A[i] = A[i] + T.float32(1.0) + i += 1 + +它会 lower 成一个带 early-exit ``break`` 的 ``while (1)`` (counter 是一个 +单元素 register buffer): + +.. code-block:: c++ + + int i_ptr[1]; + i_ptr[0] = 0; + while (1) { + if (!(i_ptr[0] < 64)) { break; } + A_ptr[i_ptr[0]] = A_ptr[i_ptr[0]] + 1.0f; + i_ptr[0] = i_ptr[0] + 1; + } diff --git a/zh/tirx_guide/language_reference/cuda/data_types.rst b/zh/tirx_guide/language_reference/cuda/data_types.rst new file mode 100644 index 00000000..18588928 --- /dev/null +++ b/zh/tirx_guide/language_reference/cuda/data_types.rst @@ -0,0 +1,117 @@ +.. Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + +.. http://www.apache.org/licenses/LICENSE-2.0 + +.. Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + +数据类型与表达式 +================ + +每个 TIRx 表达式都同时携带一个低层 **dtype** 和一个高层 **type**。 + +表达式 dtype +------------ + +``PrimExpr`` 的 ``.dtype`` 是它的标量(或向量)元素类型,例如 ``float32``、 +``float16``、``bfloat16``、``int32``、``uint8``、``bool``、低精度的 +``float8_e4m3fn`` / ``float4_e2m1fn``、``handle``(指针),以及 +``float32x4`` 这类向量形式。每种 dtype 都会打印成对应的 CUDA 类型。下面 +示例展示跨多种 dtype 分配 local/shared buffer,以及一次 vectorized +``float32x4`` load/store: + +.. code-block:: python + + @T.prim_func + def dtypes(A_ptr: T.handle, O_ptr: T.handle): + A = T.match_buffer(A_ptr, (256,), "float32") + O = T.match_buffer(O_ptr, (256,), "float32") + T.device_entry(); bx = T.cta_id([1]); tx = T.thread_id([64]) + f16 = T.alloc_local((1,), "float16") # register scalars ... + bf16 = T.alloc_local((1,), "bfloat16") + i32 = T.alloc_local((1,), "int32") + u8 = T.alloc_local((1,), "uint8") + b1 = T.alloc_local((1,), "bool") + sm = T.alloc_shared((64,), "float16") # ... and a shared tile + v = T.alloc_local((1,), "float32x4") # a vector-dtype register (float4) + v[0] = A.vload([tx * 4], dtype="float32x4") # vectorized load + O.vstore([tx * 4], v[0]) # vectorized store + # ... (use f16/bf16/i32/u8/b1/sm) ... + +会 lower 成下面的代码(省略生成 CUDA 的样板部分): + +.. code-block:: c++ + + half f16_ptr[1]; // float16 + nv_bfloat16 bf16_ptr[1]; // bfloat16 + int i32_ptr[1]; // int32 + uchar u8_ptr[1]; // uint8 + signed char b1_ptr[1]; // bool + __shared__ alignas(64) half sm_ptr[64]; // shared float16 + float4 v_ptr[1]; // float32x4 (vector) + v_ptr[0] = *(float4*)(A_ptr + tx * 4); // vectorized load + *(float4*)(O_ptr + tx * 4) = v_ptr[0]; // vectorized store + +buffer 的 dtype 本身也可以是 **vector type**:``T.alloc_local((1,), "float32x4")`` +会直接声明一个 ``float4`` register(用 ``v[0]`` 访问),而 ``float32x4`` +的 ``vload`` / ``vstore`` 会把它作为一次 16-byte 访问来搬运。vector dtype +并不绑定在 ``vload`` 上;任意 buffer 或 scalar 都可以携带它。 + +因此 dtype → CUDA 的映射如下: + +.. list-table:: + :header-rows: 1 + :widths: 34 33 33 + + * - dtype → CUDA + - dtype → CUDA + - dtype → CUDA + * - ``float32`` → ``float`` + - ``float16`` → ``half`` + - ``bfloat16`` → ``nv_bfloat16`` + * - ``int32`` → ``int`` + - ``uint8`` → ``uchar`` + - ``bool`` → ``signed char`` + * - ``float32x4`` → ``float4`` + - ``handle`` → ``T*`` (pointer) + - (vector dtypes → CUDA vector types) + +dtype 与 type +---------------- + +``dtype`` 是 *低层* 信息,说明“这些 bit 如何解释”。此外,值还拥有高层 +**type**:标量是 ``PrimType(dtype)``,指针是 +``PointerType(PrimType(dtype), scope)``。大多数表达式都是标量 +(``PrimType``);类型系统主要在 **指针** 上变得重要。 + +指针(``handle``) +------------------ + +buffer 的 ``data``,也就是它的指针,是一个 pointer type 的 ``Var``,并且 +它是 **immutable** 的(指针不会被重新赋值)。这决定了你如何获得它: + +- ``T.alloc_buffer(...)`` 会分配存储空间,**并** 定义它的 ``data`` 指针。 +- ``T.decl_buffer(..., data=ptr)`` 会在已有指针 ``Var`` ``ptr`` 上声明一个 + buffer。 +- 如果要让 buffer 背后使用一个指针 **表达式**,例如 ``T.ptx.map_shared_rank`` + (PTX ``mapa``)返回另一个 cluster CTA 的 shared address,你必须先用 + ``PointerType`` 的 ``T.let`` 把该表达式绑定成一个指针 ``Var``(``data`` + 必须是 ``Var``,不能是表达式): + + .. code-block:: python + + from tvm.ir.type import PointerType, PrimType + + ptr: T.let[T.Var(name="ptr", dtype=PointerType(PrimType("uint64")))] = \ + T.reinterpret("handle", T.ptx.map_shared_rank(mbar.ptr_to([0]), 0)) + remote_mbar = T.decl_buffer([1], "uint64", data=ptr, scope="shared") diff --git a/zh/tirx_guide/language_reference/cuda/parser_utils.rst b/zh/tirx_guide/language_reference/cuda/parser_utils.rst new file mode 100644 index 00000000..cf2ba190 --- /dev/null +++ b/zh/tirx_guide/language_reference/cuda/parser_utils.rst @@ -0,0 +1,79 @@ +.. Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + +.. http://www.apache.org/licenses/LICENSE-2.0 + +.. Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + +Parser 工具 +=========== + +有几个 helper 会在 **parse time** 生效(也就是 TVMScript 转成 TIRx 时), +让你内联 Python 计算出的值、抽出可复用片段,并打包 parser 侧状态。 + +``T.meta_var`` — 内联 Python 值 +---------------------------------------- + +``T.meta_var(x)`` 会告诉 parser:把 ``x`` 这个由 **Python** 计算出的值当作 +compile-time *meta* 值,直接内联进 IR,而不是把它解析成 script 变量。这样 +可以避免一个临时 local,也能驱动 metaprogramming:围绕 meta value 的普通 +Python ``for`` 会在 parser 中展开。 + +.. code-block:: python + + n = T.meta_var(4) # n is a Python int, inlined + for j in range(n): # unrolled at parse time + acc[0] = acc[0] + A[tx, j] + +``@T.inline`` — 内联函数 +-------------------------------- + +``@T.inline`` 定义的函数会在 parsing 期间把函数体 **内联到每个调用点**, +生成代码中不会出现调用。它遵循 Python 的 lexical(LEGB)scope 和 late +binding,因此参数会遮蔽外层变量: + +.. code-block:: python + + @T.inline + def add_into(acc, x): + acc[0] = acc[0] + x + + add_into(acc, A[tx, j]) # inlined -> acc[0] = acc[0] + A[tx, j] + +``@T.meta_class`` — parser 侧状态对象 +--------------------------------------------- + +``@T.meta_class`` 标记一个普通 Python class,使其 **实例成为 parser meta +value**:字段可以持有 buffer 和 scalar,因此你可以把相关 allocation 与状态 +打包进一个对象,并在 kernel body 中使用它。 + +.. code-block:: python + + @T.meta_class + class State: + def __init__(self, smem): + self.acc = T.alloc_local([1], "float32") + self.buf = T.decl_buffer([64], "float16", smem, scope="shared.dyn") + + s = State(smem.data) + s.acc[0] = T.float32(0.0) # use its fields like ordinary buffers + # ... s.buf[i] ... + +这很适合把 kernel 的 pipeline state(barrier、accumulator、scratch view) +组织到一起,而不是让许多分散的 local 穿过整个 body。 + +``T.constexpr`` +--------------- + +``T.constexpr`` 标记 compile-time kernel 参数,它会通过 ``@T.jit`` 的 +``.specialize(...)`` 固化进去。细节见 :ref:`zh_chap_tirx_primer`。 diff --git a/zh/tirx_guide/language_reference/cuda/threads_sync.rst b/zh/tirx_guide/language_reference/cuda/threads_sync.rst new file mode 100644 index 00000000..69822c1c --- /dev/null +++ b/zh/tirx_guide/language_reference/cuda/threads_sync.rst @@ -0,0 +1,139 @@ +.. Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + +.. http://www.apache.org/licenses/LICENSE-2.0 + +.. Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + +CUDA C++/PTX intrinsic +====================== + +当没有现成 tile primitive 覆盖你的需求时,有两条 escape hatch 可以直接触达 +硬件:**调用 backend intrinsic**(来自 ``tvm.backend.cuda`` 的 ``T.cuda.*`` / +``T.ptx.*`` 命名空间),或者 **内联原始 CUDA** 源码。 + +调用 backend intrinsic +---------------------- + +``T.cuda.*`` 和 ``T.ptx.*`` 会直接暴露 CUDA backend 的 device intrinsic: +同步、mbarrier、reduction,以及 PTX data-movement / MMA 家族: + +.. code-block:: python + + T.cuda.cta_sync() # block barrier (__syncthreads) + T.cuda.warp_sync() # __syncwarp + T.cuda.warpgroup_sync(8) # warpgroup barrier + T.cuda.cta_sum(val, num_warps, scratch.ptr_to([0])) # block-level reduction + + bar = T.alloc_shared((1,), "uint64") + T.ptx.mbarrier.init(bar.data, 1) # mbarrier for async completion + T.ptx.mbarrier.try_wait(bar.data, phase) + +下面是一个完整可运行的例子:通过 ``T.tvm_warp_shuffle_xor`` 做 warp all-reduce: + +.. code-block:: python + + @T.prim_func + def warp_reduce(A_ptr: T.handle): + A = T.match_buffer(A_ptr, (32,), "float32", align=16) + T.device_entry() + cta_id = T.cta_id([1]); warp_id = T.warp_id([1]); lane_id = T.lane_id([32]) + v = T.alloc_local((1,), "float32"); i = T.alloc_local((1,), "int32") + v[0] = T.float32(31 - lane_id) + i[0] = 16 + while i[0] >= 1: + v[0] += T.tvm_warp_shuffle_xor(0xFFFFFFFF, v[0], i[0], 32, 32) + i[0] = i[0] // 2 + A[lane_id] = v[0] + +shuffle 会直接 lower 成 ``__shfl_xor_sync``: + +.. code-block:: c++ + + v_ptr[0] = v_ptr[0] + __shfl_xor_sync(0xFFFFFFFF, v_ptr[0], i_ptr[0], 32); + +``T.ptx.*`` / ``T.cuda.*`` 下还有其他家族:``cp_async``(LDGSTS)、 +``cp_async.bulk.tensor``(TMA)、``ldmatrix`` / ``stmatrix``、``tcgen05.*`` +(Blackwell MMA)、``atomic_add``、``fence`` 等。完整 ``tvm.backend.cuda`` +参考请见 backend API reference。 + +同步语义 +-------- + +GEMM 和 Flash Attention kernel 中反复出现四种同步机制。它们控制异步引擎和 +并行线程组,所以任何一种用错,通常都会导致静默数据损坏或 deadlock。 + +**Mbarrier phase。** Mbarrier 使用一个内部 phase bit 跟踪 arrival。 +``T.ptx.mbarrier.try_wait(bar, phase)`` intrinsic 会阻塞,直到 barrier 的内部 +phase 与调用者提供的 ``phase`` 参数 *不同*。因此,当跨 loop iteration 复用 +barrier 时,调用者必须在每次 wait 之后翻转自己的本地 phase tracker +(``phase ^= 1``)。如果忘了翻转,后续 wait 会立即返回,导致引擎读取半写入 +的 memory。:ref:`zh_chap_gemm_basics` 中完整走了一遍 phase-tracking 表。 + +**Election。** ``T.ptx.elect_sync()`` 会在一个 warp 内选出 *单个 active lane*, +不是 lane 0,也不是每个 CTA 一个线程。若要把 issuer 缩小到精确一个线程, +必须配合 warp-level guard。:ref:`zh_chap_gemm_basics` 中使用 +``if warp_id == 0:`` 后接 ``if T.ptx.elect_sync():`` 的模式来发出 +``Tx.gemm_async`` 和 ``tcgen05.commit``。 + +**Named Warpgroup Barrier。** ``T.cuda.cta_sync()`` 会映射到 ``__syncthreads()``, +并要求 *每个* CTA 线程都到达。一旦 warpgroup 被 specialize 到不同代码路径, +把 ``cta_sync()`` 放进某个 warpgroup 分支就会让 kernel deadlock,因为其他 +warpgroup 永远到不了它。硬件提供 16 个 named barrier(ID 0 到 15); +``T.cuda.warpgroup_sync(10)`` 只同步一个 warpgroup 的线程。不同 warpgroup +使用不同 ID(例如 ``warpgroup_sync(wg_id + 10)``),避免撞到同一个硬件 +barrier。见 :ref:`zh_chap_gemm_advanced`。 + +**Fence。** Fence 保证 producer 的写入排在 consumer(通常是异步引擎)读取 +之前: + +.. list-table:: + :header-rows: 1 + :widths: 50 50 + + * - Fence + - 保证的顺序 + * - ``T.ptx.fence.proxy_async("shared::cta")`` + - 线程写入 shared memory,先于 async proxy(TMA store / MMA)读取它 + * - ``T.ptx.fence.mbarrier_init()`` + - mbarrier 初始化,先于后续 arrival 或 wait 使用该 barrier + * - ``T.ptx.tcgen05.fence.after_thread_sync()`` + - ``tcgen05`` writeback 边上的保守 ordering fence(Steps 8 和 9 会加入;TMA-to-MMA 路径不需要) + +内联原始 CUDA +------------- + +如果某个功能完全没有 intrinsic,可以用 +``T.cuda.func_call(name, *args, source_code=..., return_type=...)`` 从源码字符串 +注入一个 ``__device__`` 函数: + +.. code-block:: python + + SRC = r""" + __device__ __forceinline__ float my_relu(float x) { return x > 0.f ? x : 0.f; } + """ + + @T.prim_func + def k(A_ptr: T.handle, B_ptr: T.handle): + A = T.match_buffer(A_ptr, (256,), "float32") + B = T.match_buffer(B_ptr, (256,), "float32") + T.device_entry(); bx = T.cta_id([1]); tx = T.thread_id([256]) + B[tx] = T.cuda.func_call("my_relu", A[tx], source_code=SRC, return_type="float32") + +源码会原样发出,并把调用接进去: + +.. code-block:: c++ + + __device__ __forceinline__ float my_relu(float x) { return x > 0.f ? x : 0.f; } + // ... + B_ptr[tx] = my_relu(A_ptr[tx]); diff --git a/zh/tirx_guide/language_reference/index.rst b/zh/tirx_guide/language_reference/index.rst new file mode 100644 index 00000000..103e357a --- /dev/null +++ b/zh/tirx_guide/language_reference/index.rst @@ -0,0 +1,35 @@ +.. Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + +.. http://www.apache.org/licenses/LICENSE-2.0 + +.. Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + +.. _zh_chap_language_reference: + +TIRx 语言参考 +============== + +这里收录编写 TIRx device kernel 所需的完整语言特性,并从 +:ref:`zh_chap_tirx_primer` walkthrough 中拆分出来:parser 工具、数据类型与表达式、 +buffer 与内存、控制流,以及线程同步。当你需要确认某个特性的精确写法或语义时, +可以查阅这些页面。 + +.. toctree:: + :maxdepth: 1 + + cuda/parser_utils + cuda/data_types + cuda/buffers + cuda/control_flow + cuda/threads_sync From c9974cbcce5ed04a7a293d44226a9b6aa57aef89 Mon Sep 17 00:00:00 2001 From: Albert Wang Date: Sun, 28 Jun 2026 04:27:46 +0800 Subject: [PATCH 2/2] docs(i18n): translate remaining Chinese text blocks Translate leftover prose inside fenced text blocks in the Chinese docs, including performance notes, dataflow sketches, layout descriptions, and TMA/Tensor Core summaries. Keep formulas, instruction names, and hardware abbreviations unchanged. --- zh/chapter_flash_attention/index.md | 30 +++++------ zh/chapter_layout_generations/index.md | 28 +++++----- zh/chapter_performance/index.md | 74 +++++++++++++------------- zh/chapter_tensor_cores/index.md | 4 +- zh/chapter_tirx_layout_api/index.md | 4 +- zh/chapter_tma/index.md | 4 +- 6 files changed, 72 insertions(+), 72 deletions(-) diff --git a/zh/chapter_flash_attention/index.md b/zh/chapter_flash_attention/index.md index 7956b79f..dc5773b5 100644 --- a/zh/chapter_flash_attention/index.md +++ b/zh/chapter_flash_attention/index.md @@ -65,12 +65,12 @@ row_max = m_new 有了运行状态及其位置之后,我们可以把算法展开成一串具体的 tile 移动。对于一个 K/V block,kernel 从上到下走过这条 tile 路径: ```text -Q, K, V in GMEM - -> Q, K, V in SMEM by TMA load - -> S in TMEM by score MMA: QK^T - -> P in TMEM by softmax numerator: TMEM -> RF -> TMEM - -> O in TMEM by value MMA: P V - -> O in GMEM by normalization, SMEM staging, and TMA store +Q, K, V 位于 GMEM + -> Q, K, V 位于 SMEM 由 TMA 加载完成 + -> S 位于 TMEM 由分数 MMA 完成:QK^T + -> P 位于 TMEM 由 softmax 分子计算完成:TMEM -> RF -> TMEM + -> O 位于 TMEM 由值 MMA 完成:P V + -> O 位于 GMEM 由归一化、SMEM 暂存和 TMA 存储完成 ``` 它和 GEMM 的区别归结为一行。GEMM 是重复一条 MMA 链;FA4 有两个 MMA 阶段,中间坐着 softmax。后面几乎所有复杂度,都是这个额外阶段带来的后果。 @@ -150,9 +150,9 @@ warp_id = T.warp_id_in_wg([4]) 对每个流式 K/V tile,Flash Attention 都会运行两个 MMA 阶段,并由 softmax 把它们桥接起来: ```text -Q, K -> score MMA -> S +Q, K -> 分数 MMA -> S S -> softmax -> P -P, V -> value MMA -> O +P, V -> 值 MMA -> O ``` 可以把它看成三个 producer 串成的一条 pipeline。第一个 MMA 产生 attention score `S`,softmax 把 `S` 转成 numerator `P`,第二个 MMA 消费 `P` 来更新输出 accumulator `O`。按 `row_sum` 归一化会一直推迟到 epilogue,等每个 K/V tile 都贡献完之后再做。 @@ -416,13 +416,13 @@ barrier 告诉我们某个角色消费 tile 之前什么必须 *就绪*。但它 重要的是,MMA warp 不会先跑完所有 score MMA,再跑所有 value MMA。两个 Q stage 预热好之后,它会交错两种 MMA:当前 `V` block 的一次 value MMA,下一次 `K` block 的一次 score MMA,如此继续: ```text -score Q0*K[n-1] -score Q1*K[n-1] -value P0*V[n-1] -score Q0*K[n-2] -value P1*V[n-1] -score Q1*K[n-2] -value P0*V[n-2] +计算 Q0*K[n-1] 的分数 +计算 Q1*K[n-1] 的分数 +用 P0*V[n-1] 更新输出 +计算 Q0*K[n-2] 的分数 +用 P1*V[n-1] 更新输出 +计算 Q1*K[n-2] 的分数 +用 P0*V[n-2] 更新输出 ... ``` diff --git a/zh/chapter_layout_generations/index.md b/zh/chapter_layout_generations/index.md index 25505a74..839c04df 100644 --- a/zh/chapter_layout_generations/index.md +++ b/zh/chapter_layout_generations/index.md @@ -55,9 +55,9 @@ shared memory 只是 staging area。在 MMA 运行之前,operand tile 必须 数据路径如下: ```text -SMEM to registers with ldmatrix -registers to registers with mma.sync -registers back to SMEM with ordinary stores +SMEM -> 寄存器,使用 ldmatrix +寄存器 -> 寄存器,使用 mma.sync +寄存器 -> SMEM,使用普通 store ``` Ampere 的大部分 layout 故事都来自这条路径。kernel 必须以一种能高效载入的形式把 tile 存进 shared memory, @@ -191,11 +191,11 @@ Hopper shared memory matrix descriptor 是 shared memory 中 matrix tile 的一 descriptor 包含如下字段: ```text -start address -leading dimension offset -stride dimension offset -swizzle mode -base offset +起始地址 +主维度偏移 +步长维度偏移 +swizzle 模式 +基址偏移 ``` 精确解释取决于 operand major mode。对于 K-major tile,一个 stride 沿 K 前进,另一个沿 M 前进。 @@ -266,8 +266,8 @@ SFB(N, SFK) TMA 从 global memory load 到 shared memory,并不会直接 load 到 TMEM。因此 scale factor 通常分两步移动: ```text -global memory to shared memory with TMA -shared memory to TMEM with tcgen05.cp +通过 TMA 从全局内存移到共享内存 +通过 tcgen05.cp 从共享内存移到 TMEM ``` 只有在这次 copy 之后,scale factor 才进入 `tcgen05.mma` 期望读取它们的内存空间。 @@ -291,7 +291,7 @@ TCol = s replica 项会在 lane offset 0、32、64 和 96 处添加副本: ```text -TLane = r + 32 * q, where q in {0, 1, 2, 3} +TLane = r + 32 * q,其中 q ∈ {0, 1, 2, 3} TCol = s ``` @@ -300,9 +300,9 @@ TCol = s 32-bit `TCol` cell 内部还存在 byte packing。packing 取决于 `scale_vec` mode: ```text -1X: one scale value is broadcast across the 32-bit cell -2X: two scale values are packed, each duplicated -4X: four K-block scale values are packed +1X:一个 scale 值在整个 32-bit 单元中广播 +2X:打包两个 scale 值,且每个都复制一份 +4X:打包四个 K-block scale 值 ``` ![scale_vec byte 打包:1X 在 4-byte cell 中广播一个缩放因子;2X 打包两个缩放因子且各复制一份;4X 打包四个 K-block 缩放因子](../img/sf_scale_vec.svg) diff --git a/zh/chapter_performance/index.md b/zh/chapter_performance/index.md index 0c86187d..791e63a8 100644 --- a/zh/chapter_performance/index.md +++ b/zh/chapter_performance/index.md @@ -36,13 +36,13 @@ memory ceiling 是带宽乘以算术强度。如果一个 kernel 每搬运一个 基本的 roofline bound 是: ```text -attainable FLOP/s <= min(peak FLOP/s, memory bandwidth * arithmetic intensity) +可达到 FLOP/s <= min(峰值 FLOP/s, 内存带宽 * 算术强度) ``` 算术强度是: ```text -arithmetic intensity = useful FLOPs / bytes moved +算术强度 = 有用 FLOP 数 / 搬运的字节数 ``` 必须指定内存层级。对于 HBM roofline,这里的字节是 HBM 字节。对于 L2 roofline,它们是 L2 字节。 @@ -51,19 +51,19 @@ arithmetic intensity = useful FLOPs / bytes moved 在 roofline 图中,x 轴是算术强度,单位是 FLOP/byte。y 轴是可达到的性能。memory roof 是一条斜线: ```text -performance = bandwidth * arithmetic intensity +性能 = 带宽 * 算术强度 ``` compute roof 是一条水平线: ```text -performance = peak FLOP/s +性能 = 峰值 FLOP/s ``` 二者在 ridge point 处相交: ```text -ridge point = peak FLOP/s / bandwidth +ridge point = 峰值 FLOP/s / 带宽 ``` 对于这里使用的 B200 近似数字: @@ -100,11 +100,11 @@ elementwise kernel(如 GELU)和 reduction 风格的 kernel(如 RMSNorm) 对于这些 kernel,重要问题很机械: ```text -Are the loads and stores coalesced? -Are bytes moved only once? -Can the operation be fused with a producer or consumer? -Can the dtype be smaller? -Can TMA or vectorized accesses help? +加载和存储是否合并访问? +每个字节是否只搬运一次? +这个操作能否与生产者或消费者融合? +dtype 能否更小? +TMA 或向量化访问能否帮上忙? ``` 如果没有复用,也没有 fusion 机会,memory roof 就是真正的上限。 @@ -163,9 +163,9 @@ Attention 位于这两个极端之间。它的算术强度取决于序列长度 例子包括: ```text -GEMM plus elementwise epilogue -normalization folded into a neighboring op -attention computed without materializing the full score matrix +带 elementwise epilogue 的 GEMM +把 normalization 折叠进相邻操作 +在不 materialize 完整 score matrix 的情况下计算 attention ``` 第二种技术是为了复用而 blocking。如果一个 tile 载入一次,并在被逐出之前使用很多次,每个字节就支撑了更多算术工作。 @@ -183,12 +183,12 @@ GEMM 的高算术强度正是来自这种复用。其他工作负载只要存在 这意味着: ```text -move each byte once -avoid redundant reads -use coalesced or vectorized accesses -use TMA for regular bulk tiles -keep enough memory requests in flight -use smaller storage dtypes when the algorithm allows it +每个字节只搬运一次 +避免冗余读取 +使用合并访问或向量化访问 +对规则的大块 tile 使用 TMA +保持足够多未完成的内存请求 +算法允许时使用更小的存储 dtype ``` 一旦 memory-bound kernel 达到 memory roof,进一步优化计算就没有帮助。想更快,唯一办法是改变算法,让它搬运更少字节。 @@ -221,12 +221,12 @@ epilogue 排空先前结果。software pipelining 和 warp specialization 安排 一个简单 kernel 可能这样做: ```text -load tile k -compute tile k -store tile k -load tile k + 1 -compute tile k + 1 -store tile k + 1 +载入 tile k +计算 tile k +存储 tile k +载入 tile k + 1 +计算 tile k + 1 +存储 tile k + 1 ``` 这种 schedule 会让硬件闲置。load 运行时,Tensor Core 在等待。Tensor Core 运行时,copy engine 可能闲置。 @@ -235,9 +235,9 @@ store 排空时,两者都可能在等待。 pipelined kernel 则试图把彼此独立的阶段一起运行: ```text -load tile k + 1 -compute tile k -store tile k - 1 +载入 tile k + 1 +计算 tile k +存储 tile k - 1 ``` 这就是本书后面使用的 Blackwell kernel 结构背后的核心思想。TMA 处理异步数据移动。`tcgen05.mma` 处理异步 Tensor Core 工作。 @@ -250,12 +250,12 @@ tile `k` 的 epilogue 必须等 tile `k` 的 MMA 完成后才能读取 accumulat 这就是为什么后面许多章节会聚焦异步机制: ```text -TMA for global memory to shared memory movement -mbarriers for load completion and resource handoff -tcgen05 for asynchronous Tensor Core compute -TMEM for long-lived accumulators -warp specialization to separate producer and consumer roles -clusters for larger cooperative tiles and multicast +用 TMA 处理全局内存到共享内存的搬运 +用 mbarrier 表示加载完成和资源交接 +用 tcgen05 执行异步 Tensor Core 计算 +用 TMEM 存放长生命周期的累加器 +用 warp specialization 分离生产者和消费者角色 +用 cluster 支持更大的协作 tile 和 multicast ``` 它们是不同机制,但服务于同一个调度目标:让有用工作同时运行在不止一条硬件路径上。 @@ -287,9 +287,9 @@ occupancy 受每个 SM 的资源限制。主要限制包括寄存器、shared me 本书后续会不断回到同一套诊断问题: ```text -Which roof is this kernel under? -What resource is binding? -What change moves the kernel closer to that roof? +这个 kernel 受哪条 roof 约束? +哪个资源正在成为瓶颈? +什么改动能让 kernel 更接近那条 roof? ``` 对于 memory-bound kernel,答案通常是更少字节和更好的带宽使用。这意味着 fusion、coalescing、vectorized access、 diff --git a/zh/chapter_tensor_cores/index.md b/zh/chapter_tensor_cores/index.md index f6598eae..cae9ff26 100644 --- a/zh/chapter_tensor_cores/index.md +++ b/zh/chapter_tensor_cores/index.md @@ -210,8 +210,8 @@ block-scaled `tcgen05.mma` 与 dense MMA 有一条重要 placement rule 不同 这给 scale factor 带来了不同于数据 operand 的移动路径: ```text -A, B: global memory to SMEM, then MMA reads SMEM -SFA, SFB: global memory to SMEM, then tcgen05.cp copies SMEM to TMEM, then MMA reads TMEM +A, B: 从全局内存到 SMEM,随后 MMA 读取 SMEM +SFA, SFB: 从全局内存到 SMEM,随后 tcgen05.cp 将 SMEM 复制到 TMEM,最后 MMA 读取 TMEM ``` scale factor 的 TMEM layout 很紧凑。一个 128-row scale vector 可以 pack 到 32 个 Lane row 中: diff --git a/zh/chapter_tirx_layout_api/index.md b/zh/chapter_tirx_layout_api/index.md index 7f97e5c3..e379790e 100644 --- a/zh/chapter_tirx_layout_api/index.md +++ b/zh/chapter_tirx_layout_api/index.md @@ -413,7 +413,7 @@ R[2 : 4@warpid] ```text laneid = 4 * i + floor(j / 2) mod 4 -warpid = floor(j / 8) + 5 + 4 * r, where r in {0, 1} +warpid = floor(j / 8) + 5 + 4 * r,其中 r ∈ {0, 1} m = j mod 2 ``` @@ -483,7 +483,7 @@ TCol = s replica 项创建四个相隔 32 lane 的副本: ```text -TLane = r + 32 * q, where q in {0, 1, 2, 3} +TLane = r + 32 * q,其中 q ∈ {0, 1, 2, 3} TCol = s ``` diff --git a/zh/chapter_tma/index.md b/zh/chapter_tma/index.md index 48e85767..f8a4ca92 100644 --- a/zh/chapter_tma/index.md +++ b/zh/chapter_tma/index.md @@ -172,8 +172,8 @@ store 使用的 shared-memory region 可以安全复用。 所以规则很简单: ```text -TMA load: wait through an mbarrier with byte-count tracking -TMA store: wait through a commit group and wait group +TMA 加载:通过带字节计数跟踪的 mbarrier 等待 +TMA 存储:通过 commit group 和 wait group 等待 ``` 这两种机制在不同 handoff point 服务于同一个目的。load 需要让 shared-memory tile 对后续 consumer 可见。