14. def matmul(float(M,K) A, float(K,N) B) -> (output) {
output(m, n) +=! A(m, r_k) * B(r_k, n)
}
type(X,Y,…)で入力引数に制約
(要素型制約およびレンジ制約)を付与
15. def matmul(float(M,K) A, float(K,N) B) -> (output) {
output(m, n) +=! A(m, r_k) * B(r_k, n)
}
レンジ制約に同一シンボルを使用することで、
異なる引数間の制約を表現できる
16. def matmul(float(M,K) A, float(K,N) B) -> (output) {
output(m, n) +=! A(m, r_k) * B(r_k, n)
}
出力の制約はコンパイラによって自動推論される
17. def matmul(float(M,K) A, float(K,N) B) -> (output) {
output(m, n) +=! A(m, r_k) * B(r_k, n)
}
初期化付き畳み込み用記述のオペレータ
18. def matmul(float(M,K) A, float(K,N) B) -> (output) {
output(m, n) +=! A(m, r_k) * B(r_k, n)
}
左辺で定義した誘導変数を右辺で使用すると
ループが形成される
for m := 0, M
for n := 0, N
19. def matmul(float(M,K) A, float(K,N) B) -> (output) {
output(m, n) +=! A(m, r_k) * B(r_k, n)
}
ループのレンジは入力制約から決定される
e.g. m := [0. M)
20. def matmul(float(M,K) A, float(K,N) B) -> (output) {
output(m, n) +=! A(m, r_k) * B(r_k, n)
}
左辺で定義していない誘導変数を右辺で使用した場合、
既存ループの最内に新たにループが形成される
for m := 0, M
for n := 0, N
for r_k := 0, K
21. def matmul(float(M,K) A, float(K,N) B) -> (output) {
output(m, n) +=! A(m, r_k) * B(r_k, n)
}
その場合も入力の制約をもとに制約チェックが行われる
34. 簡約化結果
後段のPolyhedral Transformationで
解析・変形可能なループ構造に簡約できた
for (output.s0.m, 0, M) {
for (output.s0.n, 0, K) {
output(output.s0.m, output.s0.n) = 0.000000f
}
}
for (output.s1.m, 0, M) {
for (output.s1.n, 0, K) {
for (output.s1.r_k, 0, K) {
output(output.s1.m, output.s1.n) =
ReductionUpdate((output(output.s1.m, output.s1.n) +
(A(output.s1.m, output.s1.r_k)*
B(output.s1.r_k, output.s1.n))))
}
}
}
ループ範囲がTC言語のレンジ制約と対応している
35. tc::polyhedral::Scop
– ISL (Integer Set Library) /Polyhedral Compilation
Libraryを用いて計算されたスケジューリング
– RAW, WAR, WAW 依存関係
– メモリ配置
– Halide IR関連
• パラメータ
• 入出力
• Stmt
Polyhedral IR
Polyhedral IR
Halide IR
パラメータ/
入出力
Polyhedral IR変換
Stmt of Provide A Stmt of Provide B
パラメータ/
入出力
スケジューリング 依存関係
メモリ配置