parameters: (self, pred, body, original_loop_vars, loop_vars,
                   shape_invariants)
return_statement: return original_body_result, exit_vars
docstring: Core: Add the loop termination condition and body to the graph.
docstring_summary: Core: Add the loop termination condition and body to the graph.
docstring_tokens: Core : Add the loop termination condition and body to the graph .
function: def _BuildLoop(self, pred, body, original_loop_vars, loop_vars,
                   shape_invariants):
      """Core: Add the loop termination condition and body to the graph."""
      flat_loop_vars = nest.flatten(original_loop_vars)
  
      # Let the context know the loop variables so the loop variables
      # would be added in the outer contexts properly.
      self._InitializeValues(loop_vars)
      real_vars = loop_vars
      if self._outer_context:
        real_vars = [self._outer_context.AddValue(x) for x in loop_vars]
      with ops.control_dependencies(None):
        enter_vars = [_Enter(x, self._name, is_constant=False,
                             parallel_iterations=self._parallel_iterations,
                             use_input_shape=(shape_invariants is None))
                      for x in real_vars]
      if self._outer_context:
        control_pivot = self._outer_context.GetControlPivot().op
        for var in enter_vars:
          if _IsLoopConstantEnter(var.op.inputs[0].op):
            # pylint: disable=protected-access
            var.op._add_control_input(control_pivot)
            # pylint: enable=protected-access
      _SetShapeInvariants(real_vars, enter_vars, shape_invariants)
  
      # Fix the control inputs and control flow context of these enter ops.
      self._FixControlInputsAndContext(enter_vars)
      self._InitializeValues(enter_vars)
  
      merge_vars = [merge([x, x])[0] for x in enter_vars]
      self._pivot_for_pred = merge_vars[0]
  
      # Build the graph for pred.
      merge_vars_with_tensor_arrays = (
          _convert_flows_to_tensorarrays(flat_loop_vars, merge_vars))
      packed_vars = nest.pack_sequence_as(
          structure=original_loop_vars,
          flat_sequence=merge_vars_with_tensor_arrays)
      c = ops.convert_to_tensor(pred(*packed_vars))
      self._pivot = loop_cond(c, name="LoopCond")
      switch_vars = [_SwitchRefOrTensor(x, self._pivot) for x in merge_vars]
  
      # Build the graph for body.
      vars_for_body = [_Identity(x[1]) for x in switch_vars]
      self._pivot_for_body = vars_for_body[0]
      # Convert TensorArray flow variables inside the context back into
      # their associated TensorArrays for calling the body.
      vars_for_body_with_tensor_arrays = (
          _convert_flows_to_tensorarrays(flat_loop_vars, vars_for_body))
      packed_vars_for_body = nest.pack_sequence_as(
          structure=original_loop_vars,
          flat_sequence=vars_for_body_with_tensor_arrays)
      body_result = body(*packed_vars_for_body)
      if not nest.is_sequence(body_result):
        body_result = [body_result]
      # Compare the structure types of input and output of body.
      # For backwards compatibility, the first layer is forced to a list
      # during this comparison, because inputs are typically lists and
      # outputs of the body are typically tuples.
      nest.assert_same_structure(list(packed_vars_for_body), list(body_result))
  
      # Store body_result to keep track of TensorArrays returned by body
      original_body_result = body_result
      # Convert TensorArrays returned by body into their flow variables
      flat_result = nest.flatten(body_result)
      result = _convert_tensorarrays_to_flows(flat_result)
      result = ops.convert_n_to_tensor_or_indexed_slices(result)
  
      # Add NextIteration and the back edges to complete the loop.
      if len(merge_vars) != len(result):
        raise ValueError("Number of inputs and outputs of body must match "
                         "loop_vars: %d, %d" % (len(merge_vars), len(result)))
      next_vars = []
      for m, v in zip(merge_vars, result):
        next_vars.append(_AddNextAndBackEdge(m, v))
  
      # Add the exit ops.
      exit_vars = [exit(x[0]) for x in switch_vars]
      self._loop_exits = exit_vars
  
      # Make sure the shapes of loop outputs are correct.
      for m_var, n_var in zip(merge_vars, next_vars):
        if isinstance(m_var, ops.Tensor):
          _EnforceShapeInvariant(m_var, n_var)
  
      # Exit the loop.
      self.ExitResult(exit_vars)
  
      return original_body_result, exit_vars
