
    BVhSg                        d Z ddl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  ed      Z ed      Z ed      Z ed      Zg dZd Z  G d dejB                        Z"d Z# G d de$      Z% ejL                  d      Z'd Z(e(d         Z)d! Z*d" Z+y)#z7AutomaticControlDependencies and related functionality.    N)attr_value_pb2)context)auto_control_deps_utils)dtypes)indexed_slices)op_def_registry)ops)registry)sparse_tensor)	array_ops)control_flow_ops)control_flow_util)tensor_array_ops)nest)object_identity)tf_decorator)
CollectiveGatherCollectiveReduceCollectiveBcastSendCollectiveBcastSendV2CollectiveBcastRecvCollectiveBcastRecvV2NcclAllReduceRecv CollectiveInitializeCommunicatorCollectiveAssignGroupV2)RandomUniformRandomUniformIntRandomStandardNormalParameterizedTruncatedNormalTruncatedNormalRandomShuffleMultinomialRandomGammaRandomGammaGradRandomPoissonRandomPoissonV2)InfeedEnqueueInfeedEnqueueTupleEnqueueTPUEmbeddingSparseBatchEnqueueTPUEmbeddingIntegerBatch$EnqueueTPUEmbeddingSparseTensorBatch$EnqueueTPUEmbeddingRaggedTensorBatch'EnqueueTPUEmbeddingArbitraryTensorBatch.DynamicEnqueueTPUEmbeddingArbitraryTensorBatch)CudnnRNNCudnnRNNBackprop
CudnnRNNV2
CudnnRNNV3CudnnRNNBackpropV2CudnnRNNBackpropV3	RestoreV2SaveV2)AllToAllCrossReplicaSumCollectivePermutec                     | j                   xr: | j                  t        vxr& | j                  t        vxr | j                  t        vxs | j                  t
        v }|S N)_is_statefultypeASYNC_STATEFUL_OPSLEGACY_RANDOM_OPS&SKIPPED_ORDER_INSENSITIVE_STATEFUL_OPS_ALLOWLIST_STATELESS_OPS)oprets     ]/home/dcms/DCMS/lib/python3.12/site-packages/tensorflow/python/framework/auto_control_deps.pyop_is_statefulrF      sb    
// DGG-- CGG,,CGGAA
/ ''-
-	 
 
*    c                       e Zd ZdZdZy)ResourceTypez	read-onlyz
read-writeN)__name__
__module____qualname__	READ_ONLY
READ_WRITE rG   rE   rI   rI      s    )*rG   rI   c                     | j                   dk(  r	 | j                  d      gS | j                   dk(  r 	 | j                  t        j                        S g S # t        $ r Y g S w xY w# t        $ r Y g S w xY w)a  Returns CollectiveManager ID from the op if one exists, else None.

  CollectiveManager adds collective and no_op operations tagged with an ID,
  unique to the manager object. This function extracts that ID, or None, if the
  node was not generated by a CollectiveManager.

  Args:
    op: `Operation` to get the collective manager ID from.

  Returns:
    List of CollectiveManager IDs used by the op.
  r   _collective_manager_idStatefulPartitionedCall)r>   get_attr
ValueErrorutilsCOLLECTIVE_MANAGER_IDS)rC   s    rE   collective_manager_ids_from_oprW      s     WW""kk2344 
ww++[[5566 
)  
 
)
  
	)s"   A A$ 	A! A!$	A10A1c                   4    e Zd ZdZd Zd Zd Zd Zd Zd Z	y)	AutomaticControlDependenciesaT  Context manager to automatically add control dependencies.

  Code under this context manager will act as if a sensible set of control
  dependencies were present. More specifically:
    1. All stateful ops in the scope will execute (with the exception of ops in
       ASYNC_STATEFUL_OPS and LEGACY_RANDOM_OPS)
    2. Stateful ops which modify the same resource will execute in program order

  Note: creating variables in an automatic control dependencies context is not
  supported (the value of the variables will never change as they will keep
  getting reinitialized).

  NOT THREAD SAFE
  c                 b    t        j                         | _        t               | _        g | _        y r<   )r   ObjectIdentitySet_returned_tensorssetops_which_must_run_independent_ops)selfs    rE   __init__z%AutomaticControlDependencies.__init__   s%    ,>>@D!eDDrG   c                    t        |t        j                        rt        j                  |j
                        }t        j                  |j                        }| j                  j                  |       | j                  j                  |       t        j                  |||j                        S t        |t        j                        rt        j                  |j
                        }t        j                  |j                        }| j                  j                  |       | j                  j                  |       t        j                  |||j                        S t        |t        j                        rPt        j                  |j                        }| j                  j                  |       t        j                  ||      S t        j                  |      }| j                  j                  |       |S )a}  Acts like identity but marks the `Tensor` as a return value.

    This will possibly return a copy of the `Tensor`. Usage:

    ```
      with AutomaticControlDependencies() as a:
       ...
       t = a.mark_as_return(t)
      _ = ...(t...)  # i.e. it's safe to use t here
    ```

    Args:
      tensor: the `Tensor` to be marked

    Returns:
      a copy of the `Tensor`.
    )dense_shape)
