Skip to content

Commit 278deba

Browse files
authored
fix comments of 16410, test=develop (#16499)
* fix comments of 16410, test=develop * modify inplace_op_inference_test according to pass interface change, test=develop
1 parent 4c1ec41 commit 278deba

File tree

5 files changed

+184
-154
lines changed

5 files changed

+184
-154
lines changed

paddle/fluid/framework/CMakeLists.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,7 @@ cc_library(prune SRCS prune.cc DEPS framework_proto)
195195
cc_test(prune_test SRCS prune_test.cc DEPS op_info prune recurrent_op device_context)
196196
cc_test(var_type_inference_test SRCS var_type_inference_test.cc DEPS op_registry
197197
proto_desc)
198-
cc_test(inplace_op_inference_test SRCS inplace_op_inference_test.cc DEPS op_registry proto_desc op_info memory_optimize_helper)
199-
198+
cc_test(inplace_op_inference_test SRCS inplace_op_inference_test.cc DEPS inplace_op_pass op_registry proto_desc op_info memory_optimize_helper pass_builder)
200199
cc_library(selected_rows SRCS selected_rows.cc DEPS tensor)
201200
cc_test(selected_rows_test SRCS selected_rows_test.cc DEPS selected_rows)
202201

paddle/fluid/framework/details/inplace_op_pass.cc

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,6 @@ void InplacePass::ApplyImpl(ir::Graph* graph) const {
156156
continue;
157157
TryInplaceOpInputOutput(op, graph);
158158
}
159-
// graph->ResolveHazard(var_nodes_);
160159
}
161160

