xiangze's sparse blog

機械学習、ベイズ統計、コンピュータビジョンと関連する数学について

VTAの実装三者三様(Xilinx,Intel,Scala)

VTAのFPGAによる回路実装を比べてみます。
どれもあまり触ったことがないのでこれを機に細かいところを学んでいきます。

概観

VTAの回路モジュール図
  • instruction fetch module
  • load module
  • store module
  • input/output/weight buffer
  • load/compute store comand queue
  • compute module

- register file
- micro-op cache
- Tensor ALU
- GEMM core
といったブロックからなりCISC的なCPUとみなすことができます。TPUの構成に似た部分があります*1

このハードウェアを以下のIntel OpenCL, AMD(Xilinx) Vivado HLSではFPGA合成用の高位言語で記述していて、抽象度の高いRTL記述言語Chiselでも記述されて言います。

Intel OpenCL

tvm-vta/hardware/intelfocl at main · apache/tvm-vta · GitHub
tvm-vta/hardware/intelfocl/src/vta.cl at main · apache/tvm-vta · GitHub
の vta_core関数にすべての処理が書かれているようです(約300行)。vta.hにはサイズなどのパラメーターが書かれています。
演算精度はunsigned intです。全体が

for (int pc = 0; pc < insn_count; pc++) {

ループに囲まれたステートマシンで重み、データの読み込み、GEMM,ALUでの演算、結果の書き出しが条件ごとにあります。
演算部分で

#pragma unroll

が使われています。

AMD(Xilinx) Vivado HLS

tvm-vta/hardware/xilinx/src/vta.cc at main · apache/tvm-vta · GitHub
reset_ load_data
など各処理が関数として書かれています(約750行)。テンプレートでデータ幅を決定します。

#pragma HLS INLINE
#pragma HLS PIPELINE

が各ループに丁寧に付けられています。computeやstoreは処理が多くソフトウェア的な見た目で最後のvta関数が最上位のステートマシンになっているようです。

Chisel

ChiselはScalaベースのDSLで抽象度としてはRTLですがVerilogVHDLよりも簡潔でサイクルベースの高速なシミュレーションやJava,Scalaのソフトウェア環境が使えることで注目されています。
tvm-vta/hardware/chisel/src/main/scala/core at main · apache/tvm-vta · GitHub
モジュール、機能ごとにファイルがあります。Java,Scalaの環境はディレクトリが深いです。

行数 ファイル名
:---- :----
274 Compute.scala
49 Configs.scala
121 Core.scala
229 Decode.scala
67 EventCounters.scala
74 Fetch.scala
200 FetchVME64.scala
351 FetchWideVME.scala
149 ISA.scala
132 Load.scala
103 LoadUop.scala
250 LoadUopSimple.scala
44 Semaphore.scala
114 Store.scala
601 TensorAlu.scala
748 TensorGemm.scala
75 TensorLoad.scala
740 TensorLoadNarrowVME.scala
361 TensorLoadSimple.scala
765 TensorLoadWideVME.scala
62 TensorStore.scala
275 TensorStoreNarrowVME.scala
289 TensorStoreWideVME.scala
556 TensorUtil.scala
23 package.scala
6652 合計

Coreが回路の最上位でその下のComputeで計算の処理をしていてステートマシンがあります。ステートマシンは一番短くまとまっています。

val インスタンス名=Module(new モジュール名)

で下位のモジュールをインスタンス化しています。
Fetch,Load,Storeが複数あったりSemaphoreがあったりして高位合成よりも細かく書かないといけないようです。

testもあります
src/main/resources以下はverilog DPI-Cで書かれたメモリモデルのようです。

https://github.com/apache/tvm-vta/blob/main/hardware/chisel/src/main/scala/test/Test.scala

感想

まさに三者三様
自分でもこれをベースにSystem Verilog,System Cで書けそう。

ためになる本

ChiselでRiscVのCPUを作るという実践的入門書、GCCコンパイルしたコードが動く!拡張命令も動く!
gihyo.jp
GitHub - chadyuu/riscv-chisel-book
dockerでChisel開発環境を簡単に使えます。


深層学習コンパイラスタックと最適化

cparch-mclearn.blogspot.com