Skip to content

Commit 0da14c9

Browse files
Merge pull request #16 from PaddlePaddle/develop
update
2 parents cdecaf0 + 28521e0 commit 0da14c9

147 files changed

Lines changed: 3528 additions & 1271 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

paddle/fluid/framework/ir/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,4 +188,6 @@ endif()
188188
cc_test(test_cpu_bfloat16_pass SRCS mkldnn/cpu_bfloat16_pass_tester.cc DEPS cpu_bfloat16_pass)
189189
cc_test(test_multi_gru_fuse_pass SRCS mkldnn/multi_gru_fuse_pass_tester.cc DEPS multi_gru_fuse_pass)
190190
cc_test(test_multi_gru_seq_fuse_pass SRCS mkldnn/multi_gru_seq_fuse_pass_tester.cc DEPS multi_gru_seq_fuse_pass)
191+
set(TEST_FC_RNN_PASS_DEPS fc_gru_fuse_pass fc_lstm_fuse_pass mkldnn_placement_pass)
192+
cc_test(test_fc_rnn_mkldnn_fuse_pass SRCS mkldnn/mkldnn_fc_rnn_fuse_pass_tester.cc DEPS ${TEST_FC_RNN_PASS_DEPS})
191193
endif ()

paddle/fluid/framework/ir/fc_elementwise_layernorm_fuse_pass.cc

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,70 @@ static bool IsEqual(const std::vector<T> &x, const std::vector<T> &y) {
136136
return true;
137137
}
138138

