Skip to content

  • 体验新版
    • 正在加载...
  • 登录
  • PaddlePaddle
  • Paddle
  • Issue
  • #13197

P
Paddle
  • 项目概览

PaddlePaddle / Paddle
大约 2 年 前同步成功

通知 2325
Star 20933
Fork 5424
  • 代码
    • 文件
    • 提交
    • 分支
    • Tags
    • 贡献者
    • 分支图
    • Diff
  • Issue 1423
    • 列表
    • 看板
    • 标记
    • 里程碑
  • 合并请求 543
  • Wiki 0
    • Wiki
  • 分析
    • 仓库
    • DevOps
  • 项目成员
  • Pages
P
Paddle
  • 项目概览
    • 项目概览
    • 详情
    • 发布
  • 仓库
    • 仓库
    • 文件
    • 提交
    • 分支
    • 标签
    • 贡献者
    • 分支图
    • 比较
  • Issue 1,423
    • Issue 1,423
    • 列表
    • 看板
    • 标记
    • 里程碑
  • 合并请求 543
    • 合并请求 543
  • Pages
  • 分析
    • 分析
    • 仓库分析
    • DevOps
  • Wiki 0
    • Wiki
  • 成员
    • 成员
  • 收起侧边栏
  • 动态
  • 分支图
  • 创建新Issue
  • 提交
  • Issue看板
已关闭
开放中
Opened 9月 04, 2018 by saxon_zh@saxon_zhGuest

Fuse based on IR/PASS

Created by: Superjomn

Fusion based on IR/Analysis

PDPattern and PDNode

Pattern related:

  • We treat operator fusion problem as a modification of IR graph

    • extract some subgraphs that meets some pre-defined pattern/rules
    • remove the subgraphs and insert the new fused operator(or a new sub-graph)
  • Get a sub-graph and modify the nodes is easy, so the core problem is how to extract the subgraphs that meets some pattern, and identify the nodes in those subgraphs. We provide some basic module and concept for such graph tasks:

    • PDPattern : a pattern that defines how a target subgraph(or subgraphs) is like
    • PDNode: basic node in a PDPattern, one PDNode corresponding to one Node meets some conditions in the IR graph.
    • The prefix PD represents Pattern-Detector.
    • The PDPattern is a graph of PDNode, so there are nodes(PDNode) and edges in the pattern.
    • Usage:
    PDpattern pattern;
    PDNode* new_node = pattern.NewNode("name");
    // One can add some assertions to help extract the more specific nodes for a pattern.
    PDNode* mul_op = pattern.NewNode("some_op")->assert_is_op("mul");
    PDNode* mul_input = pattern.NewNode("some_var")->assert_is_var()->assert_is_op_input("mul");
    // more assertions can be combined.
    // Because the operator's definition is clear, free to add more assertions to make the
    // PDNode or the PDPattern's rule more clear.
    PDNode* mul_input_x = pattern.NewNode("some_var_clear")->assert_is_op_input("mul", "X");
    // Check the file graph_pattern_detector.h, there are more assertions provided.

    After creating the PDNode, we can add edges to make them a graph

    mul_op->LinksFrom({mul_input, mul_input_x});
    • a.LinksFrom({b,c}) means there are two edges, b->a, c->b
    • a.LinksTo({b, c}) means a->b, a->c
  • Some nodes in the IR after fusion be be removed, so PDNode in a pattern might not share with other patterns, such as the MUL's output variable in a FC pattern, we mark these PDNode as intermediate nodes with the API PDNode.AsIntermediate(). The PDNodes that marked as intermediate can only exists in one pattern. There are two other similar APIS AsInput and AsOutput, not works currently.

Lets take FullyConnected layer combined by mul and elementwise_add op as a example

PDPattern pattern;
// Create operator nodes
auto* mul = pattern->NewNode("mul")->assert_is_op("mul")->AsIntermediate(); // MUL will be removed after fusion, so marked as intermediate;
auto* elementwise_add = pattern->NewNode("elementwise_add")->assert_is_op("elementwise_add")->AsIntermediate();

// Create variables
auto* mul_out = pattern->NewNode("mul_out")->assert_is_op_output("mul")->AsIntermediate();

// Link each other
mul_out->LinksFrom({mul})->LinksTo({elementwise_add});

// PDPattern done

GraphPatternDetector

  • the core module to detect some patterns in the IR graph
  • finally extract some sub-graphs that meets the provided pattern
  • Basic APIs
    • mutable_pattern() get the mutable pattern object, one can customize the pattern
    • operator(graph, handler) to perform the pattern extraction
  • Usages:
GraphPatternDetector pd;
auto* pattern = pd.mutable_pattern();
// Create a pattern
// ...

auto subgraph_handler = [](const GraphPatternDetector::subgraph_t& subgraph, ir::Graph* graph) {
    // Create new ir::Nodes and insert to graph
    // remove the subgraph
};

pd(graph, subgraph_handler);

Best practice

Currently, manully defining PDPattern is quite trivial and fragile. We tried some ways to make it easier:

  • patterns to shared the PDPattern defined for different fusion passes

    • reference the namespace patterns in graph_pattern_detector.h, there should have the FC and LSTM patterns, one can use them as a function, combine them.
    • PDPattern.DotString() will return the DOT code for a pattern, one can easily visualize the pattern.
  • graph_viz_pass to visualization the modification of the IR graph.

    • After each fusion pass, add a graph_viz_pass and it will visualize the IR graph, and make it easier to compare the graphes generated by different passes.

Some real codes

https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/fluid/framework/ir/fc_lstm_fuse_pass.cc#L27

https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/fluid/framework/ir/fc_fuse_pass.cc#L33

指派人
分配到
无
里程碑
无
分配里程碑
工时统计
无
截止日期
无
标识: paddlepaddle/Paddle#13197
渝ICP备2023009037号

京公网安备11010502055752号

网络110报警服务 Powered by GitLab CE v13.7
开源知识
Git 入门 Pro Git 电子书 在线学 Git
Markdown 基础入门 IT 技术知识开源图谱
帮助
使用手册 反馈建议 博客
《GitCode 隐私声明》 《GitCode 服务条款》 关于GitCode
Powered by GitLab CE v13.7