基于 XIR 的编译器可在独立于框架的 XIR 计算图的关联环境中工作,此 XIR 计算图是从深度学习框架生成的。解析器用于移除 CNN 模型中特定于框架的属性,并将这些模型转换为基于 XIR 的计算图。编译器可将计算图拆分为多个子计算图、利用异构最优化并为子计算图生成最优化的机器代码。
如果模型包含 DPU 不支持的运算,则创建的部分子计算图将被映射到 CPU。FPGA 非常强大,可支持您创建特定 IP 以加速这些运算,从而获得更好的端到端性能。为了使用基于 XIR 的工具链来支持对 IP 进行自定义加速,请使用流水线指定的插件来扩展 XIR 和编译器。
在 Plugin.hpp 中,已声明推断类插件。插件将在编译器启动前按序执行,以对计算图进行编译,供 DPU 使用。首先为每个运算符创建子级子计算图,且插件会选取要加速的运算符。它会将这些运算符合并为更大的子计算图、将其映射到自定义 IP,并为运行时 (VART::Runner) 附上必要的信息(例如,有关子计算图的指令)。
实现插件
- 实现
Plugin::partition()
在
std::set<xir::Subgraph*> partition(xir::Graph* graph)
中,使用下列帮助函数选取所需运算,并将其合并为器件级子计算图。-
xir::Subgraph* filter_by_name(xir::Graph* graph, const std::string& name)
用于返回含特定名称的子计算图 -
std::set<xir::Subgraph*> filter_by_type(xir::Graph* graph, const std::string& type)
用于返回特定类型的子计算图。 -
std::set<xir::Subgraph*> filter_by_template(xir::Graph* graph, xir::GraphTemplate* temp)
用于返回含特定结构的子计算图。图 2. 按模板筛选 -
std::set<xir::Subgraph*> filter(xir::Graph* graph, std::function<std::set<xir::Subgraph*>(std::set<xir::Subgraph*>)> func)
支持您按自定义函数对子计算图进行筛选。此方法可帮助您查找所有未编译的子计算图。
如需合并子级子计算图,请使用
merge_subgraph()
帮助函数。但此函数只能合并相同级别的子计算图。如果子计算图列表无法合并为单一子计算图,那么帮助函数会尽可能将其合并。 -
- 请在
Plugin::partition()
函数中为所选取的子计算图指定名称、器件和运行器。 - 实现
Plugin::compile(xir::Subgraph*)
。针对 partition() 函数返回的所有子计算图都会调用该函数。您可附加有关子计算图的信息以供运行时使用。
构建插件
创建外部 get_plugin()
函数,并将实现构建到共享库中。
extern "C" plugin* get_plugin() { return new YOURPLUGIN(); }
使用插件
您可在 vai_c 命令行选项中使用 --options '{"plugins":
"plugin0,plugin1"}'
将插件库传递到编译器。执行插件时,编译器会打开库,并通过加载名为“get_plugin”的外部函数来创建插件实例。如果指定多个插件,则将按命令行选项定义的顺序来执行这些插件。DPU 和 CPU 编译将在所有插件都实现后再执行。