
    AVhM                       d Z ddlZddlmZ ddlmZ ddlmZ ddlm	Z	 ddlm
Z
 ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddl ddlmZ ddlmZ ddlmZ ddlm Z  ddl!m"Z" e#Z$dAdZ%dAdZ&	 	 	 	 	 dBdZ'dAdZ(dCdZ)dDd Z*dAd!Z+d" Z,d# Z-d$ Z.d% Z/dAd&Z0d' Z1dEd(Z2 G d) d*ejf                  +      Z4 G d, d-e4      Z5d. Z6 G d/ d0e4      Z7d1 Z8d2 Z9dAd3Z:dAd4Z; e"d5      d6        Z< e"d7g 8      ejz                  dCd9              Z> e"d7g8      ejz                  dCd:              Z# G d; d<e4      Z? e"d=g 8      d>        Z@dAd?ZA ej                  ej                  j                  ej                  e5j                  e5j                  @        ej                  ej                  j                  ej                  e7j                  e7j                  @       y)FzaControl Flow Operations.

See the [autograph](https://www.tensorflow.org/guide/autograph) guide.
    N)attr_value_pb2)control_flow_pb2)context)composite_tensor)constant_op)dtypes)indexed_slices)ops)tensor)tensor_shape)tensor_util)	type_spec)	array_ops)control_flow_util)gen_array_ops)gen_control_flow_ops)math_ops)tensor_array_ops)*)compat)dispatch)nest)variable_utils)	tf_exportc                    t        j                  | d      } t        j                  |       } t	        | t
        j                        rD| j                  j                  rt        j                  | |      S t        j                  | |      S t	        | t        j                        rt        j                   t"        | d      S t%        dt'        |        d      )zReturn a tensor with the same shape and contents as the input tensor.

  Args:
    tensor: A Tensor.
    name: A name for this operation (optional).

  Returns:
    A Tensor with the same type and value as the input Tensor.
  Tas_refnameexpand_composites8'tensor' must be a Tensor or CompositeTensor. Received: .)r
   'internal_convert_to_tensor_or_compositer   convert_variables_to_tensors
isinstance
tensor_libTensordtype_is_ref_dtyper   ref_identityr   identityr   CompositeTensorr   map_structure	_Identity	TypeErrortyper   r   s     V/home/dcms/DCMS/lib/python3.12/site-packages/tensorflow/python/ops/control_flow_ops.pyr/   r/   ;   s     66vdK& 66v>&
))*||!!''T::T22&*::;i4HH
 !!%fa1 2 2    c                 `   t        j                  | d      } t        | t        j                        r0| j
                  j                  rt        | |      S t        | |      S t        | t        j                        rt        j                  t        | d      S t        dt        |        d      )NTr   r   r    r"   r#   )r
   r$   r&   r'   r(   r)   r*   ref_next_iterationnext_iterationr   r-   r   r.   _NextIterationr0   r1   r2   s     r3   r8   r8   U   s    66vdK&
))*||!!T22F..&*::;nfMM
 !!%fa1 2 2r4   c                    t        j                  | d      } t        | t        j                        rp| j
                  j                  rrt        j                  | |      }nt        j                  | |      }r|j                  | j                                |S t        | t        j                        r!fd}t        j                  || d      S t!        dt#        |        d      )a  Creates or finds a child frame, and makes `tensor` available to it.

  The unique `frame_name` is used by the `Executor` to identify frames. If
  `is_constant` is true, `tensor` is a constant in the child frame; otherwise
  it may be changed in the child frame. At most `parallel_iterations`
  iterations are run in parallel in the child frame.

  Args:
    tensor: The tensor to be made available to the child frame.
    frame_name: The name of the child frame.
    is_constant: If true, the output is constant within the child frame.
    parallel_iterations: The number of iterations allowed to run in parallel.
    use_ref: If true, use ref_enter if tensor is of ref type.
    use_input_shape: If true, set the result's shape based on tensor's shape.
    name: A name for this operation (optional).

  Returns:
    The same tensor as `tensor`.

  Raises:
    ValueError: If any tensor in `tensor` has a less specific shape
      than its corresponding shape in `shape_invariant`.
  Tr   r   c                 $    t        |       S N)_Enter)t
frame_nameis_constantparallel_iterationsuse_input_shapeuse_refs    r3   enter_componentz_Enter.<locals>.enter_component   s    Az;0CW#% %r4   r    r"   r#   )r
   r$   r&   r'   r(   r)   r*   r   	ref_enterenter	set_shape	get_shaper   r-   r   r.   r0   r1   )	r   r>   r?   r@   rB   rA   r   resultrC   s	    `````   r3   r<   r<   c   s    < 66vdK&
))*||!!g#--
*k+>TKf $))
*k+>TKfv'')*M&*::;% % ovNN
 !!%fa1 2 2r4   c                    t        j                  | d      } t        | t        j                        rB| j
                  j                  rt        j                  | |      S t        j                  | |      S t        | t        j                        rt        j                  t        | d      S t        dt!        |        d      )a  Exits the current frame to its parent frame.

  Exit makes its input `tensor` available to the parent frame.

  Args:
    tensor: The tensor to be made available to the parent frame.
    name: A name for this operation (optional).

  Returns:
    The same tensor as `tensor`.
  Tr   r    r"   r#   )r
   r$   r&   r'   r(   r)   r*   r   ref_exit_exitr   r-   r   r.   exitr0   r1   r2   s     r3   rL   rL      s     66vdK&
))*||!!!**6488!''55&*::;dFdCC
 !!%fa1 2 2r4   c                    t        j                  |d| |g      5 }t        j                  | |dd      } t        j                  |d      }t	        | t
        j                        r!t        j                  | ||      cddd       S t	        | t        j                        st        dt        |        d	      t        j                  | d
      }|D cg c]  }t        j                  ||       }}t        | \  }}t        j                   | |d
      t        j                   | |d
      fcddd       S c c}w # 1 sw Y   yxY w)a  Forwards `data` to an output determined by `pred`.

  If `pred` is false, the `data` input is forwarded to the first output.
  Otherwise, the data goes to the second output.

  This op handles `Tensor`s and `IndexedSlices`.

  Args:
    data: The tensor to be forwarded to the appropriate output.
    pred: A scalar that specifies which output port will receive data.
    dtype: Optional element type for the returned tensor. If missing, the type
      is inferred from the type of `value`.
    name: A name for this operation (optional).

  Returns:
    `(output_false, output_true)`: If `pred` is true, data will be forwarded
    to `output_true`, otherwise it goes to `output_false`.
  SwitchdataT)r)   r   r   predr   Nz6'data' must be a Tensor or CompositeTensor. Received: r#   r    )r
   
name_scoper$   convert_to_tensorr&   r'   r(   r   switchr   r-   r0   r1   r   flattenzippack_sequence_as)	rO   rP   r)   r   tensorsr   mappedmapped_fmapped_ts	            r3   rS   rS      s8   & ~~dHtTl3 Mt66Et5D  F3D$
))*!((t$?M M .>>?dA'( 	( TT:gHOPf$++FD9PfP<h##D(dK##D(dKMM M QM Ms%   A"D;AD;D60<D;6D;;Ec                 4   t        j                  | d      } t        j                  | d      5  t        | t        j
                        r-| j                  j                  rt        | ||      cddd       S t        | ||      cddd       S # 1 sw Y   yxY w)ay  Forwards `data` to an output determined by `pred`.

  If `pred` is false, the `data` input is forwarded to the first output.
  Otherwise, the data goes to the second output.

  This op handles `Tensor`s and `IndexedSlices`.

  Args:
    data: The tensor to be forwarded to the appropriate output.
    pred: A scalar that specifies which output port will receive data.
    name: A name for this operation (optional).

  Returns:
    `(output_false, output_true)`: If `pred` is true, data will be forwarded to
    `output_true`, otherwise it goes to `output_false`.

  Raises:
    TypeError: if data is not a Tensor or IndexedSlices
  rO   r   T)ignore_existingN)
r
   convert_to_tensor_or_compositecolocate_withr&   r'   r(   r)   r*   
