2
1

More than 1 year has passed since last update.

高位合成によるFPGA回路設計を読んで、MNISTを試してみた

Last updated at Posted at 2022-03-27

はじめに

前々から、FPGAの高位合成や画像認識に興味はあったのですが、これはという書籍もなく、色々なサンプルに手を出しては、途中で挫折するということを繰り返していました。(主にpetalinuxのせいな気がする)
そんな中、これは!という書籍が発売されているのを知り、早速購入してみました。

帯に書いてあった"高位合成の初歩から丁寧に学べる待望の入門書"という売り文句は間違ってなく、大変勉強になったんですが・・・、Chapter5のVitis AIでDPUを実装し、MNISTを実行する、というところで散々ハマったので、その過程を書き記してみます。
私が回路・基板設計がメインのハードウェアエンジニアで、たまにHDLもかじったことがありますという程度のスキルレベルで、Linuxをいじったり、C++でコーディングするハードルが高いということもあり、これらの罠回避に難航したということもあるかもしれません。
ただ、MNISTを実行するだけのために、これだけの労力を費やさないとならないというのは、こういうハードルや罠の多さが、今ひとつ普及しない要因になってるんじゃ・・・とかも思ったりします。(クラウドだったら、Google Colabでサッと試せるし)

実行環境

項目 バージョン
OS Ubuntu 18.04 (Virtualbox)
ボード Ultra96v2
Vivado 2020.1
Vitis 2020.1
Petalinux 2020.1 (2019.2)
Vitis AI 1.2

罠1: Bootgenでエラー発生

5-3-2 DPU動作環境の構築で、VitisプラットフォームにDPUを組み込むところがあるんですが、森北出版さんから提供されているVitisカスタムプラットフォームを使っても、Bootgenでエラーが発生して、bootimageが生成できませんでした。エラーメッセージを見た感じ、各ファイルの格納場所の指定を変更する必要がありそう・・・というのは分かるんですが、どこでそれを変更するのかが分からん、と。

[WARNING]: [fsbl_config] a53_x64 | a53_x32 | r5_single | r5_dual is no more supported. Use 'destination_cpu' attribute for bootloader partition
[ERROR]  : Cannot read file - /home/tanaka/work/HLS_for_SW/Appendix/petalinux/boot/pmufw.elf
ERROR: [v++ 82-1008] Cannot generate bootimage


おそらくVitisプラットフォームの何処かで指定しているんだろうと思いつつも、見当がつかないので、Appendixを見ながら、Vitisプラットフォームを一から作ってみることにしました。で、一から作ってみたところ、bifファイルで指定することを把握。下記のように自分の環境に合わせ変更して、再ビルドすることで、Bootgen成功。
linux.bif
the_ROM_image:
{
       [fsbl_config] a53_x64
       [bootloader] /home/madrid/ultra96v2_work/petalinux/boot/zynqmp_fsbl.elf
       [pmufw_image] /home/madrid/ultra96v2_work/petalinux/boot/pmufw.elf
       [destination_device=pl] <bitstream>
       [destination_cpu=a53-0, exception_level=el-3, trustzone] /home/madrid/ultra96v2_work/petalinux/boot/bl31.elf
       [destination_cpu=a53-0, exception_level=el-2] /home/madrid/ultra96v2_work/petalinux/boot/u-boot.elf
}

罠2: MNISTの学習でエラー発生

5-4-2 MNISTの学習で、Keras形式のMNIST学習モデルを生成するスクリプトを実施したところ、Illegal instruction(core dumped)エラーが発生しました。どうもTensorflowをimportするところでエラーが発生しているっぽいんだけど、ググってみたら、以下のような情報を発見。


確かに、うちのPCのCPU Core-i7 3770だから、、、ダメっぽいですね。というか、もうこんなんどうしようもないやん、、、はい、PCを新調して解決しました。

注: TensorFlow 1.6 以降、バイナリは AVX 命令を使用するので、古い CPU では動作しないことがあります。

罠3: Petalinuxのバージョン間違えた

