Vitis支持向量机(SVM)加速的探索
执行摘要
本报告讨论采用Vitis™集成式软件平台作为嵌入式应用在赛灵思Zynq® UltraScale+™FPGA上加速以C代码编写的SVM(支持向量机)所需的步骤。
支持向量机是一种用途广泛的分类算法,通过将线性回归“核化”,能够对非线性决策边界进行建模。

本项目的第一阶段使用SVMLIB [Chang, Lin],随后进行修改,采用Vitis工具通过OpenCL API调用进行加速。
项目概览
本项目的初步目标在于熟悉如何使用Vitis工具加速C/C++应用/库的流程。选用SVM库的原因在于其算法数学强度高,便于将内核在后续项目中用于Versal ACAP器件中的AIE引擎。此外,本项目的长期目标是调查如何将SVM作为QAM调制加速算法,以RFSoC开发板为目标平台,延续Robert W Stewart的研究工作继续推进[Stewart 等人.]
如欲了解更详细的SVM相关介绍,请见本文参考材料部分的[Gandhi]。
本项目采用Ultra96开发板测试SVM算法的软件和加速版本。

工具流程
创建嵌入式加速应用涉及多个步骤,每一步之间都彼此关联,而且每一步也存在自身的规则和限制。以下列出关键的阶段、子阶段以及所需的工具。
平台生成
- FPGA/IPI 创建 :: Vivado
- Petalinx/Linux Linux生成 (SYSROOT) :: Petalinux
- 加速平台生成:: Vitis
应用编译/剖析
- 编译源代码用于嵌入式ARM处理器 :: GCC/Vitis
应用加速/内核开发
- 过HLS/OpenCL剖析修改指定的C/C++代码
- 在FPGA结构中实现内核 (Vitis/HLS/Vivado)
验证/测试
- 在嵌入式硬件上运行加速应用
- 剖析并与原始性能进行比较

剖析
我使用了运行Ubuntu 16.0.4.6的虚拟机进行剖析,如果运行原生Linux的,本报告中的某些说明或许并不适用。如您运行原生Linux,请忽略VM共享文件夹内复制文件的步骤。
设置Ultra96:
构建Ultra96平台
- 从Vitis wiki下载ultra96_base平台到Linux(原生或虚拟机).
- 解压缩tar -xzvf ultra96_base.tar.gz
- Cd ultra96_base
- Make
- 构建完成后:
- Cd images/linux/
- ./sdk.sh
- 该步骤用于构建linux镜像的sysroot。Sysroot包括许多库,有的是本应用所需要的。
- Sysroot生成后,复制repo到Windows/VM共享文件夹(如果sysroot生成脚本由于路径不完全匹配而造成最后一次复制失败,也可执行这一步)
- 在VM中启动Vitis工具。
- 创建新的工作空间
- 选择File->new-> Vitis application project
- 在提示选择平台时,找到包含ultra96平台(ultra96.xpfm)的工作空间文件夹并点击确定。
- 现在待选平台列表中应具有Ultra96平台,选中它。
- 设置sysroot路径为/repo_base/sysroot/sysroots/aarch64-xilinx-linux
- 右键点击应用项目并选择导入源
- 找到复制或克隆SVM源的目录并导入以下:
- svm_predict_values.cpp
- svm.cpp
- svm.h
- svm-predict.cpp
- xcl2.cpp
- xcl2.hpp
- heart_scale
- heart_scale.model
- svm.def
- 找到复制或克隆SVM源的目录并导入以下:
- 在Vitis GUI中设置构建配置为“system”。
- 在项目浏览器中双击svm_predict.sdx项目
- 这会在GUI中央部分打开面板,可在此进行项目配置。
- 可通过面板中的一个图标添加二进制容器。
- 一旦二进制容器添加进Vitis环境,就会扫描项目,查看是否存在可加速功能。一旦出现svm_predict_values功能,请即选中它。
- 点击锤子图标构建项目(这会花一些时间)
- 完成后,从项目复制sd_card文件夹的内容到micro SD卡上。
- 从/workspace/<svm_project_name>/System文件夹复制binary_container_1.xclbin(名称可能有差异),并从/src目录复制heart_scale和heart_scale.model到SD卡上。
- 将USB Ultra96板插入,连接JTAG/Serial适配器卡到Ultra96板边缘引脚接头,并通过USB线连接PC(添加到Avnet USB/serial板的链接)
- 确保Ultra96启动模式设为SD卡模式(SW2)
- 插入带有启动镜像的micro SD卡
- 用SW3按钮打开Ultra96板。
- 在Vitis GUI SDX终端面板中,点击+图标为Ultra96板添加串行终端。选择一个可用的串行端口,检查其状态消息是否显示在终端上(本演示中为USB1)。
- 串行端口设置应为:波特率115200,8位,1停止位,无奇偶校验,无流量控制。
- 用试错法确定使用哪个USB/串行端口。Ultra96会定期向活动端口打印状态消息。
- 一旦Ultra96启动,请连接其WiFi广播的SSID。这样便能够ping主机(Ultra96)。
- 这一步非常必要,因为我们正在使用的剖析工具(TCF)需要以太网连接才能通讯。
- 您可从Vitis工具终端进行以下步骤,也可以使用任何SSH终端(我用的是Putty)。
- 通过SSH登入主机,用户名为root,密码为root。
- 从/media/card/目录复制heart_scale、heart_scale.model和binary_container_1.xclbin文件到/mnt/目录
- 这一步会将必要的文件移动到TCF(目标通讯框架)代理执行的文件夹中。TCF代理生成本教程随后使用的剖析报告,以评估程序每个子例程的执行时间。
- 在目标连接面板中,双击TCF代理->Linux代理
- 修改IP地址为Ultra96主机IP地址(可能为192.168.2.1,但也可能有差异)。
- 使用测试连接按钮确认是否成功连接到TCF代理。
- 在Vitis GUI中,右键点击应用项目并选择debug as->launch on hardware (system debugger)。在提示信息处点击确认并切换到调试视图。
- 在Vitis GUI中,进入window->show view->debug并选择TCF剖析工具选项。这样便可以进行剖析和堆栈跟踪。
- 源代码面板打开后,滚动到面板底部,在返回0行处设置断点,这可避免程序在完成后退出并终止TCF代理。
- 在TCF剖析工具面板中选择开始按钮。
- 勾选“enable stack tracing”
- 在GUI顶部的图标栏选择重启按钮(F8)
- 一旦程序开始运行,您会看到功能执行剖析,如下所示:
在第12-c步中,我们添加svm_predict功能到待加速的二进制容器中。为了提供剖析比较,该项目的构建并未加速svm_predict功能。未加速测试结果见图4。

