制御フロー

Android 11 以降、NNAPI には 2 つのえ制御フロー オペレーション(IFWHILE)が追加されました。これは他のモデルを引数に取り、それらのモデルを条件付きで実行(IF)、または反復実行(WHILE)します。これにより、入力値に基づいて異なるオペレーションを実行するモデルや、展開することなくオペレーションを複数回実行するモデルを構築できます。これは、動的 RNN や seq2seq などのユースケースに重要です。

NN HAL 1.3 では、実行の入力と出力の指定に使用するメイン サブグラフなど、複数のサブグラフがモデルに組み込まれています。サブグラフは、SUBGRAPH 型のオペランドを使用して、他のサブグラフを参照できます。フレームワークは、その制御フロー オペレーションで参照されるすべてのサブグラフ内のすべてのオペレーションをアクセラレータがサポートしている場合にのみ、そのアクセラレータに制御フロー オペレーションを送信できます。

HAL インターフェース

NN HAL 1.3 では、制御フローに関連する定義は types.hal にあります。

IDevice.hal には IDevice が含まれ、そのメソッド getSupportedOperations_1_3()IFWHILE を他のオペレーションとは異なる方法で処理する必要があります。

IPreparedModel.hal には IPreparedModel が含まれ、そのメソッド execute_1_3()executeSynchronously_1_3()executeFenced() はオプションの loopTimeoutDuration 引数を取ります。

ドライバの実装

サンプル オペレーションの実装については、CpuExecutor::executeIfOperationCpuExecutor::executeWhileOperation をご参照ください。サンプル オペレーションの検証ロジックについては、validateIfOperation()validateWhileOperation() をご参照ください。

形状 1TENSOR_INT32 オペランドについては、ループカウンタとして使用できることから、算術演算と比較演算をサポートすることが重要です。同様に、形状 1TENSOR_BOOL8 オペランドを生成する演算では、IF 条件および WHILE 条件を併用する必要があります。

WHILE ループ実行のタイムアウト

無限ループを回避するため、IPreparedModel::execute_1_3()IPreparedModel::executeSynchronously_1_3()、または IPreparedModel::executeFenced() の呼び出しに渡された loopTimeoutDuration 値(省略された場合はデフォルト値)よりも WHILE ループに長い時間を要する場合は、実行を中止する必要があります。

検証

制御フローテストは、CTS と VTS のテストスイートの一部です。詳細は、検証でご確認いただけます。