Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize the subgraph generated by BuildCinnPass #36503

Merged
merged 4 commits into from
Oct 19, 2021

Conversation

thisjiang
Copy link
Contributor

@thisjiang thisjiang commented Oct 18, 2021

PR types

Others

PR changes

APIs

Describe

如题, 基于 #36345 进一步优化BuildCinnPass生成的Cinn子图逻辑:

  1. 对于非Parameter input,需要通过feed op来获取shape和dtype,因此需要额外添加一个feed node
  2. 对于Parameter output,则是从scope中获取shape和dtype,无需增加一个feed node
  3. 无论是input还是output,在子图中都需要新建一个node,以此来避免与其它图粘连,即保证子图是完全独立的

用例

其输入为一个Graph,输出为std::vector<std::unique_ptr<Graph>>,并通过cinn_subgraphs属性返回。

auto pass = paddle::framework::ir::PassRegistry::Instance().Get("build_cinn_pass");
std::vector<std::unique_ptr<Graph>> cinn_subgraphs;
pass->SetNotOwned<std::vector<std::unique_ptr<Graph>>>("cinn_subgraphs", &cinn_subgraphs);
pass->Apply(graph);

上述变量cinn_subgraphs即为我们筛选出的所有CINN支持的子图。

示例

详情示例请见单测文件:build_cinn_pass_test.cc, 具体而言,分为如下几种情况:

注:假定下述var2均为Parameter

Graph中不含任何CINN支持的Op

var1 --
       | --> fake1 --> var3 --> fake2 --> var4
var2 --

Pass前后Graph保持不变,且cinn_subgraphs为空。

Graph由全为CINN支持的OP组成

v1 --
     | --> mul --> v3 --
v2 --                   | --> add --> v5 --> relu --> v6
                   v4 --

Pass后原Graph变为:

v1 --|
v2 --| --> kCinnLaunchOp --> v6
v4 --|

cinn_subgraphs包含一个子图,注意子图中的所有结点都是新创建的,并非原Graph的结点:

feed --> v1 --
              | --> mul --> v3 --
         v2 --                   | --> add --> v5 --> relu --> v6
                   feed --> v4 --

Graph含一个CINN子图

fake1 --> v1 --
               | --> mul --> v3 --> relu --> v4 --> fake2
          v2 --

Pass后原Graph变为:

fake1 --> v1 --
               | --> kCinnLaunchOp --> v4 --> fake2
          v2 --

cinn_subgraphs包含一个子图,注意子图中的所有结点都是新创建的,并非原Graph的结点:

feed --> v1 --
              | --> mul --> v3 --> relu --> v4
         v2 --

Graph包含多个分离的CINN子图

fake1 --> v1 --
               | --> mul --> v3 --> fake2 --> v4 --> relu --> v5 --> fake3
          v2 --

Pass后原Graph变为:

fake1 -> v1 -
             | -> CinnOp -> v3 -> fake2 -> v4 -> CinnOp ->v5 -> fake3
         v2 -

cinn_subgraphs包含2个单op子图,注意子图中的所有结点都是新创建的,并非原Graph的结点:

subgraph1:
feed --> v4 --> relu --> v5
subgraph2:
feed --> v1 --
              | --> mul --> v3
         v2 --

@paddle-bot-old
Copy link

Thanks for your contribution!
Please wait for the result of CI firstly. See Paddle CI Manual for details.

thisjiang added a commit to thisjiang/Paddle that referenced this pull request Oct 18, 2021
}

// Deal with subgraph's parameter var node:
// create a new input var node, it's data will get by scope,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

参数变量为什么不也添加feed_op,这样符号执行时候都从feed_targets去获取输入变量的数据?参数变量在子图划分时会被视作输入变量吗

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. 参数变量是从scope中获取的,feed_targets中只有非参数类型的输入变量。
  2. 参数变量在子图划分时是会被视作输入变量,所以需要保留其Var结点以便在符号执行时区分要从feed_targets中拿还是scope中拿

Comment on lines +321 to +322
// Note that cluster_outputs var node maybe some subgraph op's input,
// here we need remove them.
Copy link
Contributor

@wzzju wzzju Oct 18, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cluster_outputs中的var也不会是任何子图中Op的输入吧?如果是的话,那么这个var岂不是中间节点了?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

中间结点是指:输入输入都是子图结点,这意味着中间结点是某个子图结点的输出但一定不是某个外部结点的输入。若该结点是某个外部结点的输入,那么它是output

var->inputs = {op};

// link feed var to cluster op
var->outputs.clear();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

新创建的OpNode和VarNode如果一定是空的,这些clear操作就不需要的。sub_node->inputs.clear();等语句同理。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

的确不需要,这样是为了明确新创建的var与之前的图没有任何关系

Comment on lines 131 to 132
var->inputs.clear();
var->outputs.clear();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

同上。

Comment on lines 111 to 112
var->inputs.clear();
var->outputs.clear();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

同上。

Copy link
Contributor

@wzzju wzzju left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@wzzju wzzju merged commit 6cdc5a4 into PaddlePaddle:develop Oct 19, 2021
@thisjiang thisjiang deleted the optimize_build_cinn_pass branch October 19, 2021 07:47
thisjiang added a commit that referenced this pull request Oct 23, 2021
* add cinn graph symbolization

* fix some bug

* add paddle scope to cinn scope

* add paddle scope to CINN scope in Symbolization, and add feed op when build cinn pass

* fix some bug

* fix some bug by review advices

* optimize code problem

* revert build_cinn_pass and move the change to #36503

* fix some bug after co-compilation

* perfect single test script

* remove scope and rename feed_target to input_tensor

* using std::unordered_map instead of absl::flat_hash_map

* fix single test bug

* revert to preverion for WITH_CINN has add in later PR

* full error information for CI

* full enfore information for CI pass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants