MNISTを、ハードウェアアクセラレータを使って高速化したい。 前回はChiselで初期実装を行った。シミュレーションをして、短いテストプログラムで動作確認をして、結構うまく動作するようにになったのでいよいよFPGAに書き込んで確認したい。 やってみよう。
関連記事 目次
- RISC-V ISS Spike を使ってMNISTのハードウェアアクセラレーションをシミュレーションしたい
- RISC-V ISS Spike を使ってMNISTのハードウェアアクセラレーションを実装する
- Chiselを使ってMNISTハードウェアアクセラレータを実装(実装中)
- Chiselを使ってMNISTハードウェアアクセラレータを実装(FPGAで確認)
Chisel でDot Product Acceleratorを実装する
結局以下のような実装になり、シミュレーションを実行したところ正しく動作しているようだった。
make CONFIG=RoccExampleConfig output/mnist_hw.riscv.out ./emulator-freechips.rocketchip.system-RoccExampleConfig +max-cycles=100000000 +verbose output/mnist_hw.riscv 3>&1 1>&2 2>&3 | /home/msyksphinz/riscv64/bin/spike-dasm > output/mnist_hw.riscv.out && [ $PIPESTATUS -eq 0 ] === TestNetwork === === TestNetwork === === start === Final Result : Correct = 5 / 6 Time = 9756164 - 4114178 = 5641986
6毎のMNSITの画像を使って5枚の認識に成功している。うまくいっているな。
次に、FPGAへの書き込みを行う。これはこれまでと同様にFPGA-Zynqの環境を用いた。
rocc.scala
に実装したDotProductF16モジュールを移植し、論理合成を実行した。DotProductの計算にあたり、レジスタを挿入せずにすべて組み合わせ回路で実装したが、25MHzという超低速動作のためなんとかViolation Errorは発生しなかったようだ。
こうしてFPGAのブートを行ってみる。mnistのバイナリ4種類をイメージファイルにコピーしておく。やり方は私のブログを参照。
一点注意としては、どうもmnistのバイナリをコピーしたせいでイメージが大きくなりすぎ、ちゃんとメモリ領域を考慮しないとLinuxが起動しなくなった。
Linuxイメージの領域を変更して、より多くのデータを格納できるようにしておく。
fatload mmc 0 0x3000000 uImage fatload mmc 0 0x2A00000 devicetree.dtb fatload mmc 0 0x1000000 uramdisk.image.gz # これまでは0x2000000 だったのを変更した bootm 0x3000000 0x1000000 0x2A00000
さっそくLinuxをブートして、MNISTを動作させてみる。
うーん、ソフトウェアだけで実行したもの(train_twolayernet_fix16_full
) は正しく動作しているようだが、RoCCアクセラレータを使用したもの(train_twolayernet_fix16_hw_full
)は正しく動作しなかった。
これはデバッグが大変だ。。。いくつか分解して、計算結果を確認するしか方法は無さそうだ。