139+
FCElementwiseLayerNormFusePass::FCElementwiseLayerNormFusePass() {
140+
AddOpCompat(OpCompat("fc"))
141+
.AddInput("Input")
142+
.IsTensor()
143+
.End()
144+
.AddInput("W")
145+
.IsTensor()
146+
.End()
147+
.AddInput("Bias")
148+
.IsTensor()
149+
.End()
150+
.AddOutput("Out")
151+
.IsTensor()
152+
.End()
153+
.AddAttr("in_num_col_dims")
154+
.IsNumGE(1)
155+
.End()
156+
.AddAttr("activation_type")
157+
.IsStringIn({"relu", ""})
158+
.End();
159+
160+
AddOpCompat(OpCompat("layer_norm"))
161+
.AddInput("X")
162+
.IsTensor()
163+
.End()
164+
.AddInput("Scale")
165+
.IsTensor()
166+
.End()
167+
.AddInput("Bias")
168+
.IsTensor()
169+
.End()
170+
.AddOutput("Y")
171+
.IsTensor()
172+
.End()
173+
.AddOutput("Mean")
174+
.IsOptional()
175+
.End()
176+
.AddOutput("Variance")
177+
.IsOptional()
178+
.End()
179+
180+
.AddAttr("epsilon")
181+
.IsNumGE(0.0f)
182+
.IsNumLE(0.001f)
183+
.End()
184+
.AddAttr("begin_norm_axis")
185+
.IsNumGT(0)
186+
.End();
187+
188+
AddOpCompat(OpCompat("elementwise_add"))
189+
.AddInput("X")
190+
.IsTensor()
191+
.End()
192+
.AddInput("Y")
193+
.IsTensor()
194+
.End()
195+
.AddOutput("Out")
196+
.IsTensor()
197+
.End()
198+
.AddAttr("axis")
199+
.IsNumEQ(-1)
200+
.End();
201+
}
202+
139203
void FCElementwiseLayerNormFusePass::ApplyImpl(ir::Graph *graph) const {
140204
PADDLE_ENFORCE_NOT_NULL(graph,
141205
platform::errors::InvalidArgument(
@@ -159,6 +223,11 @@ void FCElementwiseLayerNormFusePass::ApplyImpl(ir::Graph *graph) const {
159223
return;
160224
}
161225

226+
if (!IsCompat(subgraph, graph)) {
227+
LOG(WARNING) << "Pass in op compat failed.";
228+
return;
229+
}
230+
162231
VLOG(4) << "handle FCElementwiseLayerNorm fuse";
163232
GET_IR_NODE_FROM_SUBGRAPH(fc, fc, fused_pattern);
164233
GET_IR_NODE_FROM_SUBGRAPH(fc_w, fc_w, fused_pattern);

paddle/fluid/framework/ir/fc_elementwise_layernorm_fuse_pass.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class Graph;
2424

2525
class FCElementwiseLayerNormFusePass : public FusePassBase {
2626
public:
27+
FCElementwiseLayerNormFusePass();
2728
virtual ~FCElementwiseLayerNormFusePass() {}
2829

2930
protected:

paddle/fluid/framework/ir/fc_gru_fuse_pass.cc

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,9 @@ static int BuildFusion(Graph* graph, const std::string& name_scope,
4747
gru_pattern(fc_out);
4848

4949
// Create New OpDesc
50-
auto gru_creater = [&](Node* gru, Node* x, Node* weight_x, Node* weight_h,
51-
Node* bias, Node* hidden, Node* fc_bias) {
50+
auto gru_creator = [&](Node* gru, Node* x, Node* weight_x, Node* weight_h,
51+
Node* bias, Node* hidden, Node* fc_bias,
52+
const bool use_mkldnn) {
5253
OpDesc op_desc;
5354
op_desc.SetType("fusion_gru");
5455

@@ -67,6 +68,7 @@ static int BuildFusion(Graph* graph, const std::string& name_scope,
6768
gru->Op()->GetAttrIfExists<bool>("origin_mode"));
6869
// TODO(TJ): This should be a option for infer
6970
op_desc.SetAttr("use_seq", true);
71+
op_desc.SetAttr("use_mkldnn", use_mkldnn);
7072
op_desc.SetAttr("activation", gru->Op()->GetAttr("activation"));
7173
op_desc.SetAttr("gate_activation", gru->Op()->GetAttr("gate_activation"));
7274

@@ -149,21 +151,26 @@ static int BuildFusion(Graph* graph, const std::string& name_scope,
149151
LOG(INFO) << "fc_gru_fuse_pass not supported when origin_mode=True.";
150152
return;
151153
}
154+
const bool use_mkldnn =
155+
(mul->Op()->GetAttrIfExists<bool>("use_mkldnn") &&
156+
gru->Op()->GetAttrIfExists<std::string>("activation") == "tanh" &&
157+
gru->Op()->GetAttrIfExists<std::string>("gate_activation") ==
158+
"sigmoid");
152159

153160
if (with_fc_bias) {
154161
GET_IR_NODE_FROM_SUBGRAPH(mul_out, mul_out, fc_pattern);
155162
GET_IR_NODE_FROM_SUBGRAPH(fc_bias, bias, fc_pattern);
156163
GET_IR_NODE_FROM_SUBGRAPH(elementwise_add, elementwise_add, fc_pattern);
157164
GET_IR_NODE_FROM_SUBGRAPH(fc_out, elementwise_add_out, fc_pattern);
158165

159-
gru_creater(gru, x_n, w, Weight, Bias, Hidden, fc_bias);
166+
gru_creator(gru, x_n, w, Weight, Bias, Hidden, fc_bias, use_mkldnn);
160167
// Remove unneeded nodes.
161168
std::unordered_set<const Node*> marked_nodes(
162169
{mul, gru, elementwise_add, fc_out, mul_out, BatchGate,
163170
BatchResetHiddenPrev, BatchHidden});
164171
GraphSafeRemoveNodes(graph, marked_nodes);
165172
} else {
166-
gru_creater(gru, x_n, w, Weight, Bias, Hidden, nullptr);
173+
gru_creator(gru, x_n, w, Weight, Bias, Hidden, nullptr, use_mkldnn);
167174
// Remove unneeded nodes.
168175
std::unordered_set<const Node*> marked_nodes(
169176
{mul, gru, BatchGate, BatchResetHiddenPrev, BatchHidden});

paddle/fluid/framework/ir/fc_gru_fuse_pass_tester.cc

Lines changed: 5 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -12,77 +12,15 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
#include "paddle/fluid/framework/ir/fc_gru_fuse_pass.h"
16-
17-
#include <gtest/gtest.h>
18-
#include "paddle/fluid/framework/ir/pass_tester_helper.h"
15+
#include "paddle/fluid/framework/ir/fc_gru_fuse_pass_tester.h"
1916

2017
namespace paddle {
2118
namespace framework {
2219
namespace ir {
2320

24-
void AddVarToScope(Scope* param_scope, const std::string& name,
25-
const DDim& dims) {
26-
auto* tensor = param_scope->Var(name)->GetMutable<LoDTensor>();
27-
tensor->Resize(dims);
28-
tensor->mutable_data<float>(platform::CPUPlace());
29-
}
30-
31-
Scope* CreateParamScope() {
32-
auto param_scope = new Scope();
33-
AddVarToScope(param_scope, "gru_fc_w", {});
34-
AddVarToScope(param_scope, "gru_fc_b", {});
35-
AddVarToScope(param_scope, "gru_w", {});
36-
AddVarToScope(param_scope, "gru_b", {});
37-
AddVarToScope(param_scope, "gru_batch_gate_0", {});
38-
AddVarToScope(param_scope, "gru_batch_reset_hidden_prev_0", {});
39-
AddVarToScope(param_scope, "gru_batch_hidden_0", {});
40-
AddVarToScope(param_scope, "gru_hidden_0", {});
41-
AddVarToScope(param_scope, "gru_batch_gate_1", {});
42-
AddVarToScope(param_scope, "gru_batch_reset_hidden_prev_1", {});
43-
AddVarToScope(param_scope, "gru_batch_hidden_1", {});
44-
AddVarToScope(param_scope, "gru_hidden_1", {});
45-
return param_scope;
46-
}
47-
48-
TEST(FCFusePass, basic) {
49-
// inputs operator output
50-
// --------------------------------------------------------
51-
// (a, gru_fc_w) mul -> fc_0_tmp_0
52-
// (fc_0_tmp_0, gru_fc_b) elementwise_add -> fc_0_tmp_1
53-
// (fc_0_tmp_1,gru_w,gru_b gru -> gru_out_0
54-
55-
// (b, gru_fc_w) mul -> fc_1_tmp_0
56-
// (fc_1_tmp_0, gru_fc_b) elementwise_add -> fc_1_tmp_1
57-
// (fc_1_tmp_1,gru_w,gru_b) gru -> gru_out_1
58-
Layers layers;
59-
auto* a = layers.data("a");
60-
auto* b = layers.data("b");
61-
auto* fc_w = layers.data("gru_fc_w", {}, true);
62-
auto* fc_b = layers.data("gru_fc_b", {}, true);
63-
auto* gru_w = layers.data("gru_w", {}, true);
64-
auto* gru_b = layers.data("gru_b", {}, true);
65-
auto* fc_0_tmp0 = layers.mul(a, fc_w);
66-
auto* fc_0_tmp1 = layers.elementwise_add(fc_0_tmp0, fc_b);
67-
auto* gru_batch_gate_0 = layers.data("gru_batch_gate_0", {}, false);
68-
auto* gru_batch_reset_hidden_prev_0 =
69-
layers.data("gru_batch_reset_hidden_prev_0", {}, false);
70-
auto* gru_batch_hidden_0 = layers.data("gru_batch_hidden_0", {}, false);
71-
auto* gru_hidden_0 = layers.data("gru_hidden_0", {}, false);
72-
layers.gru(fc_0_tmp1, gru_w, gru_b, gru_batch_gate_0,
73-
gru_batch_reset_hidden_prev_0, gru_batch_hidden_0, gru_hidden_0);
74-
75-
auto* fc_1_tmp0 = layers.mul(b, fc_w);
76-
auto* fc_1_tmp1 = layers.elementwise_add(fc_1_tmp0, fc_b);
77-
auto* gru_batch_gate_1 = layers.data("gru_batch_gate_1", {}, false);
78-
auto* gru_batch_reset_hidden_prev_1 =
79-
layers.data("gru_batch_reset_hidden_prev_1", {}, false);
80-
auto* gru_batch_hidden_1 = layers.data("gru_batch_hidden_1", {}, false);
81-
auto* gru_hidden_1 = layers.data("gru_hidden_1", {}, false);
82-
layers.gru(fc_1_tmp1, gru_w, gru_b, gru_batch_gate_1,
83-
gru_batch_reset_hidden_prev_1, gru_batch_hidden_1, gru_hidden_1);
84-
85-
std::unique_ptr<ir::Graph> graph(new ir::Graph(layers.main_program()));
21+
namespace fc_gru_test {
22+
TEST(FcGruFusePass, basic) {
23+
std::unique_ptr<ir::Graph> graph = PrepareGraph();
8624
auto pass = PassRegistry::Instance().Get("fc_gru_fuse_pass");
8725
pass->Set("use_gpu", new bool(true));
8826
graph->Set("__param_scope__", CreateParamScope());
@@ -109,6 +47,7 @@ TEST(FCFusePass, basic) {
10947
"expectations after fuse"));
11048
}
11149

50+
} // namespace fc_gru_test
11251
} // namespace ir
11352
} // namespace framework
11453
} // namespace paddle
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
// Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
#pragma once
15+
16+
#include "paddle/fluid/framework/ir/fc_gru_fuse_pass.h"
17+
18+
#include <gtest/gtest.h>
19+
#include "paddle/fluid/framework/ir/pass_tester_helper.h"
20+
21+
namespace paddle {
22+
namespace framework {
23+
namespace ir {
24+
25+
namespace fc_gru_test {
26+
void AddVarToScope(Scope* param_scope, const std::string& name,
27+
const DDim& dims) {
28+
auto* tensor = param_scope->Var(name)->GetMutable<LoDTensor>();
29+
tensor->Resize(dims);
30+
tensor->mutable_data<float>(platform::CPUPlace());
31+
}
32+
33+
Scope* CreateParamScope() {
34+
auto param_scope = new Scope();
35+
AddVarToScope(param_scope, "gru_fc_w", {});
36+
AddVarToScope(param_scope, "gru_fc_b", {});
37+
AddVarToScope(param_scope, "gru_w", {});
38+
AddVarToScope(param_scope, "gru_b", {});
39+
AddVarToScope(param_scope, "gru_batch_gate_0", {});
40+
AddVarToScope(param_scope, "gru_batch_reset_hidden_prev_0", {});
41+
AddVarToScope(param_scope, "gru_batch_hidden_0", {});
42+
AddVarToScope(param_scope, "gru_hidden_0", {});
43+
AddVarToScope(param_scope, "gru_batch_gate_1", {});
44+
AddVarToScope(param_scope, "gru_batch_reset_hidden_prev_1", {});
45+
AddVarToScope(param_scope, "gru_batch_hidden_1", {});
46+
AddVarToScope(param_scope, "gru_hidden_1", {});
47+
return param_scope;
48+
}
49+
50+
std::unique_ptr<ir::Graph> PrepareGraph(
51+
std::string activation = "tanh", std::string gate_activation = "sigmoid") {
52+
// inputs operator output
53+
// --------------------------------------------------------
54+
// (a, gru_fc_w) mul -> fc_0_tmp_0
55+
// (fc_0_tmp_0, gru_fc_b) elementwise_add -> fc_0_tmp_1
56+
// (fc_0_tmp_1,gru_w,gru_b gru -> gru_out_0
57+
58+
// (b, gru_fc_w) mul -> fc_1_tmp_0
59+
// (fc_1_tmp_0, gru_fc_b) elementwise_add -> fc_1_tmp_1
60+
// (fc_1_tmp_1,gru_w,gru_b) gru -> gru_out_1
61+
Layers layers;
62+
auto* a = layers.data("a");
63+
auto* b = layers.data("b");
64+
auto* fc_w = layers.data("gru_fc_w", {}, true);
65+
auto* fc_b = layers.data("gru_fc_b", {}, true);
66+
auto* gru_w = layers.data("gru_w", {}, true);
67+
auto* gru_b = layers.data("gru_b", {}, true);
68+
auto* fc_0_tmp0 = layers.mul(a, fc_w);
69+
auto* fc_0_tmp1 = layers.elementwise_add(fc_0_tmp0, fc_b);
70+
auto* gru_batch_gate_0 = layers.data("gru_batch_gate_0", {}, false);
71+
auto* gru_batch_reset_hidden_prev_0 =
72+
layers.data("gru_batch_reset_hidden_prev_0", {}, false);
73+
auto* gru_batch_hidden_0 = layers.data("gru_batch_hidden_0", {}, false);
74+
auto* gru_hidden_0 = layers.data("gru_hidden_0", {}, false);
75+
layers.gru(fc_0_tmp1, gru_w, gru_b, gru_batch_gate_0,
76+
gru_batch_reset_hidden_prev_0, gru_batch_hidden_0, gru_hidden_0,
77+
nullptr, false, false, activation, gate_activation);
78+
79+
auto* fc_1_tmp0 = layers.mul(b, fc_w);
80+
auto* fc_1_tmp1 = layers.elementwise_add(fc_1_tmp0, fc_b);
81+
auto* gru_batch_gate_1 = layers.data("gru_batch_gate_1", {}, false);
82+
auto* gru_batch_reset_hidden_prev_1 =
83+
layers.data("gru_batch_reset_hidden_prev_1", {}, false);
84+
auto* gru_batch_hidden_1 = layers.data("gru_batch_hidden_1", {}, false);
85+
auto* gru_hidden_1 = layers.data("gru_hidden_1", {}, false);
86+
layers.gru(fc_1_tmp1, gru_w, gru_b, gru_batch_gate_1,
87+
gru_batch_reset_hidden_prev_1, gru_batch_hidden_1, gru_hidden_1,
88+
nullptr, false, false, activation, gate_activation);
89+
90+
std::unique_ptr<ir::Graph> graph(new ir::Graph(layers.main_program()));
91+
return std::move(graph);
92+
}
93+
} // namespace fc_gru_test
94+
} // namespace ir
95+
} // namespace framework
96+
} // namespace paddle

paddle/fluid/framework/ir/fc_lstm_fuse_pass.cc

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ int BuildFusion(Graph* graph, const std::string& name_scope, Scope* scope,
4747
// Create New OpDesc
4848
auto lstm_creator = [&](Node* lstm, Node* input, Node* weight_x,
4949
Node* weight_h, Node* bias, Node* hidden, Node* cell,
50-
Node* xx, Node* fc_bias) {
50+
Node* xx, Node* fc_bias, const bool use_mkldnn) {
5151
OpDesc op_desc;
5252
op_desc.SetType("fusion_lstm");
5353
#define SET_IN(Key, node__) op_desc.SetInput(#Key, {node__->Name()});
@@ -88,6 +88,7 @@ int BuildFusion(Graph* graph, const std::string& name_scope, Scope* scope,
8888
op_desc.SetOutput("XX", {xx->Name()});
8989
op_desc.SetAttr("is_reverse", lstm->Op()->GetAttr("is_reverse"));
9090
op_desc.SetAttr("use_peepholes", lstm->Op()->GetAttr("use_peepholes"));
91+
op_desc.SetAttr("use_mkldnn", use_mkldnn);
9192
// TODO(TJ): get from attr
9293
op_desc.SetAttr("use_seq", true);
9394

@@ -148,21 +149,30 @@ int BuildFusion(Graph* graph, const std::string& name_scope, Scope* scope,
148149
GET_IR_NODE_FROM_SUBGRAPH(Cell, Cell, lstm_pattern);
149150
GET_IR_NODE_FROM_SUBGRAPH(w, w, fc_pattern);
150151
GET_IR_NODE_FROM_SUBGRAPH(mul, mul, fc_pattern);
152+
const bool use_mkldnn =
153+
(mul->Op()->GetAttrIfExists<bool>("use_mkldnn") &&
154+
lstm->Op()->GetAttrIfExists<std::string>("gate_activation") ==
155+
"sigmoid" &&
156+
lstm->Op()->GetAttrIfExists<std::string>("cell_activation") ==
157+
"tanh" &&
158+
lstm->Op()->GetAttrIfExists<std::string>("candidate_activation") ==
159+
"tanh");
160+
151161
if (with_fc_bias) {
152162
GET_IR_NODE_FROM_SUBGRAPH(fc_out, elementwise_add_out, fc_pattern);
153163
GET_IR_NODE_FROM_SUBGRAPH(fc_bias, bias, fc_pattern);
154164
GET_IR_NODE_FROM_SUBGRAPH(mul_out, mul_out, fc_pattern);
155165
GET_IR_NODE_FROM_SUBGRAPH(elementwise_add, elementwise_add, fc_pattern);
156166
lstm_creator(lstm, subgraph.at(x), w, Weight, Bias, Hidden, Cell, fc_out,
157-
fc_bias);
167+
fc_bias, use_mkldnn);
158168
// Remove unneeded nodes.
159169
std::unordered_set<const Node*> marked_nodes(
160170
{mul, lstm, elementwise_add, mul_out, BatchGate, BatchCellPreAct});
161171
GraphSafeRemoveNodes(graph, marked_nodes);
162172
} else {
163173
GET_IR_NODE_FROM_SUBGRAPH(fc_out, mul_out, fc_pattern);
164174
lstm_creator(lstm, subgraph.at(x), w, Weight, Bias, Hidden, Cell, fc_out,
165-
nullptr);
175+
nullptr, use_mkldnn);
166176
// Remove unneeded nodes.
167177
std::unordered_set<const Node*> marked_nodes(
168178
{mul, lstm, BatchGate, BatchCellPreAct});

0 commit comments

Comments
 (0)