递归计算图 - 2023.2 简体中文

AI 引擎内核与计算图编程指南 (UG1079)

Document ID
UG1079
Release Date
2023-12-04
Version
2023.2 简体中文
C++ 的功能特性之一是递归模板。通过利用递归模板即可以递归方式创建计算图。
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);
  };
};

通过利用模板参数 Level 即可将类 RecursiveGraph 参数化,此模板参数表示递归函数的深度。在 RecursiveGraph 类中,利用模板参数 Level-1 将相同类上的例化作为 RecursiveGraph<Level-1> RG; 来执行。这将以递归方式例化 RecursiveGraph,次数为 Level-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]);
  };
};

在此示例中,在 TestRecursiveGraph 计算图内将对 RecursiveGraph 的 5 个实例进行例化。

TestRecursiveGraph RecursiveUnitTest;

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

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

递归计算图不同于 Vitis IDE 中获取的顺序计算图视图,如下所示:

图 1. 递归计算图与顺序多核计算图视图

使用递归获取的层级在计算图视图中清晰可见。