iT邦幫忙

2026 iThome 鐵人賽

DAY 27
0
Software Development

在 AI Compiler 工程師的路上系列 第 27

Day26:TileLoom :mapping、performance model 和實驗

  • 分享至 

  • xImage
  •  

昨天讀完 TileLoom 的 Introduction 和 Framework Overview,
今天繼續從 paper Section 2.2 開始,看一個 matmul 候選方案怎麼經過 spatiotemporal mapping、reuse analysis、memory operation planning 與 performance model。後半段再讀 Wormhole 與 Blackhole 的實驗,檢查 compiler 做出的這些決策是否帶來實際收益。

本篇大綱

  • Spatiotemporal mapping 的輸入是什麼?
  • Spatial 和 temporal:logical grid 怎麼放到 core grid
  • Reuse analysis:從 affine access 的依賴關係開始
  • Hardware representation:用 df dialect 描述目標硬體
  • Performance model:從 innermost loop 往外估計
  • 論文和目前專案實作的差距
  • 實驗結果

Spatiotemporal mapping 的輸入是什麼?

TileLoom 進入 dataflow planning 前,front-end 要先產生統一的 dataflow-agnostic MLIR。Paper Listing 1 用 matmul 當例子,關鍵結構可以簡化

affine.parallel (%block_id_x, %block_id_y) = ... {
  %acc = linalg.fill ...

  %result = scf.for %k = ... iter_args(%tile = %acc) {
    // 用 block id 與 k 計算 A、B tile 位址
    // memref.copy 載入 A tile 與 B tile
    // linalg.matmul 計算一個 output tile
  }

  // 寫回 C tile
}

affine.parallel 上的 %block_id_x%block_id_y 還是 logical grid indices。它們分別對應 matmul 輸出空間的 M 軸與 N 軸。scf.for %k 則在單一 output tile 內順序累加 K 軸的 partial products。

Front-end 還有一個規定是 load 與 store 的位址計算必須是 tile indices 和 intra-tile indices 的 affine function。後面 reuse analysis 才能檢查某個 memory access 依賴哪些 loop variables。

Tile-wise computation 使用 linalg 表達。Dataflow planning 不會改寫這一段運算,它主要重組外層 loops、memory allocation、copy 和 communication。

Spatial 和 temporal:logical grid 怎麼放到 core grid

假設目標硬體是 8 × 8 core grid。TileLoom 可以將上述 logical loops 改寫成 paper Listing 2 的結構

affine.parallel (%x, %y) = (0, 0) to (8, 8) {
  affine.for %tx = 0 to %grid_dim_x ceildiv 8 {
    affine.for %ty = 0 to %grid_dim_y ceildiv 8 {
      scf.for %k = ... {
        // tile-wise computation
      }
    }
  }
}

這裡有三種 loop

Loop 類型 執行方式 在 matmul 中的意義
affine.parallel (%x, %y) 實體 cores 同時執行 8 × 8 core coordinates
affine.for %tx/%ty 同一組 cores 先後處理 tile waves Logical grid 超過 8 × 8 的剩餘 work
scf.for %k 單一 core 內的順序 loop 沿 K 軸累加 output tile

Spatiotemporal mapping 會搜尋三類選擇

選擇一:logical axis 映射到哪個 spatial axis

M 軸、N 軸可以映射到 hardware x 軸或 y 軸,不同映射會改變 A 與 B tile 在 mesh 上的重用方向。

選擇二:tiling order

同一個 logical axis 也可能被多個 spatial axes 切分,Tiling 順序會決定相鄰 tiles 如何排列在 core grid 上,也會改變 NoC traffic。

選擇三:remaining loops 的 temporal order

可用的 spatial axes 分配完之後,剩下的 logical work 會變成 temporal loops。%tx%ty 的順序決定 core array 先計算哪批 tiles,因此影響 temporal reuse 和 buffer lifetime。