ref_switchrS   )rO   rP   r   s      r3   _SwitchRefOrTensorr`      s~    ( 
	+	+Dv	>$" t4 )$
))*		!	!$40) ) $4(	) ) )s   >B7BBc                    t        d | D              rt        d| z        t        j                  |d|       5 }| D cg c]  }t        j                  |d       } }t        d | D              rPt        d | D              rt        j                  | |      cddd       S t        j                  | |      cddd       S t        d	 | D              rt        j                  | d
      } | D ]3  }t        |t        j                        rt        dt        |      z         | dd D ]  }t!        j"                  | d   |d        | D cg c]  }t!        j$                  |d       }}t'        | D cg c]  }t        j                  |       }}|D cg c]  \  }}|	 }	}}|d   d   }
t!        j(                  | d   |	d      }||
fcddd       S c c}w c c}w c c}w c c}}w # 1 sw Y   yxY w)a  Returns the value of an available element of `inputs`.

  This op tests each of the tensors in `inputs` in turn to determine if any of
  them is available. If it finds an available tensor, it returns it and its
  index in `inputs`.

  It is an error if more than one tensor in `inputs` is available. If no tensor
  in `inputs` is available, the returned tensor and index are not set.

  This op handles both `Tensor`s and `IndexedSlices`. If inputs has a mix of
  `Tensor`s and `IndexedSlices`, all inputs are converted to IndexedSlices
  before merging.

  Args:
    inputs: The input tensors, at most one of which is available.
    name: A name for this operation (optional).

  Returns:
    A tuple containing the chosen input tensor and its index in `inputs`.

  Raises:
    ValueError: If any of the inputs is None, or inputs are IndexedSlices and
      some but not all have a dense_shape property.
  c              3   $   K   | ]  }|d u  
 y wr;    ).0inps     r3   	<genexpr>zmerge.<locals>.<genexpr>  s     ''s   z,At least one of the merge inputs is None: %sMergeTr   c              3   P   K   | ]  }t        |t        j                           y wr;   )r&   r'   r(   rd   vs     r3   rf   zmerge.<locals>.<genexpr>"  s     
<:a**+
<s   $&c              3   H   K   | ]  }|j                   j                    y wr;   )r)   r*   ri   s     r3   rf   zmerge.<locals>.<genexpr>#  s     3qQWW""3s    "Nc              3   p   K   | ].  }t        |t        j                  t        j                  f       0 y wr;   )r&   r	   IndexedSlicesr'   r(   ri   s     r3   rf   zmerge.<locals>.<genexpr>*  s0       Q55z7H7HI
Js   46FoptimizezType %s not supported   r   r    )any
ValueErrorr
   rQ   r$   allr   	ref_mergemerger   _as_indexed_slices_listr&   r   r-   r0   r1   r   assert_same_structurerT   rU   rV   )inputsr   re   rj   flat_inputs	componentmerged_resultsr   _flat_mergedchosen_indexmerged_inputss               r3   ru   ru     s   2 	'''
CfL
MM
~~dGV, "+  	33CEF  
<V
<<	3F3	3#--fd;"+ "+ $))&$7"+ "+ 
  
 11&5I =!!-==>1DG;<
<= abz I!""6!9a4HI GMMT\\!t<MkM , 
$
$Y
/n  0>>V>k>#A&q)l++
)[D:m\*E"+ "+0 N ?="+ "+sT   G*G;G* G*?AG*AG*	G'G*3GG*G$")G*G**G3c                 R    t        | t        j                        r| j                  S | S r;   )r&   r   TensorArrayflow)tensor_or_tensor_arrays    r3   _convert_tensorarray_to_flowr   B  s&    &(8(D(DE!&&&!!r4   c                 f    t        | t        j                        rt        j                  | |      S |S r;   )r&   r   r   build_ta_with_new_flow)r   tensor_or_flows     r3   _convert_flow_to_tensorarrayr   I  s7    &(8(D(DE223I3AC C r4   c                 d    t        | t        j                        r| S t        j                  |       S r;   )r&   r   r   r
   r]   )vars    r3   ._convert_to_tensor_or_composite_or_tensorarrayr   Q  s)    %112J		+	+C	00r4   c                     |j                   y| j                  |j                  k7  ryt        | j                   |j                         D ]-  \  }}|j                  |j                  |j                  k7  s- y y)NTF)dimsndimsrU   value)shape1shape2dim1dim2s       r3   _ShapeLessThanOrEqualr   X  se    [[\\V\\!V[[1 jdDzz$**

": 
r4   c           	      d   t        |       } |t        j                  |       S t        |t        j                        r$|j                  |       st        d|d|       |S t        |t        j                        st        dt        |             t        | t        j                        r t        j                  || j                        S 	 | j                  |      S # t        $ rH}t        dt        |       j                    dt        | j"                        j                    d      |d}~ww xY w)a  Converts a shape invariant to a TypeSpec.

  If `var` is a TensorArray, it will first be converted to its flow.

  Args:
    var: The tensor, tensor array or composite tensor whose shape is described
      by the shape invariant.
    shape: A `TypeSpec` or `TensorShape`.  If `shape` is already a `TypeSpec`,
      then it is simply returned as-is.

  Returns:
    A `TypeSpec` for `var`, consistent with the given shape.

  Raises:
    TypeError: If `shape` is a TypeSpec and not compatible with `var`.
    TypeError: If `shape` is not None, a TypeSpec, or a TensorShape.
    TypeError: If `shape` is a TensorShape, `var` is a CompositeTensor, and
      `var` doesn't implement the `_shape_invariant_to_type_spec` method.
  Nz	TypeSpec z is not compatible with z@'shape' must be one of TypeSpec, TensorShape or None. Received: zTo describe or constrain a z, use a z instead of a TensorShape.)r   r   type_spec_from_valuer&   TypeSpecis_compatible_withr0   r   TensorShaper1   r'   r(   
TensorSpecr)   _shape_invariant_to_type_specNotImplementedError__name__
_type_spec)r   shapees      r3   r   r   c  s   ( 	%S)#
]))#..%++,##C(LMMLe\556
	%[M	#$ $ Z&&'  		22O..u55 O'S	(:(:';8#..!**++EGHMNOOs   C 	D/'AD**D/c           	         t        | t        j                        r| j                         }|j                         }t	        ||      sr| j
                  j                  d   j
                  }t        j                  |      sJ |j                  d   }t        d|j                  d|j                  d|d      yt        dt        |        d      )	a  Check if the shapes of the loops variables are invariants.

  Args:
    merge_var: The tensor representing the initial values of the loop
      variables.
    next_var: The tensor representing the values of the loop variables
      after one loop iteration.

  Raises:
    ValueError: If any tensor in `merge_var` has a more specific shape than
      its corresponding tensor in `next_var`.
  r   zInput tensor 'z' enters the loop with shape z, but has shape z after one iteration. To allow the shape to vary across iterations, use the `shape_invariants` argument of tf.while_loop to specify a less-specific shape.z('merge_var' must be a Tensor. Received: r#   N)r&   r'   r(   rG   r   oprx   utilIsLoopEnterrr   r   r   r0   r1   )	merge_varnext_varm_shapen_shaperE   input_ts         r3   _EnforceShapeInvariantr     s     	:,,-!!#G  "G '2ll!!!$''ee$$$Qg %,LL'--JK K	 3  !!%i 14 5 5r4   c                    t        | t        j                        rLt        j                  |      }t        |      }|rt        | |       | j                  j                  d|       |S t        | t        j                        rXd }t        | t        j                        rt        j                  |d      }t        |      }t        j                   || |d      S t#        dt%        |        d      )	z,Add NextIteration and back edge from v to m.rp   c                 <    | j                   j                  d|       y )Nrp   )r   _update_input)m_componentv_components     r3   update_componentz-_AddNextAndBackEdge.<locals>.update_component  s    nn""1k2r4   Frn   Tr    z3'm' must be a Tensor or CompositeTensor. Received: r#   )r&   r'   r(   r
   rR   r8   r   r   r   r   r-   r	   rm   r   _as_indexed_slicesr   r.   r0   r1   )mrj   enforce_shape_invariantr   s       r3   _AddNextAndBackEdger     s    :$$%a AqA
 Q"DDq! 
( !%5563 !^112

%
%a%
8aqA.1MM
 !!%a	, - -r4   c                   J   e Zd ZdZddZddZed        Zed        Zed        Z	ed        Z
ej                  dd	       Zdd
Zd Zd Zd Zdej&                  fdZdej&                  fdZd Zd Zdej&                  fdZdej&                  fdZd Zd Zd Zd Zd Zy)ControlFlowContexta  The base class for control flow context.

  The usage pattern is a sequence of (Enter, Exit) followed by a final
  ExitResult.

  We maintain the following state for control flow contexts during graph
  construction:
   1. graph has _control_flow_context: the current context used to
      construct new nodes. Changed by ctxt.Enter() and ctxt.Exit()
   2. op has _control_flow_context: the context to which the op belongs.
      Set at the time the op is created. Immutable.
   3. A ControlFlowContext has _outer_context: the context in which this
      context is created. Set at the time a context is created. Immutable.
   4. A ControlFlowContext has _context_stack.
      Pushed and popped by ctxt.Enter() and ctxt.Exit()
  Nc                 (   g | _         t        j                         j                         | _        | j                  r%| j                  j                   j                  |        g | _        |r| j                  ||       y t               | _	        i | _
        y )Nimport_scope)_nested_contextsr
   get_default_graph_get_control_flow_context_outer_contextappend_context_stack_init_values_from_protoset_values_external_values)self
values_defr   s      r3   __init__zControlFlowContext.__init__  sz    D//1KKMD
**11$7D
"":L"I Udl !dr4   c                    t        |t        j                        sJ t        fd|j                  D              | _        t        j                         }i | _        |j                  j                         D ]M  \  }}t        j                  |      }|j                  t        j                  |            | j                  |<   O t        | j
                  t        | j                  j                               z
  D cg c]  }|j                  d      d    c}      }|D ]"  }|j                  |      j                  |        $ yc c}w )zInitializes values and external_values from `ValuesDef` protocol buffer.

    Args:
      values_def: `ValuesDef` protocol buffer.
      import_scope: Optional `string`. Name scope to add.
    c              3   J   K   | ]  }t        j                  |        y wr;   )r
   prepend_name_scope)rd   r   r   s     r3   rf   z=ControlFlowContext._init_values_from_proto.<locals>.<genexpr>  s&      ( 	ul3(    #:r   N)r&   r   	ValuesDefr   valuesr   r
   r   r   external_valuesitemsr   as_graph_elementkeyssplit_set_control_flow_context)r   r   r   gkrj   r   op_namess     `     r3   r   z*ControlFlowContext._init_values_from_proto  s-    j"2"<"<=== (&&( (DL 	AD**002 31

 
 L
1a!"!3!3

 
 L
1"3dA3 ,,T%:%:%?%?%A!BB 	a H  =66t<=	s   =Ec                     | j                   S r;   )_namer   s    r3   r   zControlFlowContext.name      ::r4   c                     | j                   S )z+Return the context containing this context.)r   r   s    r3   outer_contextz ControlFlowContext.outer_context  s     r4   c                     t        d      NAbstract methodr   r   s    r3   
grad_statezControlFlowContext.grad_state      
/
00r4   c                     t        d      r   r   r   s    r3   	back_propzControlFlowContext.back_prop  r   r4   c                     t        d      )zSerializes this into `context_def`.

    Args:
      context_def: a `ControlFlowContextDef` protocol buffer.
      export_scope: Optional `string`. Name scope to remove.
    r   r   r   context_defexport_scopes      r3   to_control_flow_context_defz.ControlFlowContext.to_control_flow_context_def  s     /
