前一篇文章手把手教你在FPGA上移植NVDLA+Tengine并且跑通任意神经网络(2)
已经说明了如何在ZYNQ上移植操作系统并且将跟文件系统替换为ubuntu16.04。到这里NVDLA的硬件和软件平台都已经搭建好了。这篇博客将带着大家在嵌入式平台上编译NVDLA/SW+Tengine。并且运行demo网络。然后笔者会从自己用pytorch搭建的网络模型开始,模型转换量化,并且用NVDLA后端调度。
Tengine-Lite 目前只支持一种 opendla 的集成编译方法,即编译opendla的软件支持,首先生成.so文件,而在Tengine编译opendla后端的时候进行链接。所以下面要获取两个仓库的代码。
git clone https://github.com/LeiWang1999/ZYNQ-NVDLA
git clone https://github.com/OAID/Tengine.git Tengine
如何加载驱动看前一篇文章手把手教你在FPGA上移植NVDLA+Tengine并且跑通任意神经网络(2)
insmod /lib/modules/4.19.0-xilinx-v2019.1/extra/opendla.ko
使用dmesg查看内核日志:
$ dmesg | tail
[ 12.817877] macb ff0e0000.ethernet eth0: link up (1000/Full)
[ 12.817900] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
[ 20.661453] opendla: loading out-of-tree module taints kernel.
[ 20.664248] Probe NVDLA config nvidia,nv_small
[ 20.669152] 0 . 12 . 5
[ 20.669155] reset engine done
[ 20.671257] [drm] Initialized nvdla 0.0.0 20171017 for a0000000.NV_nvdla_wrapper on minor 1
查看是否注册了nvdla的中断以及nvdla驱动所需的设备renderD128是否存在来确定是否真的安装完成驱动了:
root@arm:~# insmod /lib/modules/4.19.0-xilinx-v2019.1/extra/opendla.ko
root@arm:~# cat /proc/interrupts | grep nvdla
45: 0 0 GIC-0 61 Level 40000000.NV_nvdla_wrapper
root@arm:~# ls /dev/dri/
card0 renderD128
如果是嵌入式板块aarch64架构,跳过该步骤即可,直接使用NVDLA/SW仓库里的libjpeg.a.否则需要在板子上自己编译。
$ wget http://www.ijg.org/files/jpegsrc.v6b.tar.gz
$ tar -xzvf jpegsrc.v6b.tar.gz
$ cd jpeg-6b/
$ ./configure
$ make -j `nproc`
$ make install
$ cp /usr/local/lib/libjpeg.a ~/ZYNQ-NVDLA/umd/external/
编译时一定要加入-fpic选项,否则在编译NVDLA/SW会报错使用-fPIC选项编译出protobuf静态库libprotobuf.a
$ cd ~/ZYNQ-NVDLA/umd/external/protobuf-2.6/
$ apt-get install -y autoconf automake libtool
$ autoscan & aclocal & autoconf
$ automake --add-missing
$ ./configure CFLAGS="-fPIC" CXXFLAGS="-fPIC"
$ make -j `nproc`
$ make install
$ cp /usr/local/lib/libprotobuf.a ~/ZYNQ-NVDLA/umd/apps/compiler/
$ cp /usr/local/lib/libprotobuf.a ~/ZYNQ-NVDLA/umd/core/src/compiler/
将编译好的动态库文件导入Tengine工程中。
$ cd ~/ZYNQ-NVDLA/umd/
$ make -j `nproc` TOP=${PWD} TOOLCHAIN_PREFIX=/usr/bin/ compiler
$ make -j `nproc` TOP=${PWD} TOOLCHAIN_PREFIX=/usr/bin/ runtime
$ cp ~/ZYNQ-NVDLA/include -r ~/Tengine/source/device/opendla
$ cp ~/ZYNQ-NVDLA/umd/out/core/src/compiler/libnvdla_compiler/libnvdla_compiler.so -r ~/Tengine/source/device/opendla/lib/
$ cp ~/ZYNQ-NVDLA/umd/out/core/src/runtime/libnvdla_runtime/libnvdla_runtime.so -r ~/Tengine/source/device/opendla/lib/
$ cp /usr/local/lib/libprotobuf.a ~/Tengine/source/device/opendla/lib/
直接编译源码会遇到编译器预分配的内存过大的问题。
修改odla_executor.cc文件676行
nvfla compiler会默认分配0.25G的global ram 和 1G的 local ram在zcu102上内存较大,但在zynq7000上内存较小需要把这个值改小,修改的大小必须是2的幂。
$ cd ~/Tengine
$ mkdir build & cd build
$ cmake .. -DTENGINE_ENABLE_OPENDLA=ON
$ cmake --build . --target tm_classification_opendla
在Tengine 的model zoo中下载模型文件和测试图片。
$ cd examples
$ ./tm_classification_opendla -m /root/Tengine/models/resnet18-cifar10-nosoftmax-relu_int8.tmfile -i /root/Tengine/images/cat.jpg -g 32,32 -s 1,1,1
Mean value not specified, use default 104.0, 116.7, 122.7
tengine-lite library version: 1.4-dev
NVDLA time: 0.012502 seconds
model file : /root/Tengine/models/resnet18-cifar10-nosoftmax-relu_int8.tmfile
image file : /root/Tengine/images/cat.jpg
img_h, img_w, scale[3], mean[3] : 32 32 , 1.000 1.000 1.000, 104.0 116.7 122.7
Repeat 1 times, thread 1, avg time 12.62 ms, max_time 12.62 ms, min_time 12.62 ms
--------------------------------------
10.087049, 3
3.833079, 2
3.026115, 5
2.420892, 4
-0.403482, 0
--------------------------------------