每一個 mapping candidate 都會產生一個具體 loop nest。後續 reuse analysis 不需要猜測 mapping,可以直接檢查這個 loop nest 內的 affine accesses。

Reuse analysis:從 affine access 的依賴關係開始

TileLoom 對每個 memory access 檢查 affine expression 使用了哪些 induction variables。判斷規則很直接

  • Access 不依賴某個 spatial index,代表沿該軸的 cores 使用同一個 tile,存在 spatial reuse。
  • Access 不依賴某個 temporal loop variable,代表多次 tile waves 使用同一個 tile,存在 temporal reuse。
  • Access 只依賴 intra-core sequential indices,重用範圍就在單一 core 內。

以 matmul 為例

C[m, n] += A[m, k] * B[k, n]

A[m, k]n 無關,所以處理不同 n tiles 的 cores 可以共用 A tile。B[k, n]m 無關,所以處理不同 m tiles 的 cores 可以共用 B tile。實際上是 row broadcast 還是 column broadcast,取決於 M/N 軸如何映射到 hardware x/y 軸。

Spatial reuse:從 per-core global load 變成 NoC broadcast

TileLoom 先建立保守 baseline:每個 core 都在最內層 loop 自行從 global memory 載入 tile。如果 access 具有 spatial reuse,compiler 可以讓少數 producer cores 載入資料,再經由 NoC 傳給其他 cores。

一個 tile 可能只沿單一軸重用,也可能沿兩軸重用。兩軸 reuse 可以有多種具體實現,先複製到每一列再沿列 broadcast,或先複製到每一欄再沿欄 broadcast。這些方案的 global load 數量、NoC links 和 congestion 不同,所以都要交給 cost model 比較。

Temporal reuse:hoist load 與 buffer footprint

Temporal reuse 會嘗試把 load 移到更外層的 loop

before:
for tm:
  for tn:
    for tk:
      load A[tm, tk]

after hoisting:
for tm:
  load A[tm, *]
  for tn:
    for tk:
      use buffered A[tm, tk]

A[tm, tk] 移到 tn 外層,可以讓不同 tn iterations 共用 A tiles。代價是 A[tm, *] 要在 local buffer 保持更久。

Paper 用兩條規則描述這個交換

  • Load 移過一個它不依賴的 loop,重用增加,buffered region 不需要擴大
  • Load 移過一個它會依賴的 loop,同時 live 的 distinct tiles 增加,buffer footprint 也會增加

TileLoom 會列舉合法的 hoisting levels,計算每個方案需要的 buffer capacity,並排除超過硬體容量的候選。

Spatial reuse 與 temporal reuse 可以同時存在。一個 tile 可以先 broadcast 到多個 cores,然後在每個 core 的多次 temporal iterations 中重用。最後產生的 candidate 會明確記錄

  • Tile 在什麼時間點存放於哪個 memory
  • Load 是 global load 還是 broadcast
  • Broadcast 使用哪些 NoC resources
  • Buffer 的容量與 lifetime

Hardware representation:用 df dialect 描述目標硬體

Mapping 和 reuse 候選需要一份可機器讀取的硬體資料。TileLoom 使用自訂 MLIR df dialect 描述 scale-out topology、memory hierarchy、connectivity 與 intra-core compute resources。

df operation 描述的資源 Compiler 用途
df.spatial_dim(size) 可複製硬體資源的空間軸 建立 core、memory 或 network 的 coordinates
df.core(scaleout, scalein) Core array 與每個 core 內部資源 將 logical tiles 映射到 cores
df.interconnects(..., map, bandwidth) Components 之間的 links 與 per-link bandwidth 估計 broadcast path 與 traffic contention
df.memory(..., size, bandwidth) Distributed scratchpad 或 DRAM banks 檢查 capacity 與 memory cost
df.mux(dst, srcs, map) Core-to-local-memory 或 core-group-to-DRAM 的 fan-out 關係 決定哪些資源可存取哪個 memory
df.mat / df.vec / df.scalar Matrix、vector 與 scalar units 的 shape、throughput 或 latency 估計 tile-level compute time

