LoginSignup
9
5

More than 5 years have passed since last update.

Ultra96でTVMのVTAを動かしてみる

Posted at

一時的なメモです。masterにmergeされてPYNQ v2.4に対応したりすると手順が変わると思います。

準備

ホストPCのOSはUbuntu 16.04です。XilinxのSDSoC 2018.2, PetaLinux 2018.2をインストールします。Ultra96にはPYNQのimage_v2.3を用います。

Ultra96-PYNQのビルド

Ultra96-PYNQを自分でビルドする」に沿ってUltra96-PYNQのimage_v2.3をビルドします。文中のv2.4をv2.3に読み替えて下さい。途中、sensors96b.bspの作成が必要です。image_v2.3のREADME.mdUltra96 BSPの作成方法の通り実行します。

一通りビルドが完了したら、BOOT.BINを作り直します。Ultra96用のVTAは、AXI HPCでキャッシュコヒーレンシ転送をする前提になっており、Broadcasting Inner Shareableの設定をブート時にする必要があります。次のregs.initファイルを作成し、PYNQ/sdbuild/Makefileを変更します。

regs.init
.set. 0xFF41A040 = 0x3;
PYNQ/sdbuild/Makefile
 $$(BOOT_ROOT_$1)/BOOT.BIN : $$(BOOT_DEPENDS_$1) $$(BOOT_BITSTREAM_$1) | $$(BOOT_ROOT_$1)
-       cd $$(BOOT_ROOT_$1) && petalinux-package --boot --fpga $$(BITSTREAM_ABS_$1) --u-boot -p $$(PL_PROJ_$1) --force
+       cd $$(BOOT_ROOT_$1) && petalinux-package --boot --fpga $$(BITSTREAM_ABS_$1) --u-boot -p $$(PL_PROJ_$1) --force --bif-attribute init --bif-attribute-value /path/to/regs.init
        cp -f $$(PL_PROJ_$1)/images/linux/BOOT.BIN $$(BOOT_ROOT_$1)

 $$(BOOT_ROOT_$1)/image.ub : $$(BUILD_ROOT_$1)/image.its $$(BUILD_ROOT_$1)/system.dtb $$(BUILD_ROOT_$1)/$$(KERNEL_$$(ARCH_$1)) | $$(BOOT_ROOT_$1)

BOOT.BINを更新します。

$ make output/boot/Ultra96/BOOT.BIN BOARDDIR=/path/to/Ultra96-PYNQ

できたBOOT.BINをSDカードに上書きし、Ultra96を起動します。

参考:Outer Share を Inner Share にする裏技?

Ultra96用TVMの取得

開発者のThierry MoreauさんがforkしているtvmのリポジトリをホストPCにcloneします。

$ git clone --recursive https://github.com/tmoreau89/tvm.git

ブランチvta_devをチェックアウトし、ビルド用のディレクトリにconfig.cmakeをコピーします。

$ git checkout vta_dev
$ mkdir build
$ cp cmake/config.cmake build

build/config.cmake中のset(USE_LLVM OFF)set(USE_LLVM ON)に変更します。

build/config.cmake
 # - ON: enable llvm with cmake's find search
 # - OFF: disbale llvm
 # - /path/to/llvm-config: enable specific LLVM when multiple llvm-dev is available.
-set(USE_LLVM OFF)
+set(USE_LLVM ON)

 #---------------------------------------------
 # Contrib libraries

LLVM 4.0をインストールします。

sudo apt install llvm-4.0

ビルドします。

$ cd build
$ cmake ..
$ make -j4

Pythonスクリプトの実行に必要なライブラリをインストールします。

$ pip install --user numpy decorator attrs

Ultra96用VTAのbitstream作成

$ cp vta/config/ultra96_sample.json vta_config.json

として、Ultra96用の設定を使います。このconfigではVivado HLSのシミュレーションが通りませんので、vta/hardware/xilinx/Makefileを次のように変更してsimをスキップします。

vta/hardware/xilinx/Makefile
 HSI = hsi

 # HLS mode
-MODE = all
+MODE = skip_sim
 # Debug flag
 DEBUG = False
 # SLURM

bitstreamを作成します。Xilinxのツールにパスを通しておきます。

$ source /opt/sdsoc.2018.2/Vivado/2018.2/settings64.sh
$ cd vta/hardware/xilinx
$ make

bitstreamは、vta/build/hardware/xilinx/vivado/ultra96_1x16x16_a8w8o8s32_15_15_18_17_333MHz_2ns_gii1_aii2/export/vta.bitにできます。

Ultra96実機でのコンパイル

Ultra96実機でruntimeをコンパイルします。VTA Installation Guideの通りです。

