10. graph 控制 API 介绍
本章介绍了可用于初始化、运行、更新和控制外部控制器中图形执行的控制API。本章还描述了如何在输入图规范中指定运行时参数(RTP),这些参数影响内核中的数据处理,并同步或异步地更改整个图的控制流。
图形执行控制
在配备AI引擎的AMD Versal™自适应SoC中,处理系统(PS)可用于动态加载、监控和控制在AI引擎阵列上执行的图形。即使AI Engine图形作为单个比特流图像加载一次,PS程序也可以用于监视执行状态并修改图形的运行时参数。图形基类提供了许多API方法来控制可在主程序中使用的图形的初始化和执行。用于模拟图形的用户主应用程序不支持argc、argv参数。
基本的迭代图执行
下面的图形控件API显示了如何使用图形API来初始化、运行、等待和终止特定迭代次数的图形。图对象mygraph使用一个名为simpleGraph的预定义图类声明。然后,在主应用程序中,这个图形对象被初始化并运行。init()方法将图形加载到AI Engine数组中预先指定的AI Engine tiles处。这包括为每个AI引擎加载ELF二进制文件,为路由配置流交换机,以及为I/O配置DMA。它使处理器处于禁用状态。run()方法通过启用处理器来启动图形执行。在运行API中,通过在运行时提供正整数参数,可以运行特定数量的图形迭代。此表单对于调试图形执行非常有用。
API wait()用于在开始第二次运行之前等待第一次运行完成。wait具有与end相同的阻塞效果,除了它允许再次重新运行图形而不必重新初始化它。在没有中间等待的情况下连续调用run来完成该运行可能具有不可预测的效果,因为run API修改了图形的活动处理器的循环边界。
图迭代
一个图可以有多个内核、输入和输出端口。图连通性,相当于数据流图中的网络,在内核之间,内核和输入端口之间,或者内核和输出端口之间,并且可以配置为连接。当图消耗等于图中的内核所期望的缓冲区或数据流的数据样本,并且产生等于图中的所有内核的输出处所期望的缓冲区或数据流的数据样本时,图运行迭代。
图的有限执行
对于有限图形执行,图形状态在graph.run(n)上维护。在graph.run(n)之后,AI引擎未重新初始化,内存内容未清除。在下面的代码示例中,在第一次运行三次调用之后,AI Engine main()包装器代码处于内核将在下一次运行(十次迭代)中从pong缓冲区开始的状态。乒乓缓冲区选择器状态保持不变。graph.end()不清理图状态(具体地说,不重新初始化全局变量),也不清理流交换机配置。它只不过是从主干道出来的。要重新运行图形,必须重新加载PDI/ XCLBIN。
无限图形执行
下面的图形控件API展示了如何无限地运行图形。
图对象mygraph使用一个名为simpleGraph的预定义图类声明。然后,在主应用程序中,这个图形对象被初始化并运行。init()方法将图形加载到AI Engine数组中预先指定的AI Engine tiles处。这包括为每个AI引擎加载ELF二进制文件,为路由配置流交换机,以及为I/O配置DMA。它使处理器处于禁用状态。run()方法通过启用处理器来启动图形执行。这个图永远运行,因为要运行的迭代次数没有提供给run()方法。graph::run()without an argument运行AI Engine内核之前指定的迭代次数(如果图形在没有任何参数的情况下运行,则默认为无穷大)。如果图是以有限的迭代次数运行的,例如,mygraph.run(3);mygraph.run(),第二个run调用也会运行三次迭代。使用graph::run(-1)无限运行图形,而不考虑上一次运行迭代设置。
并行图执行
在以前的API方法中,只有wait()和end()方法是阻塞操作,可以无限期地阻塞主应用程序。因此,如果在顶层声明多个图,则需要适当地交错API以并行执行图,如图所示。
注意:每个图应该在初始化(init)之后才启动(运行)。此外,为了获得并行执行,所有的图必须在等待终止(结束)之前开始(运行)。
定时执行
在多速率图中,所有内核不需要执行相同次数的迭代。在这种情况下,定时执行模型更适合于测试。等待和结束API有一些变体,它们使用指定周期超时的正整数。这是API调用在禁用处理器并返回之前阻止的AI引擎周期数。阻塞条件不依赖于任何图形终止事件.在超时到期时,图形可以处于任意状态。
注意:API resume()用于从第一次超时后停止的点恢复执行。恢复只会重置计时器并启用AI引擎。在AI引擎执行已经终止后调用恢复没有任何效果。
产品参数规格
到目前为止所示的数据流图完全是静态定义的。但是,在真实的情况下,您可能需要根据某些动态条件或事件修改图形的行为。所需的修改可以在正在处理的数据中,例如修改的操作模式或新的系数表,或者它可以在图的控制流中,例如条件执行或用另一个图动态地重新配置图。在这种情况下,RTP参数是有用的。无论是内核还是图形都可以被定义为使用参数执行。还提供了其他图形API,以便在图形运行时更新或读取这些参数值。
支持两种类型的运行时参数。第一个是异步或粘性参数,它可以在任何时候由控制处理器,如处理系统(PS)改变。完成更新后,每次调用内核时都会读取它们。这些类型的参数可以用作不频繁改变的滤波器系数。
同步或触发参数是另一种受支持的运行时参数。需要触发参数的内核在控制处理器写入这些参数之前不会执行。在写操作时,内核执行一次,阅读新的更新值。完成后,内核被阻止执行,直到参数再次更新。这允许与正常流模型不同类型的执行模型,这对于阻塞同步很重要的某些更新操作可能很有用。参数可以是标量值,也可以是数组值。graph.update()API用于RTP更新。
测试数据参数
参数推断
如果整数标量值出现在内核函数的形式参数中,则该参数将成为运行时参数。在下面的示例中,参数select和result_out是运行时参数。
缓存参数作为端口与流和缓冲区创建的端口一起处理。标量和标量数据类型数组都可以作为运行时参数传递。支持的有效标量数据类型为int8、int16、int32、int64、uint8、uint16、uint32、uint64、cint16、cint32、float。
注意:结构和指针不能作为运行时参数传递。每个AI引擎都有不同的内存空间,指针在AI引擎之间传递时具有不一致的含义。此外,PS和AI引擎具有不同的指针表示。由于结构可以包含指针作为成员,因此不支持将结构作为运行时参数传递。
在下面的示例中,将一个包含32个整数的数组作为参数传递给filter_with_array_param函数。
隐式端口是为函数参数中的每个参数推断的,包括数组参数。下表描述了为每个函数参数推断的端口类型。
从该表中可以看出,当AI Engine无法对函数参数进行外部可见的更改时,将推断输入端口。当以传值方式传递型式参数时,会建立复本,因此对该复本所做的变更不会在外部可见。当参数以const限定词传递时,无法写入参数,因此这些也会被视为输入连接埠。
当向AI引擎内核传递参数引用并且AI引擎内核能够修改该参数引用时,推断出输入输出端口,并且该输入输出端口可用于允许从控制处理器读回结果。
注意:inout端口是内核本身可以读取或写入的端口。但是,从图中可以看出,inout端口只能用作输出端口。因此,inout端口只能由graph::read()读取。无法通过graph::update()更新输入输出端口。
注意事项:如果一个内核想要接受一个输入运行时参数,修改它的值,并通过一个输出运行时参数传回这个修改后的值,那么这个变量必须在arg列表中出现两次,一次作为输入,一次作为输入,例如kernel_function(int32 foo_in,int32 & foo_out)。
参数连接
输入和inout运行时参数端口都可以连接到其封闭图中的相应分层端口。这是公开参数以供运行时修改的机制。在下图中,创建了之前定义的simple_param内核的实例。这个内核有两个输入端口,一个输出端口和一个inout端口。参数列表中出现的第一个参数(在[0]中)是一个输入缓冲区。第二个参数是输出缓冲区。第三个参数是一个运行时参数(它不是缓冲区或流类型),在[1]中被推断为输入参数,因为它是按值传递的。第四个参数是运行时参数,被推断为inout参数inout [0],因为它是通过引用传递的。
注意:内核的不同端口类型in、out和inout属于它们自己的类别,并且都从图中的索引0开始。在下面的图形定义中,一个simple_param内核被实例化,缓冲区被连接到in [0]和out [0](内核的输入和输出缓冲区)。输入运行时参数连接到图形输入端口select_value,inout运行时参数连接到图形inout端口result_out。
一个数组参数可以用同样的方式挂起。编译器会自动为数组数据分配空间,这样就可以从映射内核的处理器访问数组数据。
输入参数同步
输入运行时参数端口的默认行为是触发行为。这意味着该参数在确定内核何时可以执行的规则中起着一定的作用。在这个图形示例中,内核仅在满足三个条件时执行:
·有32字节的输入数据的有效缓冲区可用
·有32字节的输出数据的空缓冲区可用
·对输入参数的写入发生
在触发模式下,对输入参数的单次写入允许内核执行一次,在每个单独的内核调用上设置输入参数值。还有一种替代模式允许异步设置输入内核参数。若要指定参数异步更新,请在连接端口时使用ADCC修饰符。
当内核端口被指定为异步端口时,它将不再在内核的触发规则中扮演角色。当参数写入一次时,会在后续的触发中观察到该值。在任何时候,PS都可以为运行时间参数写入新值。在下一次和任何后续内核触发时都会观察到该值。
Inout参数同步
inout运行时参数端口的默认行为是异步行为。这意味着控制处理器或另一个内核可以读回该参数,但生产者内核执行不受影响。对于从inout参数开始的同步行为,内核会阻塞,直到每次调用内核时读取参数值,您可以在将inout端口连接到封闭图时使用sync修饰符,如下所示。
文章来源:威视锐科技