跳转到主要内容

AI 引擎系列 9 - 运行 AI 引擎的完整系统(第一部分)

<font color="#FF8000">作者:Florentw,AMD工程师;来源:AMD开发者社区</font>

<strong>简介</strong>

在先前 AI 引擎系列博文中,我们讲解了 AI 引擎域上的 AI 引擎应用。

但正如我们在 AI 引擎系列的第一部分中所见,要在 Versal™ 硬件上运行 AI 引擎应用,很可能需要将 3 个域结合在一起来使用:AI 引擎、处理器系统 (PS) 与可编程逻辑 (PL)。
<center><img src="https://cdn.eetrend.com/files/2024-02/wen_zhang_/100578156-334119-aiyin…; alt=""></center>

在本文中,我们将演示在这 3 个不同域上运行的完整系统示例。

<strong>要求</strong>

<span data-aura-rendered-by="75:715;a">以下教程要求您: </span>
<ul data-aura-rendered-by="75:715;a">
<li>对 AMD 工具有基本了解</li>
<li>具有 C/C++ 编程语言的基本知识</li>
<li>已安装 Vitis™ 2021.1 统一软件平台</li>
<li>拥有有效的 AI 引擎工具许可证</li>
<li>从 <a target="_blank" href="http://china.xilinx.com/">Xilinx.com</a&gt;(<a target="_blank" href="https://china.xilinx.com/support/download/index.html/content/xilinx/en/…;)或从 GitHub(<a target="_blank" href="https://github.com/Xilinx/Vitis_Embedded_Platform_Source/tree/master/Xi…;)下载的 VCK190 基础平台</li>
<li>通读前几篇 <a target="_blank" href="https://support.xilinx.com/s/blogs?language=zh_CN&amp;tabset-5e36f=2">AI 引擎系列博文</a></li>
</ul>

<strong>打开完整系统工程示例</strong>

<span data-aura-rendered-by="75:715;a">这是 Vitis IDE 中集成的完整系统工程示例。我们将使用 </span><a target="_blank" href="https://support.xilinx.com/s/article/000035592?language=zh_CN&amp;t=170…; data-aura-rendered-by="75:715;a">AI 引擎系列 1 一文</a> <span data-aura-rendered-by="75:715;a">中所述步骤将其打开。</span>

1) 打开 Vitis 2021.1 统一软件平台 IDE,选择工作空间存储库。

2) 在“Welcome”(欢迎)页面上,单击“Create Application Project”(创建应用工程),如果未显示“Welcome”页面,请单击“File > New > Application Project”(文件 > 新建 > 应用工程)

3) 在显示的“Welcome”页面上,单击“Next”(下一步)。

4) 在平台选择页面上,选择 xilinx_vck190_base_202020_1 平台,然后单击“Next”。
注意:如果该页面中未列出名为 xilinx_vck190_base_202020_1 的平台,请确保您已从 GitHub 或 Xilinx.com 下载该平台

5) 使用“Add”(添加)按钮添加该仓库。

6) 创建名为 full_system_app 的新应用,该应用将在 ai_engine 上运行,然后单击“Next”:
<center><img src="https://cdn.eetrend.com/files/2024-02/wen_zhang_/100578156-334120-aiyin…; alt=""></center>

7) 在“Domain”(域)页面上,单击“Next”。
在“Templates”(模板)页面上,选择“AI Engine, PL and PS System Design”(AI 引擎、PL 和 PS 系统设计):
<center><img src="https://cdn.eetrend.com/files/2024-02/wen_zhang_/100578156-334121-aiyin…; alt=""></center>

<strong>分析模板系统</strong>
在“Explorer”(资源管理器)窗口中,可以看到创建的 full_system_app_system 工程包含 4 个子目录:
full_system_app_aie [aiengine]:这是将在 AI 引擎域上运行的应用。
full_system_app_kernels:该目录包含 RTL 内核,这些内核将在 PL 中执行,用于将 PL 域连接到 AI 引擎域。请注意,在其他系统中,RTL 内核也可能完全独立于 AI 引擎。
full_system_app_system_hw_link:该目录将包含最终系统,其中所有域都连接在一起
full_system_app [xrt]:这是 PS 上运行的应用。
<center><img src="https://cdn.eetrend.com/files/2024-02/wen_zhang_/100578156-334123-aiyin…; alt=""></center>

<strong>RTL 内核</strong>
展开 full_system_app_kernels 目录,并打开 full_system_app_kernels.prj。
<center><img src="https://cdn.eetrend.com/files/2024-02/wen_zhang_/100578156-334124-aiyin…; alt=""></center>

在“Hardware Functions”(硬件函数)部分中可见,该工程包含 3 个 RTL 内核。MM2S(存储器映射到串流)和 S2MM(串流到存储器映射)都属于 Data Mover IP,将用于为 AI 引擎馈送源自 DDR 存储器的数据。polar_clip 内核是处理内核,将接收来自 AI 引擎的数据,处理后将其发回给 AI 引擎。

我们利用现有信息即可开始绘制系统视图,如下所示:
<center><img src="https://cdn.eetrend.com/files/2024-02/wen_zhang_/100578156-334125-aiyin…; alt=""></center>

<strong>AI 引擎应用</strong>
现在来看看 AI 引擎应用中的 AI 引擎计算图 (graph)。打开 full_system_app_aie/src 下的 graph.h 文件
<center><img src="https://cdn.eetrend.com/files/2024-02/wen_zhang_/100578156-334126-aiyin…; alt=""></center>

