以前のVitis-AI v1.4 on Ultra96v2ではAvnetが用意してくれているスクリプトを使用してVitisプラットフォームを作成し、XilinxのDPU-TRDプロジェクトを使用してDPUの動作環境を生成しました。
今回は前回記事のBuild Vitis platform for Ultra96v2 (Vitis 2020.2)で作成したVitis Platformを使用して、DPUとvector addカーネルを動作させてみたいと思います。
以前のVitis-AI v1.4 on Ultra96v2記事ではXilinxが公開しているDPU-TRDのCUIフローをベースにDPUが動作する環境を構築しましたが、HWシステムの構築ではvitisに含まれるv++を直接実行しており、GUIで開けるVitisのプロジェクトは作成されていませんでした。CUIベースで新しくカーネルを追加したり、HWシステムの設定を変更するのは難しいと感じたため、GUIフローで作業を行なってみようと思います。
本記事はXilinxのDPU-TRD GUI Flowをベースにしています。DPUを追加するところは全く同じです。
また、DPUと他のHWカーネルを同時に実装することができるかも同時に試します。今回追加するカーネルはvadd(vector add)で、Vitis HLS向けの高位合成チュートリアルでも使用されている単純なカーネルです。
Environment
- Host: Ubuntu 18.04
- Target: Ultra96v2
- Vitis/Vivado/Petalinux 2020.2
Vitis-AIをダウンロードしておきます。DPU IPやDPUを使用するVitisライブラリ、DPUを実行するためのランタイムが含まれています。
git clone https://github.com/Xilinx/Vitis-AI
cd Vitis-AI
git checkout refs/tags/v1.4
前回記事のUltra96向けVitisプラットフォームが作成されていることを前提にしています。
Vitisプロジェクト
プロジェクトの作成
Vitisを起動します。
mkdir dpu_vitis_prj && cd dpu_vitis_prj
source /tools/Xilinx/Vitis/2020.2/settings64.sh
vitis
Window->Preferences->Library Repositoriesに、Vitis-AIリポジトリののdsa/DPU-TRD
ディレクトリを追加します。
File->New->Application Project
からプロジェクトを作成します。ベースとなるプラットフォームは前回記事で作成したプラットフォームを選択します。
テンプレートの選択画面ではDPU Kernel
を選択します。
プロジェクトが作成されました。
DPUコンフィグレーションの変更
Explorerウインドウのdpu_trd_kernelsからsrc->prj->Vitis->dpu_conf.vhを開いてDPUのコンフィグレーションを変更します。
26c26
< `define B1600
---
> `define B4096
81c81
< `define RAM_USAGE_HIGH
---
> `define RAM_USAGE_LOW
103c103
< `define DWCV_DISABLE
---
> `define DWCV_ENABLE
114c114
< `define POOL_AVG_DISABLE
---
> `define POOL_AVG_ENABLE
DPUのクロックとポートの設定
次にdpu_trd->src->config_gui.cfg
を開いてDPUに接続するクロックとポートの設定を変更します。今回ベースにしているプラットフォームプロジェクトのクロックは以下の通りで、150MHz/300MHzを利用したいので以下のように設定しました。また今回はDPUを1つだけ搭載するので元のポート情報の後半を削除しました。
【2022.03.16追記】
上記手法ではDPUのクロック指定が正しくできていません。
Vitis-AIのチュートリアルには以下のように書かれています。
The gui flow only support default configuration. if want to other configuration, please use commandline flow.
GUIFlowで一度ビルドすると、dpu_trd_hw_link/Hardware/dpu-link.cfg
というファイルが生成されます。このファイルの[clock], [connectivity]
を変更します。
[connectivity]
nk=DPUCZDX8G:1:DPUCZDX8G_1
[clock]
id=1:DPUCZDX8G_1.aclk
id=3:DPUCZDX8G_1.ap_clk_2
これでコマンドラインからmake
を実行し直すことでクロックが正しく設定されます。
Vector Addの追加
次に、独自カーネルのテストとしてvadd(vector_add)を追加するための作業を行います。
まず、File->New->Application Projectでアプリケーションプロジェクトを作成。名前はvaddとしました。このときSelect a system project
にdpu_trd_system
を選択することでDPUプロジェクトにvaddのカーネルとアプリケーションを追加できます。
アプリケーションテンプレートはVector Add
を選択します。
dpu_trd_system
というsystem projectの中にdpu, vadd
の2つのカーネル・2つのアプリケーションが存在する状態が確認できます。
Hardware Link Configの変更
最後にdpu_trd_system_hw_link.prjを開く。どのアクセラレーションカーネルをいくつ搭載するかの画面がある。
Active build configurationをHardwareに変更。
今回はsoftmaxコアは不要なのでsfm_xrt_topは削除、DPUCZDX8Gの個数を2個から1個に変更、さらに右上のイナズマアイコンのAdd Hardware Functionsからkrnl_vaddを追加した。
Vitisプロジェクトのビルド
Explorer
からdpu_trd_system
を選択し、全てのビルドを実行します。高位合成、Vivadoプロジェクトの自動作成、Vivado上での論理合成、配置配線、ビットストリーム生成、sysroot環境を使用したアプリケーションのクロスコンパイル等が全て自動的に実行されます。
生成されたVivadoブロックデザインを開いてみます。./dpu_trd_system_hw_link/Hardware/dpu.build/link/vivado/vpl/prj/prj.xpr
が生成されたVivadoプロジェクトです。先程設定したとおり、DPUとvaddコアが1つずつ搭載されているのが確認できます。
【2022.03.16追記】
ここではDPUのクロック指定が正しくできていません。 DPUに100/200MHzのクロックが設定されています。
ちなみに、dpuのアプリケーションのビルドは失敗してしまいました。DPUカーネルを作成するときにテンプレートから自動生成されたresnest50モデルを動作させるアプリケーションです。
おそらく前回記事でやったようにsysrootへのVARTインストールをVitisのプラットフォームを作成する前に行なっておく必要があるのだと思います。ただ、現時点ではVitisを使用しなくてもCUI上でsysrootを用いたクロスコンパイルが可能なので無視しています。Vitis上でもコンパイルしたいので、解決すれば追記します。
Create SD Card
Vitisにより生成されたSDカードイメージをSDに書き込みます。
find ./ | grep sd_card
./dpu_trd_system/Hardware/package/sd_card.img
./dpu_trd_system/Hardware/package/sd_card
./dpu_trd_system/Hardware/package/sd_card/boot.scr
./dpu_trd_system/Hardware/package/sd_card/dpu_trd
./dpu_trd_system/Hardware/package/sd_card/image.ub
./dpu_trd_system/Hardware/package/sd_card/vadd
./dpu_trd_system/Hardware/package/sd_card/system.dtb
./dpu_trd_system/Hardware/package/sd_card/BOOT.BIN
./dpu_trd_system/Hardware/package/sd_card/bl31.elf
./dpu_trd_system/Hardware/package/sd_card/pmufw.elf
./dpu_trd_system/Hardware/package/sd_card/u-boot.elf
./dpu_trd_system/Hardware/package/sd_card/fsbl.elf
./dpu_trd_system/Hardware/package/sd_card/dpu.xclbin
本当ならばsd_card.img
をSDに書き込むだけでブートに必要なファイルやrootfsが全て書き込まれるはずなのですが。。なぜかそれだけだとブートできなかったので、以下の方法でSDカードを作成しました。
cd ./dpu_trd_system/Hardware/package/
cp BOOT.BIN /media/lp6m/BOOT/
cp image.ub /media/lp6m/BOOT/
cp boot.scr /media/lp6m/BOOT/
rootfsはSWプラットフォームを作成したときのrootfs.tar.gz
を使用しました。
sudo tar xvf rootfs.tar.gz -C /media/lp6m/rootfs
アプリケーションとFPGAコンフィグレーションファイル、VART(Vitis-AI runtime)などをホームディレクトリにコピーします。
# vadd application
sudo cp vadd /media/lp6m/rootfs/home/root
# FPGA configuration file
sudo cp dpu.xclbin /media/lp6m/rootfs/home/root
# VART
cd <Vitis-AI repository dir>
sudo cp -r ./setup/mpsoc/VART /media/lp6m/rootfs/home/root
sync
以上でSDカードの作成は完了です。
動作確認
SDカードをUltra96に挿入、キーボード、USB-LAN、DP-HDMIアダプタ、電源つないで電源投入。実機の端末からifconfig
でIPアドレスを確認します。ユーザ名root, パスワードrootでssh接続が可能です。以降は実機上にssh接続して作業を行います。
まずVARTをインストールします。
root@u96v2-sbc-base-2020-2:~# cd VART/
root@u96v2-sbc-base-2020-2:~/VART# ./target_vart_setup_2020.2.sh
Verifying... ################################# [100%]
Preparing... ################################# [100%]
%prein(libunilog-1.4.0-r56.aarch64): scriptlet start
%prein(libunilog-1.4.0-r56.aarch64): execv(/bin/sh) pid 1347
%prein(libunilog-1.4.0-r56.aarch64): waitpid(1347) rc 1347 status 0
Updating / installing...
1:libunilog-1.4.0-r56 ################################# [100%]
%post(libunilog-1.4.0-r56.aarch64): scriptlet start
...
DPUの情報確認
root@u96v2-sbc-base-2020-2:~/VART# cd /home/root
root@u96v2-sbc-base-2020-2:~# cp dpu.xclbin /usr/lib/
root@u96v2-sbc-base-2020-2:~# dexplorer -w
[DPU IP Spec]
IP Timestamp : 2021-06-07 19:15:00
DPU Core Count : 1
[DPU Core Configuration List]
DPU Core : #0
DPU Enabled : Yes
DPU Arch : B1600
DPU Target Version : v1.4.1
DPU Freqency : 300 MHz
Ram Usage : High
DepthwiseConv : Disabled
DepthwiseConv+Relu6 : Disabled
Conv+Leakyrelu : Enabled
Conv+Relu6 : Enabled
Channel Augmentation : Enabled
Average Pool : Disabled
ちゃんとコンフィグしたとおりになっています。
vaddの動作確認
root@u96v2-sbc-base-2020-2:~# cd /home/root
root@u96v2-sbc-base-2020-2:~# ./vadd dpu.xclbin
Loading: 'dpu.xclbin'
TEST PASSED
vaddも動作しています!
まとめ
自分で作成したVitisプラットフォームを使用して、DPUと自分のカーネル(vadd)を搭載したシステムを構築することができました。
前回のVItisプラットフォームの作成(特にPetalinuxでwifiを使うための設定)で非常に時間がかかってしまいましたが、一度プラットフォームを作ってしまえばVitis上でシステムを構築するのはとても簡単に感じました。
— lp6m (@lp6m1) December 4, 2021