
    AVh>M                     2   d Z ddlm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g      d        Z e
jB                  dfdZ"d Z#d Z$d Z%d Z&d Z'd Z(d Z)d  Z*d! Z+d" Z,d# Z-d$ Z.d% Z/d& Z0d' Z1 G d( d)ejd                        Z3 e3       Z4ejj                  d*        Z6ejn                  jp                  e
jr                  ejn                  jt                  e
jv                  iZ<d+e
jz                  ejn                  jp                  e
j|                  ejn                  jt                  e
j~                  iZ@ejn                  jp                  ej                  ejn                  jt                  ej                  iZCd+ej                  d,ej                  ejn                  jp                  ej                  ejn                  jt                  ej                  iZHy)-z<Class implementing utilities used by tf.distribute.Strategy.    )abcN)distribute_lib)
tpu_values)values)ReduceOp)context)record)composite_tensor)ops)tensor_util)	array_ops)control_flow_ops)resource_variable_ops)variable_scope)losses_impl)nest)	tf_exportzdistribute.get_loss_reduction)v1c                     t        j                         j                  st        j                  S t        j                         j                  } | t        j                  j                  k(  s| dk(  rt        j                  S t        j                  S )z`tf.distribute.ReduceOp` corresponding to the last loss reduction.

  Returns:
    `tf.distribute.ReduceOp` corresponding to the last loss reduction for
    estimator and v1 optimizer use case. `tf.distribute.ReduceOp.SUM` otherwise.
  sum)r   get_strategy_scale_loss_for_estimatorr   SUMr   get_default_graph_last_loss_reductionr   	ReductionMEAN)last_reductions    ]/home/dcms/DCMS/lib/python3.12/site-packages/tensorflow/python/distribute/distribute_utils.pyget_loss_reductionr    '   sf     
	$	$	&	@	@ <<((*??.--111<<	    Fc                      d   }t        |t              r dd D ]K  }t        |t              sJ t        |      t        |      k(  r-J dt        |      t        |      ||fz          t        t        |            D cg c]!  t	        t        fd D                    # c}S t        |t
              r dd D ]P  }t        |t
              sJ t        |      t        |      k(  r-J dt        |       dt        |       d| d	|         t         fd
t        t        |            D              }t        |d      rt        |d      sJ |j                  |      S |S t        |t        j                        r|j                         } dd D ]{  }t        |t        j                        sJ d|d|       t        |j                               t        |      k(  rPJ dt        |      dt        |j                                        t        |      |D ci c]"  t	        t        fd D                    $ c}      S d}	 dd D ]
  }||usd}	 n |	rt        |t        j                        r|S |	rst        |      |u r|S t        |t         j"                        sut        |      |urht        |t        j$                        r$J d D cg c]  }t'        |       c}d        t        |      }
|
J  dd D ]  }|
t        |      u rJ  |
S         S c c}w c c}w c c}w )aB  Makes a nest per-replica into a nest of PerReplica/Mirrored values.

  Args:
    values: Values to regroup
    wrap_class: Class that `values` be wrapped in.
    always_wrap: Always wrap the `values` in `wrap_class` even if the values
        are the same except for DistributeVariable.
  Returns:
    Wrapped `values`.
  r      Nz*len(v) == %d, len(v0) == %d, v: %s, v0: %sc              3   (   K   | ]	  }|     y wN .0vis     r   	<genexpr>zregroup.<locals>.<genexpr>M        +qad+   z3Values to regroup had different lengths: len(v) == z, len(v0) == z, v: z, v0: c              3   ^   K   | ]#  t        t        fd D                     % yw)c              3   (   K   | ]	  }|     y wr%   r&   r'   s     r   r+   z$regroup.<locals>.<genexpr>.<genexpr>X   r,   r-   N)regrouptuple)r(   r*   always_wrapr   