Paper Listing 6 用下列結構描述 8 × 8 cores 與水平、垂直 NoC

%x = df.spatial_dim 8
%y = df.spatial_dim 8
%cores = df.core {scaleout = (%x, %y)}
%noc_h = df.interconnects ...
%noc_v = df.interconnects ...

Listing 7 再加入 per-core L1 scratchpad、DRAM banks 與它們之間的連線。Listing 8 會把 matrix unit 與 vector unit 綁定到 cores。不同 compiler passes 只需讀取自己需要的詳細程度:

  • Spatiotemporal mapping 需要 core topology 與 interconnect。
  • Data movement planning 額外需要 memory placement、capacity 與 connectivity。
  • Performance model 再使用 per-core compute throughput。

Paper Figure 3 還用 1D triple-ring 架構示範 df dialect 不只能描述 Tenstorrent 2D mesh。不過實驗仍以 Wormhole 與 Blackhole 為主,所以這裡只能確認 representation 的表達能力,不能當成 TileLoom 已在 triple-ring 硬體上完成 end-to-end 驗證。

Performance model:從 innermost loop 往外估計

Spatiotemporal mapping 與 data movement planning 會產生多個 candidates。每個 candidate 的 loops、memory operations、broadcasts 與 hardware bindings 都已經具體化。Performance model 要估計每個 candidate 的 execution time,並選出 top-k。

https://ithelp.ithome.com.tw/upload/images/20260826/20183319ZpObrJImVV.png

圖片出處:Wei Li et al.,〈TileLoom: Automatic Dataflow Planning for Tile-Based Languages on Spatial Dataflow Accelerators〉,Figure 4,CC BY 4.0

Figure 4 從左到右、從內層到外層表達三個估計尺度

  1. 將 innermost loop body 的 linalg operations 拆成 df.matdf.vecdf.scalar 可執行的 low-level operations,估計單一 core 的 compute cost。
  2. 估計 k-loop 內 load、compute 與 store 在 double buffering 下的 overlap。
  3. 再向外組合 k-loop、n-loop 與其他 loops,加入 temporal reuse 與跨 core communication cost。

Load、compute 與 store overlap

Paper 假設 innermost loop 使用 pipelined load–compute–store 與 double buffering。Iteration i 執行 compute 時,可同時處理 iteration i+1 的 load 和 iteration i-1 的 store。Steady state throughput 取決於 compute 與 data movement 哪一邊較慢,開頭與結尾還要加上 pipeline fill/drain cost。

這是 model assumption,不代表任意 backend 都能達成完整 overlap。TileLoom 用它來排序 candidates,還可以用 optional profiling 補上模型沒有描述的微架構差異。

NoC contention

多個 memory operations 可能同時使用相同 NoC links 或 DRAM banks。TileLoom 會根據 candidate 上的 resource annotations 將 transfers 分組,再按同時使用相同資源的 traffic 估計 effective bandwidth。

例如,row broadcast 只使用 horizontal links,整個 mesh 的 broadcast 可能同時使用 horizontal 與 vertical links。兩種候選就算 global load 數量相同,NoC congestion 也可能不同。

Top-k 與 hardware profiling

Model 先依 estimated time 排序,只將 top-k candidates 交給 backend 做完整 code generation 與硬體 profiling。k 較大時,找到更好 mapping 的機率提高,編譯與 profiling time 也會增加。

Front-end 與 backend 怎麼落地

Triton 與 Helion front-end

TileLoom 目前支援 Triton 與 Helion。兩邊先使用現有 Python autotuning stack 選擇 tile/block shape,再進入共同 MLIR representation。

參考用 Triton flow

Triton kernel
  → triton-shared
  → MLIR
  → custom affinization pass
  → normalized dataflow-agnostic MLIR

參考用 Helion flow

Helion kernel
  → Python-level tuning
  → Helion Device IR
  → custom lowering tool
  → normalized dataflow-agnostic MLIR

