C++ スタブの生成

動作している C++ アプリケーションのスタブを生成するには、次の操作を行います。

  1. ノード、エッジ、ポートの追加セクションの説明に従って、キャンバスにグラフを作成します。

  2. グラフをファイルへ保存セクションの説明に従ってグラフを保存します。

  3. ツールバーにある [Generate C++] アイコンをクリックして C++ ファイルを生成します。

Hello World サンプルの C++ スタブの生成

例えば、以下は Hello World サンプルの生成に利用できる 3 ノードグラフです。このグラフは、source_node とそれに続く 2 つの continue_node オブジェクトで構成されています。最初のノードの名前は s0 で、次の 2 つのノードの名前は c0 と c1 です。すべてのノードには、入力および/または出力タイプとして continue_msg オブジェクトがあります。それぞれのノードの本体は、次に示すように [C++ Function Object] フィールドで定義されます。

Hello World サンプルグラフから C++ スタブを生成するには、次の操作を行います。

  1. source_node に続いて 2 つの continue_node オブジェクトを追加してサンプルグラフを作成しエッジに接続します。[Node Properties] でノード名を変更します: source_node に s0 と名前を付け、次の 2 つの continue_node オブジェクトには c0 と c1 にします。

  2. 次のプロパティーをノードに設定します。

    ノード名

    ノードタイプ

    入力ポートタイプ

    出力ポートタイプ

    C++ 関数オブジェクト

    s0

    source_node

    なし

    continue_msg

    [](continue_msg &c) -> bool { static bool done = false; if (!done) { done = true; return true; } else { return false; } }

    c0

    continue_node

    continue_msg

    continue_msg

    [](const continue_msg &m) -> continue_msg { printf("Hello"); return m; }

    c1

    continue_node

    continue_msg

    continue_msg

    [](const continue_msg &m) -> continue_msg { printf(" World!\n"); return m; }
  3. ツールバーにある [Save] アイコンをクリックして、このグラフを HelloWorld.graphml に保存します。

  4. ツールバーにある [Generate C++] アイコンをクリックして C++ スタブを生成します。

スタブファイルの生成は、「成功」であると報告されなければいけません:

スタブファイルが正常に生成されたことを示すメッセージ

C++ コード生成の結果は、GraphML* ファイルが保存された場所にあります。ファイル名は、HelloWorld_stubs.cpp です。次のコードを含んでいる必要があります。

// // Automatically generated by Flow Graph Analyzer: // C++ Code Generator Plugin version XYZ // #define TBB_PREVIEW_FLOW_GRAPH_NODES 1 #include "tbb/flow_graph.h" #include "tbb/tick_count.h" #include "tbb/atomic.h" #include <cstdlib> using namespace std; using namespace tbb; using namespace tbb::flow; size_t key_from_message(char *k) { return reinterpret_cast<size_t>(k); } template<typename T> size_t key_from_message(const T &k) { return static_cast<size_t>(k); } static void spin_for( double weight = 0.0 ) { if ( weight > 0.0 ) { tick_count t1, t0 = tick_count::now(); const double weight_multiple = 1e-6; const double end_time = weight_multiple * weight; do { t1 = tick_count::now(); } while ( (t1-t0).seconds() < end_time ); } } int build_and_run_HelloWorld_g0() { graph HelloWorld_g0; source_node< continue_msg > s0( HelloWorld_g0, [](continue_msg &c) -> bool { static bool done = false; if (!done) { done = true; return true; } else { return false; } }, false); continue_node< continue_msg > c0( HelloWorld_g0, 0, [](const continue_msg &m) -> continue_msg { printf("Hello"); return m; }); continue_node< continue_msg > c1( HelloWorld_g0, 0, [](const continue_msg &m) -> continue_msg { printf(" World!\n"); return m; }); #if TBB_PREVIEW_FLOW_GRAPH_TRACE HelloWorld_g0.set_name("HelloWorld_g0"); s0.set_name("s0"); c0.set_name("c0"); c1.set_name("c1"); #endif make_edge( s0, c0 ); make_edge( c0, c1 ); s0.activate(); HelloWorld_g0.wait_for_all(); return 0; } int main(int argc, char *argv[]) { return build_and_run_HelloWorld_g0(); }

上記のコードでは、s0c0、および c1 ノードが前の表で説明したプロパティーを反映していることに注意してください。

利用する環境ですでにインテル® oneAPI スレッディング・ビルディング・ブロック (oneTBB) ライブラリーへのパスが設定されていれば、コマンドプロンプトからアプリケーションをビルドできます。

さらに、フローグラフ・アナライザーを使用すると、計算ノードや非同期ノードを軽量に設定するなど、ノードの実行ポリシーを制御することができます。任意のノードに軽量ポリシーを設定すると、現在のコード・ジェネレーターは oneTBB 向けのスタブを生成します。

この機能を説明するサンプルは、samples/code_generation ディレクトリーにあります。