input_node の使用

input_node の使用#

デフォルトでは、input_node はアクティブではない状態で構築されます。

template< typename Body > input_node( graph &g, Body body, bool is_active=true )

非アクティブな input_node をアクティブにするには、ノードの関数 activate を呼び出します。

input_node< int > src( g, src_body(10), false ); 
// make_edge の呼び出しで使用… 
src.activate();

すべての input_node オブジェクトは非アクティブな状態で構築され、通常はフローグラフ全体が構築された後にアクティブ化されます。

例えば、データ・フロー・グラフのコードを使用できます。この実装では、input_node は非アクティブな状態で構築され、他のすべてのエッジが作成された後にアクティブ化されます。

make_edge( squarer, summer ); 
make_edge( cuber, summer ); 
input_node< int > src( g, src_body(10), false ); 
make_edge( src, squarer ); 
make_edge( src, cuber ); 
src.activate(); 
g.wait_for_all();

この例では、input_node が最初にアクティブ状態に切り替えられると、squarer へのエッジが接続された直後に squarer にメッセージが送信される可能性があります。その後、cuber へのエッジが接続されると、cuber は以降すべてのメッセージを受信しますが、すでにいくつかを見逃している可能性があります。

通常、input_node オブジェクトを非アクティブ状態で作成し、グラフ全体が構築された後にアクティブ化するのが最も安全です。ただし、このアプローチでは、グラフの構築とグラフの実行がシリアル化されます。

一部のグラフは、input_node をアクティブにして構築と実行のオーバーラップを許可して安全に構築できます。グラフが有向非巡回グラフ (DAG) であり、各 input_node に後続ノードが 1 つしかない場合、エッジを逆位相の順序で構築すると、構築直後に input_node をアクティブにできます。つまり、最初にツリー内の最も深いエッジを作成し、最も浅いエッジに戻って作業します。例えば、src が input_node であり、func1func2 が両方とも関数ノードである場合、次のグラフでは、src が構築直後にアクティブ化されてもメッセージは失われません。

const int limit = 10; 
int count = 0;
graph g; 
oneapi::tbb::flow::graph g; 
oneapi::tbb::flow::input_node<int> src( g, [&]( oneapi::tbb::flow_control &fc ) -> int { 
    if ( count < limit ) { 
        return ++count; 
    } 
    fc.stop(); 
    return {}; 
}); 
src.activate(); 

oneapi::tbb::flow::function_node<int,int> func1( g, 1, []( int i ) -> int { 
    std::cout << i << "\n"; 
    return i; 
} ); 
oneapi::tbb::flow::function_node<int,int> func2( g, 1, []( int i ) -> int { 
    std::cout << i << "\n"; 
    return i; 
} ); 

make_edge( func1, func2 ); 
make_edge( src, func1 ); 

g.wait_for_all();

上記のコードは、func1 から func2 へのエッジが src から func1 へのエッジの前に作成されるため安全です。src から func1 へのエッジが最初に作成されると、func2 が接続される前に func1 がメッセージを生成する可能性があり、そのメッセージは失われます。また、 src には後継ノードが 1 つだけあります。src に複数の後続ノードがある場合、最初に接続した後続ノードは、その後に接続される後続ノードに届かないメッセージを受信する可能性があります。