wrap_classs    @r   r+   zregroup.<locals>.<genexpr>W   s-      ! 	+F++ZE!s   )-_fields_makezv[0]: z  v[i]: zv[0].keys: z  v[i].keys: c              3   (   K   | ]	  }|     y wr%   r&   )r(   r)   keys     r   r+   zregroup.<locals>.<genexpr>j   s     2a1S62r-   TFzids = z, values = )
isinstancelistlenranger0   r1   hasattrr5   r   Mappingkeyssettype
values_libDistributedVariablevalue_containerr   _UnreadVariableMirroredVariableid)r   r3   r2   v0r)   r*   regrouped_tuplev0keysr7   same_iddistributed_containers   ```  `  `  r   r0   r0   :   sm    ay"DABZ ;4   Vs2w ;!M"%a&#b'1b!9": ;; s2w 	+F++ZE 
 EABZ 65!!!Vs2w 6 "..1!fX]3r7) L''(ct"5 66
  !s2w! !O r9 R!!!XXo&&CKK WWYFABZ J3;;'I"a*HI']c&k) J-0[#affh--I J)J
 48   	WU2622. 	.   '!": a{g B
 > >?I [_R%8B%>I R.>>
?b#"j99: E39#:aBqE#:FCE:+B/ ,,,ABZ 9"oa&88889   
F	]:R $;s   &L2('L7"L<c                 :      fd}t        j                  ||      S )zBSpecialize a nest of regular & per-replica values for one replica.c                     t        | t        j                        st        | t        j                        s| S | j                     S r%   )r8   rA   rB   DistributedValuesr   )x
replica_ids    r   _getzselect_replica.<locals>._get   s9     	1j445q*667hXXj!!r!   r   map_structure)rP   
structuredrQ   s   `  r   select_replicarU      s    " 
		D*	--r!   c                 0    t        |       t        | |      S )z?Specialize a nest of regular & mirrored values for one replica.)assert_mirroredrU   )rP   rT   s     r   select_replica_mirroredrX      s    *	
J	//r!   c                 <      fd}t        j                  |        y)zGRaises if the structured is not composed of mirrored or regular values.c                 v    t        | t        j                        rt        |       st	        d| dd      y y )Nz/Expected value to be mirrored across replicas: z in .)r8   rA   rN   is_mirrored	TypeError)rO   rT   s    r   _assert_mirroredz)assert_mirrored.<locals>._assert_mirrored   s9    !Z112;q>j  <J2r!   NrR   )rT   r^   s   ` r   rW   rW      s     %z2r!   c                     |s:t        |t        j                        }t        j                  | j
                  |      S d }t        ||      S )zGRegroup for an update, with dependencies to ensure all updates execute.c                    t        |       dk(  rt        j                  |       S t        j                  |       }t        d | D              s|S g }| D ]m  }t        j                  |j                        5  t        j                  |g      5  |j                  t        j                  |             ddd       ddd       o t        j                  |      S # 1 sw Y   (xY w# 1 sw Y   xY w)zCConvert per-replica list `values` into Mirrored type with grouping.r#   c              3   F   K   | ]  }t        j                  |        y wr%   )r   
is_tf_type)r(   r)   s     r   r+   zAupdate_regroup.<locals>._make_grouped_mirrored.<locals>.<genexpr>   s     9Q{%%a(9s   !N)r:   rA   Mirroredr   groupallr   devicecontrol_dependenciesappendr   identity)r   gwith_depr)   s       r   _make_grouped_mirroredz.update_regroup.<locals>._make_grouped_mirrored   s    
6{a  (( 	v&A
 9&99h H /::ahh /!9!91#!> /	**1-./ / // x((/ / / /s$   3C"
%C/C"CC""C+	)r0   rA   rc   r   rS   _local_results)extendedupdatesrd   	regroupedrl   s        r   update_regrouprq      sE    	!4!45Ih55yAA)0 
0	11r!   c                 ,   d}t        | t        j                        sst        | d      r| j	                         }nVt        | t
        j                        r<t        | d      r0t        | j                  d      r| j                  j	                         }||S | S )af  Returns the container that this per-replica `value` belongs to.

  Args:
    val: A value returned by `call_for_each_replica()` or a variable created in
      `scope()`.

  Returns:
    A container that `value` belongs to.
    If value does not belong to any container (including the case of
    container having been destroyed), returns the value itself.
  N_distributed_containerhandle)r8   rA   rB   r<   rs   r
   CompositeTensorrt   )val	containers     r   rC   rC      s     )	C77	8s,-,,.i
S*::
;
#x
 
