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

graph_to_program topology sort #33949

Merged

Conversation

thisjiang
Copy link
Contributor

@thisjiang thisjiang commented Jul 4, 2021

PR types

Bug fixes

PR changes

APIs

Describe

This PR solve two problem:

  1. Try new topology sort function for graph_to_program, ensure graph node ordering same.
  2. Allow multi-graph convert to multi-block program.(control by FLAG convert_all_blocks)
  3. Other change (commit:45ed5ba merge from @zhhsplendid 's PR34289.
    1. Sub-block can use variables from parent block and forward block if the sub-block is a backward block. The corresponding graph has nodes for the variables but we didn't pass VarDesc for those nodes, this PR added it. The key code is line 98 of graph.cc.
    2. Due to i, we should distinguish the block for the nodes. We added block_id_ to node.h and related functional code. The key code is line 440 of graph.h
    3. IsConstructedByPartialProgram() should return sub_graph's is_partial_ instead of returning this graph. The key code is line 107 of graph.h
    4. while_op_eager_deletion_pass only handles MainGraph

As before, we can convert graph and program by the following code:

graph = fluid.core.Graph(before_program.desc)
ir_graph = fluid.framework.IrGraph(graph, for_test=False)
after_program = ir_graph.to_program()

The following are some examples:

y = paddle.abs(x)

image

y = paddle.increment(x)

image

cond = fluid.layers.greater_than(x, y)
ie = fluid.layers.IfElse(cond)
with ie.true_block():
    hidden = paddle.increment(t)
    ie.output(hidden)
with ie.false_block():
    hidden = paddle.increment(t)
    ie.output(hidden)

image

@paddle-bot-old
Copy link

paddle-bot-old bot commented Jul 4, 2021

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

for (auto *op : program.Block(0).AllOps()) {
ir::Node *node = CreateOpNode(op);
node->SetDescOrder(desc_order);
++desc_order;
Copy link
Contributor

Choose a reason for hiding this comment

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

45行可以和44行合并。

Copy link
Contributor Author

Choose a reason for hiding this comment

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

我觉得分开写更清晰~多一行少一行无所谓

}

if (out_ops.count(n) == 0) {
out_ops[n] = std::unordered_set<Node *>();
Copy link
Contributor

Choose a reason for hiding this comment

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

感觉只对out_ops[n]进行初始化是不够的,比如第一个op n 有很多个输入 n1, n2 ,这里就会访问out_ops[n1]和out_ops[n2].

Copy link
Contributor Author

Choose a reason for hiding this comment

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

如果只是为了初始化其实是没必要显式这么写的,unordered_map对于一个之前没遇到的key肯定先初始化再insert,这儿特意这样写的目的其实是为了确保out_opsin_ops里会有所有的node。

Copy link
Contributor Author

Choose a reason for hiding this comment

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

为表述清晰,已单独拎出来,并使用at替换[]确保没有未知op

}

while (!q.empty()) {
auto cur_op = q.top();
Copy link
Contributor

Choose a reason for hiding this comment

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

const auto cur_op = q.top();

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

block = program_pb->add_blocks();
block->set_idx(idx);
GraphToBlock(graph->GetSubGraph(idx), block);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

这个for循环是否也应该放在 if (FLAGS_convert_all_blocks) { } 中

Copy link
Contributor Author

Choose a reason for hiding this comment

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

可以的,之前我想的是如果没指定FLAGS_convert_all_blocks的话SubGraphSize的返回值应该是0,这样就不会走循环了。不过加上可以逻辑会更清晰点

@@ -14,6 +14,7 @@ limitations under the License. */

#pragma once

#include <cstdint>
Copy link
Contributor

Choose a reason for hiding this comment

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

注意到 id 是int类型的,如果desc_order也使用int类型,是不是就不用引入这个头文件了

Copy link
Contributor Author

Choose a reason for hiding this comment

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

可以的,desc_order_int或者size_t应该都行

@@ -146,10 +156,17 @@ class Node {
Type type_;
int id_;

static constexpr size_t NO_DESC_ORDER = SIZE_MAX;
size_t desc_order_;
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 Author

Choose a reason for hiding this comment

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

C++中非static const修饰的成员变量是不能在定义时赋初值的(有些编译器是直接报错有些是忽略这个初值),只能在构造函数里赋值。

Copy link
Member

Choose a reason for hiding this comment

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

嗨,看到你们的讨论,插入一下。

查看了一下,似乎是C++ 11后引入的可以在header中定义赋值。

https://stackoverflow.com/questions/24149924/has-the-new-c11-member-initialization-feature-at-declaration-made-initializati

Copy link
Contributor

Choose a reason for hiding this comment

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

是的,后续有一些讨论我和姜程在如流上沟通了

}

size_t SubGraphSize() const {
// wait for https://github.com/PaddlePaddle/Paddle/pull/33320 merged
Copy link
Contributor

Choose a reason for hiding this comment

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

这里需要的接口,在#33320 中写一个comment吧

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

Copy link
Member

@zhhsplendid zhhsplendid left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Contributor

@chenwhql chenwhql left a comment

Choose a reason for hiding this comment

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

LGTM for graph&node

@zhhsplendid zhhsplendid merged commit 167523e into PaddlePaddle:develop Jul 28, 2021
@thisjiang thisjiang deleted the add_graph_to_program_toposort branch July 28, 2021 07:10
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.

4 participants