00r4   c           	         t        j                         }|j                  j                  t	        | j
                        D cg c]  }t        j                  ||       c}       | j                  j                         D ]H  \  }}t        j                  ||      }t        j                  |j                  |      |j                  |<   J |S c c}w )zConverts the values to a `ValuesDef` protocol buffer.

    Args:
      export_scope: Optional `string`. Name scope to remove.

    Returns:
      A `ValuesDef` protocol buffer.
    )r   r   r   extendsortedr   r
   strip_name_scoper   r   r   r   )r   r   r   rj   r   s        r3   _to_values_defz!ControlFlowContext._to_values_def  s     "++-J8>t||8LM1		a	.MO%%++- Q1


q,
/a&)&:&:166<&Pj  #Q 	 	Ns   Cc                 :    | j                   j                  |       y r;   )r   add)r   r   s     r3   AddNamezControlFlowContext.AddName0  s    LLTr4   c                     t        j                         }| j                  j                  |j	                                |j                  |        y)z Enter this control flow context.N)r
   r   r   r   r   r   )r   graphs     r3   EnterzControlFlowContext.Enter4  s;    !!#Eu>>@A	##D)r4   c                     t        j                         }| j                  j                         }|j	                  |       y)zExit this control flow context.N)r
   r   r   popr   )r   r   last_contexts      r3   ExitzControlFlowContext.Exit:  s2    !!#E&&**,L	##L1r4   r   c                 V    | j                   r| j                   j                  ||       yyz/Start building a gradient colocated with an op.N)r   EnterGradientColocationr   r   gradient_uids      r3   r   z*ControlFlowContext.EnterGradientColocation@  s&    
11"lC r4   c                 V    | j                   r| j                   j                  ||       yyr   )r   ExitGradientColocationr   s      r3   r   z)ControlFlowContext.ExitGradientColocationE  s&    
00\B r4   c                 Z      j                   r fd}t        j                  ||d       yy)z6Make a list of tensors available in the outer context.c                 R    j                   j                  | j                         | S r;   )r   r   r   )xr   s    r3   fnz)ControlFlowContext.ExitResult.<locals>.fnM  s     ##AFF+r4   Tr    N)r   r   r.   )r   rH   r  s   `  r3   
ExitResultzControlFlowContext.ExitResultJ  s*     Vt<	 r4   c                 P    | j                   r| j                   j                         S y)z1Return the while context containing this context.N)r   GetWhileContextr   s    r3   r  z"ControlFlowContext.GetWhileContextR  s#      0022r4   c                    | j                         }||j                  g }}nbg g }}|j                  D ]O  }t        j                  |      }|%|j                         |k(  r|j	                  |       ?|j	                  |       Q t        |      t        |j                        k7  r!|j                          |j                  |       ||fS )z2Remove any external control dependency on this op.)r  control_inputsr   GetOutputContextr   len_remove_all_control_inputs_add_control_inputs)r   r   
while_ctxtinternal_control_inputsexternal_control_inputsr  ctxts          r3   _RemoveExternalControlEdgesz.ControlFlowContext._RemoveExternalControlEdgesX  s    %%'J 9;9J9JB69;R6   ,!$$Q' 4 4 6* D
!
(
(
+
!
(
(
+, "#s2+<+<'==##%45"$;;;r4   c                 T    | j                   r| j                   j                  |       yy)z;Notifies a scope about an operator added to an inner scope.N)r   
AddInnerOpr   r   s     r3   r  zControlFlowContext.AddInnerOpo  s$    
$$R( r4   c                      y)z1Returns the pivot node for this context, or None.Nrc   r   s    r3   GetControlPivotz"ControlFlowContext.GetControlPivott  s    r4   c                      yNFrc   r   s    r3   IsWhileContextz!ControlFlowContext.IsWhileContextx      r4   c                      yr  rc   r   s    r3   IsCondContextz ControlFlowContext.IsCondContext{  r  r4   c                      yr  rc   r   s    r3   IsXLAContextzControlFlowContext.IsXLAContext~  r  r4   c                     | j                   S r;   r   r   s    r3   __str__zControlFlowContext.__str__  s    99r4   NNr;   )r   
__module____qualname____doc__r   r   propertyr   r   r   r   abcabstractmethodr   r   r   r   r   r
   	Operationr   r   r  r  r  r  r  r  r  r  r   rc   r4   r3   r   r     s    "! =4     1 1 1 1 1 1"*2D D
Cs}} C
=<CMM <.)3== )
r4   r   )	metaclassc                       e Zd ZdZ	 	 	 	 	 	 ddZd fd	Zed        Zed        Zed        Z	ed        Z
ed        Zd	 Zd fd
	Zedd       ZddZd Zdej&                  fdZdej&                  fdZd Zd Zd Zd Z xZS )CondContextz*The context for the conditional construct.c                    t        j                         j                  |      | _        |r| j	                  ||       yt
        j                  |        || _        || _        || _	        | j                  j                  |j                         || j                  |j                  <   | j                  j                  |j                         |j                  j                  |        y)a  Creates a `CondContext`.

    Args:
      pred: The `boolean` tensor for the conditional predicate.
      pivot: The predicate tensor in this branch.
      branch: 0 or 1 representing this branch.
      name: Name of the `CondContext` python object.
      context_def: Optional `ContextDef` protocol buffer to initialize the
        `CondContext` object from.
      import_scope: Optional `string`. Name scope to add. Only used when
        initialing from protocol buffer.
    r   N)r
   r   unique_namer   _init_from_protor   r   _pred_pivot_branchr   r   r   r   r   r   )r   rP   pivotbranchr   r   r   s          r3   r   zCondContext.__init__  s    & &&(44T:DJ
KlC !!$'djdkdl lltyy!)-dDII&
lluzz"hh((.r4   c                    t        |t        j                        sJ t        j                         }t        j
                  |j                  |      | _        |j                  t        j
                  |j                  |            | _
        |j                  t        j
                  |j                  |            | _        |j                  | _        t        t         | G  |j$                  |       y)zCreates a new `CondContext` from protocol buffer.

    Args:
      context_def: `CondContextDef` protocol buffer.
      import_scope: Optional `string`. Name scope to add.
    r   r   N)r&   r   CondContextDefr
   r   r   context_namer   r   	pred_namer/  
pivot_namer0  r3  r1  superr+  r   r   )r   r   r   r   	__class__s       r3   r.  zCondContext._init_from_proto  s     k#3#B#BCCCA''(@(@,ODJ##{44lCEDJ$${55|DFDK%%DL	+t%)) & Fr4   c                     | j                   S r;   )r/  r   s    r3   rP   zCondContext.pred  r   r4   c                     | j                   S r;   r0  r   s    r3   r2  zCondContext.pivot  s    ;;r4   c                     | j                   S r;   )r1  r   s    r3   r3  zCondContext.branch  s    <<r4   c                 X    | j                         r| j                         j                  S y r;   )r  r   r   s    r3   r   zCondContext.grad_state  s&    !!#...r4   c                 X    | j                         r| j                         j                  S yr  )r  r   r   s    r3   r   zCondContext.back_prop  s&    !!#---r4   c                     | j                   S r;   r>  r   s    r3   r  zCondContext.GetControlPivot  s    ;;r4   c                 f   || j                   j                  |      rt        j                         }t	        j
                  | j                   |      |_        t	        j
                  | j                  j                   |      |_        t	        j
                  | j                  j                   |      |_
        | j                  |_        |j                  j                  t        t         | G  |             | j$                  D ]-  }|j&                  j)                         }|j+                  |       / |S y)zConverts a `CondContext` to a `CondContextDef` protocol buffer.

    Args:
      export_scope: Optional `string`. Name scope to remove.

    Returns:
      A `CondContextDef` protocol buffer.
    N)r   
startswithr   r6  r
   r   r7  r/  r8  r0  r9  r1  r3  r   	MergeFromr:  r+  r   r   nested_contextsr   r   )r   r   r   nested
