Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
wmsofts
Paddle
提交
f6d99d1f
P
Paddle
项目概览
wmsofts
/
Paddle
与 Fork 源项目一致
Fork自
PaddlePaddle / Paddle
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Paddle
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
f6d99d1f
编写于
7月 20, 2018
作者:
X
Xin Pan
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
polish
上级
c3f6e0e8
变更
4
显示空白变更内容
内联
并排
Showing
4 changed file
with
7 addition
and
220 deletion
+7
-220
paddle/fluid/framework/details/multi_devices_graph_builder.cc
...le/fluid/framework/details/multi_devices_graph_builder.cc
+0
-21
paddle/fluid/framework/details/ssa_graph_builder.cc
paddle/fluid/framework/details/ssa_graph_builder.cc
+0
-42
paddle/fluid/framework/details/ssa_graph_builder.h
paddle/fluid/framework/details/ssa_graph_builder.h
+0
-9
paddle/fluid/framework/ir/graph.cc
paddle/fluid/framework/ir/graph.cc
+7
-148
未找到文件。
paddle/fluid/framework/details/multi_devices_graph_builder.cc
浏览文件 @
f6d99d1f
...
...
@@ -216,21 +216,6 @@ std::vector<ir::Node *> SortOpsAndDelayOptimizeOp(const ir::Graph &graph) {
sorted_ret
.
insert
(
sorted_ret
.
begin
()
+
last_backward
,
optimize_ops
.
begin
(),
optimize_ops
.
end
());
for
(
ir
::
Node
*
n
:
sorted_ret
)
{
n
->
inputs
.
erase
(
std
::
remove_if
(
n
->
inputs
.
begin
(),
n
->
inputs
.
end
(),
[
n
](
ir
::
Node
*
t
)
{
return
t
->
Name
()
==
ir
::
Node
::
kControlDepVarName
;
}),
n
->
inputs
.
end
());
n
->
outputs
.
erase
(
std
::
remove_if
(
n
->
outputs
.
begin
(),
n
->
outputs
.
end
(),
[
n
](
ir
::
Node
*
t
)
{
return
t
->
Name
()
==
ir
::
Node
::
kControlDepVarName
;
}),
n
->
outputs
.
end
());
}
return
sorted_ret
;
}
...
...
@@ -365,12 +350,6 @@ std::unique_ptr<ir::Graph> MultiDevSSAGraphBuilder::Apply(
}
}
/*
Dependency graph has been constructed. However, there are still data
hazards need to be handled.
*/
PolishGraphToSupportDataHazards
(
&
result
);
/*
* Only variables should be the leaves of graph.
*/
...
...
paddle/fluid/framework/details/ssa_graph_builder.cc
浏览文件 @
f6d99d1f
...
...
@@ -17,48 +17,6 @@
namespace
paddle
{
namespace
framework
{
namespace
details
{
void
SSAGraphBuilder
::
PolishGraphToSupportDataHazards
(
ir
::
Graph
*
graph
)
{
for
(
auto
&
var_map
:
graph
->
Get
<
GraphVars
>
(
"vars"
))
{
for
(
auto
&
name_pair
:
var_map
)
{
if
(
name_pair
.
second
.
size
()
<=
1
)
{
continue
;
}
auto
it_new
=
name_pair
.
second
.
rbegin
();
auto
it_old
=
name_pair
.
second
.
rbegin
();
++
it_old
;
for
(;
it_old
!=
name_pair
.
second
.
rend
();
it_new
=
it_old
,
++
it_old
)
{
OpHandleBase
*
write_op
=
(
*
it_new
)
->
GeneratedOp
();
const
auto
&
read_ops
=
(
*
it_old
)
->
PendingOps
();
for
(
auto
*
read_op
:
read_ops
)
{
// Manually add a dependency var from read_op to write_op;
if
(
read_op
==
write_op
)
{
// Read Write is the same op.
continue
;
}
bool
has_dep
=
false
;
for
(
auto
read_out
:
read_op
->
Outputs
())
{
for
(
auto
write_in
:
write_op
->
Inputs
())
{
if
(
read_out
==
write_in
)
{
has_dep
=
true
;
break
;
}
}
}
if
(
has_dep
)
continue
;
auto
*
dep_var
=
new
DummyVarHandle
(
graph
->
CreateEmptyNode
(
"dummy"
,
ir
::
Node
::
Type
::
kVariable
));
read_op
->
AddOutput
(
dep_var
);
write_op
->
AddInput
(
dep_var
);
graph
->
Get
<
GraphDepVars
>
(
"dep_vars"
).
emplace
(
dep_var
);
}
}
}
}
}
VarHandle
*
SSAGraphBuilder
::
CreateOrGetLatestVarHandle
(
ir
::
Graph
*
graph
,
ir
::
Node
*
node
,
const
platform
::
Place
&
place
,
size_t
place_offset
)
{
...
...
paddle/fluid/framework/details/ssa_graph_builder.h
浏览文件 @
f6d99d1f
...
...
@@ -57,15 +57,6 @@ class SSAGraphBuilder : public ir::Pass {
DISABLE_COPY_AND_ASSIGN
(
SSAGraphBuilder
);
protected:
/**
* We only handle write after read(WAR), since it should not have a write
* after write in program. If there are write after write operators, we need
* prune them.
*
* https://en.wikipedia.org/wiki/Hazard_(computer_architecture)#Write_after_read_(WAR)
*/
static
void
PolishGraphToSupportDataHazards
(
ir
::
Graph
*
graph
);
static
VarHandle
*
CreateOrGetLatestVarHandle
(
ir
::
Graph
*
graph
,
ir
::
Node
*
node
,
const
platform
::
Place
&
place
,
size_t
place_offset
);
...
...
paddle/fluid/framework/ir/graph.cc
浏览文件 @
f6d99d1f
...
...
@@ -23,39 +23,6 @@ limitations under the License. */
namespace
paddle
{
namespace
framework
{
namespace
ir
{
/*
namespace {
void SortHelper(
const std::map<ir::Node *, std::unordered_set<ir::Node *>> &adj_list,
ir::Node *node, std::unordered_set<ir::Node *> *visited,
std::vector<ir::Node *> *ret) {
visited->insert(node);
for (auto adj : adj_list.at(node)) {
if (visited->find(adj) == visited->end()) {
SortHelper(adj_list, adj, visited, ret);
}
}
VLOG(3) << "topology sort insert: " << node->Name()
<< reinterpret_cast<void *>(node) << " input " << node->inputs.size();
ret->push_back(node);
}
std::vector<ir::Node*> TopologySortOperations(
const std::map<ir::Node *, std::unordered_set<ir::Node *>> &adj_list) {
std::unordered_set<ir::Node *> visited;
std::vector<ir::Node *> ret;
for (auto adj : adj_list) {
if (visited.find(adj.first) == visited.end()) {
SortHelper(adj_list, adj.first, &visited, &ret);
}
}
return ret;
}
} // namespace
*/
Graph
::
Graph
(
const
ProgramDesc
&
program
)
:
program_
(
program
)
{
VLOG
(
3
)
<<
"block in program:"
<<
program_
.
Size
();
...
...
@@ -93,6 +60,13 @@ Graph::Graph(const ProgramDesc &program) : program_(program) {
var
->
inputs
.
push_back
(
node
);
}
}
/**
* We only handle write after read(WAR), since it should not have a write
* after write in program. If there are write after write operators, we need
* prune them.
*
* https://en.wikipedia.org/wiki/Hazard_(computer_architecture)#Write_after_read_(WAR)
*/
for
(
auto
&
var
:
var_nodes
)
{
auto
&
versions
=
var
.
second
;
if
(
versions
.
size
()
<=
1
)
continue
;
...
...
@@ -121,121 +95,6 @@ Graph::Graph(const ProgramDesc &program) : program_(program) {
}
}
}
/*
bool HasCircleHelper(ir::Node* node,
const std::map<ir::Node *, std::unordered_set<ir::Node *>>
&adj_list,
std::unordered_set<ir::Node*>* visited,
std::unordered_set<ir::Node*>* in_trace) {
if (visited->find(node) == visited->end()) {
visited->insert(node);
in_trace->insert(node);
for (ir::Node *in : adj_list.at(node)) {
if (visited->find(in) == visited->end() &&
HasCircleHelper(in, adj_list, visited, in_trace)) {
return true;
} else if (in_trace->find(in) != in_trace->end()) {
return true;
}
}
}
in_trace->erase(node);
return false;
}
bool HasCircle(const std::map<ir::Node *, std::unordered_set<ir::Node *>>
&adj_list) {
std::unordered_set<ir::Node*> visited;
std::unordered_set<ir::Node*> in_trace;
for (auto& adj : adj_list) {
if (HasCircleHelper(adj.first, adj_list, &visited, &in_trace)) {
return true;
}
}
return false;
}
std::map<ir::Node *, std::unordered_set<ir::Node *>> BuildOperationAdjList(
const std::vector<ir::Node*> &nodes) {
std::map<ir::Node *, std::unordered_set<ir::Node *>> adj_list;
for (auto &n : nodes) {
if (n->NodeType() != ir::Node::Type::kOperation) continue;
if (adj_list.find(n) == adj_list.end()) {
adj_list[n] = std::unordered_set<ir::Node *>();
}
for (auto &var : n->inputs) {
for (auto &adj_n : var->inputs) {
PADDLE_ENFORCE(adj_n->NodeType() == ir::Node::Type::kOperation);
adj_list[n].insert(adj_n);
LOG(ERROR) << "adj " << adj_n->Name() << reinterpret_cast<void *>(adj_n)
<< " -> " << n->Name() << reinterpret_cast<void *>(n)
<< " via " << var->Name() << reinterpret_cast<void *>(var);
}
}
}
return adj_list;
}
std::vector<ir::Node *> TopologySortOperationsOperationFromInToOut(
const std::vector<std::unique_ptr<ir::Node>> &nodes) {
std::vector<ir::Node*> tmp;
for (auto& n : nodes) {
tmp.push_back(n.get());
}
std::map<ir::Node *, std::unordered_set<ir::Node *>> adj_list =
BuildOperationAdjList(tmp);
PADDLE_ENFORCE(!HasCircle(adj_list));
std::vector<ir::Node*> ret = TopologySortOperations(adj_list);
ir::Node *last_backward = nullptr;
std::vector<ir::Node *> optimize_ops;
for (ir::Node* n : ret) {
if (boost::get<int>(
n->Op()->GetAttr(OpProtoAndCheckerMaker::OpRoleAttrName())) ==
static_cast<int>(OpRole::kBackward)) {
last_backward = n;
} else if (boost::get<int>(
n->Op()->GetAttr(OpProtoAndCheckerMaker::OpRoleAttrName())) ==
static_cast<int>(OpRole::kOptimize)) {
optimize_ops.push_back(n);
}
}
if (last_backward) {
for (ir::Node *opt_node : optimize_ops) {
ir::Node *dep_var = CreateEmptyNode(ir::Node::kControlDepVarName,
ir::Node::Type::kVariable);
last_backward->outputs.push_back(dep_var);
dep_var->inputs.push_back(last_backward);
opt_node->inputs.push_back(dep_var);
dep_var->outputs.push_back(opt_node);
VLOG(3) << "appending connect: " << last_backward->Name()
<< reinterpret_cast<void *>(last_backward) << "->"
<< opt_node->Name() << reinterpret_cast<void *>(opt_node);
}
}
PADDLE_ENFORCE(!HasCircle(adj_list));
for (ir::Node *n : ret) {
std::unordered_set<ir::Node *> dummy;
n->inputs.erase(
std::remove_if(n->inputs.begin(), n->inputs.end(),
[n](ir::Node *t) {
return t->Name() == ir::Node::kControlDepVarName; }),
n->inputs.end());
n->outputs.erase(
std::remove_if(n->outputs.begin(), n->outputs.end(),
[n](ir::Node *t) {
return t->Name() == ir::Node::kControlDepVarName; }),
n->outputs.end());
}
return ret;
}*/
}
// namespace ir
}
// namespace framework
}
// namespace paddle
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录