フローグラフのスケーラビリティーを向上させる 1 つの方法は、ノードボディーの内部にほかの並列アルゴリズムを入れ子にすることです。アルゴリズムを入れ子にすることで、グラフのレベルで最も粗粒度の並列化を表現し、内部の入れ子でより細粒度の並列化を表現する、協調言語としてフローグラフを使用できます。
下記の例では、5 つのノードが作成されています。source_node は、ファイル matrix_source から行列のシーケンスを読み取ります。2 つの function_node、n1 および n2 は、これらの行列を受け取り、各要素に関数を適用して 2 つの新しい行列を生成します。最後の 2 つの function_node、n1_sink および n2_sink は、生成された行列を処理します。matrix_source は、n1 と n2 の両方に接続されます。ノード n1 は n1_sink に接続され、n2 は n2_sink に接続されます。n1 と n2 のラムダ式で、parallel_for は行列の要素に関数を並列に適用するために使用されます。read_next_matrix、f1、f2、consume_f1、および consume_f2 関数は提供されていません。
graph g;
source_node< double * > matrix_source( g, [&]( double * &v ) -> bool {
double *a = read_next_matrix();
if ( a ) {
v = a;
return true;
} else {
return false;
}
}, false );
function_node< double *, double * > n1( g, unlimited, [&]( double *a ) -> double * {
double *b = new double[N];
parallel_for( 0, N, [&](int i) {
b[i] = f1(a[i]);
} );
return b;
} );
function_node< double *, double * > n2( g, unlimited, [&]( double *a ) -> double * {
double *b = new double[N];
parallel_for( 0, N, [&](int i) {
b[i] = f2(a[i]);
} );
return b;
} );
function_node< double *, double * > n1_sink( g, unlimited,
[]( double *b ) -> double * {
return consume_f1(b);
} );
function_node< double *, double * > n2_sink( g, unlimited,
[]( double *b ) -> double * {
return consume_f2(b);
} );
make_edge( matrix_source, n1 );
make_edge( matrix_source, n2 );
make_edge( n1, n1_sink );
make_edge( n2, n2_sink );
matrix_source.activate();
g.wait_for_all();