nested_defr;  s        r3   to_protozCondContext.to_proto  s     			 4 4\ B$335k!$!5!5dii!Nk!224::??3?Ak"33DKK4D4D4@ Bk<<k&&
T
1,
?A)) 7& 00446
**:67 r4   c                     t        | |      }|j                          | j                  D ]  }t        ||        |j	                          |S )z:Returns a `CondContext` object created from `context_def`.r   r   r   )r+  r   rF  from_control_flow_context_defr   r   r   retrH  s       r3   
from_protozCondContext.from_proto  sH     +L
ICIIK!11 K
#J\JKHHJJr4   c                 Z    |j                   j                  | j                  |             y Nr   )	cond_ctxtCopyFromrI  r   s      r3   r   z'CondContext.to_control_flow_context_def  s!    ""4==l=#KLr4   c                    |j                   | j                  v r/| j                  j                  |j                         }||}|S |}|S |}| j                  j	                  |j                          | j
                  rY| j
                  j                  |      }| j                  j	                  |j                          || j                  |j                   <   t        j                  d      5  t        || j                        | j                     }| j
                  r%| j
                  j                  |j                         ddd       |j                  j                  j                  |j                         |j                  j!                  |        | }|4|j                  j	                  |j                          |j
                  }|4|| j                  |j                   <   |S # 1 sw Y   xY w)CAdd `val` to the current context and its outer context recursively.N)r   r   r   getr   r   AddValuer
   control_dependenciesr`   r/  r1  r  r   r   prevent_fetchingr   )r   valrH   r  s       r3   rX  zCondContext.AddValue  s   
xx4<< $$((2fnsf8 M9 +1f8 M5 f
llsxx 			$$--c2%-3fkk*##D) 4#FDJJ7E



(
(
34
 iioo&&vyy1ii))$/
 d%""  )/dCHH%M)4 4s   )AG##G,r   c                 &    | j                  |       y r;   )_AddOpInternalr  s     r3   AddOpzCondContext.AddOp(  s    r4   c                     |j                   sV j                  |       t         fd|j                  D              s|j	                   j
                  j                         nt        t        |j                               D ]e  }|j                   |   }|j                  dk(  r|j                  j                  dk(  r|}n j                  |      }||k7  sT|j                  ||       g  j                  |       |j                  j                  |j                        s|j                  dk(  r%|j	                   j
                  j                         |j                  D cg c]  }|j                   }} }|*|j                   j#                  |       |j$                  }|* j$                  st'        j(                  |      s|j                  j+                  |        j$                  r j$                  j-                  |       yyc c}w ) Add `op` to the current context.c              3   J   K   | ]  }t        j                  |        y wr;   )r   OpInContext)rd   input_opr   s     r3   rf   z-CondContext._AddOpInternal.<locals>.<genexpr>2  s%      N/7$

8T
*Nr   rg   NextIterationSymbolicGradientN)rx   r  rq   r  _add_control_inputr0  r   ranger
  r1   rX  r   r   _is_functionoutputsr   r   updater   r   
IsLoopExitrZ  r  )r   r   indexr  real_xoutput_namesr  s   `      r3   r]  zCondContext._AddOpInternal+  s   99 &&r* N;=;L;LN N 	dkknn- RYY( *%IIe77g!$$))"> &==#&Q;


5&
)!*& &&r*			rww	'2776H+H
dkknn- %'JJ/qAFF/L/D


ll,'  d 
 $//""5hh#
$$R(  0s   "H
c                    |}|j                   | j                  vr| j                  j                  |j                          | j                  rY| j                  j	                  |      }| j                  j                  |j                          || j
                  |j                   <   t        || j                        | j                     }|| j
                  |j                   <   |S | j
                  j                  |j                         }||}|S )z1Process an output tensor of a conditional branch.)
r   r   r   r   rX  r   r`   r/  r1  rW  )r   r[  real_valexternal_vals       r3   _ProcessOutputTensorz CondContext._ProcessOutputTensord  s    H
xxt||#
llsxx 			&&//4'/7hmm,#Hdjj9$,,Gh(0dCHH%
 O **..sxx8l		!Or4   c                     t        |t        j                        rt        |g| j                        S t        j                  t        |d      }| j                  t        j                  |            S )NTr    )
r&   r
   r(  with_dependenciesr0  r   r.   r   rr  rR   )r   rj   s     r3   _BuildCondTensorzCondContext._BuildCondTensorv  sW    !S]]#sDKK00



&TCa&&s'<'<Q'?@@r4   c                 L   t        j                  t         j                  j                        } |       }t        j                  t         j                  j                        }t	        |      t	        |      kD  r|t	        |      d }t        j
                  t         j                  j                        }||dd t        j                  |      5  |t               dfcddd       S t        |t         j                        s;t        j                  |      }t        j                  t        j                  |d      }ddd       |yt        j                  |      }t        j                  | j                   |d      }t        |t"        t$        f      s|g}||fS # 1 sw Y   `xY w)z.Add the subgraph defined by fn() to the graph.NTr    r!  )r
   get_collection	GraphKeys_SUMMARY_COLLECTIONr
  get_collection_refrY  no_opr&   r(  r   r%   r   r.   r   r,   ru  list
_basetuple)r   r  pre_summariesoriginal_resultpost_summariesnew_summariessummary_refrH   s           r3   BuildCondBranchzCondContext.BuildCondBranch  sd   &&s}}'H'HIMdO''(I(IJN
>S//$S%7%89m**3==+L+LMk$k!n##M2 K"$K K OS]];*GG/ ..  /TK/K $AAO$HFftZ01xfF""#K Ks   F&AFF#c                      yNTrc   r   s    r3   r  zCondContext.IsCondContext      r4   )NNN	cond_textNNr;   )r   r"  r#  r$  r   r.  r%  rP   r2  r3  r   r   r  rI  staticmethodrO  r   rX  r
   r(  r^  r]  rr  ru  r  r  __classcell__r;  s   @r3   r+  r+    s    2  #/JF&        
  
6  M"Hcmm 7)s}} 7)r$A#8r4   r+  c                 R   | j                   t        j                  k(  rt| j                  j                  r0| j                  j                  d   } | j                  j                  r0t        j                  | j                  j                  d            S t        j                  | d      S )z4Returns the shape of t or the variable it points to.r   r   Frn   )
r)   r   resourcer   rx   r   r   get_attrr   shape_internal)r=   s    r3   _resource_safe_shaper    sl    WW
$$++
$$++a.a $$++##ADDMM'$:;;		!	!!e	44r4   c                       e Zd ZdZ	 	 	 	 	 	 	 	 d dZd Zd! fd	Zed        Zed        Z	ed        Z
ed        Zed	        Zed
        Zed        Zed        Zd! fd	Zd!dZed!d       Zd Zd Zd Zdej0                  fdZdej0                  fdZdej0                  fdZd Zd Zdej0                  fdZdej0                  fdZd Z d Z!d Z"d Z#d Z$ xZ%S )"WhileContextz#The context for the loop construct.c	                     |r| j                  ||       || _        yt        j                  |        | j                  |||||       || _        y)a  "Creates a `WhileContext`.

    Args:
      maximum_iterations: Optional upper bound on number of loop iterations.
      parallel_iterations: The number of iterations allowed to run in parallel.
      back_prop: Whether backprop is enabled for this while loop.
      swap_memory: Whether GPU-CPU memory swap is enabled for this loop.
      name: Optional name prefix for the returned tensors.
      grad_state: The gradient loop state.
      context_def: Optional `WhileContextDef` protocol buffer to initialize the
        `Whilecontext` python object from.
      import_scope: Optional `string`. Name scope to add. Only used when
        initialing from protocol buffer.
    r   N)r.  r   r   _init_from_args_grad_state)	r   maximum_iterationsr@   r   swap_memoryr   r   r   r   s	            r3   r   zWhileContext.__init__  sY    . 
KlC "D	 !!$'
-/BI&. "Dr4   c                 J   t        |t              r|dk  rt        d|z        t        j                         j                  |      | _        || _        || _        || _	        || _
        d| _        d| _        d| _        g | _        g | _        t        j                         | _        y)a  Creates a new `WhileContext` from arguments.

    Args:
      maximum_iterations: Optional upper bound on number of loop iterations.
      parallel_iterations: The number of iterations allowed to run in parallel.
      back_prop: Whether backprop is enabled for this while loop.
      swap_memory: Whether GPU-CPU memory swap is enabled for this loop.
      name: Optional name prefix for the returned tensors.

    Raises:
      ValueError: If `parallel_iterations` has invalid value.
    r   z4'parallel_iterations' must be a positive integer: %sN)r&   intrr   r
   r   r-  r   _maximum_iterations_parallel_iterations
_back_prop_swap_memory_pivot_for_pred_pivot_for_bodyr0  _loop_exits_loop_enters_graph)r   r  r@   r   r  r   s         r3   r  zWhileContext._init_from_args  s     )3/4G14L 12 3 3&&(44T:DJ1D 3DDO#DDD DKDD'')DKr4   c           	      x   t        |t        j                        sJ t        j                         }t        j
                  |j                  |      | _        |j                  r5|j                  t        j
                  |j                  |            | _
        nd| _
        |j                  | _        |j                  | _        |j                  | _        |j                  t        j
                  |j"                  |            | _        |j                  t        j
                  |j&                  |            | _        |j                  t        j
                  |j*                  |            | _        |j.                  D cg c]'  }|j                  t        j
                  ||            ) c}| _        |j2                  D cg c]'  }|j                  t        j
                  ||            ) c}| _        t6        t8        | w  |j<                  |       |r| j>                  D ]v  }|j                  |      j@                  }tC        jD                  |      s4|jG                  dtI        jJ                  tM        jN                  | jP                                     x t        j                         | _)        yc c}w c c}w )zCreates a new `WhileContext` from protocol buffer.

    Args:
      context_def: `WhileContextDef` protocol buffer.
      import_scope: Optional `string`. Name scope to add.
    Nr5  r>   )s)*r&   r   WhileContextDefr
   r   r   r7  r   maximum_iterations_namer   r  r@   r  r   r  r  r  pivot_for_pred_namer  pivot_for_body_namer  r9  r0  loop_exit_namesr  loop_enter_namesr  r:  r  r   r   r   r   r   r   	_set_attrr   	AttrValuer   as_bytesr   r  )	r   r   r   r   	exit_name
enter_nametensor_namer   r;  s	           r3   r.  zWhileContext._init_from_proto  sI    k#3#C#CDDDA''(@(@,ODJ**!"!3!3

 
 !D!D!-/"0d "&d + ? ?D!++DO#//D--{>>MOD --{>>MOD $${55|DFDK
 %44 	
311)\JKD &66 	
311*lKLD 
,&)) ' F
  O+,//B
