onnx-mlir

Logo

MLIRコンパイラインフラストラクチャにおけるONNXモデルの表現と参照ローワーリング

GitHubでプロジェクトを見る onnx/onnx-mlir

ハウツー

Pythonを使用した推論
C/C++を使用した推論
Javaを使用した推論

参考文献

ONNXダイアレクト
OMTensor C99ランタイムAPI
OMTensorList C99ランタイムAPI
OMTensor JavaランタイムAPI
OMTensorList JavaランタイムAPI
ONNXダイアレクトの生成
ドキュメントについて

開発

オペレーションの追加
テストガイドライン
エラー処理
コマンドラインオプション
インストルメンテーション
定数伝播
アクセラレータの追加

ツール

ツール

RunONNXModel.py
DocCheck

このプロジェクトはonnxによって保守されています。

GitHub Pagesでホスト — テーマはorderedlistによって提供されています。

テスト

onnx-mlirでは、実装の正確性を確保するために3種類のテストがあります。

  1. ONNXバックエンドテスト
  2. LLVM FileCheckテスト
  3. 数値テスト
  4. gdbの使用
  5. ONNXモデル動物園

ONNXバックエンドテスト

バックエンドテストは、onnxノードとモデルテストに基づいたonnx-mlirのエンドツーエンドテストです。C/C++の.soライブラリとJNIの.jarアーカイブの両方についてテストが可能です。各C/C++テストターゲットに対して-jniサフィックスを追加すると、対応するJNIテストターゲットが得られます。テストを実行するには、次のコマンドを使用します。

cmake --build . --config Release --target check-onnx-backend[-jni]

バックエンドテストを実行するには、third_party/onnxなどのパッケージをインストールする必要があります。独自のonnxパッケージをpip install your-onnx-mlir/third_party/onnxコマンドでインストールできます。JNIテストにはjsoniter jarが必要です。システム上にインストールされたバージョンが見つからない場合、デフォルトでMavenリポジトリからダウンロードされます。ONNX-MLIRをビルドする際にcmakeオプションONNX_MLIR_BUILD_JSONITERを有効にすると、jsoniter jarはGitHubリポジトリからクローンされたソースからローカルにビルドされます。jsoniter jarをローカルでビルドするには、Mavenビルドツールがインストールされている必要があります。

onnxパッケージによって提供されるすべてのテストケースは、test/backend/all_test_names.txtファイルにリストされています。check-onnx-backendは、それらのいくつかを選択的に実行します。check-onnx-backendによって実行されるonnxのノードとモデルテストは、test/backend/test.pyの変数test_to_enableによって定義されます。ユーザーは環境変数TEST_CASE_BY_USERを使用して1つのテストケースをテストできます。例えば、

TEST_CASE_BY_USER=selected_test_name cmake --build . --config Release --target check-onnx-backend[-jni]

TEST_CASE_BY_USERが指定されている場合、中間結果、.onnxファイル、.soファイルはデバッグのためにbuild/test/backendに保持されます。生成された共有ライブラリに特定の命令が含まれているかどうかを確認する必要がある場合は、環境変数TEST_INSTRUCTION_CHECKをtrueに設定し、テスト名の後に命令名を追加します(例:TEST_CASE_BY_USER=selected_test_name,instruction_name)。onnxテスト名にサフィックス_cpuを追加する必要があることに注意してください。

ONNXでサポートされているテストケース

ファイルtest/backend/all_test_names.txtには、ONNXパッケージによって提供されるすべてのテストケースが含まれています。test/backend/inference_backend.pyにテストケースを追加することで、テストケースを有効にできます。all_test_names.txtは「make check-onnx-backend-case」コマンドで自動的に生成されます。更新が必要となるのは、ONNXパッケージがアップグレードされた場合のみです。

ONNXでサポートされているテストケースを現在のバックエンドテストに追加する

演算子のONNXからKrnlへの変換が追加された場合、この演算子の対応するバックエンドテストをtest.pyに追加する必要があります。利用可能なテストケースはthird_party/onnx/onnx/backend/test/case/nodeにあります。新しいテストは、test/backend/all_test_names.txtで新しい演算子を探すことで特定できます。新しいテストを特定したら、test/backend/inference_backend.pyに新しいテストを追加できます。onnxテスト名にサフィックス_cpuを追加する必要があることに注意してください。テストに関連して、新しい演算子のテストの実行方法を定義できます。例えば

        "test_and2d_cpu": {STATIC_SHAPE:{}, DYNAMIC_SHAPE:{-1:{-1}}, CONSTANT_INPUT:{-1}},

