再帰グラフ - 2023.2 日本語

AI エンジン カーネルおよびグラフ プログラミング ガイド (UG1079)

Document ID
UG1079
Release Date
2023-12-04
Version
2023.2 日本語
C++ の特徴の 1 つに、再帰テンプレートがあります。グラフは再帰テンプレートを利用することで再帰的に作成できます。
template<int Level>
class RecursiveGraph: public adf::graph {
private:
  adf::kernel k;
  RecursiveGraph<Level-1> RG;

public:
  adf::port<input> din;
  adf::port<output> dout;

  RecursiveGraph() {
    k = adf::kernel::create(passthrough);
    adf::source(k) = "kernels.cpp";
    adf::runtime<ratio>(k) = 0.9;

    adf::connect(din, k.in[0]);
    adf::connect(k.out[0], RG.din);
    adf::connect(RG.dout, dout);
  };
};


template<>
class RecursiveGraph<1>: public adf::graph {
private:
  adf::kernel k;

public:
  adf::port<input> din;
  adf::port<output> dout;

  RecursiveGraph() {
    k = adf::kernel::create(passthrough);
    adf::source(k) = "kernels.cpp";
    adf::runtime<ratio>(k) = 0.9;

    adf::connect(din, k.in[0]);
    adf::connect(k.out[0], dout);
  };
};

クラス RecursiveGraph は、再帰関数の深さを表すテンプレート パラメーター Level でパラメーター指定されます。RecursiveGraph クラス内で、テンプレート パラメター Level-1 を使用して RecursiveGraph<Level-1> RG; と同じクラスのインプリメンテーションが実行されます。これにより、RecursiveGraphLevel-1 回繰り返しインスタンシエートされます。RecursiveGraph<1> クラスの特殊化は、再帰のストップ コンディションとして動作します。

class TestRecursiveGraph: public adf::graph {
public:
  adf::input_plio plin;
  adf::output_plio plout;

  RecursiveGraph<5> Recursive;

  TestRecursiveGraph()
  {
    plin = adf::input_plio::create("input",adf::plio_64_bits,"data/Input_64.txt",500);
    adf::connect(plin.out[0],Recursive.din);

    plout = adf::output_plio::create("output",adf::plio_64_bits,"data/Output.txt",500);
    adf::connect(Recursive.dout,plout.in[0]);
  };
};

この例では、RecursiveGraph のインスタンスが 5 つ、TestRecursiveGraph グラフにインスタンシエートされます。

TestRecursiveGraph RecursiveUnitTest;

int main(int argc, char ** argv) {

  RecursiveUnitTest.init();
  RecursiveUnitTest.run(NFRAMES*NITERATIONS);
  RecursiveUnitTest.end();
  return 0;
}

次に、Vitis アナライザーで得られる再帰グラフをシーケンシャル グラフと対比させて示します。

図 1. 再帰グラフとシーケンシャル グラフによる複数カーネルの表示

グラフ表示で、再帰性によって得られた階層が確認できます。