実行環境のところに、2020.1 (2019.2)と書いたんですが、最初あまり考えず、元からインストールしてあった2019.2を使用していました。まあ、自分の思慮不足、不注意と言ってしまえば、それまでなんですが、ちょっとバージョンが違っただけでここまで挙動変わるのは・・・初心者には結構つらい。まさかPetalinuxのバージョンが問題になっているとは気づかず、様々なトラブルシューティングをする羽目に陥っていました。

ライブラリ入ってない問題

DPUのバイナリ作成も完了し、VARTのサンプルプログラムと合わせて、Ultra96v2ボードにコピーしてしてみたところ、複数のライブラリが入ってないというエラーが発生。下記は無理やり適当なバイナリをscpでもってきてrpmでインストールしてみたが、バージョンが古く動かなかった時のログ。

root@ultra96v2_base:~/MNIST# ./MNIST dpu_mnist_0.elf 
./MNIST: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.26' not found (required by /usr/lib/libxir.so.1)

dnf使えない問題

不足しているライブラリをインストールするために、dnfコマンドを使おうとしたが、リポジトリが登録されておらず使えない。どこのリポジトリをどうやって登録すればいいんだ??とハマったあげく、Xilinxから提供されている?リポジトリを登録したら、何とかライブラリをインストールできるように。

root@ultra96v2_base:/etc/yum.repos.d# dnf -v repolist
DNF version: 2.7.5
cachedir: /var/cache/dnf/aarch64/thud
petalinux_v2020.3-generic                                                      1.9 MB/s | 3.6 MB     00:01    
not found deltainfo for: petalinux_v2020.3-generic
not found updateinfo for: petalinux_v2020.3-generic
Xilinx-v2020.3: using metadata from Fri Apr  2 22:24:00 2021.
Last metadata expiration check: 0:00:05 ago on Fri Mar 18 16:58:24 2022.

Repo-id      : Xilinx-v2020.3
Repo-name    : petalinux_v2020.3-generic
Repo-revision: 1617402240
Repo-updated : Fri Apr  2 22:24:00 2021
Repo-pkgs    : 10215
Repo-size    : 3.7 G
Repo-baseurl : http://petalinux.xilinx.com/sswreleases/rel-v2020.3/generic/rpm/aarch64/
Repo-expire  : 172800 second(s) (last: Fri Mar 18 16:58:24 2022)
Repo-filename: /etc/yum.repos.d/CentOS-Base.repo
Total packages: 10215

DPUから応答がない問題

ようやくライブラリのインストールが終わって、VARTサンプルプログラムを実行したところ、execute_asyncした後、DPUから応答がない。エラーログでググっても、それらしい解決方法も見当たらないし、結構お手上げでした。ただ、この辺で、そもそもなんでライブラリのインストールが必要だったんだ?書籍ではそんな手順の記載はなかったし、どこかで何かの手順に問題があったんじゃ?と思い、改めて見直したところ、書籍ではpetalinux 2020.1を使用していることに気づく。もしかして、これが原因??と思い、petalinux 2020.1を入れて、改めてVitisプラットフォームの作成を行うことにしました。

root@ultra96v2_base:~/MNIST# ./MNIST dpu_mnist_0.elf 
WARNING: Logging before InitGoogleLogging() is written to STDERR
I0318 19:33:13.888545  2321 main.cc:195] create running for subgraph: mnist_0
out_dims : 1, 1, 1, 10
in_dims  : 1, 28, 28, 1
F0318 19:33:23.977075  2321 xrt_cu.cpp:165] Check failed: is_done cu timeout! core_idx 0  handle=0x55cd4e5760 ENV_PARAM(XLNX_DPU_TIMEOUT) 10000 state 1 ERT_CMD_STATE_COMPLETED 4 ms 10010  bo=4is_done 0 
*** Check failure stack trace: ***
Aborted
root@ultra96v2_base:~/MNIST#

罠4: U-Bootが正常に起動しない