function_tokens: def _BuildLoop ( self , pred , body , original_loop_vars , loop_vars , shape_invariants ) : flat_loop_vars = nest . flatten ( original_loop_vars ) # Let the context know the loop variables so the loop variables # would be added in the outer contexts properly. self . _InitializeValues ( loop_vars ) real_vars = loop_vars if self . _outer_context : real_vars = [ self . _outer_context . AddValue ( x ) for x in loop_vars ] with ops . control_dependencies ( None ) : enter_vars = [ _Enter ( x , self . _name , is_constant = False , parallel_iterations = self . _parallel_iterations , use_input_shape = ( shape_invariants is None ) ) for x in real_vars ] if self . _outer_context : control_pivot = self . _outer_context . GetControlPivot ( ) . op for var in enter_vars : if _IsLoopConstantEnter ( var . op . inputs [ 0 ] . op ) : # pylint: disable=protected-access var . op . _add_control_input ( control_pivot ) # pylint: enable=protected-access _SetShapeInvariants ( real_vars , enter_vars , shape_invariants ) # Fix the control inputs and control flow context of these enter ops. self . _FixControlInputsAndContext ( enter_vars ) self . _InitializeValues ( enter_vars ) merge_vars = [ merge ( [ x , x ] ) [ 0 ] for x in enter_vars ] self . _pivot_for_pred = merge_vars [ 0 ] # Build the graph for pred. merge_vars_with_tensor_arrays = ( _convert_flows_to_tensorarrays ( flat_loop_vars , merge_vars ) ) packed_vars = nest . pack_sequence_as ( structure = original_loop_vars , flat_sequence = merge_vars_with_tensor_arrays ) c = ops . convert_to_tensor ( pred ( * packed_vars ) ) self . _pivot = loop_cond ( c , name = "LoopCond" ) switch_vars = [ _SwitchRefOrTensor ( x , self . _pivot ) for x in merge_vars ] # Build the graph for body. vars_for_body = [ _Identity ( x [ 1 ] ) for x in switch_vars ] self . _pivot_for_body = vars_for_body [ 0 ] # Convert TensorArray flow variables inside the context back into # their associated TensorArrays for calling the body. vars_for_body_with_tensor_arrays = ( _convert_flows_to_tensorarrays ( flat_loop_vars , vars_for_body ) ) packed_vars_for_body = nest . pack_sequence_as ( structure = original_loop_vars , flat_sequence = vars_for_body_with_tensor_arrays ) body_result = body ( * packed_vars_for_body ) if not nest . is_sequence ( body_result ) : body_result = [ body_result ] # Compare the structure types of input and output of body. # For backwards compatibility, the first layer is forced to a list # during this comparison, because inputs are typically lists and # outputs of the body are typically tuples. nest . assert_same_structure ( list ( packed_vars_for_body ) , list ( body_result ) ) # Store body_result to keep track of TensorArrays returned by body original_body_result = body_result # Convert TensorArrays returned by body into their flow variables flat_result = nest . flatten ( body_result ) result = _convert_tensorarrays_to_flows ( flat_result ) result = ops . convert_n_to_tensor_or_indexed_slices ( result ) # Add NextIteration and the back edges to complete the loop. if len ( merge_vars ) != len ( result ) : raise ValueError ( "Number of inputs and outputs of body must match " "loop_vars: %d, %d" % ( len ( merge_vars ) , len ( result ) ) ) next_vars = [ ] for m , v in zip ( merge_vars , result ) : next_vars . append ( _AddNextAndBackEdge ( m , v ) ) # Add the exit ops. exit_vars = [ exit ( x [ 0 ] ) for x in switch_vars ] self . _loop_exits = exit_vars # Make sure the shapes of loop outputs are correct. for m_var , n_var in zip ( merge_vars , next_vars ) : if isinstance ( m_var , ops . Tensor ) : _EnforceShapeInvariant ( m_var , n_var ) # Exit the loop. self . ExitResult ( exit_vars ) return original_body_result , exit_vars