Core planning pipeline 只要接收相同的 affine/linalg/scf representation,就可以共用後續 passes。當然,這還是 paper 展示的兩個 front-ends,不能直接推論任意 tile DSL 都已經可以接入。

TT-Metalium backend

TileLoom 會將 dataflow-aware MLIR lower 到 TT-Metalium C API。TT-Metalium 提供 coarse-grained compute、synchronization、buffer allocation 與 data movement primitives。

TileLoom 在 block-level 計算圖上執行 lifetime analysis,用 operation lifetime 決定 buffer allocation,並安排 memory、compute 與 data movement operations 之間的同步。TT-Metalium 再將這些 coarse-grained operations 降成硬體指令。

論文和目前專案實作的差距

上面是 2026 年 5 月的 arXiv v2 說明 df dialect。截至 2026 年 8 月,Loom 公開專案的架構已經重構,硬體拓樸、運算資源與效能模型分別由 ADL、MLAR 與 Loom dialect 負責。

論文 v2(2026 年 5 月) Loom main(2026 年 8 月查閱)
df.spatial_dimdf.coredf.memorydf.interconnects 描述硬體拓樸 ADL dialect 負責 MLIR 中的 spatial dimensions、memory banks、processors 與 architecture composition
df.matdf.vecdf.scalar 同時表達運算單元與其成本 MLAR 用 Rust 資料結構描述 memory、compute processor、data mover、network 與 resource;運算功能使用一般 func.funclinalg.* 搭配 Loom annotations,效能模型則由 Rust 或 YAML 表達
Dataflow planning 產生候選方案,再由 performance model 排名 loom-dataflow 先列舉 mapping、標註 reuse 與 copy choices,輸出 Execution Task Graph(ETG)JSON;loom-mlar 依目標架構解析 ETG,最後由 loom.solver 使用 CPMpy/CP-SAT 選擇 block sizes
Triton 與 Helion 都有論文中的 front-end flow 目前 Loom README 記錄的 end-to-end 主流程從 Helion 開始;loom-dataflow 仍保留 Triton IR 測試與相關 passes,但公開文件沒有把 Triton 列成目前主流程的對等入口
Backend 產生 TT-Metalium executable 目前 TT backend 被拆成可選的 loom2ttkernel 階段,將 bufferized Loom MLIR 往 TTKernel、tt-mlir 與 tt-metal 的 code generation inputs lowering

現行 ADL 的 operations 包括 adl.spatial_dimadl.memory.bankadl.memory.arrayadl.processor.computeadl.processor.dmoveradl.arch.composeadl.arch.scale。它們和論文中的 df.* 沒有逐項對應,例如 ADL 裡找不到把 df.matdf.vecdf.scalar 原封不動換字首後的 operations。因此,ADL 比較接近 df 裡硬體拓樸部分的後繼表示,完整的 architecture 與 performance model 要連同 MLAR 一起看。目前的 Loom architecture 文件 也把兩者分開,loom-dataflow 擁有 ADL 與 Loom dialect,loom-mlar 提供 architecture description 與 schedule evaluation。

目前程式還不確定是否可以重現論文 performance model 宣稱的能力,還在研究中,目前公開實作能執行到哪個範圍,還是要以專案文件和程式碼為準。loom-mlar README 列出的限制包括,parallel schedule 已經可以序列化,但 evaluator 尚未實作它的評估,resource maps 可以表示 contention 關係,schedule evaluator 還不會執行 resource-aware parallel scheduling。這和論文後面要估算的跨 core parallel execution 與 NoC contention 直接相關。

Evaluation setup

論文在兩代 Tenstorrent cards 上實驗

項目 Wormhole Blackhole
Core topology 8 × 8 12 × 10
On-chip SRAM 108 MB 180 MB
DRAM 12 GB GDDR6 32 GB GDDR6
Off-chip bandwidth 288 GB/s 512 GB/s
FP16 peak throughput 64 TFLOPS 162 TFLOPS