在 graph.h 文件中,可以看到此计算图包含 2 个内核:interpolator 和 classify。

interpolator = kernel::create(fir_27t_sym_hb_2i);
classify = kernel::create(classifier);

这些内核与计算图端口之间的连接定义如下:

<a target="_blank" href="http://graph.in/">graph.in</a&gt; -&gt; interpolator -&gt; graph.clip_in → graph.clip_out -&gt; classify -&gt; graph.out

<pre data-aura-rendered-by="75:715;a">connect&lt; window&lt;INTERPOLATOR27_INPUT_BLOCK_SIZE, INTERPOLATOR27_INPUT_MARGIN&gt; &gt;(in, <a rel="noopener" target="_blank" href="http://interpolator.in/">interpolator.in</a>[0]); connect&lt; window&lt;POLAR_CLIP_INPUT_BLOCK_SIZE&gt;, stream &gt;(interpolator.out[0], clip_in); connect&lt; stream &gt;(clip_out, <a rel="noopener" target="_blank" href="http://classify.in/">classify.in</a>[0]); connect&lt; window&lt;CLASSIFIER_OUTPUT_BLOCK_SIZE&gt; &gt;(classify.out[0], out);</pre>

打开 graph.cpp 文件。在该文件顶部有 4 个 PLIO(要连接到 PL 的 I/O),分别名为 in0、out0、pl_to_ai_source 和 ai_to_pl_sink,这些 PLIO 均已定义、已添加到平台并已连接到该计算图。

<pre data-aura-rendered-by="75:715;a">PLIO *in0 = new PLIO(&quot;DataIn1&quot;, adf::plio_32_bits,&quot;data/input.txt&quot;); PLIO *out0 = new PLIO(&quot;DataOut1&quot;,adf::plio_32_bits, &quot;data/output.txt&quot;); PLIO *pl_to_ai_source = new PLIO(&quot;polar_clip_in&quot;,adf::plio_32_bits, &quot;data/input1.txt&quot;); PLIO *ai_to_pl_sink = new PLIO(&quot;polar_clip_out&quot;, adf::plio_32_bits,&quot;data/output1.txt&quot;); simulation::platform&lt;2,2&gt; platform(in0,pl_to_ai_source, out0,ai_to_pl_sink); clipped clipgraph; connect&lt;&gt; net0(platform.src[0], <a rel="noopener" target="_blank" href="http://clipgraph.in/">clipgraph.in</a&gt;); connect&lt;&gt; net1(clipgraph.clip_in,platform.sink[1]); connect&lt;&gt; net2(platform.src[1],clipgraph.clip_out); connect&lt;&gt; net3(clipgraph.out, platform.sink[0]);</pre>

我们利用此新信息即可更新系统视图,如下所示:
<center><img src="https://cdn.eetrend.com/files/2024-02/wen_zhang_/100578156-334127-aiyin…; alt=""></center>

但在 MM2S、S2MM 和 polar_clip PL 内核与 AI 引擎之间缺少连接。此连接是在硬件链接应用中通过 v++ 来建立的。

<strong>硬件链接应用</strong>
v++ 硬件链接应用用于将各域(主要是 AIE 与 PL)连接在一起。只需观察传递给 v++ 的选项即可检查将要建立的连接。

在“Assistant”(助手)视图中,右键单击 full_system_app_system/full_system_app_hw_link/Emulation-HW 下的 binary_container_1,然后单击下列设置:
<center><img src="https://cdn.eetrend.com/files/2024-02/wen_zhang_/100578156-334128-aiyin…; alt=""></center>

在“Binary Container Settings”(二进制容器设置)中,查看 v++ 配置设置:
<center><img src="https://cdn.eetrend.com/files/2024-02/wen_zhang_/100578156-334129-aiyin…; alt=""></center>

这将打开以下窗口以显示 v++ 配置设置:
<center><img src="https://cdn.eetrend.com/files/2024-02/wen_zhang_/100578156-334130-aiyin…; alt=""></center>

从中可见,已指定下列连接选项:

[connectivity]
stream_connect=mm2s_1.s:ai_engine_0.DataIn1
stream_connect=ai_engine_0.DataOut1:s2mm_1.s

根据<a target="_blank" href="https://docs.xilinx.com/r/zh-CN/ug1076-ai-engine-environment/%E9%85%8D%…;《AI 引擎工具和流程用户指南》(UG1076)</a> 所述,计算单元(或内核实例)的命名约定是 &lt;kernel&gt;_#,其中 # 表示 CU 实例。

因此,对应于该工程内的内核 mm2s、s2mm 和 polar_clip 的 CU 名称分别是 mm2s_1、s2mm_1 和 polar_clip_1(使用 Vitis GUI 时,CU 的第一个实例始终是 <kernel>_1,第二个实例是 <kernel>_2,以此类推)。stream_connect 选项定义为 <compute_unit_name>.<kernel_interface_name>:<compute_unit_name>.<kernel_interface_name>。

例如,在此工程中,要将 mm2s_1(计算单元名称)的名为 s(内核接口名称)的 AXI4-Stream 接口连接到 ai_engine_0(计算单元名称)IP 中计算图的 DataIn1(接口名称)输入,所使用的选项如下:

stream_connect=mm2s.s:ai_engine_0.DataIn1.

这样即可完成系统视图,如下所示:
<center><img src="https://cdn.eetrend.com/files/2024-02/wen_zhang_/100578156-334131-aiyin…; alt=""></center>

<strong>后续步骤</strong>
在下一篇博文中,我们将构建系统、分析部分生成的输出,并在硬件仿真中运行。