AI 引擎系列 3 - AI 引擎内核简介

简介

 
AI 引擎系列的上一篇博文 中,我们认识了 AI 引擎应用的顶层计算图 (graph) 文件。从中我们了解了如何使用此计算图文件来例化内核、将内核连接在一起以及将内核连接到 AI 引擎阵列端口。

在本篇博文中,我们将聊聊内核。在所使用的模板中,有 2 个内核(分别名为 first second)用于实现相同的函数,该函数名为 simple


 


 AI 引擎系列 3 - AI 引擎内核简介_第1张图片


要求


下文要求您已通读 AI 引擎系列 1  AI 引擎系列 2 

AI 引擎内核简介

 
每个 AI 引擎内核都是 1 个使用专用内部调用编写的 C/C++ 程序,专用于处理 VLIW 矢量处理器。AI 引擎内核代码是使用 AI 引擎编译器 (aiecompiler) 编译的,此编译器包含在 Vitis™ 核开发套件内。AI 引擎编译器通过编译内核来生成 1 ELF 文件并在 1 AI 引擎上运行该文件。

多个内核可在单个 AI 引擎上运行,但单个内核无法在多个 AI 引擎上运行。您负责将其函数分区为多个内核,以供在多个 AI 引擎上运行。

打开位于 src/kernels 下的 kernels.cc 文件:


AI 引擎系列 3 - AI 引擎内核简介_第2张图片



我们可以看到其中已添加 adf 数据流库头文件 (adf.h),就像计算图文件中一样。其中包含的另一个头文件 include.h 用于为内核定义参数。在此例中,仅定义了样本数 NUM_SAMPLES,定义的值为 32
在第 6 行,可以看到内核函数的原型:

void simple(input_window_cint16 * in, output_window_cint16 * out) 
 
  

首先,请注意该函数并未返回任何值(返回空值)。所有内核都须满足此要求。
然后可以看到该内核函数含 2 个参数
 

  • 第一个调入的函数是输入窗口接口,其中含 16 位复数样本 (input_window_cint16)。这意味着每个输入样本都是 1 32 位码字(16 位表示实数部分,16 位表示虚数部分)。
  • 第二个调出的函数是输出窗口接口,其中含 16 位复数样本 (output_window_cint16)


8 行到第 13 行用于保存内核的处理循环:

for (unsigned i=0; i
  window_readincr(in, c1);
  c2.real = c1.real+c1.imag;
  c2.imag = c1.real-c1.imag;
  window_writeincr(out, c2);
}
 
  

每次循环迭代都耗用 1 个存储在变量 c1 中的 16 位复数输入样本(使用 window_readincr),并生成 1 个取自变量 c2 16 位复数输出样本(使用 window_writeincr)。

输出样本的值包含实数部分和虚数部分,其中实数部分是输入样本的实数部分和虚数部分之和,虚数部分则是输入样本的实数部分和虚数部分之差。

值得注意的是,此操作不使用 AIE 内部函数(专用于处理矢量处理器的函数),因此仅在标量单元上运行,并且不会利用矢量处理单元。有此导致生成的内核无法达成 AI 引擎的最佳性能。

由于循环具有 32 次迭代,每次迭代耗用 1 32 位样本(16 位复数样本)并生成 1 32 位样本,因此内核需要 128 字节 (32*32/8) 的输入窗口和 128 字节的输出窗口。在前文中提到过,该值是在计算图中设置的,用于连接内核。
 

connect< window<128> > net0 (in, first.in[0]);
connect< window<128> > net1 (first.out[0], second.in[0]);
connect< window<128> > net2 (second.out[0], out);
 
  
 
  

数据访问机制
 
源自此处所示模板的内核当前正在使用窗口来访问数据。AIE 内核还有一种可用的访问类型,即串流访问。
 

 

基于窗口的访问

 
当内核使用基于窗口的访问时,它会直接读取当前运行的 AI 引擎的本地存储器或某个相邻 AI 引擎的本地存储器。

仅当输入窗口已满时,才会在 AI 引擎中加载内核。这意味着内核的首次调用在填充输入窗口时将存在初始时延。但由于存储器可用作为乒乓缓冲器,内核执行期间下一组数据可以写入存储器中,并准备就绪以供下一次迭代使用。
 

基于串流的访问

 
当内核使用基于串流的访问时,它会直接读取 AXI-Stream 接口。在此情况下,内核会按逐个样本来读取数据。

使用串流时,如果下游内核无法快速处理数据,就可能对上游内核产生反压,但如果上游内核生成数据的速度不够快,那么也可能造成下游内核中出现停滞。

 

下一步

 
在本系列的前 3 篇博文中,我们探讨了 AI 引擎应用的不同文件。在下一篇博文中,我们将以 x86 为目标运行 AI 引擎编译器,然后运行 x86 仿真器。

你可能感兴趣的:(Vitis,AI,引擎系列,Vitis,Vitis,AI,AMD,人工智能)