,,|%//&//$))2LMO	O '')DK-
s   <,J2>,J7c                     | j                   S )z7The maximum number of iterations that will be executed.)r  r   s    r3   r  zWhileContext.maximum_iterations+  s     ###r4   c                     | j                   S )z4The number of iterations allowed to run in parallel.)r  r   s    r3   r@   z WhileContext.parallel_iterations0  s     $$$r4   c                     | j                   S )z1True iff backprop is enabled for this while loop.)r  r   s    r3   r   zWhileContext.back_prop5  s     ??r4   c                     | j                   S )z<True iff GPU-CPU memory swap is enabled for this while loop.)r  r   s    r3   r  zWhileContext.swap_memory:       r4   c                     | j                   S )z?The boolean tensor representing the loop termination condition.r>  r   s    r3   r2  zWhileContext.pivot?  s     ;;r4   c                     | j                   S )z-The list of enter tensors for loop variables.)r  r   s    r3   loop_enterszWhileContext.loop_entersD  r  r4   c                     | j                   S )z,The list of exit tensors for loop variables.)r  r   s    r3   
loop_exitszWhileContext.loop_exitsI       r4   c                     | j                   S )zThe gradient loop state.)r  r   s    r3   r   zWhileContext.grad_stateN  r  r4   c           	         || j                   j                  |      rAt        j                         }t	        j
                  | j                   |      |_        | j                  |_        | j                  /t	        j
                  | j                  j                   |      |_
        | j                  |_        | j                  |_        t	        j
                  | j                  j                   |      |_        t	        j
                  | j"                  j                   |      |_        t	        j
                  | j&                  j                   |      |_        |j*                  j-                  | j.                  D cg c]"  }t	        j
                  |j                   |      $ c}       |j0                  j-                  | j2                  D cg c]"  }t	        j
                  |j                   |      $ c}       |j4                  j7                  t8        t:        | {  |             | j>                  D ]-  }|j@                  jC                         }|jE                  |       / |S yc c}w c c}w )zConverts a `WhileContext` to a `WhileContextDef` protocol buffer.

    Args:
      export_scope: Optional `string`. Name scope to remove.

    Returns:
      A `WhileContextDef` protocol buffer.
    NrR  )#r   rD  r   r  r
   r   r7  r  r@   r  r  r  r   r  r  r  r  r  r  r0  r9  r  r   r  r  r  r   rE  r:  r  r   r   rF  r   r   )r   r   r   lrG  rH  r;  s         r3   rI  zWhileContext.to_protoS  s    			 4 4\ B$446k!$!5!5dii!Nk(,(A(Ak%		!	!	-.1.B.B$$))</9+"ook $ 1 1k(+(<(<



#
#\)3k%(+(<(<



#
#\)3k%"33DKK4D4D4@ Bk!!((>B>N>N*9:#

qvv|
4* 	 ""))>B>O>O+9:#

qvv|
4+ 	 &&
d
2
2
MO)) 7& 00446
**:67 *+s   7'I"'I'c                 Z    |j                   j                  | j                  |             y rQ  )r  rT  rI  r   s      r3   r   z(WhileContext.to_control_flow_context_def{  s!    ##DMM|M$LMr4   c                     t        | |      }|j                          | j                  D ]  }t        ||        |j	                          |S )zReturns a `WhileContext` object created from `context_def`.

    Args:
      context_def: A `WhileContextDef` protocol buffer.
      import_scope: Optional `string`. Name scope to add.

    Returns:
      A `WhileContext` Python object.
    rK  r   )r  r   rF  rL  r   rM  s       r3   rO  zWhileContext.from_proto~  sH     ;\
JCIIK!11 K
#J\JKHHJJr4   c                     | S r;   rc   r   s    r3   r  zWhileContext.GetWhileContext  s    Kr4   c                 J    | j                   | j                   S | j                  S r;   )r  r  r   s    r3   r  zWhileContext.GetControlPivot  s&    '!!!r4   c                    |}|j                   | j                  v}||j                  j                  | uz  }|r| j                  j	                  |j                          t        j                         j                         }|r|j                         }|j                  rt        j                  |j                        }t        j                  |j                        r|j                  }|r|j                         }||j                  j                  k(  r6|j                  j                  |      }|| j                  |j                   <   |S | j                   | j                   j#                  |      }t        j$                  d      5  t'        || j(                  d| j*                        }|j,                  j/                  |       | j                   r%| j                   j1                  |j                         ddd       | j3                  g       | j                  j	                  |j                          || j                  |j                   <   |}|S | j                  j5                  |j                         }||}|S # 1 sw Y   xY w)rV  NT)r?   r@   )r   r   r   _control_flow_contextr   r
   r   r   r  r   r   rk  r   forward_contextGetRealValuer   r   rX  rY  r<   r   r  r   prevent_feedingr  _FixControlInputsAndContextrW  )	r   r[  rH   	new_value	grad_ctxtforward_ctxtrp  rE   
actual_vals	            r3   rX  zWhileContext.AddValue  s   F,I --T99I
llsxx 
 '')CCEi	--/	--cff5,__SVV$'55L)99;lY11AAA ++88=H.6D!!#((+O				($$--c2##D) 3JJ $ 9 9	;
 	##E*



(
(
23 &&w/ lluzz"(-dCHH%f
 M ((,,SXX6j		M)3 3s   A0I<<Jr   c                 
   t        j                  |      s|j                  dv rt        j                         j                         }|r|j                         }|j                  rt        j                  |j                  d   j                        }||j                  j                  k(  rJ|j                  d   j                  j                         }|j                  |       |j                  |       y| j                  |       y)r`  >   RankSizeShaper   N)r   IsInXLAContextr1   r
   r   r   r  r   rx   r   r  r   r]  )r   r   r  op_input_forward_ctxtop_input_ctxts        r3   r^  zWhileContext.AddOp  s     r"rww2K'K'')CCEi	--/	"&"6"6ryy|"G
"i&:&:&J&JJIIaLOOEEGM((7((,r4   c                 P   |j                   dv r)|j                  | j                         j                         |j                  sv| j                  |      \  }}|s)|j                  | j                         j                         |j                  D ]'  }| j                  j                  |j                         ) nt        t        |j                              D ]:  }|j                  |   }| j                  |      }||k7  s)|j                  ||       < | j                  |      \  }}| j                  |       |j                  D ]'  }| j                  j                  |j                         ) |rt        j                   d      5  | j#                          |D cg c]:  }|j                  r,t%        j&                  |j                  d         j                  < }}| j)                          ddd       |j+                  |       | j,                  st/        j0                  |      sG|j2                  j5                  |       |j                  D ]  }|j2                  j7                  |        | j,                  r| j,                  j9                  |       yyc c}w # 1 sw Y   xY w)zAdd `op` to the current context.

    We move any external control dependencies of the op to the loop pivot, to
    ensure they get executed.
    )PartitionedCallStatefulPartitionedCallNr   )r1   rf  r  r   rx   r  ri  r   r   r   rg  r
  rX  r   _MaybeAddControlDependencyr
   rY  r   r   r,   r   r  r   r   rk  r   rZ  r  r  )r   r   r  external_inputsr  rl  rm  r|   s           r3   r]  zWhileContext._AddOpInternal  s3    
ww@@D00255699(,(H(H(L%no
d224778zz !! ! RYY( *%IIeq!Q;


5&
)	*  ;;B?a %%b)zz !! ! ##D) 

 %
yy qyy|,//
 

 			 	_-$//""5hh#zz $!
  #$ 
$$R( 
 s   J?JJJJ%c                 n    d } ||      r*|j                  | j                         j                         yy)zDAdd a control input to the op if it only depends on loop invariants.c                     | j                   ry| j                  j                  | j                        s| j                  dk(  ry| j                  D ]#  }t        j                  |j                        r# y y)z.Determines if `op` needs a control dependency.Fre  T)r  r   rh  r1   rx   r   IsLoopConstantEnterr   )r   r  s     r3   	_IsOpFreez:WhileContext._MaybeAddControlDependency.<locals>._IsOpFree"  s`    						rww	'2776H+Hyy !''- r4   N)rf  r  r   )r   r   r  s      r3   r  z'WhileContext._MaybeAddControlDependency  s2     }D002556 r4   c                    t        j                  dd      }|H|j                  j                  j                  d   j                  }|j                  j                  |       | j                          | j                  |j                         t        || j                  d| j                  d      }| j                  j                  |       t        ||g      d   }t        || j                         }t#        j$                  |d   d      }t'        |      }|j                  j)                  d|       t+        |d   d      }	| j,                  j                  |	       | j/                  |	g       | j1                          |	|fS )aB  Adds a loop that counts the number of iterations.

    This is added to the forward loop at the time when we start to
    create the loop for backprop gradient computation. Called in
    the outer context of this forward context.

    The pseudocode is:
      `n = 0; while (_pivot) { n++; }`

    Note that a control dependency is added to `n` to ensure the correct
    execution order of stack push ops.

    Args:
      outer_grad_state: The outer grad state. None if not nested.

    Returns:
      The number of iterations taken by the forward loop and the loop index.
    r   f_countr   Fr?   r@   r   rp   )r   constantforward_indexr   rx   rf  r   r   r   r<   r   r  r  r   ru   rS   r0  r   r   r8   r   rL   r  r  r   )
r   outer_grad_statenouter_add_openter_nmerge_nswitch_nrl  next_ntotal_iterationss
             r3   AddForwardLoopCounterz"WhileContext.AddForwardLoopCounter4  sB   & 	QY/A# &3366==a@CClddl+JJLLL	

 55G 	G$Wg&'*Ggt{{+HLL!a(EE"FJJQ'HQKi8OO+,OO%&'IIKV##r4   c                    |j                   t        j                         u}|rt        j                  |      }nt        j                  dd      }| j                          | j                  |j                         t        || j                  d| j                  d      }| j                  j                  |       t        ||g      d   }|| _        |rt        j                  dd      }t#        j$                  |      }t'        |d      | _        t+        || j(                        }t#        j,                  |d   |      }	|	| _        t1        |	      }
|j2                  j5                  d|
       t7        |d   d      }| j8                  j                  |       |%|j:                  j=                  |j2                         | j?                  |g       | jA                          |
