@ -33,15 +33,14 @@ void SegmentInputs(std::vector<std::shared_ptr<Scope>>& step_scopes,
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  PADDLE_ENFORCE ( ! inlinks . empty ( ) ,  " no in links are provided. " ) ; 
 
					 
					 
					 
					  PADDLE_ENFORCE ( ! inlinks . empty ( ) ,  " no in links are provided. " ) ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  for  ( size_t  i  =  0 ;  i  <  inlinks . size ( ) ;  + + i )  { 
 
					 
					 
					 
					  for  ( size_t  i  =  0 ;  i  <  inlinks . size ( ) ;  + + i )  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    Tensor *  input  = 
 
					 
					 
					 
					    Tensor *  input  = 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					        step_scopes [ 0 ] - > GetVariable ( inlinks [ i ] . external ) - > GetMutable < Tensor > ( ) ; 
 
					 
					 
					 
					        step_scopes [ 0 ] - > FindVar ( inlinks [ i ] . external ) - > GetMutable < Tensor > ( ) ; 
 
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					    DDim  dims  =  input - > dims ( ) ; 
 
					 
					 
					 
					    DDim  dims  =  input - > dims ( ) ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    PADDLE_ENFORCE ( static_cast < size_t > ( dims [ 0 ] )  = =  seq_len , 
 
					 
					 
					 
					    PADDLE_ENFORCE ( static_cast < size_t > ( dims [ 0 ] )  = =  seq_len , 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					                   " all the inlinks must have same length " ) ; 
 
					 
					 
					 
					                   " all the inlinks must have same length " ) ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    DDim  step_dims  =  slice_ddim ( dims ,  1 ,  dims . size ( ) ) ; 
 
					 
					 
					 
					    DDim  step_dims  =  slice_ddim ( dims ,  1 ,  dims . size ( ) ) ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    for  ( size_t  j  =  0 ;  j  <  seq_len ;  j + + )  { 
 
					 
					 
					 
					    for  ( size_t  j  =  0 ;  j  <  seq_len ;  j + + )  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					      Tensor *  step_input  =  step_scopes [ j ] 
 
					 
					 
					 
					      Tensor *  step_input  = 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					                               - > CreateVariable ( inlinks [ i ] . internal ) 
 
					 
					 
					 
					          step_scopes [ j ] - > NewVar ( inlinks [ i ] . internal ) - > GetMutable < Tensor > ( ) ; 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					                               - > GetMutable < Tensor > ( ) ; 
 
					 
					 
					 
					 
				
			 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					      * step_input  =  input - > Slice < float > ( j ,  j  +  1 ) ; 
 
					 
					 
					 
					      * step_input  =  input - > Slice < float > ( j ,  j  +  1 ) ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					      step_input - > Resize ( step_dims ) ; 
 
					 
					 
					 
					      step_input - > Resize ( step_dims ) ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    } 
 
					 
					 
					 
					    } 
 
				
			 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
							 
						
					 
					 
					@ -53,12 +52,12 @@ void ConcatOutputs(std::vector<std::shared_ptr<Scope>>& step_scopes,
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					                   const  size_t  seq_len )  { 
 
					 
					 
					 
					                   const  size_t  seq_len )  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  for  ( size_t  i  =  0 ;  i  <  outlinks . size ( ) ;  i + + )  { 
 
					 
					 
					 
					  for  ( size_t  i  =  0 ;  i  <  outlinks . size ( ) ;  i + + )  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    Tensor *  output  = 
 
					 
					 
					 
					    Tensor *  output  = 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					        step_scopes [ 0 ] - > GetVariable ( outlinks [ i ] . external ) - > GetMutable < Tensor > ( ) ; 
 
					 
					 
					 
					        step_scopes [ 0 ] - > FindVar ( outlinks [ i ] . external ) - > GetMutable < Tensor > ( ) ; 
 
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    // TODO(qingiqng) remove following code after adding
 
 
					 
					 
					 
					    // TODO(qingiqng) remove following code after adding
 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    // InferShape in RecurrentGradientOp
 
 
					 
					 
					 
					    // InferShape in RecurrentGradientOp
 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    DDim  step_dims  =  step_scopes [ 0 ] 
 
					 
					 
					 
					    DDim  step_dims  =  step_scopes [ 0 ] 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					                         - > GetVariable ( outlinks [ i ] . internal ) 
 
					 
					 
					 
					                         - > FindVar ( outlinks [ i ] . internal ) 
 
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					                         - > GetMutable < Tensor > ( ) 
 
					 
					 
					 
					                         - > GetMutable < Tensor > ( ) 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					                         - > dims ( ) ; 
 
					 
					 
					 
					                         - > dims ( ) ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    std : : vector < int >  dims_vec  =  vectorize ( step_dims ) ; 
 
					 
					 
					 
					    std : : vector < int >  dims_vec  =  vectorize ( step_dims ) ; 
 
				
			 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
							 
						
					 
					 
					@ -66,9 +65,8 @@ void ConcatOutputs(std::vector<std::shared_ptr<Scope>>& step_scopes,
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    output - > mutable_data < float > ( make_ddim ( dims_vec ) ,  platform : : CPUPlace ( ) ) ; 
 
					 
					 
					 
					    output - > mutable_data < float > ( make_ddim ( dims_vec ) ,  platform : : CPUPlace ( ) ) ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    for  ( size_t  j  =  0 ;  j  <  seq_len ;  j + + )  { 
 
					 
					 
					 
					    for  ( size_t  j  =  0 ;  j  <  seq_len ;  j + + )  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					      Tensor *  step_output  =  step_scopes [ j ] 
 
					 
					 
					 
					      Tensor *  step_output  = 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					                                - > GetVariable ( outlinks [ i ] . internal ) 
 
					 
					 
					 
					          step_scopes [ j ] - > FindVar ( outlinks [ i ] . internal ) - > GetMutable < Tensor > ( ) ; 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					                                - > GetMutable < Tensor > ( ) ; 
 
					 
					 
					 
					 
				
			 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					      // TODO(luotao02) data type and platform::DeviceContext() should set
 
 
					 
					 
					 
					      // TODO(luotao02) data type and platform::DeviceContext() should set
 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					      // correctly
 
 
					 
					 
					 
					      // correctly
 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					      ( output - > Slice < float > ( j ,  j  +  1 ) ) 
 
					 
					 
					 
					      ( output - > Slice < float > ( j ,  j  +  1 ) ) 
 
				
			 
			
		
	
	
		
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
					 
					@ -97,14 +95,14 @@ void LinkMemories(std::vector<std::shared_ptr<Scope>>& scopes,
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  std : : shared_ptr < Scope >  scope  =  scopes [ step_id ] ; 
 
					 
					 
					 
					  std : : shared_ptr < Scope >  scope  =  scopes [ step_id ] ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  std : : shared_ptr < Scope >  linked_scope  =  scopes [ step_id  +  offset ] ; 
 
					 
					 
					 
					  std : : shared_ptr < Scope >  linked_scope  =  scopes [ step_id  +  offset ] ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  for  ( auto &  attr  :  memories )  { 
 
					 
					 
					 
					  for  ( auto &  attr  :  memories )  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    auto  mem  =  scope - > CreateVariable ( attr . pre_var ) - > GetMutable < Tensor > ( ) ; 
 
					 
					 
					 
					    auto  mem  =  scope - > NewVar ( attr . pre_var ) - > GetMutable < Tensor > ( ) ; 
 
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					    // maybe share variable is better?
 
 
					 
					 
					 
					    // maybe share variable is better?
 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    auto  linked_mem  =  linked_scope - > GetVariable ( attr . var ) - > GetMutable < Tensor > ( ) ; 
 
					 
					 
					 
					    auto  linked_mem  =  linked_scope - > FindVar ( attr . var ) - > GetMutable < Tensor > ( ) ; 
 
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					    mem - > ShareDataWith < float > ( * linked_mem ) ; 
 
					 
					 
					 
					    mem - > ShareDataWith < float > ( * linked_mem ) ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    // TODO(qingqing) remove following code
 
 
					 
					 
					 
					    // TODO(qingqing) remove following code
 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    // the memory of current step should be allocated in step net
 
 
					 
					 
					 
					    // the memory of current step should be allocated in step net
 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    auto  m  =  scope - > CreateVariable ( attr . var ) - > GetMutable < Tensor > ( ) ; 
 
					 
					 
					 
					    auto  m  =  scope - > NewVar ( attr . var ) - > GetMutable < Tensor > ( ) ; 
 
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					    // for unit test, as addOp and mulOp are null currently, if not
 
 
					 
					 
					 
					    // for unit test, as addOp and mulOp are null currently, if not
 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    // mutable_data, mem.data() in output will be error. We will
 
 
					 
					 
					 
					    // mutable_data, mem.data() in output will be error. We will
 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    // remove this line after merge the correct addOp and mulOp.
 
 
					 
					 
					 
					    // remove this line after merge the correct addOp and mulOp.
 
 
				
			 
			
		
	
	
		
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
					 
					@ -172,7 +170,7 @@ void InitArgument(const ArgumentName& name,
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					}   // namespace rnn
 
 
					 
					 
					 
					}   // namespace rnn
 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					void  RecurrentAlgorithm : : InferShape ( const  std : : shared_ptr < Scope > &  scope )  const  { 
 
					 
					 
					 
					void  RecurrentAlgorithm : : InferShape ( const  std : : shared_ptr < Scope > &  scope )  const  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  seq_len_  =  scope - > GetVariable ( ( arg_ - > inlinks [ 0 ] ) . external ) 
 
					 
					 
					 
					  seq_len_  =  scope - > FindVar ( ( arg_ - > inlinks [ 0 ] ) . external ) 
 
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					                 - > GetMutable < Tensor > ( ) 
 
					 
					 
					 
					                 - > GetMutable < Tensor > ( ) 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					                 - > dims ( ) [ 0 ] ; 
 
					 
					 
					 
					                 - > dims ( ) [ 0 ] ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  CreateScopes ( scope ) ; 
 
					 
					 
					 
					  CreateScopes ( scope ) ; 
 
				
			 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
							 
						
					 
					 
					@ -187,10 +185,10 @@ void RecurrentAlgorithm::InferShape(const std::shared_ptr<Scope>& scope) const {
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  InitMemories ( step_scopes [ 0 ] ) ; 
 
					 
					 
					 
					  InitMemories ( step_scopes [ 0 ] ) ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  PADDLE_ENFORCE ( scope - > HasVariable ( arg_ - > step_net ) , 
 
					 
					 
					 
					  PADDLE_ENFORCE ( scope - > FindVar ( arg_ - > step_net ) , 
 
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					                 " stepnet [%s] is not in scope. " , 
 
					 
					 
					 
					                 " stepnet [%s] is not in scope. " , 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					                 arg_ - > step_net ) ; 
 
					 
					 
					 
					                 arg_ - > step_net ) ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  Variable *  net  =  scope - > GetVariable ( arg_ - > step_net ) ; 
 
					 
					 
					 
					  Variable *  net  =  scope - > FindVar ( arg_ - > step_net ) ; 
 
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					  PADDLE_ENFORCE ( net  ! =  nullptr ,  " failed to get step net " ) ; 
 
					 
					 
					 
					  PADDLE_ENFORCE ( net  ! =  nullptr ,  " failed to get step net " ) ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  // If the InferShape is called in OperatorBase's run function,
 
 
					 
					 
					 
					  // If the InferShape is called in OperatorBase's run function,
 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  // the rnn op only needs to do InferShape for the first time step
 
 
					 
					 
					 
					  // the rnn op only needs to do InferShape for the first time step
 
 
				
			 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
							 
						
					 
					 
					@ -204,14 +202,14 @@ void RecurrentAlgorithm::InferShape(const std::shared_ptr<Scope>& scope) const {
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  auto  outlinks  =  arg_ - > outlinks ; 
 
					 
					 
					 
					  auto  outlinks  =  arg_ - > outlinks ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  for  ( size_t  i  =  0 ;  i  <  outlinks . size ( ) ;  i + + )  { 
 
					 
					 
					 
					  for  ( size_t  i  =  0 ;  i  <  outlinks . size ( ) ;  i + + )  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    DDim  step_dims  =  step_scopes [ 0 ] 
 
					 
					 
					 
					    DDim  step_dims  =  step_scopes [ 0 ] 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					                         - > GetVariable ( outlinks [ i ] . internal ) 
 
					 
					 
					 
					                         - > FindVar ( outlinks [ i ] . internal ) 
 
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					                         - > GetMutable < Tensor > ( ) 
 
					 
					 
					 
					                         - > GetMutable < Tensor > ( ) 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					                         - > dims ( ) ; 
 
					 
					 
					 
					                         - > dims ( ) ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    std : : vector < int >  dims_vec  =  vectorize ( step_dims ) ; 
 
					 
					 
					 
					    std : : vector < int >  dims_vec  =  vectorize ( step_dims ) ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    // now only support fixed length
 
 
					 
					 
					 
					    // now only support fixed length
 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    dims_vec . insert ( dims_vec . begin ( ) ,  seq_len_ ) ; 
 
					 
					 
					 
					    dims_vec . insert ( dims_vec . begin ( ) ,  seq_len_ ) ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    Tensor *  output  = 
 
					 
					 
					 
					    Tensor *  output  = 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					        step_scopes [ 0 ] - > GetVariable ( outlinks [ i ] . external ) - > GetMutable < Tensor > ( ) ; 
 
					 
					 
					 
					        step_scopes [ 0 ] - > FindVar ( outlinks [ i ] . external ) - > GetMutable < Tensor > ( ) ; 
 
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					    output - > Resize ( make_ddim ( dims_vec ) ) ; 
 
					 
					 
					 
					    output - > Resize ( make_ddim ( dims_vec ) ) ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  } 
 
					 
					 
					 
					  } 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					} 
 
					 
					 
					 
					} 
 
				
			 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
							 
						
					 
					 
					@ -220,7 +218,7 @@ void RecurrentAlgorithm::Run(const std::shared_ptr<Scope>& scope,
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					                             const  platform : : DeviceContext &  dev_ctx )  const  { 
 
					 
					 
					 
					                             const  platform : : DeviceContext &  dev_ctx )  const  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  auto  step_scopes  =  GetStepScopes ( scope ) ; 
 
					 
					 
					 
					  auto  step_scopes  =  GetStepScopes ( scope ) ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  Variable *  net  =  scope - > GetVariable ( arg_ - > step_net ) ; 
 
					 
					 
					 
					  Variable *  net  =  scope - > FindVar ( arg_ - > step_net ) ; 
 
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					  for  ( size_t  step_id  =  0 ;  step_id  <  seq_len_ ;  step_id + + )  { 
 
					 
					 
					 
					  for  ( size_t  step_id  =  0 ;  step_id  <  seq_len_ ;  step_id + + )  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    // the link memory is done in InferShape
 
 
					 
					 
					 
					    // the link memory is done in InferShape
 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    // maybe remove following code after testing
 
 
					 
					 
					 
					    // maybe remove following code after testing
 
 
				
			 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
							 
						
					 
					 
					@ -236,7 +234,7 @@ void RecurrentAlgorithm::Run(const std::shared_ptr<Scope>& scope,
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					void  RecurrentAlgorithm : : CreateScopes ( std : : shared_ptr < Scope >  scope )  const  { 
 
					 
					 
					 
					void  RecurrentAlgorithm : : CreateScopes ( std : : shared_ptr < Scope >  scope )  const  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  // TODO(xxx) Only two scopes are needed for inference, this case will be
 
 
					 
					 
					 
					  // TODO(xxx) Only two scopes are needed for inference, this case will be
 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  // supported later.
 
 
					 
					 
					 
					  // supported later.
 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  auto  step_scopes  =  scope - > GetVariable ( arg_ - > step_scopes ) 
 
					 
					 
					 
					  auto  step_scopes  =  scope - > FindVar ( arg_ - > step_scopes ) 
 
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					                         - > GetMutable < std : : vector < std : : shared_ptr < Scope > > > ( ) ; 
 
					 
					 
					 
					                         - > GetMutable < std : : vector < std : : shared_ptr < Scope > > > ( ) ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  if  ( seq_len_  >  step_scopes - > size ( ) )  { 
 
					 
					 
					 
					  if  ( seq_len_  >  step_scopes - > size ( ) )  { 
 
				
			 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
							 
						
					 
					 
					@ -244,12 +242,12 @@ void RecurrentAlgorithm::CreateScopes(std::shared_ptr<Scope> scope) const {
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					      std : : shared_ptr < Scope >  step_scope  =  std : : make_shared < Scope > ( scope ) ; 
 
					 
					 
					 
					      std : : shared_ptr < Scope >  step_scope  =  std : : make_shared < Scope > ( scope ) ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					      // Now all variables in scope must be created outside of op.
 
 
					 
					 
					 
					      // Now all variables in scope must be created outside of op.
 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					      auto  net_op  =  scope - > GetVariable ( arg_ - > step_net ) - > GetMutable < NetOp > ( ) ; 
 
					 
					 
					 
					      auto  net_op  =  scope - > FindVar ( arg_ - > step_net ) - > GetMutable < NetOp > ( ) ; 
 
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					      for  ( auto &  input  :  net_op - > inputs_ )  { 
 
					 
					 
					 
					      for  ( auto &  input  :  net_op - > inputs_ )  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					        step_scope - > CreateVariable ( input ) ; 
 
					 
					 
					 
					        step_scope - > NewVar ( input ) ; 
 
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					      } 
 
					 
					 
					 
					      } 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					      for  ( auto &  output  :  net_op - > outputs_ )  { 
 
					 
					 
					 
					      for  ( auto &  output  :  net_op - > outputs_ )  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					        step_scope - > CreateVariable ( output ) ; 
 
					 
					 
					 
					        step_scope - > NewVar ( output ) ; 
 
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					      } 
 
					 
					 
					 
					      } 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					      step_scopes - > push_back ( std : : make_shared < Scope > ( step_scope ) ) ; 
 
					 
					 
					 
					      step_scopes - > push_back ( std : : make_shared < Scope > ( step_scope ) ) ; 
 
				
			 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
							 
						
					 
					 
					@ -259,21 +257,18 @@ void RecurrentAlgorithm::CreateScopes(std::shared_ptr<Scope> scope) const {
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					void  RecurrentAlgorithm : : InitMemories ( std : : shared_ptr < Scope >  step_scope )  const  { 
 
					 
					 
					 
					void  RecurrentAlgorithm : : InitMemories ( std : : shared_ptr < Scope >  step_scope )  const  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  for  ( auto &  attr  :  arg_ - > memories )  { 
 
					 
					 
					 
					  for  ( auto &  attr  :  arg_ - > memories )  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    Tensor *  pre_mem  = 
 
					 
					 
					 
					    Tensor *  pre_mem  =  step_scope - > NewVar ( attr . pre_var ) - > GetMutable < Tensor > ( ) ; 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					        step_scope - > CreateVariable ( attr . pre_var ) - > GetMutable < Tensor > ( ) ; 
 
					 
					 
					 
					    PADDLE_ENFORCE ( step_scope - > FindVar ( attr . boot_var ) , 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					    PADDLE_ENFORCE ( step_scope - > HasVariable ( attr . boot_var ) , 
 
					 
					 
					 
					 
				
			 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					                   " memory [%s]'s boot variable [%s] not exists " , 
 
					 
					 
					 
					                   " memory [%s]'s boot variable [%s] not exists " , 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					                   attr . var , 
 
					 
					 
					 
					                   attr . var , 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					                   attr . boot_var ) ; 
 
					 
					 
					 
					                   attr . boot_var ) ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    Tensor *  boot_mem  = 
 
					 
					 
					 
					    Tensor *  boot_mem  =  step_scope - > FindVar ( attr . boot_var ) - > GetMutable < Tensor > ( ) ; 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					        step_scope - > GetVariable ( attr . boot_var ) - > GetMutable < Tensor > ( ) ; 
 
					 
					 
					 
					 
				
			 
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					    pre_mem - > ShareDataWith < float > ( * boot_mem ) ; 
 
					 
					 
					 
					    pre_mem - > ShareDataWith < float > ( * boot_mem ) ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    // TODO(qingqing) remove following code
 
 
					 
					 
					 
					    // TODO(qingqing) remove following code
 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    // the memory of current step should be allocated in step net
 
 
					 
					 
					 
					    // the memory of current step should be allocated in step net
 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    // here for unit test
 
 
					 
					 
					 
					    // here for unit test
 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    auto  cur_step_mem  = 
 
					 
					 
					 
					    auto  cur_step_mem  =  step_scope - > NewVar ( attr . var ) - > GetMutable < Tensor > ( ) ; 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					        step_scope - > CreateVariable ( attr . var ) - > GetMutable < Tensor > ( ) ; 
 
					 
					 
					 
					 
				
			 
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					    cur_step_mem - > mutable_data < float > ( boot_mem - > dims ( ) ,  platform : : CPUPlace ( ) ) ; 
 
					 
					 
					 
					    cur_step_mem - > mutable_data < float > ( boot_mem - > dims ( ) ,  platform : : CPUPlace ( ) ) ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  } 
 
					 
					 
					 
					  } 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					} 
 
					 
					 
					 
					} 
 
				
			 
			
		
	
	
		
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
					 
					@ -337,9 +332,8 @@ void RecurrentGradientAlgorithm::Run(
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    const  platform : : DeviceContext &  dev_ctx )  const  { 
 
					 
					 
					 
					    const  platform : : DeviceContext &  dev_ctx )  const  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  auto  step_scopes  =  GetStepScopes ( scope ) ; 
 
					 
					 
					 
					  auto  step_scopes  =  GetStepScopes ( scope ) ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  rnn : : SegmentInputs ( step_scopes ,  arg_ - > inlinks ,  seq_len_ ) ; 
 
					 
					 
					 
					  rnn : : SegmentInputs ( step_scopes ,  arg_ - > inlinks ,  seq_len_ ) ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  PADDLE_ENFORCE ( scope - > HasVariable ( arg_ - > step_net ) , 
 
					 
					 
					 
					  PADDLE_ENFORCE ( scope - > FindVar ( arg_ - > step_net ) ,  " step net is not in scope. " ) ; 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					                 " step net is not in scope. " ) ; 
 
					 
					 
					 
					  Variable *  net  =  scope - > FindVar ( arg_ - > step_net ) ; 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					  Variable *  net  =  scope - > GetVariable ( arg_ - > step_net ) ; 
 
					 
					 
					 
					 
				
			 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					  PADDLE_ENFORCE ( net  ! =  nullptr ,  " failed to get step net " ) ; 
 
					 
					 
					 
					  PADDLE_ENFORCE ( net  ! =  nullptr ,  " failed to get step net " ) ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  for  ( int  step_id  =  seq_len_  -  1 ;  step_id  > =  0 ;  - - step_id )  { 
 
					 
					 
					 
					  for  ( int  step_id  =  seq_len_  -  1 ;  step_id  > =  0 ;  - - step_id )  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    if  ( static_cast < size_t > ( step_id )  ! =  seq_len_  -  1 )  { 
 
					 
					 
					 
					    if  ( static_cast < size_t > ( step_id )  ! =  seq_len_  -  1 )  { 
 
				
			 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
							 
						
					 
					 
					@ -354,31 +348,29 @@ void RecurrentGradientAlgorithm::Run(
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					void  RecurrentGradientAlgorithm : : LinkBootMemoryGradients ( 
 
					 
					 
					 
					void  RecurrentGradientAlgorithm : : LinkBootMemoryGradients ( 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    std : : shared_ptr < Scope >  step_scope )  const  { 
 
					 
					 
					 
					    std : : shared_ptr < Scope >  step_scope )  const  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  for  ( auto &  attr  :  arg_ - > memories )  { 
 
					 
					 
					 
					  for  ( auto &  attr  :  arg_ - > memories )  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    Tensor *  mem_grad  = 
 
					 
					 
					 
					    Tensor *  mem_grad  =  step_scope - > NewVar ( attr . var ) - > GetMutable < Tensor > ( ) ; 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					        step_scope - > CreateVariable ( attr . var ) - > GetMutable < Tensor > ( ) ; 
 
					 
					 
					 
					 
				
			 
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					    PADDLE_ENFORCE ( mem_grad  ! =  nullptr , 
 
					 
					 
					 
					    PADDLE_ENFORCE ( mem_grad  ! =  nullptr , 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					                   " boot_tensor should be retrieved before " ) ; 
 
					 
					 
					 
					                   " boot_tensor should be retrieved before " ) ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    PADDLE_ENFORCE ( step_scope - > HasVariable ( attr . boot_var ) , 
 
					 
					 
					 
					    PADDLE_ENFORCE ( step_scope - > FindVar ( attr . boot_var ) , 
 
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					                   " memory [%s]'s boot variable [%s] not exists " , 
 
					 
					 
					 
					                   " memory [%s]'s boot variable [%s] not exists " , 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					                   attr . var , 
 
					 
					 
					 
					                   attr . var , 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					                   attr . boot_var ) ; 
 
					 
					 
					 
					                   attr . boot_var ) ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    Tensor *  boot_mem_grad  = 
 
					 
					 
					 
					    Tensor *  boot_mem_grad  = 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					        step_scope - > CreateVariable ( attr . boot_var ) - > GetMutable < Tensor > ( ) ; 
 
					 
					 
					 
					        step_scope - > NewVar ( attr . boot_var ) - > GetMutable < Tensor > ( ) ; 
 
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					    boot_mem_grad - > ShareDataWith < float > ( * mem_grad ) ; 
 
					 
					 
					 
					    boot_mem_grad - > ShareDataWith < float > ( * mem_grad ) ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  } 
 
					 
					 
					 
					  } 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					} 
 
					 
					 
					 
					} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					void  RecurrentGradientAlgorithm : : InferShape ( 
 
					 
					 
					 
					void  RecurrentGradientAlgorithm : : InferShape ( 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    const  std : : shared_ptr < Scope > &  scope )  const  { 
 
					 
					 
					 
					    const  std : : shared_ptr < Scope > &  scope )  const  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  seq_len_  =  scope - > GetVariable ( ( arg_ - > inlinks [ 0 ] ) . external ) 
 
					 
					 
					 
					  seq_len_  =  scope - > FindVar ( ( arg_ - > inlinks [ 0 ] ) . external ) 
 
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					                 - > GetMutable < Tensor > ( ) 
 
					 
					 
					 
					                 - > GetMutable < Tensor > ( ) 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					                 - > dims ( ) [ 0 ] ; 
 
					 
					 
					 
					                 - > dims ( ) [ 0 ] ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  auto  step_scopes  =  GetStepScopes ( scope ) ; 
 
					 
					 
					 
					  auto  step_scopes  =  GetStepScopes ( scope ) ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  rnn : : SegmentInputs ( step_scopes ,  arg_ - > inlinks ,  seq_len_ ) ; 
 
					 
					 
					 
					  rnn : : SegmentInputs ( step_scopes ,  arg_ - > inlinks ,  seq_len_ ) ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  PADDLE_ENFORCE ( scope - > HasVariable ( arg_ - > step_net ) , 
 
					 
					 
					 
					  PADDLE_ENFORCE ( scope - > FindVar ( arg_ - > step_net ) ,  " step net is not in scope. " ) ; 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					                 " step net is not in scope. " ) ; 
 
					 
					 
					 
					  Variable *  net  =  scope - > FindVar ( arg_ - > step_net ) ; 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					  Variable *  net  =  scope - > GetVariable ( arg_ - > step_net ) ; 
 
					 
					 
					 
					 
				
			 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					  PADDLE_ENFORCE ( net  ! =  nullptr ,  " failed to get step net " ) ; 
 
					 
					 
					 
					  PADDLE_ENFORCE ( net  ! =  nullptr ,  " failed to get step net " ) ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  for  ( int  step_id  =  seq_len_  -  1 ;  step_id  > =  0 ;  - - step_id )  { 
 
					 
					 
					 
					  for  ( int  step_id  =  seq_len_  -  1 ;  step_id  > =  0 ;  - - step_id )  { 
 
				
			 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
							 
						
					 
					 
					@ -391,14 +383,14 @@ void RecurrentGradientAlgorithm::InferShape(
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  auto  outlinks  =  arg_ - > outlinks ; 
 
					 
					 
					 
					  auto  outlinks  =  arg_ - > outlinks ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  for  ( size_t  i  =  0 ;  i  <  outlinks . size ( ) ;  i + + )  { 
 
					 
					 
					 
					  for  ( size_t  i  =  0 ;  i  <  outlinks . size ( ) ;  i + + )  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    DDim  step_dims  =  step_scopes [ 0 ] 
 
					 
					 
					 
					    DDim  step_dims  =  step_scopes [ 0 ] 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					                         - > GetVariable ( outlinks [ i ] . internal ) 
 
					 
					 
					 
					                         - > FindVar ( outlinks [ i ] . internal ) 
 
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					                         - > GetMutable < Tensor > ( ) 
 
					 
					 
					 
					                         - > GetMutable < Tensor > ( ) 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					                         - > dims ( ) ; 
 
					 
					 
					 
					                         - > dims ( ) ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    std : : vector < int >  dims_vec  =  vectorize ( step_dims ) ; 
 
					 
					 
					 
					    std : : vector < int >  dims_vec  =  vectorize ( step_dims ) ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    // now only support fixed length
 
 
					 
					 
					 
					    // now only support fixed length
 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    dims_vec . insert ( dims_vec . begin ( ) ,  seq_len_ ) ; 
 
					 
					 
					 
					    dims_vec . insert ( dims_vec . begin ( ) ,  seq_len_ ) ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    Tensor *  output  = 
 
					 
					 
					 
					    Tensor *  output  = 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					        step_scopes [ 0 ] - > GetVariable ( outlinks [ i ] . external ) - > GetMutable < Tensor > ( ) ; 
 
					 
					 
					 
					        step_scopes [ 0 ] - > FindVar ( outlinks [ i ] . external ) - > GetMutable < Tensor > ( ) ; 
 
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					    output - > Resize ( make_ddim ( dims_vec ) ) ; 
 
					 
					 
					 
					    output - > Resize ( make_ddim ( dims_vec ) ) ; 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  } 
 
					 
					 
					 
					  } 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  LinkBootMemoryGradients ( step_scopes [ 0 ] ) ; 
 
					 
					 
					 
					  LinkBootMemoryGradients ( step_scopes [ 0 ] ) ;