isinstancer   IndexedSlicesr   identityvaluesindicesr\   addrc   r   SparseTensorr   TensorArrayflowbuild_ta_with_new_flow)r`   tensorrg   rh   rl   s        rE   mark_as_returnz+AutomaticControlDependencies.mark_as_return   s{   $ &.667!!&--0f""6>>2g
  )
  ())
'v'9'9; ;	FM66	7!!&--0f""6>>2g
  )
  (''
6v'9'9; ;	F,88	9,d
  &44VTBB
 'Fv&MrG   c                     | j                   j                  |       |j                  dt        j                  d             y)a]  Marks the given op as independent.

    Overrides any other rule for the op.

    Independent ops are guaranteed to execute before the return values, but
    are allowed to run in parallel with everything else. Use in programs which
    can guarantee that an op has side effects that don't affect any other op.

    Args:
      op: An operation
    _independent_side_effectsT)bN)r_   append	_set_attrr   	AttrValue)r`   rC   s     rE   run_independentlyz.AutomaticControlDependencies.run_independently   s2     	  $LL,n.F.F.NOrG   c                     t        j                         r| S t        j                         }|| _        d|_        | |_        |j                         | _        | S )NT)	r   executing_eagerlyr	   get_default_graph_graph_add_control_dependenciesexperimental_acd_managernum_operations_n_operations)r`   gs     rE   	__enter__z&AutomaticControlDependencies.__enter__	  sP      "k 	ADK"&A!%A))+DKrG   c                    |j                   d   }t        j                  |      }|j                  t        j
                  k(  r7|j                  j                  dk(  r| j                  |j                  |||       |j                  d   }t        j                  |      }||v ryt        j                  |j                  d      }	|j                  j                  |	d   j                  _        |j                  |	d   j                         ||v r|j                  ||          |	d   j                  ||<   ||v r!||   j                  |	d   j                         |j                  D ]'  }
|	d   j                  |t        j                  |
      <   ) y)a  Processes a switch node for a resource input.

    When tensorflow creates a cond, it creates a control flow context for each
    branch of the cond. Each external tensor accessed by that branch is routed
    through a switch op, which gets created in the graph _after_ the op which
    uses that tensor get created.

    If the resource comes from another switch op we process that one first.

    _process_switch creates a corresponding merge node for the switch node. This
    merge node is added to the outer control flow context of the switch
    node. We also ensure that:

      1. The switch node executes after the previous op which used the resource
         tensor

      2. Any op which uses a resource output of the switch node executes before
         the merge for the switch node.

      3. The next op which uses the input resource to the switch node (which
         might be another switch node for the other branch of the conditional)
         will execute after the merge node is done.

      4. The merge node is marked as must_run so it will run even if no
         subsequent operation uses the resource.

    Args:
      switch_op: the switch op to be processed
      ops_which_must_run: the set of ops which must run
      last_write_to_resource: map from resource tensor to last op updating
        it
      merge_for_resource: map from resource tensor to merge which must follow
        all usages of it.
    r   SwitchNartificial_merge)name)inputsr	   	tensor_iddtypedtypes_moduleresourcerC   r>   _process_switchoutputsr   merge_control_flow_contextouter_contextri   _add_control_input)r`   	switch_opr^   last_write_to_resourcemerge_for_resourceinpinput_idoutput	output_id	new_mergeos              rE   r   z,AutomaticControlDependencies._process_switch  se   J 

