階層的グラフ - 2023.2 日本語

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

Document ID
UG1079
Release Date
2023-12-04
Version
2023.2 日本語
グラフには、カーネルとサブグラフを混在させることができます。複数のカーネルをインスタンシエートする場合は、配列として、または特定の名前を付けて宣言できます。次の例では、テンプレート パラメーターで、配列として宣言されるカーネルの数を指定しています。
template <int NK>
class MultiKernelGraph: public adf::graph {
private:
  adf::kernel k[NK];

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

  MultiKernelGraph() {
    for(int i=0;i<NK;i++)
    {
      k[i] = adf::kernel::create(passthrough);
      adf::source(k[i]) = "kernels.cpp";

      adf::runtime<ratio>(k[i]) = 0.9;
    }
    adf::connect(din, k[0].in[0]);
    for(int i=0;i<NK-1;i++)
      adf::connect(k[i].out[0], k[i+1].in[0]);
    adf::connect(k[NK-1].out[0], dout);
  };
};
class TestGraphMulti: public adf::graph {
public:
  adf::input_plio plin;
  adf::output_plio plout;

  MultiKernelGraph<3> Multi;

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

    plout = adf::output_plio::create("output2",adf::plio_64_bits,"data/Output2.txt",500);
    adf::connect(Multi.dout,plout.in[0]);
  };
};
図 1. グラフ ビュー

前述のとおり、グラフはカーネルとサブグラフを含むことができます。テストベンチ .cpp のコードは、複数のグラフをインスタンシエートし、個別に実行できます。

TestGraphSimple Simple_UnitTest;
TestGraphMulti Multi_UnitTest;

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

  Simple_UnitTest.init();
  Multi_UnitTest.init();

  Simple_UnitTest.run(NFRAMES*NITERATIONS);
  Multi_UnitTest.run(NFRAMES*NITERATIONS);

  Simple_UnitTest.end();
  Multi_UnitTest.end();
  return 0;
}

Vitis IDE では、グラフ ビューに 2 つの独立したグラフが表示されます。

図 2. 複数のグラフ

これら 2 つのグラフは、テストベンチにインスタンシエートされる 3 つ目のグラフに含めることも可能です。

class TestGraph: public adf::graph {
public:
  adf::input_plio plin1,plin2;
  adf::output_plio plout1,plout2;

  SimplestGraph Simple;
  MultiKernelGraph Multi;

  TestGraph()
  {
    plin1 = adf::input_plio::create("input1",adf::plio_64_bits,"data/Input_64.txt",500);
    adf::connect(plin1.out[0],Simple.din);

    plout1 = adf::output_plio::create("output1",adf::plio_64_bits,"data/Output1.txt",500);
    adf::connect(Simple.dout,plout1.in[0]);

    plin2 = adf::input_plio::create("input2",adf::plio_64_bits,"data/Input_64.txt",500);
    adf::connect(plin2.out[0],Multi.din);

    plout2 = adf::output_plio::create("output2",adf::plio_64_bits,"data/Output2.txt",500);
    adf::connect(Multi.dout,plout2.in[0]);

  };
};
TestGraph UnitTest;

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

  UnitTest.init();
  UnitTest.run(NFRAMES*NITERATIONS);
  UnitTest.end();
  return 0;
}
図 3. 複合グラフ ビュー

シーケンシャル カーネルやパラレル カーネルを含むより複雑なグラフを作成できます。この複雑なグラフでは、データフローがグラフ全体で複数回分割および統合され、AI エンジン アレイを介してバッファーやストリームを使用してデータが転送されます。

VeryComplexGraph() {
  // Declare Kernels
  for(int i=0;i<2;i++)
  {
    simple[i] = adf::kernel::create(passthrough);
    adf::source(simple[i]) = "kernels.cpp";
    adf::runtime<ratio>(simple[i]) = 0.9;
  }

  // Connections
  // Inputs
  connect(din[0],split[0].din);
  connect(din[1],split[1].din);

  // Outputs
  connect(merge[2].dout,dout[0]);
  connect(split[3].dout[0],dout[1]);
  connect(split[3].dout[1],dout[2]);

  // Internal connections
  connect(split[0].dout[0],multi3.din);
  connect(multi3.dout,merge[2].din[0]);
  connect(split[0].dout[1],merge[0].din[0]);
  connect(split[1].dout[0],merge[0].din[1]);
  connect(merge[0].dout,simple[0].in[0]);
  connect(simple[0].out[0],split[2].din);
  connect(split[2].dout[0],multi2[1].din);
  connect(multi2[1].dout,merge[2].din[1]);
  connect(split[2].dout[1],simple[1].in[0]);
  connect(simple[1].out[0],merge[1].din[0]);
  connect(split[1].dout[1],multi2[0].din);
  connect(multi2[0].dout,merge[1].din[1]);
  connect(merge[1].dout,split[3].din);
};
図 4. 複雑なグラフ ビュー

このグラフ ビューでは、複雑なデータフローが複数のポイントで分割および統合されていることがわかります。データフローの一部が PL に出入りする必要がある場合、リンク フェーズで PL カーネルに接続する、対応する出力ポートと入力ポートが表示されます。