FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

Rocket-ChipでMNISTのプログラムを動かす (2. RTLシミュレーション・FPGA動作)

Rocket-Chipでディープラーニング的なプログラムを動かして、RoCCのアクセラレータで高速化することができないか、いろいろ試行している。

まずは前哨戦として、C/C++で作成したMNISTのプログラムを動かしてRISC-Vで動作させたいと思っている。 RISC-Vでコンパイルしたプログラムを動作確認させる場合の方法はいろいろあって、

  • SpikeなどのISSで流して挙動を確認する。
  • Rocket-ChipのRTLシミュレーションで挙動を確認する。
  • FPGAで動かして挙動を確認する。
  • HiFive1などのASICを動かして挙動を確認する

などの方法がある。この中で、HiFive1以外は同じ動きを確認できるはずだ(HiFive1は32-bitなので同じプログラムが動かない)。

関連記事

Rocket-ChipでRTLシミュレーションを実行するときになる、ローディングが遅すぎる問題

Rocket-ChipのRTLとシミュレーション結果を解析するとわかるが、Rocket-Chipはメインのプログラムに入る前に、DPIを使ってbinファイルからテキストとデータを抽出し、RTL側に流し込み、次にリセットを解除してプログラムを動かす、という結構面倒なことをやっている。 このときに問題になるのが、流すべきバイナリのサイズが異常に大きくなってしまうと、なかなかプログラムが始まらないということだ。 ディープラーニング系のプログラムではこれは引っ掛かりやすいだろう。

私も同じだ。MNISTの学習データを乗せただけでもRocket-Chipのローディング時間が非常に長くなり、普通には動作しなくなった。 私のMNISTのプログラムは200枚の画像を使って動作をテストしているが、200枚の画像を全部ロードすると全くRocket-Chipがスタートしない。 これは問題だ。

RISC-V のISS であるSpikeを使用して、とりあえずの挙動を観察する。

次に、Spikeシミュレータを使ってシミュレーションをしてみる。 今のところはこれが一番お手軽だ。非常に高速で、動作を簡単に確認することができる。

$ spike ./train_twolayernet_fix16_full
=== TestNetwork ===
=== TestNetwork ===
 === start ===
Correct = 0
Correct = 1
Correct = 2
...
Correct = 182
Correct = 183
Correct = 184
Final Result : Correct = 185 / 200
Time = 0d0ed1dd - 0000272e = 0d0eaaaf

200毎のMNISTのプログラムなんて、一瞬で解析してしまう。非常に便利。

画像のサイズを落としてどうにかしてRTLシミュレーションを実行する

どうにかしてバイナリのサイズを減らし、Rocket-ChipのRTLシミュレーションで挙動を確認できないだろうか。 ということで、入力する画像のサイズを減らして、とりあえず実行できるようにする。 今回は画像のサイズを減らして、ロードするバイナリのサイズを減らす。 train_twolayernet_fix16_fullが画像データをすべてロードしたもので、train_twolayernet_fix16が画像のサイズを減らして、最初の6枚だけテストを行う。

$ ls -lt train_twolayernet_fix16 train_twolayernet_fix16_full
-rwxrwxr-x 1 msyksphinz msyksphinz 8043496  113 15:09 train_twolayernet_fix16_full
-rwxrwxr-x 1 msyksphinz msyksphinz  207488  113 15:09 train_twolayernet_fix16

画像の少ない train_twolayernet_fix16 を使うと、非常に時間がかかるがシミュレーションをできるようになった。 この方法のメリットは、命令の実行ログが残っているので性能解析が行いやすい点だ。

$ make CONFIG=DefaultConfig output/train_twolayernet.riscv.out
./emulator-freechips.rocketchip.system-DefaultConfig +max-cycles=100000000 +verbose output/train_twolayernet.riscv 3>&1 1>&2 2>&3 | /home/msyksphinz/riscv64/bin/spike-dasm  > output/train_twolayernet.riscv.out && [ $PIPESTATUS -eq 0 ]
=== TestNetwork ===
=== TestNetwork ===
 === start ===
Correct = 0
Correct = 1
Correct = 2
Correct = 3
Correct = 4
Fail = 5
Correct = 5
Time = 0114d6ae - 003e0a7d = 00d6cc31

FPGAにRocket-Chipを実装して動作させる

最後はRTLではなく、FPGAにRocket-Chipを実装して動作させる方法だ。

Rocket-ChipのFPGAへの実装方法は、本ブログでも頻繁に取り上げているので、以下を参照してほしい。

msyksphinz.hatenablog.com

msyksphinz.hatenablog.com

FPGAならば実機なので、非常に高速だ。200毎のMNISTのテストも普通に実行することができた。 正しく動作しているようだ。次は、RTLシミュレーションで取得したログを用いて、性能解析に進んでいこう。

f:id:msyksphinz:20180113153545g:plain