AI エンジン グラフ アプリケーションのシミュレーション
この章では、AI エンジン アプリケーションを異なるレベルの抽象化、精度、および速度でシミュレーションするために使用可能なさまざまな実行ターゲットについて説明します。AI エンジン グラフは、3 つのシミュレーション環境でシミュレーションできます。
x86 シミュレータは、x86 論理シミュレータ に説明されているように、論理シミュレータです。AI エンジン グラフの論理シミュレーションに使用でき、カーネルとグラフの開発サイクル早期のイテレーションに非常に有益です。ただし、タイミング、リソース、またはパフォーマンス情報は提供されません。
AI エンジン シミュレータ (aiesimulator) は、AI エンジン アレイのタイミングおよびリソースをモデル化し、NoC、DDR メモリ、PL、および PS にはトランザクション レベルのタイミング情報を含む SystemC モデルを使用します。これにより、AI エンジン アプリケーションのパフォーマンス解析を高速に実行でき、AI エンジン リソースの使用をサイクル近似のタイミング情報を使用して正確に見積もることができます。
特定のボードおよびプラットフォームをターゲットとする AI エンジン グラフ全体を PL カーネルおよびホスト アプリケーションと共にシミュレーションする準備ができたら、Vitis™ ハードウェア エミュレーション フローを使用できます。このフローには、AI エンジンの SystemC モデル、NoC、DDR メモリ、PL、および PS のトランザクション レベルの SystemC モデルが含まれます。PL カーネルおよび IP の RTL シミュレーション モデルを含めることもできます。このフローで使用可能なオプションを、この章で説明します。
Vitis ツール フローを使用したアプリケーションの統合 および Vitis IDE の使用 に説明するように、Vitis™ コンパイルでは IDE からシミュレータを実行するためのシステム レベルのプロジェクトがビルドされます。コマンド ラインまたはスクリプトでオプションを指定することもできます。
AI エンジン SystemC シミュレータ
Versal™ ACAP AI エンジン SystemC シミュレータ (aiesimulator) には、AI エンジン アレイに加え、グローバル メモリ (DDR メモリ) およびネットワーク オン チップ (NoC) のモデリングが含まれています。SystemC シミュレーション ターゲットを使用してアプリケーションをコンパイルすると、AI エンジン SystemC シミュレータを次のように起動できます。
aiesimulator –-pkg-dir=./Work
AI エンジン コンパイラにより、さまざまなコンフィギュレーション ファイルとバイナリ ファイルが --pkg-dir オプションを使用して指定した Work ディレクトリ (AI エンジン グラフ アプリケーションのコンパイル を参照) に生成されます。グラフは、main アプリケーションとして記述された制御スレッドにより初期化、実行、および終了されます。AI エンジン コンパイラは、PS IP ラッパーが直接シミュレータに読み込まれるように制御スレッドをコンパイルします。
デフォルトでは、graph.run() オプションによりグラフが無限に実行されるよう指定されます。AI エンジン コンパイラでは、データフロー グラフを無限の While ループで実行するコードが生成されるため、シミュレーションも無限に実行されます。デバッグ用に終了するプログラムを作成するには、グラフ コードで graph.run(<number_of_iterations>) を使用して反復回数を指定します。反復回数は、正の整数で指定します。
graph::run(-1) は、永続的に実行されるグラフを指定します。AI エンジン シミュレータ コマンドは、まずコンパイラで生成された Work/config/scsim_config.json ファイルで指定されているようにシミュレータを設定します。これには、PL IP ブロックとその接続の読み込み、I/O データ ファイル ドライバーの設定、および NoC とグローバル メモリ (DDR メモリ) 接続の設定が含まれます。その後、指定の PS アプリケーションを実行し、シミュレータを終了します。
AI エンジン シミュレータには、カーネル コードの printfs をイネーブルにしてコンソールに表示されるようにし、プロファイル情報を生成する --profile オプションがあります。また、--dump-vcd
<filename> オプションを使用すると、シミュレーション中に VCD (Value Change Dump) が生成されます。指定のクロック サイクル数後にシミュレーションを終了するには、--simulation-cycle-timeout
<number-of-cycles> を使用できます。
graph.run() を使用して実行回数を指定しない場合、シミュレーションは無限に実行されます。シミュレーションを終了するには、Ctrl+c キーを 2 回押します。--simulation-cycle-timeout オプションを使用してシミュレータを停止するサイクルを指定します。これにより、プロファイル レポートに表示される各実行の合計サイクル数が同じになります。printfs をイネーブルにするためにカーネル コードに <iostream> を含めないでください。カーネル コードで #include
<iostream> を使用すると、x86 シミュレータおよび SystemC シミュレータの両方でコンパイル エラーが発生します。シミュレータのオプション
このセクションでは、AI エンジン シミュレータ (aiesimulator) のすべてのオプションを説明します。ほとんどの場合、pkg-dir を指定するだけで十分です。
| オプション | 説明 |
|---|---|
| -h, --help | ヘルプ メッセージを表示します。 |
| --dump-vcd FILE | VCD 波形情報を FILE にダンプします。指定したファイル名に .vcd が付けられるので、拡張子を指定する必要はありません。 |
| --gm-init-file <file> | ファイルからグローバル メモリ イメージを読み出します。グローバル メモリのシミュレーション に説明するように、メモリ初期化ファイルが読み込まれます。 |
| --pkg-dir <PKG_DIR> | パッケージ ディレクトリを指定します (例: ./Work)。 |
| --profile | 使用されているすべてのコアのプロファイリング データを生成します。stdout に printf トレース メッセージを生成し、シミュレーション中にプロファイリング統計を収集します。これにより、シミュレータの速度が多少低下します。オプションで、 |
| --simulation-cycle-timeout CYCLES | アプリケーションを読み込んだ後、指定のサイクル数実行します。 ヒント: 指定したタイムアウト時間後にシミュレーション セッションを終了するには、 --simulation-cycle-timeout オプションを使用します。ただし、デバッグ プロセス中にシミュレーション タイムアウトを指定する際は、タイムアウト サイクル数に達するとデバッグが終了するので、サイクル数を大きな値に設定してください。 |
| --online [-ctf] [-wdb] |
ヒント:
--online オプションと --dump-vcd オプションを同時に使用することはできません。両方のオプションを指定すると、--online のみが適用されます。 |
| --enable-memory-check | ランタイム プログラムおよびデータ メモリ境界アクセス チェックをイネーブルにします。アクセス違反は、警告メッセージとしてレポートされます。デフォルトでは、このオプションはディスエーブルになっています。 |
シミュレーションの入力および出力データ ストリーム
入力/出力ストリームのデフォルトのビット幅は 32 ビットです。ビット幅は、シミュレーション入力ファイルの各行のサンプル数を指定します。次の表に、データ型および PLIO データ幅に基づく入力ファイルの各行のサンプルの解釈を示します。次の表に、データ型および PLIO データ幅に基づく入力ファイルの各行のサンプルの解釈を示します。
| データ型 | PLIO 32 ビット | PLIO 64 ビット | PLIO 128 ビット |
|---|---|---|---|
PLIO *in0 = new
PLIO("DataIn1", adf::plio_32_bits) |
PLIO *in0 = new
PLIO("DataIn1", adf::plio_64_bits) |
PLIO *in0 = new
PLIO("DataIn1", adf::plio_128_bits) |
|
| int8 | // 各行に 4 個の値 6 8 3 2 |
// 各行に 8 個の値 6 8 3 2 6 8 3 2 |
// 各行に 16 個の値 6 8 3 2 6 8 3 2 6 8 3 2 6 8 3 2 |
| int16 | // 各行に 2 個の値 24 18 |
// 各行に 4 個の値 24 18 24 18 |
// 各行に 8 個の値 24 18 24 18 24 18 24 18 |
| int32 | // 各行に 1 個の値 2386 |
// 各行に 2 個の値 2386 2386 |
// 各行に 4 個の値 2386 2386 2386 2386 |
| int64 | なし | 45678 | // 各行に 2 個の値 45678 95578 |
| cint16 | // 各行に 1 個の cint 値 (実数部、虚数部) 1980 485 |
// 各行に 2 個の cint 値 1980 45 180 85 |
// 各行に 4 個の cint 値 1980 485 180 85 980 48 190 45 |
| cint32 | なし | // 各行に 1 個の cint 値 (実数部、虚数部) 1980 485 |
// 各行に 2 個の cint 値 1980 45 180 85 |
| float | // 各行に 1 個の浮動小数点値 893.5689 |
// 各行に 2 個の浮動小数点値 893.5689 3459.3452 |
// 各行に 4 個の浮動小数点値 893.5689 39.32 459.352 349.345 |
| cfloat | なし | // 各行に 1 個の浮動小数点 cfloat 値 (実数部、虚数部) 893.5689 24156.456 |
// 各行に 2 個の浮動小数点 cfloat 値 (実数部、虚数部) 893.5689 24156.456 93.689 256.46 |
グローバル メモリのシミュレーション
アプリケーションが GMIO 仕様 (GMIO 属性 を参照) を使用してグローバル メモリにアクセスする場合、シミュレーションで DDR メモリと DDR メモリを PL および AI エンジンに接続する配線ネットワークをモデル化する必要があります。AI エンジンから DDR メモリへの接続は、DMA データ ムーバーにより制御されます。DMA データ ムーバーは AI エンジン アレイ インターフェイスに組み込まれており、PS プログラムの GMIO API で制御されます。PL ブロックの AXI4-Stream ポートから DDR メモリへの接続は、ソフト GMIO データ ムーバー ブロックにより制御されます。このブロックは、シミュレーション用に AI エンジン コンパイラにより自動的に生成されます。データ ムーバーは、PL ブロックからのストリーミング インターフェイスを、GMIO 属性 に示す特定の開始アドレス、ブロック サイズ、バースト サイズを持つ NoC 上のメモリ マップド AXI4 インターフェイス トランザクションに変換します。
グローバル メモリを使用するシミュレーション中、DDR メモリを定義済みのデータで初期化するメモリ データ ファイルを --gm-init-file オプションを使用して指定できます。テキスト形式のこのファイルは、指定のアドレスから開始する DDR メモリのバイト ダンプです。このファイルのフォーマットは、次のとおりです。
<startaddr>:
<byte>
<byte>
…
AI エンジン シミュレータを起動する際にグローバル メモリを初期化するには、次のコマンドを使用します。
aiesimulator –-pkg-dir=./Work -–gm-init-file=dump.txt
シミュレータは、使用された DDR メモリの出力バイト ダンプもシミュレーション出力ディレクトリ (デフォルトでは aiesimulator_output) に生成します。出力ファイルはベース アドレス 0x0 から開始し、名前は DDR メモリ バンク内の場所に基づいて付けられます (例: DDRMC_SITE_X1Y0.mem)。このファイルを使用してグローバル メモリ トランザクションを確認できます。
ハードウェア エミュレーションのシミュレータ オプション
AI エンジン シミュレータは、AI エンジン グラフ アプリケーションのシミュレーションに使用されるオプションをリストするオプションファイルを生成します。このオプション ファイルは、AI エンジン シミュレータを実行すると自動的に生成されます。初期のグラフ レベルのシミュレーションで使用した AI エンジン シミュレータ オプションは、AI エンジン シミュレータを使用して、システム レベルのハードウェア エミュレーションで再利用できます。必要に応じてオプション ファイルを手動で編集し、ほかのオプションを指定することもできます。次の表に、aiesim_options.txt ファイルで指定可能なオプションをリストします。このファイルは、aiesimulator コマンドに --dump-vcd または --profile オプションのいずれかを使用した場合に、aiesimulator_output ディレクトリに作成されます。このファイルは、システムの実行 に説明されているように、launch_hw_emu.sh スクリプトを使用してハードウェア エミュレーターを起動するときにコマンド ライン オプションの一部として指定できます。次にコマンド例を示します。
./launch_hw_emu.sh \
-add-env VITIS_LAUNCH_WAVEFORM_BATCH=1 \
-aie-sim-options ${FULL_PATH}/aiesimulator_output/aiesim_options.txt
${FULL_PATH}: ファイルまたはディレクトリへの絶対パスを指定します。
| コマンド | 引数 | 説明 |
|---|---|---|
AIE_DUMP_VCD |
<filename> | AIE_DUMP_VCD を指定すると、シミュレーションで VCD データが生成され、指定した <filename>.vcd に保存されます。 |
AIE_PROFILE |
All | (1,2)(3,4)... | 使用されるすべての AI エンジンまたは選択した AI エンジンをプロファイリングします。ハードウェア エミュレーションでは、sim/behav_waveform/xsim ディレクトリにプロファイル データが生成され、Vitis アナライザーで default.aierun_summary ファイルを開くと表示できます。このオプションを使用すると、ADF カーネルの printf データも sim/behav_waveform/xsim/simulate.log ファイルに記録されます。 |
AIE_PKG_DIR |
/path_to_work_dir/Work | これは必須のオプションで、パスを AI エンジン コンパイラで生成された Work ディレクトリに設定します。このオプションを指定しない場合、生成された sim/behav_waveform/xsim/default.aierun_summary ファイルには正しい Work ディレクトリ設定が含まれず、Vitis アナライザーのサマリ ファイルの表示に影響します。 |
次のコマンドを使用すると、ハードウェア エミュレーション中に XSIM 波形 GUI を開くことができます。
./launch_hw_emu.sh -g
Vivado ロジック シミュレータ GUI を使用してエミュレーションを起動せずに波形データをログに記録するためのアドバンス オプションも追加できます。次にコマンド例を示します。
./launch_hw_emu.sh \
-user-pre-sim-script pre-sim.tcl
pre-sim.tcl には、波形を追加したり、デザイン波形をログに記録する Tcl コマンドが含まれます。例は 『Vitis 統合ソフトウェア プラットフォームの資料』 (UG1416) の Vitis アプリケーション アクセラレーション開発フロー、Tcl コマンドは 『Vivado Design Suite ユーザー ガイド: ロジック シミュレーション』 (UG900) を参照してください。
サードパーティ シミュレータのイネーブル
| シミュレータ | v++ --link コンフィギュレーション |
|---|---|
| Questa Advanced Simulator | EXPORT
simulator=questa |
| Xcelium | EXPORT
simulator=xcelium |
| VCS | EXPORT
simulator=vcs |
変更したら、デザインを通常どおりビルドし、launch_hw_emu.sh スクリプトを実行して新しいシミュレータを使用します。エミュレーションの詳細は、システムの実行 を参照してください。
x86 論理シミュレータ
AI エンジン グラフおよびカーネルの開発を開始する際は、デザインの動作を検証することが重要です。これは論理シミュレーションと呼ばれ、デザインのバグを特定するのに有益です。たとえば、グラフのウィンドウ サイズはカーネルの反復回数に関係します。大型グラフの各カーネルが正しい数のサンプルを消費して生成するかどうかをトラブルシューティングするのは、時間のかかる繰り返し作業です。x86 シミュレータは、反復実行が高速で、データの可視化に優れているので、このような動作をテスト、デバッグ、および検証するのに理想的です。x86 シミュレーションでは、タイミング、リソース、またはパフォーマンス情報は提供されません。x86 シミュレータは、ツール開発マシン上でのみ実行されます。つまり、パフォーマンスとメモリ使用量は、開発マシンで定義されます。
AI エンジン シミュレータでは AI エンジン アレイのメモリが完全にモデル化されますが、これは AI エンジン シミュレータが AI エンジンのメモリ空間に制限されるということです。x86 シミュレータはこの制限を受けまず、デバッグ printf()s、大型アレイ、および変数が無制限に提供されます。カーネルをシングル ステップ実行できる機能と組み合わせると、複雑なデザインの問題をすばやく特定して解決できます。
カーネル開発に役立つマクロが提供されています。これらのマクロは、x86 シミュレータと使用するためのもので、メンテナンス目的でコードに含めておくことができます。x86 シミュレータにはこれらの利点がありますが、トレードオフもあります。サポートされていないタイプのグラフ コンストラクトがあり、サイクル精度の動作が AI エンジン シミュレータと x86 シミュレータの間で一致するとは限りません。x86 シミュレータは、AI エンジン シミュレータの代わりにはなりません。動作を検証してパフォーマンス情報を取得するには、すべてのデザインで AI エンジン シミュレータも実行する必要があります。プロジェクト開発の段階によって、適切なツールは異なります。
x86 シミュレータを実行するには、AI エンジン コンパイラのターゲットを x86sim に変更します。
aiecompiler --target=x86sim graph.cpp
アプリケーションを x86 シミュレーション用にコンパイルしたら、x86 シミュレータを次のように起動できます。
x86simulator
次に、x86 シミュレータ コマンドのヘルプを示します。
$ x86simulator [-h] [--help] [--h] [--pkg-dir=PKGDIR]
optional arguments:
-h,--help --h show this help message and exit
--pkg-dir=PKG_DIR Set the package directory. ex: Work
--timeout=secs Terminate simuation after specified number of seconds
--gdb Invoke from gdb
AI エンジン コンパイラにより x86 ネイティブ シミュレーション用にコンパイルされたバイナリが Work ディレクトリ (AI エンジン グラフ アプリケーションのコンパイル を参照) に生成され、x86 シミュレータにより自動的に開始されます。
入力および出力ファイルは、グラフ コードの次の部分で指定されます。
adf::PLIO in1("In", adf::plio_32_bits, "In1.txt");
adf::PLIO out1("Out", adf::plio_32_bits, "Out1.txt");
simulation::platform<1,1> platform(&in1,&out1)
x86 シミュレータを実行すると、現在の作業ディレクトリで data/In1.txt が検索されます。このファイルは、ADF グラフにより使用される入力の 1 つです。x86 シミュレータの出力ファイルを AI エンジン シミュレータの出力ファイルと区別するため、Out1.txt は current_working_dir/x86simulator_output/data/ に配置されます。
シミュレータで生成される出力ファイルは、ゴールデン出力と比較できます (空白の違いは無視)。
diff –w <data>/golden.txt <data>/output.txt
デザインのコンパイル
GNU デバッガーを使用すると、IDE ベースのデバッガーと同様に C/C++ のデバッグを実行できます。ブレークポイントの設定、シングル ステップ、関数のステップ オーバー、およびブレークポイントでの複数のヒット カウントが可能です。AI エンジン カーネルの開発では、x86 シミュレータにより、GDB を使用してカーネル コードをシングル ステップ デバッグできます。
GDB を使用するには、AI エンジン コンパイラの target 引数を x86sim に設定する必要があります。
aiecompiler --target=x86sim graph.cpp
さらに、プリプロセッサ指示子 -O0 を使用してコンパイルすると、最適化が最小限に抑えられ、デバッグの可視性が向上します。さらにデバッグの可視性を上げる必要がある場合は、コンパイラの最適化レベルを下げることができます。最適化パラメーターをプリプロセッサに渡すには、次を使用します。
aiecompiler --target=x86sim --Xpreproc=-O0 graph.cpp
GDB の使用
適切なターゲットに対するコンパイルが完了したら、シミュレーションを起動して GDB インスタンスを自動的に接続できます。対話型の GDB セッションを起動するには、コマンドを次のように --gdb オプションを使用して実行します。
x86simulator --gdb
x86 シミュレータを gdb オプションを使用して実行すると、デフォルトで graph.cpp の main() に入る前に停止します。グラフは実行されていないので、実行が AI エンジン カーネルが開始する前に停止します。GDB を終了するには、quit と入力します。コマンドの詳細は、help を使用してください。
break <kernel_function_name>continue (短縮形 c) と入力すると、デバッガーが <kernel function name> のブレークポイントまで実行されます。ブレークポイントに達したら、ローカル スタック変数および関数引数を確認できます。次の表に、これらの変数を確認するためによく使用される GDB 命令のいくつかを示します。
| コマンド | 説明 |
|---|---|
info stack |
現在のブレークポイントでの関数呼び出しスタックの情報を表示します。 |
info
locals |
呼び出しスタックに表示されている関数呼び出しのスコープ内におけるローカル変数の現在のステータスを表示します。 |
print
<local_variable_name> |
1 つの変数の現在の値を表示します。 |
finish |
現在の関数呼び出しを終了しますが、シミュレーションは停止したままにします。 |
continue |
デバッガーを完了まで実行します。 |
GDB は、多くの機能を持つ高度なデバッガーです。GDB の詳細な使用方法は、この資料では説明しません。詳細は、https://www.gnu.org/software/gdb/を参照してください。
マクロ
ザイリンクスでは、x86 シミュレータを使用する際に有益な定義済みのコンパイラ マクロを提供しています。最上位グラフ (通常は graph.cpp) で、次のプリプロセッサ マクロを、適切なコードを含めるか除外するかを指定する条件 #if を使用して使用すると有益です。
| マクロ | 説明 |
|---|---|
| __X86SIM__ | コードを x86sim フローにのみで使用するよう指定します。 |
| __AIESIM__ | コードを aiesimulator フローにのみで使用するよう指定します。 |
|
X86SIM_KERNEL_NAME |
printf() と共に使用して、インストルメンテーション テキストにカーネル インスタンス名を付けます。 |
_ で囲まれたマクロは、前後にアンダースコアが 2 つずつあります。次に、マクロ コードの例を示します。
myAIEgraph g;
#if defined(__AIESIM__) || defined(__X86SIM__)
int main()
{
g.init();
g.run(4);
g.end();
return 0;
}
#endif
上記の例では、__X86SIM__ マクロがgraph.cpp ファイルで使用される main() に設定されています。この main() はエミュレーション フローでは除外する必要がありますが、これらのマクロを使用して制御できます。また、x86 シミュレーション中にのみデバッグ インストルメンテーションをイネーブルにする場合に __X86SIM__ マクロを使用することもできます。
printf() マクロ
x86 シミュレータは、複数のカーネルを個別のスレッドで並列に実行します。これは、printf() デバッグ メッセージを標準出力で表示したときに、メッセージが混ざって表示され、どちらのメッセージなのかはっきりしない場合があります。どのカーネルがどの行のメッセージを出力したのかを特定するには、X86SIM_KERNEL_NAME マクロを使用すると便利です。次に、このマクロを printf() と組み合わせて使用する例を示します。
#include <adf/x86sim/x86simDebug.h>
void simple(input_window_float * in, output_window_float * out) {
for (unsigned i=0; i<NUM_SAMPLES;i++) {
float val = window_readincr(in);
window_writeincr(out,val+0.15);
}
static int count = 0;
printf("%s: %s %d\n",__FILE__,X86SIM_KERNEL_NAME,++count);
}
カーネルでの printf() の使用
ベクター データ型は、AI エンジン カーネル コードで最もよく使用されるデータ型です。カーネルのベクター演算をデバッグするには、printf を使用すると有益です。
ベクター データ型での printf() の使用
printf() を使用してベクター データ型を表示するには、次の手法を証できます。
v4cint16 input_vector;
...
int16_t* print_ptr =(int16_t*)&input_vector;
for (int qq=0; qq<4;qq++) //4 here so we print two int16s, real + imag per loop.
printf("vector re: %d, im: %d\r\n",print_ptr[2*qq],print_ptr[2*qq+1]);
}
AI エンジン シミュレータでは、printf() 出力を使用するには --profile オプションが必要です。x86 シミュレータでは、printf 呼び出しをイネーブルにするのに追加のオプションは必要ありません。これが、x86 シミュレータの利点の 1 つです。
std::cout を使用しないことをお勧めします。x86 シミュレータはマルチスレッドで実行されるので、std::cout を使用すると、その出力が混ざって表示されます。その代わり、printf() を使用することをお勧めします。考慮事項
メモリ モデル
スタティックまたはグローバル変数を含むソース ファイルは、複数の AI エンジンで共有されます。これは、AI エンジン シミュレータの動作とは異なります。複数のカーネルが同じメモリにアクセスする場合、x86 シミュレータ モデルはカーネル メモリごとに割り当てられません。すべてのカーネルで同じグローバル スコープ メモリが共有されます。複数のカーネルで同じメモリに読み出しおよび書き込みを実行すると、x86 シミュレーション中にデータ破損が発生します。この問題を回避するには、メモリ割り当て関数のスコープをカーネルに設定するか、メモリを完全にモデル化する AI エンジン シミュレータを使用してください。
グラフ API 呼び出し
時間を指定した実行用のグラフ コンストラクト (graph.wait(N)、graph.resume()、および graph.end(N)) の動作は、AI エンジン シミュレータと x86 シミュレータで異なります。N は、AI エンジン シミュレータではプロセッサのサイクル タイムアウトを指定し、x86 シミュレータではウォール クロック タイムアウトをミリ秒で指定します。そのため、テストベンチを時間を指定して実行する場合は、AI エンジン シミュレータと x86 シミュレータの結果 (特に生成される出力) が異なることがあります。
プリプロセッサに関する考察事項
x86sim をターゲットとして AI エンジン コンパイラを実行する際、--Xchess オプションは無視されます。これは、x86sim フローではカーネル特定のコンパイル オプションはサポートされないということです。
これについて次の例で説明します。C コードでコンパイル時間を変更するには、#ifndef などのプリプロセッサ指示子を使用するのが一般的な方法です。これらのプリプロセッサ指示子を制御するには、コマンド ライン コンパイラ オプションを使用して #defines を渡すのが便利です。次のコード ブロック例には、プリプロセッサ指示子によって、2 つの異なる動作があります。
void example_kernel()
{
#ifdef SIM
printf("Sumulation Mode\n");
#else
printf("Default Mode\n");
#endif
}
AI エンジン コンパイラでハードウェア (hw) をターゲットとする際にコンパイル時に SIM マクロを定義するには、次を使用します。
aiecompiler -target=hw -Xchess="example_kernel:-DSIM"
コンパイル ターゲットが x86simulator に設定されている場合は -Xchess 引数は無視されるので、x86 シミュレータには SIM は定義されず、カーネルの出力はデフォルト モードになります。
x86 シミュレータでプリプロセッサ オプションを指定する必要がある場合は、-Xchess の代わりに aiecompiler -target=x86sim --Xpreproc を使用します。この方法で渡すオプションは、すべてのソース コードおよびすべてのターゲット フローに適用されることに注意してください。
| オプション | 説明 |
|---|---|
--Xchess=<string> |
各 AI エンジンのコードのコンパイルに使用される CHESS コンパイラにカーネル特定のオプションを渡すために使用できます。 オプション文字列は<kernel-function>:<optionid>=<value> のように指定します。このオプション文字列は、指定したカーネル関数がマップされている AI エンジンに生成されたソース ファイルのコンパイル中に含められます。 |
--Xpreproc=<string> |
すべてのソース コードのコンパイルでプリプロセッサ段階に一般オプションを渡します ( --Xpreproc=-D<var>=<value> |
パケット スイッチングおよび RTP
x86 シミュレータと AI エンジン シミュレータには、パケット スイッチングおよびランタイム パラメーター (RTP) に関して重要な違いがあります。これらの詳細は、ランタイム パラメーターの指定 および 明示的パケット スイッチング を参照してください。
パケット スイッチングおよび RTP は、AI エンジン シミュレータと x86 シミュレータの違いとして現れます。どちらの場合でも、これらの違いは正しいものであることを理解しておくことが重要です。明示的パケット スイッチング で説明したように、パケット スイッチングされたストリームは、すべてのデザイン フロー (x86 シミュレータ、AI エンジン シミュレータ、およびハードウェア エミュレーション) で不確定です。
パケット スイッチング
パケット ストリーム接続には、パケット ID フィールドがあります。パケット ID フィールドのソースが ADF グラフ内である場合、x86 シミュレータではパケット ID に正規ゼロベース インデックス スキームが使用されます。分割ノードの出力の最初の分岐がパケット ID 0 となり、その後 1、2、3 のように続きます。パケット ID フィールドのソースが ADF グラフ外である場合、AI エンジン シミュレータと x86 シミュレータの間に違いがあります。この違いを解決するには、パケット スイッチングおよび AI エンジン シミュレータ でソースが ADF グラフ外である場合にカスタム パケット ID を指定することに関する追加情報を参照してください。
パケットの結合の特性により、x86 シミュレータと AI エンジン シミュレータで生成される結果が不確定なものになります。1 つのパケット分割分岐の AI エンジンがほかの分岐より早く処理を終了した場合、そのデータがパケット結合出力の最初に現れます。どのコアが最初に終了するかは、カーネル コードおよび入力データによります。そのため、ダウンストリームの処理ブロックはこの動作に対処する必要があります。
同期および非同期 RTP
同期および非同期ランタイム パラメーターは、x86 シミュレータで完全にサポートされています。RTP がアップデートされる正確なタイミングとサイクル精度は、x86 シミュレータと AI エンジン シミュレータで異なります。非同期 RTP は特に、非同期であるため、カーネルに影響するサイクルは特定されません。これは、x86 シミュレータでも AI エンジン シミュレータでも同様です。
ベスト プラクティス
x86 シミュレータは、次の推奨事項に従って使用するのがベストです。
- カーネル関数の変数のスコープを指定します。
- x86 シミュレータのテストベンチを単純なものにします。
init()、run(X)、およびend()を使用します。 - ADF グラフ クラスの変数のスコープを指定します (グローバル グラフ スコープのテーブル および C++ カーネル クラスのサポート を参照)。