作者無法取得完整的 proprietary hardware specification,因此用 isolated microbenchmarks 測量 matrix/vector unit throughput、effective NoC bandwidth 與 DRAM bandwidth,再將這些數值填入 df hardware representation。這一點同時是方法與限制:hardware model 可以由測量建立,測量沒有覆蓋的微架構行為則會變成 model error。

下面 end-to-end 結果都使用 performance model 排名第一的 top-1 candidate,沒有執行 optional profiling-based tuning。因此,Table 2 呈現 static architecture model 與 dataflow planning 直接選出方案後的效能。

Table 2

https://ithelp.ithome.com.tw/upload/images/20260826/20183319vOTprRjONY.png

圖片出處:Wei Li et al.,〈TileLoom: Automatic Dataflow Planning for Tile-Based Languages on Spatial Dataflow Accelerators〉,Table 2,CC BY 4.0

Table 2 報告多個 input shapes 的 geometric mean

Kernel Baseline Wormhole Blackhole
FlashAttention TTNN library implementation 1.94× 1.98×
Flash Decode TTNN library implementation 0.84× 0.87×
GEMM TTNN library implementation 0.95× 1.10×
Mamba Chunk Scan TTNN unfused implementation 27.23× 16.27×

前三列可以與 TTNN library implementation 比較。Mamba Chunk Scan 的 baseline 是由現有 TTNN operations 組成的 unfused implementation,TileLoom 使用 fused Helion kernel。因此 27.23× 和 16.27× 包含 fusion 與 dataflow planning 的綜合影響,不能和前三列當成同一種 baseline。

FlashAttention:reuse 能夠變成 DRAM traffic reduction

Paper 測量 non-causal FlashAttention,sequence length 從 1024 到 16384,attention heads 為 64 或 128,batch size 則依 DRAM capacity 調整。

https://ithelp.ithome.com.tw/upload/images/20260826/20183319NT61CD736X.png

圖片出處:Wei Li et al.,〈TileLoom: Automatic Dataflow Planning for Tile-Based Languages on Spatial Dataflow Accelerators〉,Figure 5,CC BY 4.0

圖的上半是 Blackhole,下半是 Wormhole。X 軸是 (batch size B, sequence length L, heads N) 組合,Y 軸是 normalized performance,TTNN 固定為 1。TileLoom 在圖中的結果約為 1.88×~2.06×。

Paper 將收益歸因於 attention operands 的 on-chip reuse:mapping 讓 key tiles 可以在多個 query/value tiles 之間共用,減少重複 DRAM loads。這張圖支持的範圍是論文測量的 non-causal FlashAttention shapes,不能直接推廣到 causal attention 或任意 attention implementation。

Flash Decode:可用 mapping space 變小

Flash Decode 可視為 query length = 1 的 attention。Query axis 幾乎沒有 spatial parallelism,主要 parallelism 來自 batch 與 key/value sequence split。Compiler 能嘗試的 dataflow mappings 變少,重點轉到 cross-core gather-reduce 和 block-level code quality。

TileLoom 在 Wormhole 達到 TTNN 的 0.84×,Blackhole 為 0.87×。Paper 的解釋是 TTNN baseline 含有針對 Flash Decode 手工調校的 scheduling 與 reduction 最佳化。這組結果也說明自動 dataflow planning 的收益受 workload parallelism 形狀限制。

GEMM:硬體的 compute-to-bandwidth ratio 會改變收益

GEMM 在 Wormhole 是 0.95× TTNN,在 Blackhole 是 1.10×。Paper 將差異連到兩代硬體的 compute-to-bandwidth ratio:Blackhole 的 FP16 peak throughput 是 Wormhole 的 2.53×,off-chip bandwidth 則是 1.78×。Compute 成長快於 off-chip bandwidth 後,memory traffic 與 placement 對效能的影響變大。