petalinux 2020.1でVitisプラットフォームを再作成し、DPUを組み込むところまで終わって、ようやくUltra96v2に書き込んでみたところ、U-bootが正常に起動しませんでした。これだ!と考えた原因をつぶしこんでみたら、そもそもBootせず、状況がより悪化するという事態に、若干心が折れそうになったんですが・・・、全く同じ現象が発生し、解決方法まで書いてくれている方を発見(本当に助かりました)。
Bootパーティションに、boot.scrも追加でコピーしたら、正常に起動するようになりました。

  • BOOT.BIN
  • image.ub
  • dpu.xclbin
  • boot.scr <--これを追加

Release 2020.1   Mar 25 2022  -  16:03:34
NOTICE:  ATF running on XCZU3EG/silicon v4/RTL5.1 at 0xfffea000
NOTICE:  BL31: v2.2(release):xilinx_rebase_v2.2_2020.1
NOTICE:  BL31: Built : 15:43:28, Mar 25 2022


U-Boot 2020.01 (Mar 25 2022 - 15:59:59 +0000)

Model: Avnet Ultra96 Rev1
Board: Xilinx ZynqMP
DRAM:  2 GiB
PMUFW:  v1.1
EL Level:       EL2
Chip ID:        zu3eg
NAND:  0 MiB
MMC:   mmc@ff160000: 0, mmc@ff170000: 1
In:    serial@ff010000
Out:   serial@ff010000
Err:   serial@ff010000
Bootmode: SD_MODE
Reset reason:   EXTERNAL
Net:   No ethernet found.
Hit any key to stop autoboot:  0
switch to partitions #0, OK
mmc0 is current device
Scanning mmc 0:1...
## Executing script at 20000000
Wrong image format for "source" command
SCRIPT FAILED: continuing...
switch to partitions #0, OK
mmc0 is current device
Scanning mmc 0:1...
Card did not respond to voltage select!
Warning: SPI speed fallback to 100 kHz
unrecognized JEDEC id bytes: ff, ff, ff
Failed to initialize SPI flash at 0:0 (error -2)
SCRIPT FAILED: continuing...


no devices available
SCRIPT FAILED: continuing...
starting USB...
Bus dwc3@fe300000: Register 2000440 NbrPorts 2
Starting the controller
USB XHCI 1.00
scanning bus dwc3@fe300000 for devices... 4 USB Device(s) found
       scanning usb for storage devices... 0 Storage Device(s) found

Device 0: unknown device

Device 1: unknown device
scanning bus for devices...

Device 0: unknown device
No ethernet found.
missing environment variable: pxeuuid
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/00000000
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/0000000
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/000000
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/00000
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/0000
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/000
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/00
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/0
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/default-arm-zynqmp-zynqmp
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/default-arm-zynqmp
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/default-arm
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/default
No ethernet found.
Config file not found
No ethernet found.
No ethernet found.

MNISTの実行

罠4の回避後、MNISTが動作することをようやく確認できました。MNISTのサンプルを試してみるだけで、2~3週間かかったので、うまく動いたときの感動は、Google colabでのMNISTとは雲泥の差ですよ、良い意味でも悪い意味でも。
次は、YOLOv3を試してみようと思いますが、また新たな罠にハマらないことを願うばかりです。

root@ultra96v2_v2020_1:~/MNIST# ./MNIST dpu_mnist_0.elf 
WARNING: Logging before InitGoogleLogging() is written to STDERR
I0325 16:33:50.311563   741 main.cc:203] create running for subgraph: mnist_0
out_dims : 1, 1, 1, 10
in_dims  : 1, 28, 28, 1
Image : one_9819.jpg, label = 1
Image : five_6491.jpg, label = 5
Image : eight_9150.jpg, label = 8
Image : nine_9386.jpg, label = 9
Image : six_8240.jpg, label = 6
Image : two_1256.jpg, label = 2
Image : three_9925.jpg, label = 3
Image : zero_9095.jpg, label = 0
Image : four_8500.jpg, label = 4
Image : seven_9262.jpg, label = 7
Elapsed Time per frame: 532[us]
root@ultra96v2_v2020_1:~/MNIST#
2
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1