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. 递归计算图与顺序多核计算图视图
使用递归获取的层级在计算图视图中清晰可见。