3131#include " paddle/fluid/framework/ir/graph.h"
3232#include " paddle/fluid/framework/ir/graph_helper.h"
3333
34- DEFINE_bool (enable_subgraph_optimize, false ,
35- " SubGraph also reuse global graph variables, it will reduce the "
36- " memory occupation"
37- " but a higher risk of memory reuse error. default disabled." );
38- DEFINE_string (memory_optimize_debug, " " ,
39- " debug the operator output variable when do the variable reuse."
40- " memory reuse pass."
41- " only for debug, default disabled." );
42-
4334namespace paddle {
4435namespace framework {
4536namespace ir {
@@ -57,15 +48,6 @@ void MemoryOptimizePass::ApplyImpl(ir::Graph* graph) const {
5748 auto * op_desc = op->Op ();
5849 // some op in graph has no op desc
5950 if (op_desc == nullptr ) continue ;
60- if (OpHasSubBlock (op_desc)) {
61- if (FLAGS_enable_subgraph_optimize) {
62- SubGraphOptimize (op_desc);
63- } else {
64- VLOG (3 ) << op->Name ()
65- << " has subblock, but disable subgraph optimize. skipped." ;
66- continue ;
67- }
68- }
6951
7052 for (auto & var : op->outputs ) {
7153 if (var->IsVar () && !var->IsCtrlVar () && skip_set_.count (var->Name ())) {
@@ -82,13 +64,6 @@ void MemoryOptimizePass::ApplyImpl(ir::Graph* graph) const {
8264 << " replace it again. Skip this candidate." ;
8365 cache = pool_.FindNextBestFitNode (var, cache);
8466 }
85- if (var->Name () == FLAGS_memory_optimize_debug) {
86- VLOG (3 ) << " start match var " << DebugString (var) << " of op "
87- << op->Name ();
88- VLOG (3 ) << pool_.ToString ();
89- VLOG (3 ) << " matched in pool : "
90- << ((cache == nullptr ) ? " False" : " True" );
91- }
9267
9368 if (cache != nullptr ) {
9469 int node_idx_in_pool = pool_.GetNodeIndexInPool (cache);
@@ -128,81 +103,6 @@ void MemoryOptimizePass::ApplyImpl(ir::Graph* graph) const {
128103 graph->ResolveHazard (var_nodes_);
129104}
130105
131- void MemoryOptimizePass::SubGraphOptimize (OpDesc* op_desc) const {
132- // conditional block, while op and their grad op
133- auto * sub_block_desc =
134- AttrReader (op_desc->GetAttrMap ()).Get <BlockDesc*>(" sub_block" );
135-
136- // create a mirror block to construct an IR Graph.
137- ProgramDesc prog;
138- auto * copy_block = prog.MutableBlock (0 );
139- for (auto * op : sub_block_desc->AllOps ()) {
140- auto * copy_op = copy_block->AppendOp ();
141- copy_op->CopyFrom (*op);
142- copy_op->Flush ();
143- }
144-
145- for (auto * var : sub_block_desc->AllVars ()) {
146- auto * copy_var = copy_block->Var (var->Name ());
147- copy_var->SetDataType (var->GetDataType ());
148- // only lod tensor can be reused. So ignore the multiple dims case.
149- copy_var->SetType (var->GetType ());
150- copy_var->SetShape (var->GetShape ());
151- copy_var->SetPersistable (var->Persistable ());
152- }
153-
154- ir::Graph sub_graph (prog);
155- std::unordered_set<ir::Node*> sub_graph_all_ops;
156- FilterVariables (sub_graph.Nodes (), [&](ir::Node* var) {
157- // sub_graph_all_ops.emplace(var);
158- if (var->IsVar () && !var->IsCtrlVar ()) {
159- sub_graph_all_ops.emplace (var);
160- }
161- });
162- int sub_reuse_id = 0 ;
163- // subgraph nodes is unordered, reuse need to follow the desc order.
164- // find the right op node through the descs
165- for (auto * sub_op_desc : sub_block_desc->AllOps ()) {
166- ir::Node* sub_op = nullptr ;
167- for (auto * node : sub_graph_all_ops) {
168- if (node->Op () == sub_op_desc) {
169- sub_op = node;
170- break ;
171- }
172- }
173- PADDLE_ENFORCE (sub_op != nullptr );
174- for (auto * var : sub_op->outputs ) {
175- if (NodeCanReused (var)) {
176- ir::Node* cache = pool_.FindBestFitNode (var);
177- if (cache != nullptr ) {
178- if (var->Var ()->GetDataType () != cache->Var ()->GetDataType ()) {
179- continue ;
180- }
181- int node_idx_in_pool = pool_.GetNodeIndexInPool (cache);
182- VLOG (3 ) << string::Sprintf (
183- " !!! %s, %s => %s, cache idx %d, pool size %d" ,
184- std::to_string (sub_reuse_id++), DebugString (var),
185- DebugString (cache), node_idx_in_pool,
186- static_cast <int >(pool_.size ()));
187- // NOTE(dzh): subblock is not in IR graph. Modify the block_desc
188- // immediately to make the subblock variable reuse strategy take
189- // effect. Because it is a single op in graph. No need to
190- // update the ir nodes.
191- // FIXME(liuwei1031): Graph is not aware of the existence of
192- // BlockDescs and ProgramDescs.
193- // The operations related to BlockDesc or ProgramDesc should perform
194- // on Graph or Node directly!
195- sub_op_desc->Rename (var->Name (), cache->Name ());
196- if (sub_op_desc->Block () != nullptr &&
197- sub_op_desc->Block ()->HasVar (var->Name ())) {
198- sub_op_desc->Block ()->RemoveVar (var->Name ());
199- }
200- }
201- }
202- }
203- }
204- }
205-
206106void MemoryOptimizePass::CollectSkipVarsSet (ir::Graph* graph) const {
207107 // fill skip_set_
208108 PADDLE_ENFORCE (graph->Has (kMemOptSkipVars ));
0 commit comments