Wormhole GEMM 常接近 compute-bound,減少 DRAM traffic 對 runtime 的幫助有限,TileLoom 也還沒有 TTNN 手工 GEMM library 的所有微架構專用最佳化。Blackhole 的 memory pressure 較高,TileLoom 的 spatial reuse 與 placement search 就有更多發揮空間。

Mamba Chunk Scan:先看 baseline 再看倍率

Mamba Chunk Scan 是 linear-attention kernel。TTNN 沒有對應的 fused implementation,所以 paper 用現有 TTNN operations 組成 unfused baseline;TileLoom 的輸入是 fused Helion tile-level kernel。

Wormhole 27.23× 與 Blackhole 16.27× 說明這套 compiler stack 可以將 fused tile kernel 落到實際硬體,並明顯超過該 unfused baseline。倍率同時包含 operator fusion、intermediate data movement 減少與 dataflow planning,無法單獨證明 mapping pass 貢獻了多少收益。

Ablation 和 model validation

論文 Section 3.3 提供了幾個可以縮小因果解釋範圍的結果

Spatial reuse

作者關閉 spatial-reuse pass,強制 operands 都從 DRAM 載入。Spatial reuse 在較小、較 memory-bound 的 GEMM 上收益較大;問題規模增加、arithmetic intensity 提高之後,runtime 逐漸接近 compute roof,減少 DRAM traffic 不一定會等比例變成 speedup。論文報告這些 GEMM configurations 的 DRAM accesses 平均減少 70%。

Temporal reuse

作者比較開啟與關閉 temporal reuse 的 GEMM。在 M 或 N 較大、K 較小的 memory-bound settings,temporal reuse 最高帶來 1.12× speedup。當重用收益小時,performance model 會降低這些 mappings 的排名,最後可能選到與關閉 temporal reuse 相同的 mapping。

Performance model accuracy

Paper 在 Wormhole 上比較多種 GEMM shapes 的 predicted throughput 與 measured throughput,geometric-mean difference 為 17%。Model 的目標是 candidate ranking 與 trend prediction,不是 cycle-accurate simulation。這個 17% 差異不能省略,也解釋了 optional top-k profiling 的用途。

Top-k trade-off

在 Wormhole 8 × 8 mesh 上,top-2 相對 top-1 的 geometric-mean performance 提高 4.7%,top-5 提高 7%。Paper 報告超過 top-3 後收益很快飽和,compile time 則接近線性增加。這支持一個有範圍的工程判斷:靜態 model 先縮小 candidates,再用少量 profiling 處理錯排的候選。

複習一下

  • 實驗硬體:end-to-end evaluation 是 Tenstorrent Wormhole 與 Blackhole。df dialect 可描述其他 topology,paper 沒有對其他 vendor 硬體做同等程度的 end-to-end 實驗。
  • Hardware model:部分 proprietary parameters 來自 isolated microbenchmarks,仍有微架構細節未被建模。
  • Mapping space:TileLoom 搜尋 tiling-based spatiotemporal mappings、hoisting 與 broadcast plans,結果受這個候選空間的表達能力影響。
  • Baseline:FlashAttention、Flash Decode 與 GEMM 對 TTNN library implementation;Mamba Chunk Scan 對 unfused TTNN composition。
  • Kernel shape:Flash Decode 顯示 workload 沒有足夠 spatial parallelism 與 reuse 時,planning space 本身就很受限。
  • Performance model:論文報告 17% geometric-mean prediction difference,model 主要用來排序,必要時由 profiling 選出 final top-1。

明天開始看 test/Passes/mm/IR。從 frontend、canonicalization 與 explicit memory access 三個階段開始,先確認 paper Listing 1 的 dataflow-agnostic matmul 在 repository 裡長什麼樣子。

參考資料


上一篇
Day25:TileLoom :spatial dataflow accelerator 的編譯問題
下一篇
Day27:Loom-dataflow :matmul IR 從 frontend 到 explicit memory access
系列文
在 AI Compiler 工程師的路上32
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言