图5给出了svm_predict映射到硬件加速的软件绘图。可以看到,加速功能事实上比非加速版所耗用的执行时间更长。

目标硬件未必总能实现所期望的加速结果,这来自多种原因,最常见的原因包括:
- 数据移动没有优化
- 更大的数据突发能够提高工具优化硬件的能力。小规模事务的握手和延迟会降低数据移动效率。
- 算法不适合优化
- 某些算法更适用于硬件加速,比方说大型并行数学/向量运算和专用流水线逻辑等。
- 加速效果有限的算法需要频繁占用执行流水线并从存储器获取新的数据。
- 未使用或未有效使用工具编译指令来定义接口、数据移动和加速目标。
本教程涵盖简单硬件加速案例中的剖析,在有关示例中并没有实施优化。后续将进一步介绍如何优化SVM库代码的细节,以实现硬件加速。
挑战和经验教训
我们在设计流程几乎各个阶段都能学到新的技能和方法。
在开发周期早期阶段,我们显然会意识到脚本或基于Make的构建进程对可重复性和迭代进程加速非常重要。因此,我们针对平台创建、Petalinux构建和Vitis软件平台编译生成了一系列构建脚本和Makefiles。
一旦将SVM代码移植到A53s,那么下一步就是明确哪部分算法能较为轻松地在PL(可编程逻辑)中加速。为核隔离出代码的方式相对直观,但由于Vitis软件平台对可用C/C++代码的某些限制,需要对代码进行大幅度修改。这些限制包括需要移除mallocs并修改结构,进而去除嵌入式指针。完成上述工作后,在加速内核之前的最后一步就是修改代码,以适应OpenCL框架的要求。OpenCL框架要求属于一项较为关键的经验教训。数据移动和存储器分配需要在设计进程中提前规划,这样才能实现最大限度的加速。
本项目最后一个挑战就是明确为什么加速内核返回的结果与非加速内核不同。加速器的低层次调试属于一大难点,因为软件代码与硬件波形图及接口的关联并不明显。为调试解决上述差异性问题,我们插入了预处理器指令,禁用OpenCL结构,并通过g++运行尽可能多的代码,这样就能用相同的Makefiles构建加速和非加速版本,从而进一步减少两个版本之间的差异。经过分析,我们能对C++代码进行修正,并从加速内核得到正确的值。
后续步骤
下一步即将开展的工作就是加速大部分算法,实现更大幅度的加速。完成这一步之后,需要进一步探索如何让SVM算法适用于QPSK波形,并将设计移植到ZCU111 RFSoC板上。此外,我们也希望分析在Versal中使用AIE的优势,这对Versal系列器件中的DSP应用来说也是一项要求。
结论
Vitis环境为加速PL和AIE中的应用提供了后续发展的良好平台。Vitis软件平台的脚本化特性为嵌入式系统加速提供了有力的补充,也非常适合成体系的软件开发环境要求。内核调试虽存在一定难度,但Vitis Analysis工具可大幅降低工作负担。
嵌入式加速是一项复杂的工作,需要深入掌握软硬件之间的互动,但优势在于能大幅提升性能和吞吐量。项目初期工作完成后,我们清楚地看到,Vitis软件平台是应对上述挑战的有效工具。
参考文献
[Chang, Lin] Chih-Chung Chang and Chih-Jen Lin, LIBSVM : a library for support vector machines. ACM Transactions on Intelligent Systems and Technology, 2:27:1--27:27, 2011. Software available at http://www.csie.ntu.edu.tw/~cjlin/libsvm
[Stewart et al.] Software Defined Radio with RFSoC & PYNQ: https://www.xilinx.com/support/documentation/university/XDF_2018/XDF_2018_Posters_ALL%2033.pdf
[Gandhi] Support Vector Machine – Introduction to Machine Learning Algorithms: https://towardsdatascience.com/support-vector-machine-introduction-to-machine-learning-algorithms-934a444fca47