ホストPC
$ mkdir <mountpoint>
$ sshfs xilinx@192.168.3.1:/home/xilinx <mountpoint>
$ cd <mountpoint>
$ git clone --recursive https://github.com/tmoreau89/tvm.git
$ cd ~
$ sudo umount <mountpoint>
$ ssh xilinx@192.168.3.1
Ultra96
% cd /home/xilinx/tvm
% git checkout -f vta_dev
% mkdir build
% cp cmake/config.cmake build/
% cp vta/config/ultra96_sample.json build/vta_config.json
% cd build
% cmake ..
% make runtime vta -j2

RPCサーバを起動します。

Ultra96
% cd /home/xilinx/tvm
% sudo ./apps/pynq_rpc/start_rpc_server.sh # pw is 'xilinx'
INFO:RPCServer:bind to 0.0.0.0:9091

実行

ホストPCからbitstreamを転送します。vta/tests/python/pynq/test_program_rpc.pyの中でビットストリームを直接指定します。

vta/tests/python/pynq/test_program_rpc.py
-program_rpc_bitstream()
+program_rpc_bitstream("/path/to/tvm/vta/build/hardware/xilinx/vivado/ultra96_1x16x16_a8w8o8s32_15_15_18_17_333MHz_2ns_gii1_aii2/export/vta.bit")
 reconfig_rpc_runtime()

環境変数を設定します。

ホストPC
$ export TVM_HOME=/path/to/tvm
$ export PYTHONPATH=$TVM_HOME/vta/python:$TVM_HOME/python:$TVM_HOME/topi/python:$TVM_HOME/nnvm/python
$ export VTA_ULTRA96_RPC_HOST=192.168.3.1
$ export VTA_ULTRA96_RPC_PORT=9091

実行します。

ホストPC
$ python <tvm root>/vta/tests/python/pynq/test_program_rpc.py

準備完了です。2D convolutionのテストベンチを実行します。

ホストPC
$ python <tvm root>/vta/tests/python/integration/test_benchmark_topi_conv2d.py
('resnet-18.C2', Conv2DWorkload(batch=1, height=56, width=56, in_filter=64, out_filter=64, hkernel=3, wkernel=3, hpad=1, wpad=1, hstride=1, wstride=1))
VTA TEST PASSED: Time cost = 0.00229248 sec/op, 100.856 GOPS
('resnet-18.C4', Conv2DWorkload(batch=1, height=56, width=56, in_filter=64, out_filter=128, hkernel=3, wkernel=3, hpad=1, wpad=1, hstride=2, wstride=2))
VTA TEST PASSED: Time cost = 0.00102993 sec/op, 112.246 GOPS
('resnet-18.C5', Conv2DWorkload(batch=1, height=56, width=56, in_filter=64, out_filter=128, hkernel=1, wkernel=1, hpad=0, wpad=0, hstride=2, wstride=2))
VTA TEST PASSED: Time cost = 0.000634823 sec/op, 20.2341 GOPS
('resnet-18.C6', Conv2DWorkload(batch=1, height=28, width=28, in_filter=128, out_filter=128, hkernel=3, wkernel=3, hpad=1, wpad=1, hstride=1, wstride=1))
VTA TEST PASSED: Time cost = 0.00198324 sec/op, 116.583 GOPS
('resnet-18.C7', Conv2DWorkload(batch=1, height=28, width=28, in_filter=128, out_filter=256, hkernel=3, wkernel=3, hpad=1, wpad=1, hstride=2, wstride=2))
VTA TEST PASSED: Time cost = 0.0011103 sec/op, 104.121 GOPS
('resnet-18.C8', Conv2DWorkload(batch=1, height=28, width=28, in_filter=128, out_filter=256, hkernel=1, wkernel=1, hpad=0, wpad=0, hstride=2, wstride=2))
VTA TEST PASSED: Time cost = 0.000512048 sec/op, 25.0856 GOPS
('resnet-18.C9', Conv2DWorkload(batch=1, height=14, width=14, in_filter=256, out_filter=256, hkernel=3, wkernel=3, hpad=1, wpad=1, hstride=1, wstride=1))
VTA TEST PASSED: Time cost = 0.0016426 sec/op, 140.759 GOPS
('resnet-18.C10', Conv2DWorkload(batch=1, height=14, width=14, in_filter=256, out_filter=512, hkernel=3, wkernel=3, hpad=1, wpad=1, hstride=2, wstride=2))
VTA TEST PASSED: Time cost = 0.00101667 sec/op, 113.71 GOPS
('resnet-18.C11', Conv2DWorkload(batch=1, height=14, width=14, in_filter=256, out_filter=512, hkernel=1, wkernel=1, hpad=0, wpad=0, hstride=2, wstride=2))
VTA TEST PASSED: Time cost = 0.000585341 sec/op, 21.9446 GOPS
('resnet-18.C12', Conv2DWorkload(batch=1, height=7, width=7, in_filter=512, out_filter=512, hkernel=3, wkernel=3, hpad=1, wpad=1, hstride=1, wstride=1))
VTA TEST PASSED: Time cost = 0.00174309 sec/op, 132.644 GOPS
9
5
0

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
9
5