#**6
7 **335i+44r!   c                     t        | dd      S )z@Determine if a variable is ds variable or TPU mirrored variable.is_distributed_variableFgetattrr)   s    r   ry   ry      s    	-u	55r!   c                     t        | dd      S )z-Determine if an object is a DistributedTable.is_distributed_tableFrz   r|   s    r   r~   r~      s    	*E	22r!   c                 ^    | j                   }|r|j                  |urt        d| d|      y )Nzh`colocate_vars_with` must only be passed a variable created in this tf.distribute.Strategy.scope(), not z created in scope: )_distribute_strategyrn   
ValueError)r)   rn   variable_strategys      r   _validate_colocate_extendedr     s?    ,,	/88H
 
	    Ir!   c                 l    t        | t        j                        st        d|       t	        | |       y )Ni`colocate_vars_with` must only be passed a variable created in this tf.distribute.Strategy.scope(), not: )r8   rA   rB   r   r   r)   rn   s     r   &validate_colocate_distributed_variabler     s3    	Az55	6
56	9: : a*r!   c                 P    t        | d      st        d|       t        | |       y )Nr   r   )r<   r   r   r   s     r   validate_colocater     s.    	*	+
56	9: : a*r!   c                    | j                  dt        j                  j                        }|t        j                  j                  k(  rt        dt        | d         z         |t        j                  j                  t        j                  j                  t        j                  j                  fvrt        d|d| d         |t        j                  j                  k(  rt        j                  j                  S |S )z3Validate that given synchronization value is valid.synchronizationz`NONE` variable synchronization mode is not supported with tf.distribute strategy. Please change the `synchronization` for variable: namez'Invalid variable synchronization mode:  for variable: )	getvsVariableSynchronizationAUTONONEr   strON_READON_WRITE)kwargsr   s     r   _validate_synchronizationr     s    JJ0!99>>@/22777
	6&>*	+, , R77??77@@77<<> > 	&.	*+ + 22777%%...	r!   c                 R   | j                  dt        j                  j                        }|t        j                  j                  t        j                  j                  t        j                  j
                  t        j                  j                  fvrt        d|d| d         |S )Naggregationz#Invalid variable aggregation mode: r   r   )r   r   VariableAggregationr   r   r   ONLY_FIRST_REPLICAr   )r   r   s     r   _validate_aggregationr   3  s    

="*@*@*E*EF+//44//33//44//BBD D !6&>3 4 4	r!   c                    |j                  dd      rd}nd}|j                  dd      }|t        j                  j                  g}g |d<   t	        |      }||d<   t        |      }t        | j                  dd      }	|j                  d	d       t        j                         5   |di |}
|
D ]5  }t        |d
      s|j                  t        j                         |_        7 |	r8|j                  |      } ||      }|j                  |      } || |
||      }n|j                  |      } || |
|      }ddd       t        j                          st        j"                         }|j                  dd      ru|j%                  t        j                  j&                         |j)                  t        j                  j&                        }
D ]  }t+        |      D ]  \  }}||u s||=     |j-                  |       |S t        j                  j.                  |v r.t        j,                  t        j                  j.                         S # 1 sw Y   xY w)zHCreate distributed variables with given synchronization and aggregation.!experimental_batch_initializationNLazyVariableClassVariableClasscollectionsr   _use_var_policyFcaching_device_initializer_op)r   )
var_policy	trainableTr&   )popr   	GraphKeysGLOBAL_VARIABLESr   r   r{   rn   r	   stop_recordingr<   r   r   no_opr   r   executing_eagerlyr   rh   TRAINABLE_VARIABLESget_collection_ref	enumerateadd_to_collectionsGLOBAL_STEP)strategyreal_mirrored_creatorclass_mappingpolicy_mappingr   variable_class_keyvar_collectionsr   r   use_var_policy
value_listr)   var_policy_clsr   var_clsresultrj   lvaluer*   trainable_variables                        r   create_mirrored_variabler   ?  sD    ZZ3T:,(JJ}d3/}}556O&-f5/ .&	%f-+8,,.?G. 	**t$
  :&00J  5	%	&1+<+<+D,2245
 %))/:n!k:j!!"45gx[ZPf!!/2gx[9f':0 
	"	"	$A zz+t$S]]>>?