S )a=  Add the backprop loop that controls the iterations.

    This is added to the backprop loop. It is used to control the loop
    termination of the backprop loop. Called in the outer context of
    this grad context.

    The pseudocode is:
      `n = count; while (n >= 1) { n--; }`

    Note that a control dependency is added to `final_zero` to ensure the
    correct execution order of stack pop ops.

    Args:
      count: The number of iterations for backprop.
      outer_grad_state: The outer grad state. None if not nested.

    Returns:
      The loop index.
    rp   b_countr   Fr  r   )!r   r
   r   r   r,   r   r  r   r   r   r<   r   r  r  r   ru   r  r   greater_equal	loop_condr0  rS   subtractr  r8   r   r   rL   r  	grad_syncrf  r  r   )r   countr  in_separate_functionsoneenter_countmerge_countrP   switch_countrl  
next_count
final_zeros               r3   AddBackpropLoopCounterz#WhileContext.AddBackpropLoopCountere  s   ( "KKs/D/D/FF  'e   3cJJLLL

 55K 	K(k23A6K&D  3c!!+s3DDy1DK+t{{3Ll1os3E D&JNN  J/l1oI6JOO:&#   33JMMB 	OOZL!IIKr4   c                    | j                          |j                         }|j                         rr| j                  r| j                  j	                          t        j                  d|j                  |d      }| j                  r| j                  j                          n|j                  d   }t        | j                  t              r| j                  j                  | j                  j                  }|j                  j	                          t        j                  |d      }|j                  j                          | j                  j                  }|j!                  |      }	| j                  j	                          |j#                  |	|      }
t        j$                  |
|j                        }| j                  j                          n| j                  r| j                  j	                          t        j                  |d      }t        j$                  ||j                        }| j                  r| j                  j                          | j	                          | j'                  |j(                         t+        || j,                  d| j.                  d      }| j0                  j3                  |       t5        ||gd      d   }t7        || j8                        \  }}t;        j<                  ||      }t?        |      }|j@                  jC                  d|       tE        |d      }| jF                  j3                  |       | jI                  |g       |S )	a  Add an accumulation loop for every loop invariant.

    This is added to the backprop loop. It is used to accumulate partial
    gradients within each loop iteration. Called when in the gradient while
    context.

    The pseudocode is:
      ```
      acc = 0.0;
      while (_pivot) {
        acc += grad;
      }
      ```

    Args:
      op: The Enter op for a loop invariant.
      grad: The partial gradient of an iteration for a loop invariant.

    Returns:
      The gradient for a loop invariant.
    r   b_accr   r   Frn   r  r   rp   )%r   rG   is_fully_definedr   r   r   r  r)   rx   r&   r  r   r  r   r  r  AddForwardAccumulatorAddBackpropAccumulatedValuezerosr   r   r<   r   r  r  r   ru   rS   r0  r   r   r8   r   r   rL   r  r  )r   r   gradr   accr   r  zeros_shaper  history_zeros_shape
real_shape	enter_acc	merge_accswitch_acc_falseswitch_acc_trueadd_accnext_acc
result_accs                     r3   AddBackpropAccumulatorz#WhileContext.AddBackpropAccumulator  s   , 	IIK NNE			  "  DJJe'Jc			!iile
T''
6



'
'
366""((*..uuE""'')??;;.DD  "%AA.
ooj$**5!



"
"
$..uuEook4::6



!
!
#JJLLL

 55I 	I&y),7;A>I(.y$++(F%oll?D1Gg&HLLq(+&W5JOO:&OOZL!r4   c                 
   |j                   }|j                  }|j                  }| j                          | j                  r| j                  j                          |j                         j                         rt        j                  t        j                  d      g|j                         j                  dd z         }| j                  r| j                  j                          t        j                  d|j                  |d      }| j                  rp| j                  j                          nUt        |j                   d         dd }t#        j$                  dg|gd      }t#        j&                  ||j                        }t        j                  dg|j                        }d}	||j                         j                         r}| j                  r| j                  j                          t        j                  d|j                  |j                               }	| j                  r_| j                  j                          nDt#        j(                  t#        j*                  |j                   d   d|j                  	      d
      }	| j                  r| j                  j                          | j                          | j-                  |j.                         | j-                  |j.                         ||g}
|	,| j-                  |	j.                         |
j1                  |	       |
D cg c]'  }t3        || j4                  d| j6                  dd      ) }}|d   j9                  dg       |j:                  j                  3|d   j9                  dg|j:                  j=                         dd z          | j>                  jA                  |       |D cg c]  }tC        ||gd      d    }}|D cg c]  }tE        || jF                         }}tI        |dd ||g      D cg c]   \  }}t#        j$                  |d   |gd      " }}}|	+|j1                  tK        jL                  ||d   d                |D cg c]  }tO        |       }}tI        ||      D ]!  \  }}|jP                  jS                  d|       # |D cg c]  }tU        |d   d       }}| jV                  jA                  |       | jY                  |       t[        j\                  |d   |d   |	
|d         S d      S c c}w c c}w c c}w c c}}w c c}w c c}w )a  This is used for accumulating gradients that are IndexedSlices.

    This is essentially the equivalent of AddBackpropAccumulator but optimized
    for things like updating embeddings from within a while loop.

    Args:
      op: The Enter op for a loop invariant.
      grad: The partial gradients represented as an IndexedSlices.

    Returns:
      The accumulated IndexedSlices gradient of the loop invariant.
    rp   Nr   r  r  )r)   r   F)ro   out_typern   )r?   r@   rA   r   r      )indicesr   dense_shape)/r   r  r  r   r   r   rG   r  r   r   	Dimensionr   r   r  r)   r  rx   r   concatr  
zeros_liker  r   r   r   r<   r   r  rF   r   as_listr  r   ru   rS   r0  rU   r   maximumr8   r   r   rL   r  r  r	   rm   )r   r   r   r   r  r  values_shape
values_accindices_acc	shape_accinit_accr  r  r  
switch_accxaxvacc_indexed_slicesr
  xmxnexit_accs                         r3   #AddBackpropIndexedSlicesAccumulatorz0WhileContext.AddBackpropIndexedSlicesAccumulator  s    [[FllG""KIIK
 **,!--|/E/Ea/H.I.4.>.>.@.E.Eab.I/J Kl			  "''
V\\G=j			!)"))A,7;l%%sL&91=l??<v||Dj&&sGMM:KI				 	1	1	3