1
C}}S!H
yyM***svv{{h/F
366#57M-/q!Ff%I&& && 24I 	''55 aLOO) 9Q<??+))""#9(#CD'0|8$%%"55ilooF =-6q\__q)*=rG   c                    t        j                         ry | j                  t        j                         ur-t        d| j                   dt        j                                t        | j                  dd       }||j                  | j                  _        nd| j                  _        d | j                  _        i }t        j                  t              }i }i }t               }	i }
| j                  j                         | j                  d  }|D ]  }t        j                   |      rt               }|j"                  t$        v r| j'                  |       || j(                  v r|	j+                  |       gt-        j.                  |j"                        Ct1        |      rI|j"                  t2        j4                  vst7        d |j8                  D              r|	j+                  |       |j"                  dk(  r	 |||j;                  d      <   |j"                  dk(  r,|j>                  d	   j@                  tB        jD                  k(  r9|j"                  d
k(  rV|	D ]C  }|jG                  |       |j>                  D ]!  }t        jH                  |      }||v s|||<   # E t        |g      }	t               }tK        |      D ]  \  }}|tL        jN                  k(  }t        jH                  |      }||v r4|j+                  |       |jP                  j"                  dk(  r| jS                  |jP                  |	||
       |jT                  jV                  }||v r1|s||   jX                  |jX                  u r|j+                  ||          ||
