从 Android 11 开始,NNAPI 包含两个控制流操作(IF
和 WHILE
),它们使用其他模型作为参数,并有条件地执行这些运算 (IF
) 或重复执行这些运算 (WHILE
)。这样就可以构建模型,这些模型基于输入值执行不同的操作,或者在不展开的情况下多次执行操作。这在动态 RNN 和 seq2seq 等用例中非常重要。
在 NN HAL 1.3 中,该模型包含多个子图,包括用于指定执行的输入和输出的主子图。子图可以使用 SUBGRAPH
类型的运算数引用其他子图。只有当加速器支持该控制流运算引用的所有子图中的所有运算时,框架才能向加速器发送控制流运算。
HAL 接口
在 NN HAL 1.3 中,与控制流相关的定义位于 types.hal
中。
IF
和WHILE
运算类型SUBGRAPH
运算数类型和相应的SUBGRAPH
运算数生命周期- 包含主子图和引用子图列表的
Model
结构 - 包含
ifPerformance
和whilePerformance
的Capabilities
结构
IDevice.hal
包含 IDevice
,其方法 getSupportedOperations_1_3()
必须以与其他运算不同的方式处理 IF
和 WHILE
。
IPreparedModel.hal
包含 IPreparedModel
,其方法 execute_1_3()
、executeSynchronously_1_3()
和 executeFenced()
采用可选的 loopTimeoutDuration
参数。
驱动程序实现
如需查看运算实现示例,请参阅 CpuExecutor::executeIfOperation
和 CpuExecutor::executeWhileOperation
。
如需查看运算验证示例,请参阅 validateIfOperation()
和 validateWhileOperation()
。
请注意,支持对形状 1
的 TENSOR_INT32
运算数进行算术和比较运算,因为它们可以用作循环计数器。
同样,生成形状 1
的 TENSOR_BOOL8
运算数的运算应与 IF
和 WHILE
条件一起使用。
WHILE 循环执行超时
为了防止无限循环,如果 WHILE
循环花费的时间长于传递到 IPreparedModel::execute_1_3()
、IPreparedModel::executeSynchronously_1_3()
或 IPreparedModel::executeFenced()
的调用的 loopTimeoutDuration
值(如果省略,则为默认值),必须取消执行。
验证
控制流测试是 CTS 和 VTS 测试套件的一部分。如需了解详情,请参阅验证。