入れ子のアルゴリズムを使用したスケーラビリティーの向上

フローグラフのスケーラビリティーを向上させる 1 つの方法は、ノードボディーの内部にほかの並列アルゴリズムを入れ子にすることです。アルゴリズムを入れ子にすることで、グラフのレベルで最も粗粒度の並列化を表現し、内部の入れ子でより細粒度の並列化を表現する、協調言語としてフローグラフを使用できます。

下記の例では、5 つのノードが作成されています。source_node は、ファイル matrix_source から行列のシーケンスを読み取ります。2 つの function_noden1 および n2 は、これらの行列を受け取り、各要素に関数を適用して 2 つの新しい行列を生成します。最後の 2 つの function_noden1_sink および n2_sink は、生成された行列を処理します。matrix_source は、n1n2 の両方に接続されます。ノード n1n1_sink に接続され、n2n2_sink に接続されます。n1n2 のラムダ式で、parallel_for は行列の要素に関数を並列に適用するために使用されます。read_next_matrixf1f2consume_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();

関連情報