v r|
|   jG                  |       |r||   j[                  |       |j]                  ||          g ||<   |||<    t1        |      r+|s)|jX                  d |v r|jG                  |d           ||d <   t_        |      }|D ]=  }||v r|jG                  ||          |||<   !||v r|jG                  ||          |||<   ? |r)s'|D cg c]  }|jX                  |jX                  u r| }}|ja                  |        | jb                  j]                  |	       d }te        tg        jh                  t        | jj                        d            D ]  \  }}| jb                  sg }|jT                  jV                  r8|d	k(  r/tm        jn                         }|ja                  | jb                         |g}n;| jb                  D cg c]&  }|jX                  |jP                  jX                  u r|( }}|jP                  ja                  |        || _8        y # t<        $ r Y w xY wc c}w c c}w )NzdWithin the automatic control dependency context, the default graph cannot change. Upon entry it was z, but on exit it changed to outer_graphFc              3   <   K   | ]  }|j                           y wr<   )	consumers).0r   s     rE   	<genexpr>z8AutomaticControlDependencies.__exit__.<locals>.<genexpr>  s     <v  "<s   NoOprQ   r   r   MergeT)expand_composites)9r   rx   rz   r	   ry   RuntimeErrorgetattrr{   r|   collectionsdefaultdictlistr]   get_operationsr~   r   IsInWhileLoopr>   'MUST_RUN_ORDER_INSENSITIVE_STATEFUL_OPSrv   r_   ri   r   getrF   rU   RESOURCE_READ_OPSanyr   rS   rT   r   r   r   r   r   r   _get_resource_inputsrI   rM   rC   r   graphbuilding_functionr   rs   updaterW   _add_control_inputsr^   	enumerater   flattenr\   r   no_opcollective_manager_ids_used)r`   unused_typeunused_valueunused_tracebackr   r   "reads_since_last_write_to_resource collective_manager_scopes_openedcollective_manager_scopes_usedr^   r   new_operationsrC   control_inputsr   r   r   resource_inputsresource_typeis_readis_building_functionmanager_ids
manager_idccontrol_output_opidxrupdated_ops_which_must_runs                               rE   __exit__z%AutomaticControlDependencies.__exit__W  s     "{{#//11//3{{m <..0134 4
 $++}d;K.9.S.Sdkk+.3dkk++/DKK(   *5)@)@)F& (*$%'"[[//1$2D2D2EFN<  l-		(	(	,un	;	; 	r"	t$$	$r" rww'/"GG5222<<<r" 
F		+- +2;;&,( )
 
H	1!3!3}7M7M!M 
G	# 	4A



"XX 4c}}S)H1113$X.4	4 !"Yo !5R 8 0
#}<#9#99==% &
H%66;;("


svv'957IK!xx99--!$X.DD))*5h?@))
X
&
9
9"
=
,X
6
=
=b
A


 B8 L
M9;
,X
6-/
 
*;0> 
_&&.))


 6t <
=')t$ 326k# 
:*99


 @ L
M9;
*:
6 99!!"@"LM79
(
4
: 
 4%
&&"*B*BB 
 

 	^,Yl-^ 	""#56T$001TJL =Q		 	 %'"77$$ AX 0 6 6 811$2I2IJ(9':
$ 00(((ADD,F,FF (
$ ( 	
  !;<'=* (FD$S  	
	R
4(s   8V-#!V=+W-	V:9V:N)
rJ   rK   rL   __doc__ra   ro   rv   r   r   r   rO   rG   rE   rY   rY      s*    
*XP==~HFrG   rY   acd_resource_resolversc                 0    t         j                  |        | S )a  Register a function for resolving resources touched by an op.

  `f` is called for every Operation added in the ACD context with the op's
  original resource reads and writes. `f` is expected to update the sets of
  resource reads and writes in-place and return True if it updated either of the
  sets, False otherwise.

  Example:
  @register_acd_resource_resolver
  def identity_resolver(op, resource_reads, resource_writes):
    # op: The `Operation` being processed by ACD currently.
    # resource_reads: An `ObjectIdentitySet` of read-only resources.
    # resource_writes: An `ObjectIdentitySet` of read-write resources.
    def update(resource_inputs):
      to_remove = []
      to_add = []
      for resource in resource_inputs:
        if resource.op.type == "Identity":
          to_remove.append(resource)
          to_add.extend(resource.op.inputs)
      for t in to_remove:
        resource_inputs.discard(t)
      resource_inputs.update(to_add)
      return to_add or to_remove
    return update(resource_reads) or update(resource_writes)

  Args:
    f: Python function with signature
    (Operation, ObjectIdentitySet, ObjectIdentitySet) -> bool

  Returns:
    The function `f` after adding it to the registry.
  ) _acd_resource_resolvers_registryregister)fs    rE   register_acd_resource_resolverr   %  s    D #++A.	
(rG   c                 .    ~ d } ||      xs  ||      S )z;Replaces Identity output with its input in resource_inputs.c                    g }g }| D ]R  }|j                   j                  dk(  s|j                  |       |j                  |j                   j                         T |D ]  }| j                  |        | j                  |       |xs |S )NIdentity)rC   r>   rs   extendr   discardr   )r   	to_removeto_addr   ts        rE   r   z"_identity_resolver.<locals>.updateO  s    IF# *			Z	'"hkk(()*  !a !6"YrG   rO   )rC   resource_readsresource_writesr   s       rE   _identity_resolverr   K  s#     	
 
		:6/#::rG   c              #   X  K   t        j                  |       \  }}d}|sTd}t        j                         D ]8  }t        j	                  |      | ||      }|r|j                  |      }|xr | }: |sT|D ]  }|t        j                  f  |D ]  }|t        j                  f  yw)z6Returns an iterable of resources touched by this `op`.FTN)	rU   get_read_write_resource_inputsr   r   lookup
differencerI   rM   rN   )rC   readswrites	saturatedkeyupdatedr   s          rE   r   r   ^  s     66r:-%)I/446 	,
 177<ROg	  (+Gi	,   &al$$
%%& 'al%%
&&'s   A0B*37B*c                 :      fd}t        j                   |      S )a%  Wraps f to automatically insert control dependencies.

  The inserted dependencies ensure that:
    1. All stateful ops in f run when the result of f runs
    2. Updates to the same resources happen in order.

  Args:
    f: the function to be wrapped.

  Returns:
    The wrapped function.
  c                      t               5 } | i |}t        j                  |      D cg c]  }|j                  |       }}t        j                  ||      cd d d        S c c}w # 1 sw Y   y xY wr<   )rY   r   r   ro   pack_sequence_as)argskwargsaresultr   result_flatr   s         rE   wrapperz/automatic_control_dependencies.<locals>.wrapper  sn    	%	' 81$!&!f26,,v2FGQQ%%a(GkG""6;78 8G8 8s    A*A%A*%A**A3)r   make_decorator)r   r   s   ` rE   automatic_control_dependenciesr   w  s    8 
	$	$Q	00rG   ),r   r   enumtensorflow.core.frameworkr   tensorflow.python.eagerr   tensorflow.python.frameworkr   rU   r   r   r   r   r	   r
   r   tensorflow.python.opsr   r   r   r   tensorflow.python.utilr   r   r   	frozensetr?   r@   r   rA   rB   rF   EnumrI   rW   objectrY   Registryr   r   r   r   r   rO   rG   rE   <module>r      s    >   4 + H ? 6 7 + 0 5 + 2 3 2 ' 2 /       , , \ +4 	5 	+ '  *3 	4 	* &	 499 
4fF6 fFR $58#4#45M#N  #L  ;  ;$'21rG   