"
"
$(({  (=(=(?A	



!
!
#(($$		!u{7H7HJ	
 
JJLLL!LL!!"Z(H
ll9>>"ooi  $,   	JJ $ 9 9!	I  aLD6"(ldVj&6&6&>&>&@&DDEI&9BCA1vG,Q/CIC2;<Q&DKK(<J<
 *Ra.7F*;<B 	"Q%a(   0 0jmA>N OP+=>aq!>H>i* !Bee!R ! 3==QQqT(=H=OO8$OOH''{#,#8HQKD D ?CD DG D< ? >s$   +,T8T=5U(%UU	Uc                     t               | _        |D ]Y  }t        |t        j                        r&| j                  j                  |j                         Ct        dt        |       d       y)z'Makes the values known to this context.z.'values' must be a list of Tensors. Received: r#   N)	r   r   r&   r'   r(   r   r   r0   r1   )r   r   r  s      r3   _InitializeValueszWhileContext._InitializeValues`  sb    5DL 1	Az((	)  %%)!WIQ0 1 	1	1r4   c                 P   t        j                  d t        j                  |d            }| j                  |       | j                  r)|D cg c]  }| j                  j                  |       }}n|}g }	t        j                  d      5  t        ||      D ]  \  }
}t        |
| j                  d| j                  d      }t        |
j                         |      r|j                  |       n-t        d|
j                    d|
j                          d	| d
      |j"                  j%                  |       | j                  r%| j                  j'                  |j(                         |	j+                  |        	 ddd       | j                  }d}|#|!|j-                         }|j                  }||!|c|	D ]^  }t/        j0                  |j(                  j2                  d   j(                        s:|j(                  j5                  |j(                         ` | j7                  |	       | j                  |	       |	| _        |	D cg c]  }t;        ||g      d    }}|d   | _        t        j                  t>        ||      }t        j@                  ||d      }t        jB                   ||       }tE        |d      | _#        |D cg c]  }tI        || jF                         }}|D cg c]  }tK        |d          }}|d   | _&        t        j                  t>        ||      }t        j@                  ||d      }t        jN                  t        jP                  jR                        } || }t        jN                  t        jP                  jR                        }t        jT                  |      s|g}tW        |      tW        |      kD  ry|tW        |      d }t        jX                  t        jP                  jR                        }||dd t        j                  |      5  d }t        j                  ||d      }ddd       t[        j\                  |      }t        j^                  ta        |      ta        |      d       |}t        j                  tb        t        j                  |d      d      }t        jd                  |      }tW        |      tW        |      k7  r$t        dtW        |       dtW        |       d      g } t        ||      D ]   \  }!}"| j+                  tg        |!|"             " |D cg c]  }ti        |d          }#}|#| _5        | jm                  |#       ||#fS c c}w # 1 sw Y    xY wc c}w c c}w c c}w # 1 sw Y   UxY wc c}w )z?Core: Add the loop termination condition and body to the graph.c                     | j                   S r;   r  )specs    r3   <lambda>z)WhileContext._BuildLoop.<locals>.<lambda>n  s
    TZZ r4   Tr    NF)r?   r@   rA   z"The shape invariant specified for z^ is not compatible with the initial shape of the loop variable. It enters the loop with shape z', but the specified shape invariant is r#   r   	structureflat_sequencer!   LoopCondr   rp   c                 d    t        | t        j                        r| S t        j                  |       S r;   )r&   r   r   r   r,   )r  s    r3   map_fnz'WhileContext._BuildLoop.<locals>.map_fn  s)    +778H##A&
&r4   zCNumber of inputs and outputs of 'body' must match 'loop_vars'. Got z' for the number of inputs/outputs, and z for 'loop_vars'.)7r   r.   rT   r&  r   rX  r
   rY  rU   r<   r   r  r   rG   rF   rr   r   r   r  r  r   r   r  r   r  rx   rf  r  r  ru   r  r   rV   rR   r  r0  r`   r/   r  rw  rx  ry  	is_nestedr
  rz  r   r%   rw   r|  r    convert_n_to_tensor_or_compositer   rL   r  r  )$r   rP   bodyflat_orig_loop_varsflat_loop_varsloop_vars_signatureflat_shape_invariantsr  	real_vars
enter_varsreal_varshape_invariant	enter_varr   control_pivotr   
merge_varsmerge_vars_with_tensorarrayspacked_varscswitch_varsvars_for_bodyvars_for_body_with_tensorarrayspacked_vars_for_bodyr~  body_resultr  r  r  r0  original_body_resultrH   	next_varsr   rj   	exit_varss$                                       r3   
_BuildLoopzWhileContext._BuildLoopj  s_    !..(DAC 	>*<JKq4&&//2KiK iJ		!	!$	' %'*96K'L %
#(OJJ $ 9 9!#	 !!3!3!5G


o
.28==/ B,,4,>,>,@+A B..=->aAB B 	''	2



(
(
6)$)%%0 ''MM

#(=#335m#22m 
#(=   6###CFFMM!$4$7$78
&&
#
#M$4$4
56 	$$Z0:&"D,67q%A-"7J7%a=D#'#5#5$&9:$G  ''%2 K 	dK01AAJ/DK?IJ!%a5JKJ /::Yqt_:M:(+D '+&8&8$&9='J#00%5  &&s}}'H'HIM,-K''(I(IJN>>+& Mk
>S//$S%7%89m**3==+L+LMk$k!n##M2 	9	' ((K49	9 !==kJK
 	!"D$5O '$[D9 F 11&9F :#f+% ++.z?*; <..1&k]:KM N N IJ' 21*1a012 &11ad1I1 D 	OOI** L
% %X 8 K ;&	9 	9L 2s7   "U5C/U:	VV0V'VV#:VV c                    t        j                  |d      }t        j                  t        |      }t        j                  t        t        j                  |d            }|t        j                  t
        ||      }nt        j                  t
        |      }	 | j                          t        j                         j                         5  | j                  |||||      \  }	}
ddd       | j                          t        j                  	d      }t        j                  t        |
      }t        j                  |	|d      }|r|S t        |
      dk(  r|d   S |S # 1 sw Y   |xY w# | j                          w xY w)z9Add the loop termination condition and body to the graph.Tr    Nr+  rp   r   )r   rT   r.   r   r   r   r   r
   r   _mutation_lockrJ  r   r   rV   r
  )r   rP   r3  	loop_varsshape_invariantsreturn_same_structurer4  r5  r6  rG  rI  flat_resultexit_vars_with_tensorarrayspacked_exit_varss                 r3   	BuildLoopzWhileContext.BuildLoop  si   
 ,,yDI""6	CI ''$Y$79N # ..
'4DF !..
'4

jjl   "113 !*.//$+^+!'i!
 iik,,3tLK #'"4"4$k9#> ,,&1 
 $'	Na$7a M=MM+! !
 iiks$   2E, E %E,  E)%E, ,E>c                    t        j                         }|D ];  }t        |t        j                        r|g}nt        dt        |       d      |D ]  }|j                  j                  d   j                  }|j                  |g      }g }|D ]n  }	d}
t        j                  |	      }| j                  }|d n|j                         }||k7  r|||k(  rd}
n|j                  }||k7  r|
s^|j                  |	       p |j                  j                  |        |j                  j!                  |       |j#                  |j                          > y )Nz.'enters' must be a list of Tensors. Received: r#   r   TF)r
   r   r&   r'   r(   r0   r1   r   rx    _control_dependencies_for_inputsr   r	  r   r  r   r   r  '_record_op_seen_by_control_dependencies)r   entersr   r   xsr  inp_opr  outer_control_inputsr   keep_as_control_inputop_ctxt
outer_ctxtouter_while_contexts                 r3   r  z(WhileContext._FixControlInputsAndContext'  sa   !!#E <	Az((	)S %%)!WIQ0 1 	1 <!Q""??I!  	,B #'
))"-'))*)3);!+!;!;!= g%!Z3F%F&+##11J	 g%
 # ''+	, 	
&&t,	  !5655add;+<<r4   c                      yr  rc   r   s    r3   r  zWhileContext.IsWhileContextH  r  r4   )N
   TFwhile_contextNNNr;   )&r   r"  r#  r$  r   r  r.  r%  r  r@   r   r  r2  r  r  r   rI  r   r  rO  r  r  rX  r
   r(  r^  r]  r  r  r  r  r$  r&  rJ  rS  r  r  r  r  s   @r3   r  r    s   + #'#% # "@!*F4*l $ $ % %            &PN  " 
6pcmm 43)s}} 3)j73== 7*/$b@DPs}} PdeDCMM eDN1J+X/Nb<Br4   r  c           	         t        | t        t        f      s| g} g }| D ]  }t        |t        j                        rt        |g|      }t        j                  |      }t        |t        j                        r%|j                  t        j                  |             ~|j                  t        j                  t        j                  |j                        t        j                  |j                                      |S )af  Return x as a list of Tensors or IndexedSlices.

  For entries of `x` that are Operations, this returns an Identity of `p`
  with a dependency on the operation.

  Args:
    x: A Tensor/IndexedSlices/Operation or a list or tuple of them.
    p: A Tensor to return for entries in `x` that are Operations.

  Returns:
    A list of Tensors or IndexedSlices.
  )r&   r|  r}  r
   r(  rt  r]   r'   r(   r   r   r,   r	   rm   r   r  )r  pr  rj   s       r3   _AsTensorListrd  O  s     
Aj)	*	
A! 	La!S]]#
QC
#a**1-A!Z&&'hhy!!!$%hh

&
&  *I,>,>qyy,IKL	L 
(r4   c                 :   t        |       t        |      k(  sJ d       t        | |      D ]n  \  }}|j                  |j                  k(  r J d|j                  d|j                  d|j                  j                  d|j                  j                  d	        y )Nz9Values returned by a() and b() must have the same length.zValues returned by a() [z] and b() [z] must have the same type: , r#   )r
  rU   r)   r   )abr  ys       r3   _CheckResultsrj  m  s    	Q3q6	 CAC	!Qi Qda77agg Q$%FFAFFAGGLL!'',,	PQQr4   c           	         t        j                         r|S t        j                  |dt	        |       |gz         5 }t        j
                  |      5  t        j                  |       5  t        j                  |      }t        |t        j                        r[t        j                  t        |j                  |      |j                  |j                        cddd       cddd       cddd       S t        ||      cddd       cddd       cddd       S # 1 sw Y   nxY w	 ddd       n# 1 sw Y   nxY wddd       y# 1 sw Y   yxY w)a)  Produces the content of `output_tensor` only after `dependencies`.

  In some cases, a user may want the output of an operation to be
  consumed externally only after some other dependencies have run
  first. This function ensures returns `output_tensor`, but only after all
  operations in `dependencies` have run. Note that this means that there is
  no guarantee that `output_tensor` will be evaluated after any `dependencies`
  have run.

  See also `tf.tuple` and `tf.group`.

  Args:
    dependencies: Iterable of operations to run before this op finishes.
    output_tensor: A `Tensor` or `IndexedSlices` that will be returned.
    name: (Optional) A name for this operation.

  Returns:
    Same as `output_tensor`.

  Raises:
    TypeError: if `output_tensor` is not a `Tensor` or `IndexedSlices`.
  control_dependencyr   N)r   executing_eagerlyr
   rQ   r|  r^   rY  r]   r&   r	   rm   r/   r   r  r  )dependenciesoutput_tensorr   s      r3   rt  rt  v  s+   .  
~~d0<(M?:< 
5?C			=	) 5##L1 5::=Im^%A%AB--,,48-:O:O'')5 55 5
5 
5 =t45 55 5
5 
55 5 55 5 5
5 
5 
5sT   ED0'A/D	D0	E2D>	D0	ED#D0'	E0D9	5EEc                    t        j                  |      5  | t        |      cd d d        S t        j                  |       5  t        |      cd d d        cd d d        S # 1 sw Y   nxY w	 d d d        y # 1 sw Y   y xY w)Nr   )r
   rY  r{  device)devdepsr   s      r3   _GroupControlDepsrt    sz    
%  
{    ::c?  $   	        	     s(   A8A8A"	A8"A+	'A88Bgroupc            
      r   t        j                         ry|j                  dd      }|r+t        ddj	                  |j                               z         t        j                  |d|       5 }| st        |      cddd       S i }t        j                  | d      D ]T  }t        |d	      st        d
| dt        |       d      |j                  }||v r||   j                  |       O|g||<   V t!        |      dk(  r,|j#                         \  \  }}t%        |||      cddd       S g }d }t'        ||      D ]   }|j                  t%        |||                " t        j(                  |      5  t        |      cddd       cddd       S # 1 sw Y   nxY w	 ddd       y# 1 sw Y   yxY w)a  Create an op that groups multiple operations.

  When this op finishes, all ops in `inputs` have finished. This op has no
  output.

  Note: *In TensorFlow 2 with eager and/or Autograph, you should not require
  this method, as ops execute in the expected order thanks to automatic control
  dependencies.* Only use `tf.group` when working with v1
  `tf.Graph` code.

  When operating in a v1-style graph context, ops are not executed in the same
  order as specified in the code; TensorFlow will attempt to execute ops in
  parallel or in an order convenient to the result it is computing.  `tf.group`
  allows you to request that one or more results finish before execution
  continues.

  `tf.group` creates a single op (of type `NoOp`), and then adds appropriate
  control dependencies.  Thus, `c = tf.group(a, b)` will compute the same graph
  as this:

      with tf.control_dependencies([a, b]):
          c = tf.no_op()

  See also `tf.tuple` and
  `tf.control_dependencies`.

  Args:
    *inputs: Zero or more tensors to group.
    name: A name for this operation (optional).

  Returns:
    An Operation that executes all its inputs.

  Raises:
    ValueError: If an unknown keyword argument is provided.
  Nr   zUnknown keyword arguments: rf  
group_depsr   Tr    rq  z<'inputs' should be zero or more (nested) Tensors. Received 'z' with type 'z'.rp   c                     | dS | S )z6A sort key that allows None to be compared to strings. rc   )rr  s    r3   
device_keyzgroup.<locals>.device_key  s    ;R'C'r4   key)r   rm  r   rr   joinr   r
   rQ   r{  r   rT   hasattrr0   r1   rq  r   r
  r   rt  r   rY  )rx   kwargsr   ops_on_devicere   rr  rs  rz  s           r3   ru  ru    s   L  	FD	!$
2TYYv{{}5MM
NN
~~dL&1 !T! ! M||Fd; #S(# %%(EtCykE F 	FJJc		c!!#&!Uc# =Q"((*lksDsDt4'! !. D( m4 >
kk#Cs);<=> 
	!	!$	'  A! !@  A! ! !s2   ,F-B F-.A
F-8F	F-F 	F--F6tuple)v1c                     t        | ||      S )aY  Groups tensors together.

  The returned tensors have the same value as the input tensors, but they
  are computed only after all the input tensors have been computed.

  Note: *In TensorFlow 2 with eager and/or Autograph, you should not require
  this method, as ops execute in the expected order thanks to automatic control
  dependencies.* Only use `tf.tuple` when working with v1 `tf.Graph` code.

  See also `tf.group` and `tf.control_dependencies`.

  Example:
  >>> with tf.Graph().as_default():
  ...   with tf.compat.v1.Session() as sess:
  ...     v = tf.Variable(0.0)
  ...     a = tf.constant(1.0)
  ...     sess.run(tf.compat.v1.global_variables_initializer())
  ...     for i in range(5):
  ...       update_op = v.assign_add(1.0)
  ...       b = a + v
  ...       res_b = sess.run(b)
  ...       res_v = sess.run(v)
  ...       print(res_v)
  0.0
  0.0
  0.0
  0.0
  0.0

  >>> with tf.Graph().as_default():
  ...   with tf.compat.v1.Session() as sess:
  ...     v = tf.Variable(0.0)
  ...     a = tf.constant(1.0)
  ...     sess.run(tf.compat.v1.global_variables_initializer())
  ...     for i in range(5):
  ...       update_op = v.assign_add(1.0)
  ...       calc = [a + v]
  ...       # `tf.tuple` ensures `update_op` is run before `b`
  ...       b = tf.tuple(calc, [tf.group(update_op)])
  ...       res_b = sess.run(b)
  ...       res_v = sess.run(v)
  ...       print(res_v)
  1.0
  2.0
  3.0
  4.0
  5.0


  Args:
    tensors: A list of `Tensor`s or `IndexedSlices`, some entries can be `None`.
    control_inputs: List of additional ops to finish before returning.
    name: (optional) A name to use as a `name_scope` for the operation.

  Returns:
    Same as `tensors`.

  Raises:
    ValueError: If `tensors` does not contain any `Tensor` or `IndexedSlices`.
    TypeError: If `control_inputs` is not a list of `Operation` or `Tensor`
      objects.

  )rW   r   r  )r  )rW   r  r   s      r3   tuple_v2r    s    D 
wT.	IIr4   c                 T   t        j                         r| S t        j                  |d|       5 }| D cg c]J  }t	        |t        j
                        st        j                  |      s||nt        j                  |      L } }| D cg c],  }|(t	        |t        j
                        r|n|j                  . }}|rp|D ]k  }t	        |t        j                        r|j                  }n1t	        |t        j
                        st        dt        |             |j                  |       m t        t!        |      d       }|st#        d|  d      t%        | }g }| D ]  }t        j                  |      r|j                  t'        |g|             5t	        |t        j
                        r:t        j(                  |g      5  |j                  t%        |             ddd       |j                  d        |cddd       S c c}w c c}w # 1 sw Y   xY w# 1 sw Y   yxY w)aG  Group tensors together.

  This creates a tuple of tensors with the same values as the `tensors`
  argument, except that the value of each tensor is only returned after the
  values of all tensors have been computed.

  `control_inputs` contains additional ops that have to finish before this op
  finishes, but whose outputs are not returned.

  This can be used as a "join" mechanism for parallel computations: all the
  argument tensors can be computed in parallel, but the values of any tensor
  returned by `tuple` are only available after all the parallel computations
  are done.

  See also `tf.group` and
  `tf.control_dependencies`.

  Args:
    tensors: A list of `Tensor`s or `IndexedSlices`, some entries can be `None`.
    name: (optional) A name to use as a `name_scope` for the operation.
    control_inputs: List of additional ops to finish before returning.

  Returns:
    Same as `tensors`.

  Raises:
    ValueError: If `tensors` does not contain any `Tensor` or `IndexedSlices`.
    TypeError: If `control_inputs` is not a list of `Operation` or `Tensor`
      objects.

  r  NzB'control_inputs' must only contain Operation or Tensor. Received: c                     | j                   S r;   )_id)r   s    r3   r*  ztuple.<locals>.<lambda>s  s
     r4   r{  z3'tensors' must have at least one Tensor. Received: r#   )r   rm  r
   rQ   r&   r(  r   
is_tf_typerR   r   r'   r(   r0   r1   r   r   r   rr   ru  rt  rY  )rW   r   r  r=   
gating_opsrA  gatetpls           r3   r  r  :  s   D  N
~~dGW- # AH;< CMM*k.D.DQ.Gi 	
!33A6	7G  = 3==)qtt3J 
  !a**+dd!As}}-7)%& & 	! J->?J $$+9A/ 0 0*D
C 				"

$dVQ/0a'%%tf- 	
**U1X
	 	 	

4 G# #4	 	?# #sB   HAHH1H9DHH!H
HHHH'c                   F     e Zd ZdZ fdZd fd	Zd Zd Zd Zd Z	 xZ
S )	XLAControlFlowContextz1Base class for XLA and TPU control flow contexts.c                 8    t         t        |           d| _        y )Nr  )r:  r  r   r   )r   r;  s    r3   r   zXLAControlFlowContext.__init__  s    	
/1(DJr4   c                 .    t         t        |   ||       y r;   )r:  r  r   )r   r   r   r;  s      r3   r   z1XLAControlFlowContext.to_control_flow_context_def  s     


,,7Fr4   c                      yr  rc   r   s    r3   r  z"XLAControlFlowContext.IsXLAContext  r  r4   c                      y r;   rc   )r   r|   s     r3   r^  zXLAControlFlowContext.AddOp  s    r4   c                     |S r;   rc   )r   r  s     r3   rX  zXLAControlFlowContext.AddValue  s    Hr4   c                      y)zOReturns whether the tf.function should be retraced if the context changes.
    Frc   r   s    r3   RequiresUniqueFunctionRetracingz5XLAControlFlowContext.RequiresUniqueFunctionRetracing  s     r4   r;   )r   r"  r#  r$  r   r   r  r^  rX  r  r  r  s   @r3   r  r    s%    9)G	r4   r  z&__internal__.get_enclosing_xla_contextc                      t        j                         } | C| j                         }|!t        |t              r|S |j
                  }|!t        | dd      } | Cy)z6Recursively find and return the XLAControlFlowContext.Nouter_graph)r
   r   r   r&   r  r   getattr)r   context_s     r3   get_enclosing_xla_contextr    sl     


!%..0H

	H3	4''h 
 E=$/E 	 
r4   c                    | j                  d      r!t        j                  | j                  |      S | j                  d      r!t        j                  | j
                  |      S t        d| j                  d      z        )zDeserializes `context_def` into the appropriate ControlFlowContext.

  Args:
    context_def: ControlFlowContextDef proto
    import_scope: Optional `string`. Name scope to add.

  Returns:
    A ControlFlowContext subclass
  rS  r   r  z'Unknown ControlFlowContextDef field: %sr  )HasFieldr+  rO  rS  r  r  r   
WhichOneofrK  s     r3   rL  rL    s     +&!!L " : :,'""\ # ; ;E'226:; 	< <r4   )
proto_typerI  rO  r;   )Fr`  TTNr!  )rN   )T)Jr$  r&  tensorflow.core.frameworkr   tensorflow.core.protobufr   tensorflow.python.eagerr   tensorflow.python.frameworkr   r   r   r	   r
   r   r'   r   r   r   tensorflow.python.opsr   r   r   r   r   r   r   *tensorflow.python.ops.gen_control_flow_opstensorflow.python.utilr   r   r   r    tensorflow.python.util.tf_exportr   r  r}  r/   r8   r<   rL   rS   r`   ru   r   r   r   r   r   r   r   ABCMetar   r+  r  r  rd  rj  rt  rt  ru  add_dispatch_supportr  r  r  rL  register_proto_functionrx  COND_CONTEXTr6  rI  rO  WHILE_CONTEXTr  rc   r4   r3   <module>r     s$  
  4 5 + 8 3 . 6 + < 4 3 1 + ; / 6 * 2 9 ) + ' 1 6
 
242  !22j22"MJ))X=+@"1(OV5<8z3;; zzW$ W|5Z% Z@<Q#5L  7K K\ 7r	@J  @JF wi	E  EP. 8 3; <"<(   MM..!!%%	'   MM//""&&	(r4   