本文转载自:<span id="profileBt"><a href="https://mp.weixin.qq.com/s/VcdQs88AqPUVb_wTqnb0qA"> 硬码农二毛哥微信公众号</a></span>
<strong>Vitis AI 设计流程</strong>
Vitis AI 和Vitis IDE需要下面三个基本步骤:
<center><img src="http://xilinx.eetrend.com/files/2021-09/%E5%8D%9A%E5%AE%A2/100553321-21…; alt=""></center>
<li>构建模型</li>
<li>构建硬件平台</li>
<li>构建可执行软件</li>
Vitis AI Runtime:使用C++或Python写应用程序
导入Vitis AI Library,运行编译好的模型文件。
<strong>Runtime Overview</strong>
Vitis AI开发套件提供high-leve C++/Python APIs(VART)进行从云到边器件开发。对于边缘DPU,除了VART,还可以使用advanced low-level C++/Python APIs。
<li>VART APIs</li>
VART(Vitis AI Runtime),high-level
<li>Advanced APIs</li>
advanced low-level APIs源于DNNDK(Deep Neural Network Development Kit )
<strong>Programming Model</strong>
理解DPU programming model,需要先明白DPU Kernel,DPU Task,DPU Node和DPU Tensor。
<li>DPU Kernel</li>
通过Vitis AI compiler编译生成的ELF文件就是DPU Kernel,使用dpuLoadKernel() 导入DPU Kernel。
<li>DPU Task</li>
通过dpuCreateTask() 为DPU Kerne创建任务。
<li>DPU Node</li>
DPU Node是网络模型中的基本单元,包含三种类型,boundary input node, boundary output node, and internal node。
boundary input node:the first node in a kernel
boundary output node:the last node in a kernel
internal node:other nodes
通过VAI_C编译后,可获取Input node和output node名字。
<li>DPU Tensor</li>
DPU Tensor是用来存储信息的多维数据集合,Tensor弹性包含height, width, channel等。
通常图片存储格式CHW(ChannelHeightWidth )。
DPU存储输入输出Tensor格式HWC(HeightWidthChannel )。
<strong>VAI_C</strong>
Once the compilaton is successful, VAI_C will generate ELF object fles and kernel informaton for deployment
运行docker
<pre>./docker_un.sh xilinx/vitis-ai:1.2.82</pre>
activate TensorFlow tool conda environment
<pre>conda activate vitis-ai-tensorflow</pre>
运行dlet,从HWH中解析DPU配置参数
<pre>$ dlet -f ./system.hwh
[DLet]Generate DPU DCF file dpu-06-18-2020-12-00.dcf successfully.</pre>
打开arch.json,确保dcf参数与生成DCF文件名一致
<center><img src="http://xilinx.eetrend.com/files/2021-09/%E5%8D%9A%E5%AE%A2/100553321-21…; alt=""></center>
下载resnet-50
<pre>./download_model.sh</pre>
tf_resnetv1_50_imagenet_224_224_6.97G:
tf:Tensorflow
resnetv1_50:神经网络
imagenet:数据集
224_224:输入数据大小
6.97G:处理器计算能力
使用VAI_C编译网络模型
<pre>./custom_platform_compile.sh</pre>
DPU Nodes name
<img src="http://xilinx.eetrend.com/files/2021-09/%E5%8D%9A%E5%AE%A2/100553321-21…; alt="">
将生成的.elf文件拷贝到vitis工程中
deactivate TensorFlow tool conda environment
<pre>conda deactivate</pre>
退出docker
<pre>exit</pre>
<strong>Advanced APIs开发步骤</strong>
1. dpuOpen() 打开DPU
2. kernelResnet50 = dpuLoadKernel(KRENEL_RESNET50) 导入DPU kernel Resnet50
3. taskResnet50 = dpuCreateTask(kernelResnet50, 0) 创建任务
4. runResnet50(taskResnet50) 运行任务
5. dpuDestroyTask(taskResnet50) 销毁任务
6. dpuDestroyKernel(kernelResnet50) 销毁DPU kernel,释放资源
7. dpuClose() 关闭DPU
第4步runResnet50为自定义函数,函数中调用API dpuRunTask() 运行DPU任务。
<strong>runResnet50</strong>
ListImages()
<center><img src="http://xilinx.eetrend.com/files/2021-09/%E5%8D%9A%E5%AE%A2/100553321-21…; alt=""></center>
该函数输入为待预测图片路径path,将path路径内图片文件名存储到vector输出。
<li>判断path是否是有效的目录</li>
<li>打开目录</li>
<li>读取每一条目录</li>
<li>判断文件类型是否为图片</li>
<li>将图片名存入vector</li>
<li>关闭目录</li>
<li>对图片进行排序</li>
LoadWords()
<img src="http://xilinx.eetrend.com/files/2021-09/%E5%8D%9A%E5%AE%A2/100553321-21…; alt="">
<li>打开指定路径文件words.txt</li>
<li>读取文档中每行数据,将数据写入vector</li>
dpuGetOutputTensorAddress():获取输出Tensor地址
dpuGetOutputTensorSize():获取输出Tensor size(Byte)
dpuGetOutputTensorChannel():获取输出Tensor channel,分类的种类
dpuGetOutputTensorScale():获取输出Tensor scale value
dpuSetInputImage2():将图片送到DPU,caffe 模块使用
dpuRunTask():运行DPU任务
dpuGetTaskProfile():获取DPU任务执行时间
dpuRunSoftmax():输入包括进入softmax数据地址、分类种类、scale,输出分类结果。
TopK():
<center><img src="http://xilinx.eetrend.com/files/2021-09/%E5%8D%9A%E5%AE%A2/100553321-21…; alt=""></center>
输入d为softmax的结果,输出顺序与标签顺序一致。size为分类的种类,k指定输出分类结果个数,vkinds为标签数据。该函数显示概率最高的前k个预测结果。