は、テストtest_and2d_cpuを(1)静的形状で、(2)すべての入力を動的形状に強制して、(3)すべての入力を定義済み定数に強制して実行できることを示しています。これは、ほとんどの演算子に推奨される設定です。ただし、一部の演算子は特定の引数に対して動的形状を許容しません。このような場合は、関数のどの引数を動的形状にするかを明示的に決定できます。{-1:{-1}}式で指定します。test/backend/inference_backend.pyファイルには、どの引数や引数の次元を動的に設定するかを指定する方法に関する明確な指示が含まれています。

未知の次元を持つテスト

動的テンソルサイズでのテストは、チェッカーでも使用されている次のコマンドを使用することで最も簡単に実行できます。

cmake --build . --config Release --target check-onnx-backend-dynamic[-jni]

onnxノードテストは通常、入力テンソルに対して既知の次元サイズを持っています。そのため、未知の次元を持つテンソルをテストするために、モデルインポーター(Build/FrontendONNXTransformer.cpp)は、そのようなケースを生成する機能を提供します。環境変数IMPORTER_FORCE_DYNAMICが設定されている場合、フロントエンドインポートはモデルのすべての入力テンソルのすべての次元(デフォルト)を-1に変換します。例えば、

IMPORTER_FORCE_DYNAMIC='-1:-1' all dimensions of all the inputs will be changed
IMPORTER_FORCE_DYNAMIC='0:-1' all dimensions of the first input will be changed
IMPORTER_FORCE_DYNAMIC='0:-1|1:0,1' all dimensions of the first input and the 1st and 2nd dimensions of the second input will be changed

IMPORTER_FORCE_DYNAMICのBackus-Naur Form(BNF)は次のとおりです。

<ImportForceDynamicExpr> :== `'` <expr> `'`
                  <expr> ::= <inputString> | <inputString> `|` <expr>
            <inputString ::= <inputIndex> `:` <dimString>
             <dimString> ::= <dimIndex> | <dimIndex> `,` <dimString>
            <inputIndex> ::= <index>
              <dimIndex> ::= <index>
                 <index> ::= -1 | <number>
                <number> ::= <digit> | <digit><number>
                 <digit> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

-1は、セマンティックにすべての入力またはすべての次元を表し、最優先順位を持ちます。例:'0: -1, 0'は、最初の入力のすべての次元が変更されることを意味します。入力と次元のインデックスは0から始まります。

例えば、test_add_cpuのデフォルトモデルは

func @main_graph(%arg0: tensor<3x4x5xf32>, %arg1: tensor<3x4x5xf32>) -> tensor<3x4x5xf32>

IMPORTER_FORCE_DYNAMIC='-1:-1'の場合、結果は

func @main_graph(%arg0: tensor<?x?x?xf32>, %arg1: tensor<?x?x?xf32>) -> tensor<?x?x?xf32>

IMPORTER_FORCE_DYNAMIC='0:-1'の場合、結果は

func @main_graph(%arg0: tensor<?x?x?xf32>, %arg1: tensor<3x4x5xf32>) -> tensor<3x4x5xf32>

IMPORTER_FORCE_DYNAMIC='0:0,2|1:1'の場合、結果は

func @main_graph(%arg0: tensor<?x4x?xf32>, %arg1: tensor<3x?x5xf32>) -> tensor<3x4x5xf32>

これは、既存のノードテストを動的テンソルに使用する方法です。すべてのテストケースが動的テンソルでパスするわけではないため、test/backend/test.pyにはIMPORTER_FORCE_DYNAMICが定義されている場合にパスしないテストを指定するリストtest_not_for_dynamicがあります。

定数入力を持つテスト

onnxノードテストは実行時に入力テンソルを受け入れるため、onnxモデルのコンパイル時には入力が定数ではありません。しかし、実際には入力が定数になる場合があり、そのような状況をテストしたいと考えています。

定数入力でのテストは、チェッカーでも使用されている次のコマンドを使用することで最も簡単に実行できます。

cmake --build . --config Release --target check-onnx-backend-constant[-jni]