s}}@@
Aa %%.q\ 	!A!((!	 &1 
- }}  O33==44f=	-Y: :s   $I?IA0IIc                 (     t        | dd              S )N_is_mirroredc                       y)NFr&   r&   r!   r   <lambda>zis_mirrored.<locals>.<lambda>  s    r!   rz   rv   s    r   r\   r\     s    
5'#~}
5	88r!   c                     t        |        S r%   )r\   r   s    r   is_sync_on_readr     s    	r!   c                   4     e Zd ZdZ fdZd Zd Zd Z xZS )CachingScopeLocalz;Class for maintaining thread local state for caching scope.c                 F    t         t        |           d| _        d| _        y )Nr   )superr   __init__new_cache_scope_countcache_scope_exited_count)self	__class__s    r   r   zCachingScopeLocal.__init__  s!    	
T+-!"D$%D!r!   c                 .    | xj                   dz  c_         y Nr#   )r   r   s    r   enter_scopezCachingScopeLocal.enter_scope  s    !#r!   c                 .    | xj                   dz  c_         y r   )r   r   s    r   
exit_scopezCachingScopeLocal.exit_scope  s    !!Q&!r!   c                 4    | j                   | j                  kD  S r%   )r   r   r   s    r   in_caching_scopez"CachingScopeLocal.in_caching_scope  s    %%(E(EEEr!   )	__name__
__module____qualname____doc__r   r   r   r   __classcell__)r   s   @r   r   r     s    C&
$'Fr!   r   c               #      K   	 t         j                         rt        d      t         j                          d t         j	                          y# t         j	                          w xY ww)a  Scope for caching variable reads for AggregatingVariable.

  The variable reads for AggregatingVariable inside this scope are cached. i.e.
  the first read of variable reads the value from possibly remote handle, but
  subsequent reads are returned using local cached value.

  For example:
  strategy = ParameterServerStrategy...
  with strategy.scope():
    # Variable v is of AggregatingVariable type with actual variable residing
    # on PS.
    v = tf.Variable(1.0)

  with distribute_utils.cache_variable_reads():
    v.read_value()  # Reads value 1.0
    v.assign(constant_op.constant(5.0))  # v changes to 5.0
    t1 = v.read_value()
    t2 = v.read_value()  # Both t1 & t2 return cached value 1.0 from local CPU.

  Notes about cache_variable_reads scope:
  1. Nesting of scope cache_variable_reads() is not supported
  2. And when caching scope is enabled, the thread enabling the cache and
    mirrored_run._MirroredReplicaThread threads spawned from it will have
    caching enabled.

  Yields:
    A context for caching variables.
  z+cache_variable_reads scope cannot be nestedN)caching_scope_localr   r   r   r   r&   r!   r   cache_variable_readsr     sK     >%++-DEE##%	""$""$s   A)7A A)A&&A)r   r   )Ir   r   r   
contextlib	threadingtensorflow.python.distributer   r   tpu_values_libr   rA   (tensorflow.python.distribute.reduce_utilr   tensorflow.python.eagerr   r	   tensorflow.python.frameworkr
   r   r   tensorflow.python.opsr   r   r   r   r   tensorflow.python.ops.lossesr   tensorflow.python.utilr    tensorflow.python.util.tf_exportr   r    
PerReplicar0   rU   rX   rW   rq   rC   ry   r~   r   r   r   r   r   r   r\   r   localr   r   contextmanagerr   r   r   OnWritePolicyr   OnReadPolicyVARIABLE_POLICY_MAPPINGrB   rE   SyncOnReadVariableVARIABLE_CLASS_MAPPINGTPUOnWritePolicyTPUOnReadPolicyTPU_VARIABLE_POLICY_MAPPINGTPUDistributedVariableTPULazyDistributedVariableTPUMirroredVariableTPUSyncOnReadVariableTPU_VARIABLE_CLASS_MAPPINGr&   r!   r   <module>r      s   C    7 E = = + * 8 + 3 + 2 7 6 4 ' 6 ./0 1$  *44% `F. 0	32B566
3
 ++(	I^9F	 F$ ()  %% %%` '')A)A&&
(?(?  Z33'')D)D&&
(E(E  '')H)H&&(F(F  ^::BB'')K)K&&(L(L	 r!   