162161
void InplacePass::InplaceModifyDesc(const std::string& var,
@@ -168,7 +167,7 @@ void InplacePass::InplaceModifyDesc(const std::string& var,
168167
auto* op_desc = op->Op();
169168
op_desc->RenameInput(var, cache_var);
170169
op_desc->RenameOutput(var, cache_var);
171-
if (op_desc->Block()->HasVar(var)) op_desc->Block()->RemoveVar(var);
170+
172171
op_desc->Flush();
173172
}
174173
}
@@ -265,8 +264,6 @@ void InplacePass::WithdrawModify(const NodeSwapQueue& nodes,
265264
void InplacePass::TryInplaceOpInputOutput(ir::Node* op,
266265
ir::Graph* graph) const {
267266
VLOG(4) << "Try to inplace op " << op->Name();
268-
// PADDLE_ENFORCE(op->Op() != nullptr && op->Op()->Block() != nullptr,
269-
// "op_desc is nullptr");
270267
// some pre-requirments need to meet if the op want to inplaced.
271268
PADDLE_ENFORCE(op->Op() != nullptr, "op_desc is nullptr");
272269

@@ -446,19 +443,20 @@ bool GraphView::CheckDeps(ir::Node* var, ir::Node* current_op) const {
446443

447444
// check if op2 depends on op1's output
448445
bool GraphView::CheckOpDeps(ir::Node* op1, ir::Node* op2) const {
449-
auto print_op = [&](ir::Node* op, const char* name) {
450-
std::ostringstream os;
451-
os << " " << name << " : " << op->Name() << " ";
452-
os << "Input args : ";
453-
for (auto& arg : op->inputs) os << arg->Name() << " ";
454-
os << "Output args : ";
455-
for (auto& arg : op->outputs) os << arg->Name() << " ";
456-
os << "Level : " << op_level_.at(op);
457-
VLOG(4) << os.str();
458-
};
459-
print_op(op1, "OP1");
460-
print_op(op2, "OP2");
461-
446+
if (VLOG_IS_ON(4)) {
447+
auto print_op = [&](ir::Node* op, const char* name) {
448+
std::ostringstream os;
449+
os << " " << name << " : " << op->Name() << " ";
450+
os << "Input args : ";
451+
for (auto& arg : op->inputs) os << arg->Name() << " ";
452+
os << "Output args : ";
453+
for (auto& arg : op->outputs) os << arg->Name() << " ";
454+
os << "Level : " << op_level_.at(op);
455+
VLOG(4) << os.str();
456+
};
457+
print_op(op1, "OP1");
458+
print_op(op2, "OP2");
459+
}
462460
if (op1 == op2) return true;
463461
if (op_level_.at(op1) >= op_level_.at(op2)) return false;
464462

paddle/fluid/framework/details/memory_optimize_helper_test.cc

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -142,16 +142,15 @@ TEST(OrderedSet, FindBestFitNode) {
142142
for (auto& node : nodes) {
143143
pool.Insert(node.get());
144144
}
145-
// FIXME(liuwei1031) this API has changed,
146-
// disable these tests temporarily
147-
// FindNextBestFitNode
148-
// auto* n = nodes[0].get();
149-
// auto* cache = pool.FindBestFitNode(n);
150-
// PADDLE_ENFORCE(cache->Name() == "a");
151-
// cache = pool.FindNextBestFitNode(n, cache);
152-
// PADDLE_ENFORCE(cache->Name() == "c");
153-
// cache = pool.FindNextBestFitNode(n, cache);
154-
// PADDLE_ENFORCE(cache->Name() == "b");
145+
146+
auto* n = nodes[0].get();
147+
auto* cache = pool.FindBestFitNode(n);
148+
ASSERT_TRUE(cache->Name() == "a" || cache->Name() == "c");
149+
auto* cache_b = pool.FindNextBestFitNode(n, cache);
150+
ASSERT_TRUE(cache_b->Name() != cache->Name());
151+
ASSERT_TRUE(cache_b->Name() == "a" || cache_b->Name() == "c");
152+
cache = pool.FindNextBestFitNode(n, cache_b);
153+
ASSERT_TRUE(cache == nullptr);
155154
}
156155

157156
} // namespace details

paddle/fluid/framework/inplace_op_inference_test.cc

Lines changed: 146 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,14 @@
1212
See the License for the specific language governing permissions and
1313
limitations under the License. */
1414

15+
#include <iostream>
1516
#include <iterator>
17+
#include <memory>
1618
#include <string>
19+
#include <vector>
1720
#include "gtest/gtest.h"
21+
#include "paddle/fluid/framework/details/inplace_op_pass.h"
22+
#include "paddle/fluid/framework/ir/pass_builder.h"
1823
#include "paddle/fluid/framework/op_info.h"
1924
#include "paddle/fluid/framework/op_registry.h"
2025
#include "paddle/fluid/framework/operator.h"
@@ -165,118 +170,147 @@ REGISTER_OPERATOR(multi_out_grad, f::NOP, f::MultiOutGradInplaceInToOut,
165170
namespace paddle {
166171
namespace framework {
167172

168-
// TEST(InferInplace, SingleOpInplaceInToOut) {
169-
// ProgramDesc prog;
170-
// auto* op = prog.MutableBlock(0)->AppendOp();
171-
// op->SetType("single_op");
172-
// op->SetInput("X", {"test2_a", "test2_b", "test2_c"});
173-
// op->SetOutput("Out", {"test2_out"});
174-
//
175-
// prog.MutableBlock(0)->Var("test2_a")->SetType(proto::VarType::LOD_TENSOR);
176-
// prog.MutableBlock(0)->Var("test2_a")->SetShape({32, 64, 128, 128});
177-
// prog.MutableBlock(0)->Var("test2_b")->SetType(proto::VarType::LOD_TENSOR);
178-
// prog.MutableBlock(0)->Var("test2_c")->SetType(proto::VarType::LOD_TENSOR);
179-
// prog.MutableBlock(0)->Var("test2_out");
180-
// prog.MutableBlock(0)->Var("test2_out")->SetShape({32, 16, 128, 128});
181-
//
182-
// auto& infer_inplace = OpInfoMap::Instance().Get(op->Type()).infer_inplace_;
183-
// auto in_to_outs = infer_inplace(*op);
184-
// EXPECT_EQ(in_to_outs.size(), 1ul);
185-
// auto it = in_to_outs.begin();
186-
// EXPECT_EQ(it->first, "test2_a");
187-
// EXPECT_EQ(it->second, "test2_out");
188-
// }
189-
//
190-
// TEST(InferInplace, SingleGradOpInplaceInToOut) {
191-
// ProgramDesc prog;
192-
// auto* op = prog.MutableBlock(0)->AppendOp();
193-
// op->SetType("single_op_grad");
194-
// op->SetInput(GradVarName("Out"), {"test2_out"});
195-
// op->SetOutput(GradVarName("X"), {"test2_a", "test2_b", "test2_c"});
196-
//
197-
// prog.MutableBlock(0)->Var("test2_a")->SetType(proto::VarType::LOD_TENSOR);
198-
// prog.MutableBlock(0)->Var("test2_a")->SetShape({32, 16, 1024, 1024});
199-
// prog.MutableBlock(0)->Var("test2_b")->SetType(proto::VarType::LOD_TENSOR);
200-
// prog.MutableBlock(0)->Var("test2_c")->SetType(proto::VarType::LOD_TENSOR);
201-
// prog.MutableBlock(0)->Var("test2_out");
202-
// prog.MutableBlock(0)->Var("test2_out")->SetShape({32, 16, 1024, 1024});
203-
//
204-
// auto& infer_inplace = OpInfoMap::Instance().Get(op->Type()).infer_inplace_;
205-
// auto in_to_outs = infer_inplace(*op);
206-
// EXPECT_EQ(in_to_outs.size(), 1ul);
207-
// auto it = in_to_outs.begin();
208-
// EXPECT_EQ(it->first, "test2_out");
209-
// EXPECT_EQ(it->second, "test2_a");
210-
// }
211-
//
212-
// TEST(InferInplace, MultiOutInplaceInToOut) {
213-
// ProgramDesc prog;
214-
// auto* op = prog.MutableBlock(0)->AppendOp();
215-
// op->SetType("multi_out_op");
216-
// op->SetInput("X", {"a0", "a1"});
217-
// op->SetInput("Y", {"b0"});
218-
// op->SetInput("Z", {"c0", "c1"});
219-
// op->SetOutput("Out", {"o0"});
220-
// op->SetOutput("YOut", {"y0"});
221-
// op->SetOutput("ZOut", {"z0"});
222-
//
223-
// prog.MutableBlock(0)->Var("a0")->SetType(proto::VarType::LOD_TENSOR);
224-
// prog.MutableBlock(0)->Var("b0")->SetType(proto::VarType::LOD_TENSOR);
225-
// prog.MutableBlock(0)->Var("c0")->SetType(proto::VarType::LOD_TENSOR);
226-
// prog.MutableBlock(0)->Var("c1")->SetType(proto::VarType::LOD_TENSOR);
227-
// prog.MutableBlock(0)->Var("o0");
228-
// prog.MutableBlock(0)->Var("y0");
229-
// prog.MutableBlock(0)->Var("z0");
230-
// prog.MutableBlock(0)->Var("a0")->SetShape({32, 16, 1024, 1024});
231-
// prog.MutableBlock(0)->Var("b0")->SetShape({32, 16, 1024, 1024});
232-
// prog.MutableBlock(0)->Var("c0")->SetShape({32, 16, 1024, 1024});
233-
// prog.MutableBlock(0)->Var("o0")->SetShape({32, 16, 1024, 1024});
234-
// prog.MutableBlock(0)->Var("y0")->SetShape({32, 16, 1024, 1024});
235-
// prog.MutableBlock(0)->Var("z0")->SetShape({32, 16, 1024, 1024});
236-
//
237-
// auto& infer_inplace = OpInfoMap::Instance().Get(op->Type()).infer_inplace_;
238-
// auto in_to_outs = infer_inplace(*op);
239-
// EXPECT_EQ(in_to_outs.size(), 3ul);
240-
// std::unordered_map<std::string, std::string> expects = {
241-
// {"a0", "o0"}, {"b0", "y0"}, {"c0", "z0"},
242-
// };
243-
// EXPECT_TRUE(expects == in_to_outs);
244-
// }
245-
//
246-
// TEST(InferInplace, MultiGradInplaceInToOut) {
247-
// ProgramDesc prog;
248-
// auto* op = prog.MutableBlock(0)->AppendOp();
249-
// op->SetType("multi_out_grad");
250-
// op->SetInput(GradVarName("Out"), {"o0"});
251-
// op->SetInput(GradVarName("YOut"), {"y0"});
252-
// op->SetInput(GradVarName("ZOut"), {"z0"});
253-
// op->SetOutput(GradVarName("X"), {"a0", "a1"});
254-
// op->SetOutput(GradVarName("Y"), {"b0"});
255-
// op->SetOutput(GradVarName("Z"), {"c0", "c1"});
256-
//
257-
// prog.MutableBlock(0)->Var("a0")->SetType(proto::VarType::LOD_TENSOR);
258-
// prog.MutableBlock(0)->Var("b0")->SetType(proto::VarType::LOD_TENSOR);
259-
// prog.MutableBlock(0)->Var("c0")->SetType(proto::VarType::LOD_TENSOR);
260-
// prog.MutableBlock(0)->Var("c1")->SetType(proto::VarType::LOD_TENSOR);
261-
// prog.MutableBlock(0)->Var("o0");
262-
// prog.MutableBlock(0)->Var("y0");
263-
// prog.MutableBlock(0)->Var("z0");
264-
// prog.MutableBlock(0)->Var("a0")->SetShape({32, 16, 1024, 1024});
265-
// prog.MutableBlock(0)->Var("b0")->SetShape({32, 16, 1024, 1024});
266-
// prog.MutableBlock(0)->Var("c0")->SetShape({32, 16, 1024, 1024});
267-
// prog.MutableBlock(0)->Var("o0")->SetShape({32, 16, 1024, 1024});
268-
// prog.MutableBlock(0)->Var("y0")->SetShape({32, 16, 1024, 1024});
269-
// prog.MutableBlock(0)->Var("z0")->SetShape({32, 16, 1024, 1024});
270-
//
271-
// auto& infer_inplace = OpInfoMap::Instance().Get(op->Type()).infer_inplace_;
272-
// auto in_to_outs = infer_inplace(*op);
273-
//
274-
// EXPECT_EQ(in_to_outs.size(), 3ul);
275-
// std::unordered_map<std::string, std::string> expects = {
276-
// {"o0", "a0"}, {"y0", "b0"}, {"z0", "c0"},
277-
// };
278-
// EXPECT_TRUE(expects == in_to_outs);
279-
// }
173+
void FakeSuccData(ProgramDesc* prog) { // NOLINT
174+
prog->MutableBlock(0)->Var("test2_a")->SetType(proto::VarType::LOD_TENSOR);
175+
prog->MutableBlock(0)->Var("test2_a")->SetShape({32, 64, 128, 128});
176+
prog->MutableBlock(0)->Var("test2_b")->SetType(proto::VarType::LOD_TENSOR);
177+
prog->MutableBlock(0)->Var("test2_c")->SetType(proto::VarType::LOD_TENSOR);
178+
prog->MutableBlock(0)->Var("test2_out");
179+
prog->MutableBlock(0)->Var("test2_out")->SetShape({64, 32, 128, 128});
180+
}
181+
182+
void FakeNoInplaceData(ProgramDesc* prog) { // NOLINT
183+
prog->MutableBlock(0)->Var("test2_a")->SetType(proto::VarType::LOD_TENSOR);
184+
prog->MutableBlock(0)->Var("test2_a")->SetShape({32, 64, 128, 128});
185+
prog->MutableBlock(0)->Var("test2_b")->SetType(proto::VarType::LOD_TENSOR);
186+
prog->MutableBlock(0)->Var("test2_c")->SetType(proto::VarType::LOD_TENSOR);
187+
prog->MutableBlock(0)->Var("test2_out");
188+
prog->MutableBlock(0)->Var("test2_out")->SetShape({64, 31, 128, 128});
189+
}
190+
191+
ir::Node* GetNodeFromGraph(ir::Graph* g, std::string name) {
192+
ir::Node* op_node = nullptr;
193+
for (auto& item : g->Nodes()) {
194+
if (item->Name() == name) {
195+
op_node = item;
196+
break;
197+
}
198+
}
199+
return op_node;
200+
}
201+
202+
std::unique_ptr<ir::Graph> test_SingleOpInplaceInToOut(
203+
std::unique_ptr<ir::Graph> g) {
204+
std::unique_ptr<details::InplacePass> pass(new details::InplacePass());
205+
ir::Node* op_node = GetNodeFromGraph(g.get(), "single_op");
206+
EXPECT_NE(op_node, nullptr);
207+
pass->Apply(g.get());
208+
return g;
209+
}
210+
211+
TEST(InferInplace, SingleOpInplaceInToOut) {
212+
ProgramDesc prog;
213+
auto* op = prog.MutableBlock(0)->AppendOp();
214+
op->SetType("single_op");
215+
op->SetInput("X", {"test2_a", "test2_b", "test2_c"});
216+
op->SetOutput("Out", {"test2_out"});
217+
218+
FakeSuccData(&prog);
219+
std::unique_ptr<ir::Graph> g(new ir::Graph(prog));
220+
g = test_SingleOpInplaceInToOut(std::move(g));
221+
auto op_node = GetNodeFromGraph(g.get(), "single_op");
222+
223+
EXPECT_EQ(op_node->outputs[0]->Name(), "test2_a");
224+
}
225+
226+
TEST(InferInplace, SingleOpInplaceInToOutNoInplace) {
227+
ProgramDesc prog;
228+
auto* op = prog.MutableBlock(0)->AppendOp();
229+
op->SetType("single_op");
230+
op->SetInput("X", {"test2_a", "test2_b", "test2_c"});
231+
op->SetOutput("Out", {"test2_out"});
232+
233+
FakeNoInplaceData(&prog);
234+
std::unique_ptr<ir::Graph> g(new ir::Graph(prog));
235+
g = test_SingleOpInplaceInToOut(std::move(g));
236+
auto op_node = GetNodeFromGraph(g.get(), "single_op");
237+
238+
EXPECT_EQ(op_node->outputs[0]->Name(), "test2_out");
239+
}
240+
241+
TEST(InferInplace, MultiOutInplaceInToOut) {
242+
ProgramDesc prog;
243+
auto* op = prog.MutableBlock(0)->AppendOp();
244+
op->SetType("multi_out_op");
245+
op->SetInput("X", {"a0", "a1"});
246+
op->SetInput("Y", {"b0"});
247+
op->SetInput("Z", {"c0", "c1"});
248+
op->SetOutput("Out", {"o0"});
249+
op->SetOutput("YOut", {"y0"});
250+
op->SetOutput("ZOut", {"z0"});
251+
252+
prog.MutableBlock(0)->Var("a0")->SetType(proto::VarType::LOD_TENSOR);
253+
prog.MutableBlock(0)->Var("b0")->SetType(proto::VarType::LOD_TENSOR);
254+
prog.MutableBlock(0)->Var("c0")->SetType(proto::VarType::LOD_TENSOR);
255+
prog.MutableBlock(0)->Var("c1")->SetType(proto::VarType::LOD_TENSOR);
256+
prog.MutableBlock(0)->Var("o0");
257+
prog.MutableBlock(0)->Var("y0");
258+
prog.MutableBlock(0)->Var("z0");
259+
prog.MutableBlock(0)->Var("a0")->SetShape({32, 16, 1024, 1024});
260+
prog.MutableBlock(0)->Var("b0")->SetShape({32, 16, 1024, 1024});
261+
prog.MutableBlock(0)->Var("c0")->SetShape({32, 16, 1024, 1024});
262+
prog.MutableBlock(0)->Var("o0")->SetShape({32, 16, 1024, 1024});
263+
prog.MutableBlock(0)->Var("y0")->SetShape({32, 16, 1024, 1024});
264+
prog.MutableBlock(0)->Var("z0")->SetShape({32, 16, 1024, 1024});
265+
266+
std::unique_ptr<ir::Graph> g(new ir::Graph(prog));
267+
std::unique_ptr<details::InplacePass> pass(new details::InplacePass());
268+
pass->Apply(g.get());
269+
auto op_node = GetNodeFromGraph(g.get(), "multi_out_op");
270+
ASSERT_TRUE(op_node != nullptr);
271+
EXPECT_EQ(op_node->outputs[0]->Name(), "a0");
272+
EXPECT_EQ(op_node->outputs[1]->Name(), "b0");
273+
EXPECT_EQ(op_node->outputs[2]->Name(), "c0");
274+
}
275+
276+
TEST(InferInplace, MultiGradInplaceInToOut) {
277+
ProgramDesc prog;
278+
auto* op = prog.MutableBlock(0)->AppendOp();
279+
op->SetType("multi_out_grad");
280+
op->SetInput(GradVarName("Out"), {"o0"});
281+
op->SetInput(GradVarName("YOut"), {"y0"});
282+
op->SetInput(GradVarName("ZOut"), {"z0"});
283+
op->SetOutput(GradVarName("X"), {"a0", "a1"});
284+
op->SetOutput(GradVarName("Y"), {"b0"});
285+
op->SetOutput(GradVarName("Z"), {"c0", "c1"});
286+
287+
prog.MutableBlock(0)->Var("a0")->SetType(proto::VarType::LOD_TENSOR);
288+
prog.MutableBlock(0)->Var("b0")->SetType(proto::VarType::LOD_TENSOR);
289+
prog.MutableBlock(0)->Var("c0")->SetType(proto::VarType::LOD_TENSOR);
290+
prog.MutableBlock(0)->Var("c1")->SetType(proto::VarType::LOD_TENSOR);
291+
prog.MutableBlock(0)->Var("o0");
292+
prog.MutableBlock(0)->Var("y0");
293+
prog.MutableBlock(0)->Var("z0");
294+
prog.MutableBlock(0)->Var("a0")->SetShape({32, 16, 1024, 1024});
295+
prog.MutableBlock(0)->Var("b0")->SetShape({32, 16, 1024, 1024});
296+
prog.MutableBlock(0)->Var("c0")->SetShape({32, 16, 1024, 1024});
297+
prog.MutableBlock(0)->Var("o0")->SetShape({32, 16, 1024, 1024});
298+
prog.MutableBlock(0)->Var("y0")->SetShape({32, 16, 1024, 1024});
299+
prog.MutableBlock(0)->Var("z0")->SetShape({32, 15, 1024, 1024});
300+
301+
std::unique_ptr<ir::Graph> g(new ir::Graph(prog));
302+
std::unique_ptr<details::InplacePass> pass(new details::InplacePass());
303+
pass->Apply(g.get());
304+
auto op_node = GetNodeFromGraph(g.get(), "multi_out_grad");
305+
ASSERT_TRUE(op_node != nullptr);
306+
EXPECT_EQ(op_node->outputs[0]->Name(), "o0");
307+
EXPECT_EQ(op_node->outputs[2]->Name(), "y0");
308+
EXPECT_EQ(op_node->outputs[3]->Name(), "c0");
309+
310+
std::unordered_map<std::string, std::string> expects = {
311+
{"o0", "a0"}, {"y0", "b0"}, {"z0", "c0"},
312+
};
313+
}
280314

281315
} // namespace framework
282316
} // namespace paddle

0 commit comments

Comments
 (0)