単一のonnxノード(例:test_add_cpu)をテストするには、TEST_CONSTANTIMPORTER_FORCE_CONSTANTの2つの環境変数を使用します(例:

TEST_CONSTANT=true IMPORTER_FORCE_CONSTANT="0" TEST_CASE_BY_USER=test_add_cpu make check-onnx-backend[-jni]

これにより、最初の入力(インデックス0)が定数になり、モデルの入力は2つから1つになります。

環境変数IMPORTER_FORCE_CONSTANTは、,で区切られたインデックスのリストです(0から開始、またはすべての入力インデックスの場合は-1)。例:0, 2, 3または-1

入力シグネチャテスト

チェッカーでも使用されている次のコマンドを使用して、さまざまなデータ型を持つonnxモデルの入力シグネチャをテストします。

cmake --build . --config Release --target check-onnx-backend-signature

SIMD命令の有効化

サポートされているプラットフォーム(現在s390xのみ)では、バックエンドテストはコンパイルされたモデルに対してSIMD命令を生成できます。SIMDを有効にするには、TEST_MCPU環境変数を設定します(例:

TEST_MCPU=z14 cmake --build . --config Release --target check-onnx-backend[-jni]

バックエンドテストの実行

utils/RunONNXLib.cppで定義されているツールは、TEST_CASE_BY_USER=selected_test_name make check-onnx-backendコマンドを使用して生成されたものなど、.soモデルからファイルを簡単に実行するために使用できます。 onnx-mlir/src/Compiler/CompilerUtils.cppファイルのoverridePreserveFiles値をKeepFilesOfType::Allなどに設定することで、他の方法でビルドされたモデルも保存できます。

onnxモデルがonnx-mlirでサポートされている現在のバージョンよりも古い場合、環境変数INVOKECONVERTERをtrueに設定してonnxバージョンコンバーターを呼び出すことができます。例えば、INVOKECONVERTER=true make check-onnx-backendでは、すべてのテストケースに対してコンバーターが呼び出されます。test.pyには、個々のケースでコンバーターを呼び出すためのtest_need_converterというリストがあります。

このツールは、モデルによって提供されるシグネチャを直接スキャンし、必要な入力をランダムな値で初期化してから、モデルに関数呼び出しを行います。このプログラムは、gdblldbvalgrindなどの他のツールと組み合わせて使用できます。ユーティリティオプションを一覧表示するには、実行時に-hまたは--helpフラグを使用するだけです。

まず、ツールのコンパイルを行う必要があります。これは2つのモードのいずれかで実行できます。最初のモードでは、ツールは静的にリンクされたモデルでコンパイルされます。このモードでは、.soファイルを含めることに加えて、コンパイル時に-D LOAD_MODEL_STATICALLY=0オプションが必要です。最適なのは、onnx-mlir/utilsディレクトリのbuild-run-onnx-lib.shスクリプトを使用して、モデルをパラメーターとして渡してツールをコンパイルすることです。Macでライブラリパスの問題を回避するには、モデルがビルドされたディレクトリでコンパイルされたツールを実行します。

# Compile tool with model.
cd onnx-mlir/build
sh ../utils/build-run-onnx-lib.sh test/backend/test_add/test_add.so
# Run the tool to run the model (substitute `Release` for `Debug` for the release version).
Debug/bin/run-onnx-lib
# or, on Mac, run the tool in the directory where the model was built
(cd test/backend; ../../Debug/bin/run-onnx-lib)
# if test_add.so was built in `test/backend`:
cd test/backend; ../../Debug/bin/onnx-mlir --EmitLib test_add/test_add.onnx

(Macではotool -L test_add.soでライブラリのパスを確認できます。)

2番目のモードでは、モデルなしでツールがコンパイルされます。これは実行時に渡されます。このオプションを有効にするには、-D LOAD_MODEL_STATICALLY=1オプションを使用してツールをコンパイルするだけです。上記と同じスクリプトを使用できますが、引数は必要ありません。このツールは、実行時にツールに.soモデルファイルを渡す限り、任意のディレクトリから実行できます。

# Compile tool without a model.
cd onnx-mlir/build
sh ../utils/build-run-onnx-lib.sh
# Run the tool with an argument pointing to the model.
Debug/bin/run-onnx-lib test/backend/test_add/test_add.so

LLVM FileCheckテスト

中間表現を入力として与え、LLVM FileCheckユーティリティを使用して出力IRをチェックすることで、1つのパスの機能をテストできます。例えば、シェイプ推論のテストケースtest.mlirがあります。

func @test_default_transpose(%arg0 : tensor<5x5x1x32xf32>) -> tensor<*xf32> {
  %0 = "onnx.Transpose"(%arg0) : (tensor<5x5x1x32xf32>) -> tensor<*xf32>
  "std.return"(%0) : (tensor<*xf32>) -> ()

このテストケースでシェイプ推論パスを実行すると、次の出力が得られます。

module  {
  func @test_default_transpose(%arg0: tensor<5x5x1x32xf32>) -> tensor<32x1x5x5xf32> {
    %0 = "onnx.Transpose"(%arg0) {perm = [3, 2, 1, 0]} : (tensor<5x5x1x32xf32>) -> tensor<32x1x5x5xf32>
    return %0 : tensor<32x1x5x5xf32>
  }
}

出力結果を手動で確認します。出力が正しい場合、将来自動的にチェックできるよう出力結果を対応させます。以下のコマンドを使用します。

Debug/bin/onnx-mlir-opt --shape-inference test.mlir | python ../utils/mlir2FileCheck.py 

以下の結果が得られます。

// mlir2FileCheck.py
// CHECK-LABEL:  func @test_default_transpose
// CHECK-SAME:   ([[PARAM_0_:%.+]]: tensor<5x5x1x32xf32>) -> tensor<32x1x5x5xf32> {
// CHECK:           [[VAR_0_:%.+]] = "onnx.Transpose"([[PARAM_0_]]) {perm = [3, 2, 1, 0]} : (tensor<5x5x1x32xf32>) -> tensor<32x1x5x5xf32>
// CHECK:           return [[VAR_0_]] : tensor<32x1x5x5xf32>
// CHECK:         }

ソースコードとチェックコードを結合し、適切なテストケースに追加します。ONNXダイアレクトのすべてのテストケースは、test/mlir/onnxディレクトリにまとめられています。これらのテストケースは、make check-onnx-litで実行できます。このターゲットはビルドの必須要件です。

数値テスト

ONNXパッケージが提供するテストに加えて、数値的な正確性をテストするために数値テストを使用します。目標は、広範な数値に基づいた単体テストを提供することです。これは、最適化変換が有効で正しいことを保証するために非常に重要です。特定のアーキテクチャパラメータ(ベクトル幅など)に合わせて専門化するにつれて、より多くのコーナーケースが発生します。数値テストは、テスト対象の演算の単純でナイーブな(そして非常に遅い)実装に基づいて、膨大な数の数値に基づいた単体テストを生成し、演算のローワーリングと最適化の正確性を検証するために使用されます。

数値テストは、以下の2つのコンポーネントが独立して分離されるように構成する必要があります。

テストケースパラメータを生成する方法は2つあります。

  // RapidCheck test case generation.
  bool success = rc::check("convolution implementation correctness", []() {
    const auto N = *rc::gen::inRange(1, 10);
    const auto C = *rc::gen::inRange(1, 20);
    const auto H = *rc::gen::inRange(5, 20);
    const auto W = *rc::gen::inRange(5, 20);

    const auto kH = *rc::gen::inRange(1, 15);
    const auto kW = *rc::gen::inRange(1, 15);

    // We don't want an entire window of padding.
    const auto pHBegin = *rc::gen::inRange(0, kH - 1);
    const auto pHEnd = *rc::gen::inRange(0, kH - 1);
    const auto pWBegin = *rc::gen::inRange(0, kW - 1);
    const auto pWEnd = *rc::gen::inRange(0, kW - 1);

    // Make sure we have at least 1 output per dimension.
    RC_PRE((H >= kH) && (W > kW));

    RC_ASSERT(isOMConvTheSameAsNaiveImplFor(
        N, C, H, W, kH, kW, pHBegin, pHEnd, pWBegin, pWEnd));
  });
  assert(success && "error while performing RapidCheck tests");

数値テストに関連付けられたMLIRファイルを確認することが便利な場合があります。そのためには、src/Compiler/CompilerUtils.cppoverridePreserveFiles変数を、保持するファイルの種類(例:KeepFilesOfType::All)に設定するのが最も簡単です。そうすれば、モデルのコンパイル方法に関係なく、入力および出力MLIRファイル、未最適化および最適化されたバイトコードファイル、およびいくつかの追加バイナリファイルが保持されます。

失敗した場合、RapidCheck(数値テストに使用されるインフラストラクチャ)とONNXモデルの両方により、ユーザーは同じ値でテストを再実行できます。テストを実行すると、次の出力が表示される場合があります。

Model will use the random number generator seed provided by "TEST_SEED=1440995966"
RapidCheck Matrix-Vector test case generation.
Using configuration: seed=4778673019411245358

以下の2つの環境変数にシード値を記録することにより

export RC_PARAMS="seed=4778673019411245358"
export TEST_SEED=1440995966

それぞれ、RapidCheckで使用されるランダムシードと、ONNX入力ベクトルを生成するために使用されるランダムシードを強制的に同じにすることができます。最初のもの(RC_PARAMS)のみを設定すると、同じテスト構成が実行されますが、入力値は異なります。両方とも設定すると、まったく同じ実行のために同じ構成と入力を使用します。

精度チェックのためにATOLとRTOLを変更する必要がある場合は、環境変数TEST_ATOLTEST_RTOLを新しい値に設定します。

SIMD命令の有効化

現在s390xのみサポートされているプラットフォームでは、数値テストはコンパイルされたモデルに対してSIMD命令を生成できます。SIMDを有効にするには、TEST_ARGS環境変数を設定します(例:)。

TEST_ARGS="-mcpu=z14" CTEST_PARALLEL_LEVEL=$(nproc) cmake --build . --config Release --target check-onnx-numerical

特定のアクセラレータのテスト

現在、アクセラレータNNPAのテストを提供しています。こちらで説明されています。

gdbの使用

ONNXモデルのソースコードを取得します

ONNXモデルをコンパイルする際に、オプション--preserveMLIRを追加します。your_model_name.input.mlirという名前の、MLIR形式のモデルのソースコードが作成されます。演算の行情報は、バイナリまでアタッチされ、伝播されます。コンパイルされたライブラリをgdbで実行すると、モデル内で停止し、ONNX演算に関してステップ実行できます。モデルtest_add.onnxの例を以下に示します。

$Debug/bin/onnx-mlir --preserveMLIR test_add.onnx
$. ../utils/build-run-onnx-lib.sh
$gdb Debug/bin/run-onnx-lib
(gdb) b run_main_graph
(gdb) run ./test_add.so
(gdb) list
1	builtin.module  {
2	  builtin.func @main_graph(%arg0: tensor<3x4x5xf32>, %arg1: tensor<3x4x5xf32>) -> tensor<3x4x5xf32> {
3	    %0 = "onnx.Add"(%arg0, %arg1) : (tensor<3x4x5xf32>, tensor<3x4x5xf32>) -> tensor<3x4x5xf32>
4	    return %0 : tensor<3x4x5xf32>
5	  }
(gdb) b 3
Breakpoint 2 at 0x3fffdf01778: file /home/chentong/onnx-mlir/build/test_add.input.mlir, line 3.
(gdb) c
Continuing.

Breakpoint 2, main_graph () at /home/chentong/onnx-mlir/build/test_add.input.mlir:3
3	    %0 = "onnx.Add"(%arg0, %arg1) : (tensor<3x4x5xf32>, tensor<3x4x5xf32>) -> tensor<3x4x5xf32>
(gdb) n
[Detaching after vfork from child process 2333437]
#  0) before op=     Add VMem:  6804
[Detaching after vfork from child process 2333470]
#  1) after  op=     Add VMem:  6804
4	    return %0 : tensor<3x4x5xf32>
(gdb)

インストルメンテーションの出力は、ONNX演算レベルでのgdbステップが正しく動作したことを示しています。インストルメンテーションでonnx-mlirを実行するには追加のフラグが必要ですが、gdbには必要ありません。ソースファイルはtest_add.input.mlirです。今後の作業の1つは、gdbでONNXレベルでシンボルをサポートすることです。テンソルをgdbで出力できれば非常に便利です。

LLVMデバッグサポートを使用します

LLVMとMLIRプロジェクトにトレースコードを追加する標準的な方法は、LLVM_DEBUGマクロを使用することです。LLVMの公式ドキュメントはこちらです。

デバッグ制御下で単一の「プリントアウト」を挿入するには、次のテンプレートを使用できます。

#include "llvm/Support/Debug.h"

#define DEBUG_TYPE "my_opt_name_here"
...
LLVM_DEBUG(llvm::dbgs() << "debug msg here" <<  obj_to_print << "\n");

デバッグトレースをトリガーするには、コンパイラを–debug-only=my_opt_name_hereで呼び出すだけです。

ソースファイルに1つのトレースメッセージしかない場合など、DEBUG_WITH_TYPEと呼ばれる別のマクロを使用できます。その場合、DEBUG_TYPEを定義せずに、代わりに以下を使用できます。

DEBUG_WITH_TYPE("my_debug_msg", llvm::dbgs() << "my trace msg here\n");

コードのより大きな部分を保護するには、このテンプレートを使用できます。

LLVM_DEBUG({
  for(i...) {
    llvm::dbgs() << "emit trace for a: " << a << "\n";
    compute b;  // should be side effects free
    llvm::dbgs() << "emit trace for 'b':" << b << "\n";
    ...
});

このサポートをプロジェクトで使用している例は、これらのファイルにあります。

これらのデバッグステートメントは、--debug-only=my_opt_name_hereオプションをonnx-mlirまたはonnx-mlir-optに追加することで有効にできます。

ONNXモデル動物園

RunONNXModelZoo.pyというPythonスクリプトを提供して、ONNXモデルズーのモデルで推論精度を確認します。RunONNXModelZoo.pyは、RunONNXModel.pyが同じフォルダにある必要があります。たとえば、mnist-8で推論精度を確認するには

$ mkdir test && cd test
$ ln -s /onnx-mlir/utils/RunONNXModel.py
$ ln -s /onnx-mlir/utils/RunONNXModelZoo.py
$ ONNX_MLIR_HOME=/onnx-mlir/build/Release/ python RunONNXModelZoo.py -m mnist-8 -c="-O3"

スクリプトを-hで実行して、すべてのオプションを確認します。モデルを指定するための-mフラグとコンパイルオプションを指定するための-cフラグに加えて、便利なオプションとしては、onnxモデルを現在のディレクトリに.tgzファイルとして残すための-kフラグ、および多くのデバッグ情報を表示するための-l debugフラグがあります。

使用可能なモデルを確認するには、スクリプトを-pで実行して使用可能なモデルのリストを表示するか、不完全な名前を付けて-mを使用すると、スクリプトが正確な名前を提案します。

-mを使用してモデルを指定しないと、スクリプトはONNXモデルズーのすべてのモデルをチェックします。

ONNXモデルズーのパフォーマンス分析

モデルズー(または任意のモデル)のパフォーマンス情報を収集する場合は、最も簡単な方法は、コンパイル時に必要な統計情報を要求することです(-profile-irフラグを使用)。出力統計をファイルに転送し、make-report.pyを使用して分析します。例:

> ONNX_MLIR_INSTRUMENT_FILE=run.log RunONNXModelZoo.py -c "-O3 -march=arm64 --profile-ir=Onnx" -m bertsquad-10
...
> make-report.py -r run.log
...
Statistics start (all ops).
  onnx.Add, 112, 0.0130570
  onnx.Cast, 105, 0.0001860
  onnx.Concat, 55, 0.0001290
  onnx.Constant, 473, 0.0008220

ランタイムプロファイリング情報は、特定のコンパイル時統計情報と組み合わせることもできます。SIMD統計に興味があるとしましょう。コンパイラに-opt-reportオプションを使用して出力するコンパイル時統計情報を知らせ、RunONNXModelZoo.py--log-to-fileオプションを使用してコンパイラ出力を保持するように知らせます。例:

> ONNX_MLIR_INSTRUMENT_FILE=run.log RunONNXModelZoo.py -c "-O3 -march=arm64 -opt-report=Simd --profile-ir=Onnx" -m bertsquad-10 --log-to-file compile.log
...
> make-report.py -c compile.log -r run.log
...
Statistics start (all ops).
  onnx.Add-simd, 112, 0.0130570
  onnx.Cast, 23, 0.0000650
  onnx.Gemm, 1, 0.0003570
  onnx.Gemm-simd, 72, 0.8109330

上記のリストでは、ベクトル化された演算は、それぞれの演算名に-simd接尾辞を追加して個別に要約されます。

同じオプションと環境変数は、RunONNXModel.pyRunONNXModelZoo.pyで同様に機能します。