
    AVhɆ                        d Z ddlZddlZddl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 ddlmZ ddl m!Z! ddl"m#Z# g dZ$ G d dejJ                  e!jL                        Z' G d dejJ                  e!jL                        Z(d)dZ) ejT                  e'e)       d)dZ+ ejT                  e(e+       e(jY                           G d dejJ                        Z- G d d ej\                        Z/ G d! d"ej`                        Z1 ejd                         Z3d# Z4ejj                  d$        Z6 G d% d&e7      Z8 G d' d(e1      Z9y)*z7Various classes representing distributed values for PS.    N)distribute_lib)distribute_utils)values)values_util)coordinator_context)context)dtypes)ops)tensor)tensor_conversion_registry)	array_ops)handle_data_util)
lookup_ops)resource_variable_ops)variable_scope)save_context)base)core)numpy_compat)_create_resource_initialize_destroy_resourcec                   *   e Zd ZdZd Zd Zd Zed        Zd Z	d Z
d Zd	 Zd
 Zed        Zd Zed        Zedej$                  fd       Zd Zd ZdDdZdDd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 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+ Z.d, Z/d- Z0d. Z1d/ Z2d0 Z3d1 Z4d2 Z5d3 Z6d4 Z7d5 Z8d6 Z9dDd7Z:d8 Z;d9 Z<d: Z=d; Z>d< Z?d= Z@d> ZAd? ZBd@ ZCdA ZDdB ZEdEdCZFy)FAggregatingVariablezDA wrapper around a variable that aggregates updates across replicas.c                 b    || _         || _        t        j                  |       |_        || _        y N)_distribute_strategy_vweakrefref_aggregating_container_aggregation)selfstrategyvaggregations       V/home/dcms/DCMS/lib/python3.12/site-packages/tensorflow/python/distribute/ps_values.py__init__zAggregatingVariable.__init__6   s,     (DDG  '{{40A#D    c                    t        j                  | j                        5  t        j                  | j
                  |      }ddd        t        |       | j                  | j                        }||t        |       <   |S # 1 sw Y   AxY w)ab  Perform a deepcopy of the `AggregatingVariable`.

    Unlike the deepcopy of a regular tf.Variable, this keeps the original
    strategy and devices of the `AggregatingVariable`.  To avoid confusion
    with the behavior of deepcopy on a regular `Variable` (which does
    copy into new devices), we only allow a deepcopy of a `AggregatingVariable`
    within its originating strategy scope.

    Args:
      memo: The memoization object for `deepcopy`.

    Returns:
      A deep copy of the current `AggregatingVariable`.

    Raises:
      RuntimeError: If trying to deepcopy into a different strategy.
    N)r$   r%   r&   )	r   enter_or_assert_strategyr   copydeepcopyr   typer"   id)r#   memor%   copied_variables       r'   __deepcopy__z AggregatingVariable.__deepcopy__>   s}    $ 
	0	01J1J	K '
--
&a' !d4j**
%%'O
 %DDN' 's   !BB
c                     | j                   S r   r   r#   s    r'   getzAggregatingVariable.get\       77Nr)   c                     | j                   S r   )r   r5   s    r'   distribute_strategyz'AggregatingVariable.distribute_strategy_   s    $$$r)   c                 .    t        | j                  |      S r   getattrr   r#   names     r'   __getattr__zAggregatingVariable.__getattr__c       477D!!r)   c                     t        j                   j                        5  |j                  d      t        j                         ret        j
                           j                  g|i |cd d d        S  j                  j                  j                   ||      cd d d        S t        j                         }|sJ  j                  t        j                  j                  k(  r)t        t        j                   j#                  d            	 	 	 d fd	}|j%                  |||      cd d d        S # 1 sw Y   y xY w)Nfargskwargsr   )variable_typec           	          t        j                  | |j                        }|r)t        |t        j
                        r|j                  d   }| j                  j                  |f|||d      S )Nr   )use_lockingr>   
read_valuerC   )r   apply_aggregationr"   
isinstancer   
PerReplicaextendedupdate)r$   valuerH   r>   rI   r%   rB   r#   s         r'   merge_fnz2AggregatingVariable._assign_func.<locals>.merge_fn~   sz    
 ++HeT=N=N,02!jv'8'89;;q>D""))4!, *	 *  r)   )FNT)r   r+   r   popin_cross_replica_contextget_update_replica_idr   rM   rN   get_replica_contextr"   vsVariableAggregationNONE
ValueErrorr   aggregation_error_msgformat
merge_call)r#   rD   rE   replica_contextrP   rB   s   `    @r'   _assign_funcz AggregatingVariable._assign_funcf   s5   		0	01J1J	K )N
**S/a		0	0	2//1=477,T,V,)N )N ((1188!$v 9 /)N )N )<<>
  6 6 ; ;;//66 5 7 78 8 "' $		$ ))(f)MS)N )N )Ns   AD<;(D<-BD<<Ec                 0    d } | j                   |d|i|S )Nc                 &     | j                   |i |S r   )
assign_subvarakws      r'   <lambda>z0AggregatingVariable.assign_sub.<locals>.<lambda>       .#..!*Br*B r)   rB   r]   )r#   rD   rE   assign_sub_fns       r'   r`   zAggregatingVariable.assign_sub   $    BM4t>}>v>>r)   c                 0    d } | j                   |d|i|S )Nc                 &     | j                   |i |S r   )
assign_addra   s      r'   re   z0AggregatingVariable.assign_add.<locals>.<lambda>   rf   r)   rB   rg   )r#   rD   rE   assign_add_fns       r'   rl   zAggregatingVariable.assign_add   ri   r)   c                 0    d } | j                   |d|i|S )Nc                 &     | j                   |i |S r   )assignra   s      r'   re   z,AggregatingVariable.assign.<locals>.<lambda>   s    jcjj!&:r&: r)   rB   rg   )r#   rD   rE   	assign_fns       r'   rp   zAggregatingVariable.assign   s$    :I44:y:6::r)   c                 .    | j                   j                  S r   r   initializerr5   s    r'   rt   zAggregatingVariable.initializer       77r)   c                 6    | j                   j                         S r   r   initialized_valuer5   s    r'   rx   z%AggregatingVariable.initialized_value       77$$&&r)   c                 .    | j                   j                  S r   r   initial_valuer5   s    r'   r|   z!AggregatingVariable.initial_value       77   r)   returnc                 .    | j                   j                  S r   r   opr5   s    r'   r   zAggregatingVariable.op       77::r)   c                 6    | j                   j                         S r   )r   rO   r5   s    r'   rO   zAggregatingVariable.value   s    77==?r)   c                 6    | j                   j                         S r   )r   rI   r5   s    r'   rI   zAggregatingVariable.read_value   s    77r)   Nc                 <    | j                   j                  ||      S N)r>   r   sparse_readr#   indicesr>   s      r'   r   zAggregatingVariable.sparse_read       77wT22r)   c                 8    | j                   j                  |      S r   r   evalr#   sessions     r'   r   zAggregatingVariable.eval       77<<  r)   c                 .    | j                   j                  S r   r   graphr5   s    r'   r   zAggregatingVariable.graph       77==r)   c                 .    | j                   j                  S r   r   devicer5   s    r'   r   zAggregatingVariable.device       77>>r)   c                 .    | j                   j                  S r   r   shaper5   s    r'   r   zAggregatingVariable.shape   r   r)   c                     | j                   S r   )r"   r5   s    r'   r&   zAggregatingVariable.aggregation   s    r)   c                 .    | j                   j                  S r   r   synchronizationr5   s    r'   r   z#AggregatingVariable.synchronization       77"""r)   c                 .    | j                   j                  S r   r   r>   r5   s    r'   r>   zAggregatingVariable.name       77<<r)   c                 .    | j                   j                  S r   r   	trainabler5   s    r'   r   zAggregatingVariable.trainable       77r)   c                 .    | j                   j                  S r   r   dtyper5   s    r'   r   zAggregatingVariable.dtype   r   r)   c                     t        | j                  t              r| j                  j                         S t        j
                  | j                  iS r   )rK   r   CachingVariable _gather_saveables_for_checkpoint	trackableVARIABLE_VALUE_KEYr5   s    r'   r   z4AggregatingVariable._gather_saveables_for_checkpoint   s8    $''?+WW5577(($''22r)   c                 h     | j                   j                  |||fi |}|| j                      || <   |S For implementing `Trackable`.r   _export_to_saved_model_graphr#   
object_map
tensor_mapoptionsrE   resource_lists         r'   r   z0AggregatingVariable._export_to_saved_model_graph   D    
 9DGG88Z9@LDJLM!$''*Jtr)   c                     | j                   j                  |       | |vr2t        | j                  || j                      | j                        || <   yyr   N)r   _copy_trackable_to_cpur   r   r"   r#   r   s     r'   r   z*AggregatingVariable._copy_trackable_to_cpu   sP     	GG"":.:,T-F-F-7-@-1->->@j r)   c                      | j                   |z   S r   r4   r#   os     r'   __add__zAggregatingVariable.__add__       77Q;r)   c                      || j                   z   S r   r4   r   s     r'   __radd__zAggregatingVariable.__radd__       tww;r)   c                      | j                   |z
  S r   r4   r   s     r'   __sub__zAggregatingVariable.__sub__   r   r)   c                      || j                   z
  S r   r4   r   s     r'   __rsub__zAggregatingVariable.__rsub__   r   r)   c                      | j                   |z  S r   r4   r   s     r'   __mul__zAggregatingVariable.__mul__  r   r)   c                      || j                   z  S r   r4   r   s     r'   __rmul__zAggregatingVariable.__rmul__  r   r)   c                      | j                   |z  S r   r4   r   s     r'   __truediv__zAggregatingVariable.__truediv__	  r   r)   c                      || j                   z  S r   r4   r   s     r'   __rtruediv__z AggregatingVariable.__rtruediv__  r   r)   c                      | j                   |z  S r   r4   r   s     r'   __floordiv__z AggregatingVariable.__floordiv__      77a<r)   c                      || j                   z  S r   r4   r   s     r'   __rfloordiv__z!AggregatingVariable.__rfloordiv__  s    <r)   c                      | j                   |z  S r   r4   r   s     r'   __mod__zAggregatingVariable.__mod__  r   r)   c                      || j                   z  S r   r4   r   s     r'   __rmod__zAggregatingVariable.__rmod__  r   r)   c                      | j                   |k  S r   r4   r   s     r'   __lt__zAggregatingVariable.__lt__  r   r)   c                      | j                   |k  S r   r4   r   s     r'   __le__zAggregatingVariable.__le__  r   r)   c                      | j                   |kD  S r   r4   r   s     r'   __gt__zAggregatingVariable.__gt__!  r   r)   c                      | j                   |k\  S r   r4   r   s     r'   __ge__zAggregatingVariable.__ge__$  r   r)   c                      | j                   |z  S r   r4   r   s     r'   __and__zAggregatingVariable.__and__'  r   r)   c                      || j                   z  S r   r4   r   s     r'   __rand__zAggregatingVariable.__rand__*  r   r)   c                      | j                   |z  S r   r4   r   s     r'   __or__zAggregatingVariable.__or__-  r   r)   c                      || j                   z  S r   r4   r   s     r'   __ror__zAggregatingVariable.__ror__0  r   r)   c                      | j                   |z  S r   r4   r   s     r'   __xor__zAggregatingVariable.__xor__3  r   r)   c                      || j                   z  S r   r4   r   s     r'   __rxor__zAggregatingVariable.__rxor__6  r   r)   c                      | j                   |   S r   r4   r   s     r'   __getitem__zAggregatingVariable.__getitem__9  s    771:r)   c                 0    t        | j                  ||      S r   powr   )r#   r   modulos      r'   __pow__zAggregatingVariable.__pow__<  s    tww6""r)   c                 .    t        || j                        S r   r   r   s     r'   __rpow__zAggregatingVariable.__rpow__?  s    q$''?r)   c                     | j                    S r   r4   r5   s    r'   
__invert__zAggregatingVariable.__invert__B      GG8Or)   c                     | j                    S r   r4   r5   s    r'   __neg__zAggregatingVariable.__neg__E  r   r)   c                 ,    t        | j                        S r   )absr   r5   s    r'   __abs__zAggregatingVariable.__abs__H      tww<r)   c                 d    	 | j                   j                  |      S # t        $ r	 t        cY S w xY wr   )r   __div__AttributeErrorNotImplementedr   s     r'   r  zAggregatingVariable.__div__K  s/    WW__Q     //c                 d    	 | j                   j                  |      S # t        $ r	 t        cY S w xY wr   )r   __rdiv__r  r  r   s     r'   r	  zAggregatingVariable.__rdiv__R  s1    WWa   r  c                 d    	 | j                   j                  |      S # t        $ r	 t        cY S w xY wr   )r   
__matmul__r  r  r   s     r'   r  zAggregatingVariable.__matmul__Y  s1    WW"" r  c                 d    	 | j                   j                  |      S # t        $ r	 t        cY S w xY wr   )r   __rmatmul__r  r  r   s     r'   r  zAggregatingVariable.__rmatmul__`  s1    WW  ## r  c                 ,    t        | j                        S r   strr   r5   s    r'   __str__zAggregatingVariable.__str__g  r  r)   c                 ,    t        | j                        S r   reprr   r5   s    r'   __repr__zAggregatingVariable.__repr__j      =r)   c                      yz6Pass resource_variable_ops.is_resource_variable check.N r5   s    r'    _should_act_as_resource_variablez4AggregatingVariable._should_act_as_resource_variablem      r)   c                 >    | j                   j                  |||      S )Nr   r>   as_ref)r   _dense_var_to_tensorr#   r   r>   r  s       r'   r  z(AggregatingVariable._dense_var_to_tensorq  s    77''e$v'NNr)   r   NNF)G__name__
__module____qualname____doc__r(   r2   r6   propertyr9   r?   r]   r`   rl   rp   rt   rx   r|   r
   	Operationr   rO   rI   r   r   r   r   r   r&   r   r>   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r	  r  r  r  r  r  r  r  r)   r'   r   r   2   s   L$< % %"*NX??;  ' ! ! #--   3!         # #      3
@#	Or)   r   c                      e Zd ZdZd Zd Zd Zd Zd)dZd Z	d	 Z
d
 Zd Zed        Zd Zed        Zedej$                  fd       Zd Zd)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)dZd Zd Z d Z!d Z"d  Z#d! Z$d" Z%d*d#Z&e'd$        Z(e'd%        Z)d& Z*d' Z+d( Z,y)+r   z;A wrapper around a variable that caches read value locally.c                 .    || _         d | _        d| _        y )Nr   )r   _cache_current_new_cache_scope_count)r#   r%   s     r'   r(   zCachingVariable.__init__x  s    DGDK*+D'r)   c                     | j                   S r   r4   r5   s    r'   r6   zCachingVariable.get}  r7   r)   c                 .    t        | j                  |      S r   r;   r=   s     r'   r?   zCachingVariable.__getattr__  r@   r)   c                     t         j                  j                         r| j                         S | j                  j                         S r   )r   caching_scope_localin_caching_scopecached_read_valuer   rI   r5   s    r'   rI   zCachingVariable.read_value  s6    ++<<>##%%77r)   Nc                 <    | j                   j                  ||      S r   r   r   s      r'   r   zCachingVariable.sparse_read  r   r)   c                    t         j                  j                  | j                  kD  r| xj                  dz  c_        d | _        t        j                  d      5  | j                  | j                  cd d d        S t        j                  | j                        | _        | j                  cd d d        S # 1 sw Y   y xY w)N   zCPU:0)
r   r/  new_cache_scope_countr+  r*  r
   r   r   identityr   r5   s    r'   r1  z!CachingVariable.cached_read_value  s    ,,BB++	,
))Q.)dk	G	 		 {{   ((1{{  s   B4;/B44B=c                 :     | j                   j                  |i |S r   )r   r`   r#   rD   rE   s      r'   r`   zCachingVariable.assign_sub      477t.v..r)   c                 :     | j                   j                  |i |S r   )r   rl   r8  s      r'   rl   zCachingVariable.assign_add  r9  r)   c                 :     | j                   j                  |i |S r   )r   rp   r8  s      r'   rp   zCachingVariable.assign  s    477>>4*6**r)   c                 .    | j                   j                  S r   rs   r5   s    r'   rt   zCachingVariable.initializer  ru   r)   c                 6    | j                   j                         S r   rw   r5   s    r'   rx   z!CachingVariable.initialized_value  ry   r)   c                 .    | j                   j                  S r   r{   r5   s    r'   r|   zCachingVariable.initial_value  r}   r)   r~   c                 .    | j                   j                  S r   r   r5   s    r'   r   zCachingVariable.op  r   r)   c                     t         j                  j                         r| j                         S | j                  j                         S r   )r   r/  r0  r1  r   rO   r5   s    r'   rO   zCachingVariable.value  s3    ++<<>##%%77==?r)   c                 8    | j                   j                  |      S r   r   r   s     r'   r   zCachingVariable.eval  r   r)   c                 .    | j                   j                  S r   r   r5   s    r'   r   zCachingVariable.graph  r   r)   c                 .    | j                   j                  S r   r   r5   s    r'   r   zCachingVariable.device  r   r)   c                 .    | j                   j                  S r   r   r5   s    r'   r   zCachingVariable.shape  r   r)   c                 .    | j                   j                  S r   r   r5   s    r'   r   zCachingVariable.synchronization  r   r)   c                 .    | j                   j                  S r   r   r5   s    r'   r>   zCachingVariable.name  r   r)   c                 .    | j                   j                  S r   r   r5   s    r'   r   zCachingVariable.trainable  r   r)   c                 .    | j                   j                  S r   r   r5   s    r'   r   zCachingVariable.dtype  r   r)   c                 .    | j                   j                  S r   )r   
constraintr5   s    r'   rJ  zCachingVariable.constraint  s    77r)   c                 L    t        j                  | j                         |      S )Nr   )r   
np_asarraynumpy)r#   r   s     r'   	__array__zCachingVariable.__array__  s    ""4::<u==r)   c                 P    t        | j                         j                               S r   )complexrO   rN  r5   s    r'   __complex__zCachingVariable.__complex__  s    4::<%%'((r)   c                 P    t        | j                         j                               S r   )intrO   rN  r5   s    r'   __int__zCachingVariable.__int__  s    tzz|!!#$$r)   c                 P    t        | j                         j                               S r   )floatrO   rN  r5   s    r'   	__float__zCachingVariable.__float__  s    ##%&&r)   c                 |    t        j                         r| j                         j                         S t	        d      )Nz:numpy() is only available when eager execution is enabled.)r   executing_eagerlyrI   rN  NotImplementedErrorr5   s    r'   rN  zCachingVariable.numpy  s6      "__$$&&
FH Hr)   c                 ,    t        | j                        S r   r  r5   s    r'   r  zCachingVariable.__str__  r  r)   c                 ,    t        | j                        S r   r  r5   s    r'   r  zCachingVariable.__repr__  r  r)   c                      yr  r  r5   s    r'   r  z0CachingVariable._should_act_as_resource_variable  r  r)   c                     t         j                  j                         r| j                         S | j                  j                  ||d      S )NFr  )r   r/  r0  r1  r   r  r   s       r'   r  z$CachingVariable._dense_var_to_tensor  s?    ++<<>##%%77''e$u'MMr)   c                 z    t         j                  j                  D ]  }|dk(  s|dk(  r| j                  |         y)z%Register overloads for all operators.__eq____ne__N)r   TensorOVERLOADABLE_OPERATORS_tensor_overload_operator)clsoperators     r'    _overload_overloadable_operatorsz0CachingVariable._overload_overloadable_operators  s=     MM88 .	X	X!5	##H-	.r)   c                 ^    t        t        j                  |      fd}t        | ||       y)z1Delegate an operator overload to `tensor.Tensor`.c                 8     | j                         g|i |S r   rO   )r%   rD   rE   tensor_operators      r'   	_operatorz<CachingVariable._tensor_overload_operator.<locals>._operator  s    QWWY8888r)   N)r<   r   rc  setattr)rf  rg  rm  rl  s      @r'   re  z)CachingVariable._tensor_overload_operator  s&     fmmX6O9C9%r)   c                 :    t         j                  | j                  iS r   )r   r   r   r5   s    r'   r   z0CachingVariable._gather_saveables_for_checkpoint  s    (($''22r)   c                 h     | j                   j                  |||fi |}|| j                      || <   |S r   r   r   s         r'   r   z,CachingVariable._export_to_saved_model_graph  r   r)   c                 z    | j                   j                  |       | |vrt        || j                            || <   yyr   )r   r   r   r   s     r'   r   z&CachingVariable._copy_trackable_to_cpu  s;     	GG"":.:(DGG)<=j r)   r   r!  )-r"  r#  r$  r%  r(   r6   r?   rI   r   r1  r`   rl   rp   r&  rt   rx   r|   r
   r'  r   rO   r   r   r   r   r   r>   r   r   rJ  rO  rR  rU  rX  rN  r  r  r  r  classmethodrh  re  r   r   r   r  r)   r'   r   r   u  s   C,
" 
3//+  ' ! ! #--  
!       # #        >)%'H	N
 . . & &3	>r)   r   c                 (    | j                  |||      S r   r  rb   r   r>   r  s       r'   _tensor_conversion_aggregaterv  '      		!	!%v	66r)   c                 (    | j                  |||      S r   rt  ru  s       r'   _tensor_conversion_cachingry  1  rw  r)   c                   H    e Zd ZdZd Zed        Zed        Zd Z	d Z
d Zy)	PerWorkerVariablea  A wrapper around unsynced variables created on workers.

  `PerWorkerVariable`s are variables that are stored on workers and not
  synchronized. A `PerWorkerVariable` is really a wrapper around multiple
  independent `Variable`s stored on independent worker machines. 
  `PerWorkerVariable` is currently only tested and supported when used with
  `ParameterServerStrategy`. A `PerWorkerVariable` can be created by creating a
  `Variable` within strategy scope and using the `per_worker_variable` flag,
  e.g.:

  ```
  with strategy.scope():
    var = tf.Variable(initial_value=0.0, per_worker_variable=True)
  ```

  The implementation modifies the graph to ensure that a worker's local version
  of the variable is used for computation at call time, while needing only one
  function trace and requiring no code changes beyond the `per_worker_variable`
  flag. `PerWorkerVariable`s can thus be treated like a standard `Variable`, but
  support is experimental and not all ops have been tested.

  All per-worker values can be retrieved and read into a list via
  `PerWorkerVariable.read_all()`.

  Caveats:
    - `PerWorkerVariable`s should not be used as direct inputs to a
      `tf.function`. That is, they should not appear in a tf.function header as
      an input argument. However they can still be read and manipulated in a
      `tf.function`.
    - The `shape` argument must be fully-defined (no `None` entries) or left
      empty. Partially-defined shapes are not yet supported.
    - Automatic control dependencies do not work with `PerWorkerVariable`s, so
      returning a `PerWorkerVariable` is not supported, and `read_all()` should 
      be used to retrieve values. (TODO: b/286052052)
    - `PerWorkerVariable`s should not be created within a `tf.function`.
  c                 p   |j                   | _        d | _        t        j                  |fi || _         |d	i || _        |j                  d      8t        j                         5  t        j                          | _        d d d        n
|d   | _        d | _        | j                  j                  | _        | j                  j                   | _        d| _        |j                  d      | _        |j                  d      d| _        n|d   dz   | _        |j                  dd      | _        y # 1 sw Y   xY w)
Nin_graph_modeF	unique_idhandle_namez
Variable:0z:0validate_shapeTr  )_cluster_coordinator_coordinator_per_worker_vars	functoolspartial_var_creator_coordinator_instancer6   r
   
init_scoper   rZ  _in_graph_mode_cached_valuer   _shaper   _dtype
_trainable
_unique_id_handle_name_validate_shape)r#   r$   next_creatorrE   s       r'   r(   zPerWorkerVariable.__init__a  s    55D D!)),A&AD!-!7!7D zz/"*>> >")";";"==> > #?3dD,,22DK,,22DKDOjj-DOzz- (&d /$6d!::&6=D> >s   &D,,D5c                      y)zEOverride to be a no-op to avoid metaclass creating ResourceVariables.Nr  )rf  rD   rE   s      r'   _variable_callz PerWorkerVariable._variable_callz  s     r)   c                    t        j                         st        j                         r| j                  j
                  S | j                          | j                         \  }}t        j                         j                  ||      S r   )r   rZ  r   in_save_contextr  handle_maybe_create_per_worker_varshandle_call_time_valuer
   get_default_graphcapture_call_time_valuer#   closurespecs      r'   r  zPerWorkerVariable.handle  sk      "l&B&B&D''...
((*113mgt""$<<

 r)   c                 R      fd}|t         j                  j                        fS )zReturns a closure to run for a handle at call time and its spec.

    This function is called in self.handle to create a placeholder
    which returns a handle on some worker or on the coordinator.
    c                      t        j                         } | r@j                  j                  | j                     }| j                  |      }|j                  S j                  j                  S r   )r   get_current_dispatch_contextr  _valuesworker_indexmaybe_get_remote_valuer  r  dispatch_contextremote_valueretr#   s      r'   r  z9PerWorkerVariable.handle_call_time_value.<locals>.closure  sb    ,IIK	,,44))+55lCzz ))000r)   rk  )PerWorkerVariableSpecr  r  r#   r  s   ` r'   r  z(PerWorkerVariable.handle_call_time_value  s.    	1 )((//1 1 1r)   c                 r    | j                   s+| j                  j                  | j                        | _         yy)z9Create variable on each worker if it hasn't been created.N)r  r  _create_per_worker_variablesr  r5   s    r'   r  z/PerWorkerVariable._maybe_create_per_worker_vars  s2      



8
89J9J
K  !r)   c                 p    | j                   j                  D cg c]  }|j                          c}S c c}w )zESynchronously read variables from all workers into a list of Tensors.)r  r  r6   )r#   wvs     r'   read_allzPerWorkerVariable.read_all  s(    #44<<=BFFH===s   3N)r"  r#  r$  r%  r(   rr  r  r&  r  r  r  r  r  r)   r'   r{  r{  ;  sE    #J>2    1(M>r)   r{  c                   *     e Zd Zd fd	Z fdZ xZS )r  c                 `    t         |   |j                  |j                  |       || _        y r   )superr(   r   r   _value)r#   rO   r>   	__class__s      r'   r(   zPerWorkerVariableSpec.__init__  s&    	GU[[%++D9DKr)   c                 z    t         |   |      }t        j                  || j                  j
                         |S r   )r  placeholder_valuer   set_handle_datar  _handle_data)r#   placeholder_contextplaceholderr  s      r'   r  z'PerWorkerVariableSpec.placeholder_value  s3    '+,?@K$$[$++2J2JKr)   )NN)r"  r#  r$  r(   r  __classcell__r  s   @r'   r  r    s     r)   r  c                   N    e Zd ZdZd Zd Zd Zd Zed        Z	ed        Z
d Zy	)
DistributedTablea/  A distributed StaticHashTable for ParameterServerStrategy.

  An instance of DistributedTable has copies of a StaticHashTable and its
  resource handle on the coordinator of each worker, created at the
  DistributedTable instance initialization time with initializers on each
  worker. Users can call methods on a DistributedTable as if it were a
  StaticHashTable, which leads to execution with the resource local to the
  consumer worker (or the coordinator, if calling from the coordinator). This
  implementation relies on the fact that the methods of StaticHashTable are
  queried with the resource handle (instead of the python object).

  Currently, at saving time, a DistributedTable is saved as a StaticHashTable on
  the coordinator, and restoring a DistributedTable from SavedModel is not
  supported.
  c                 \   t         j                  j                  | j                  j                  d      j                  d        |       | _        || _        |j                  | _	        d | _
        t        j                         | _        t        j                         s| j!                          y y )NPSSDistributedLookupTabler4  )r   'distribution_strategy_input_api_counterget_cellr  r"  increase_byr  _wrapped_creatorr  r  _distributed_table	threadingLock _distributed_table_creation_lockr   r  _maybe_build_distributed_table)r#   r$   wrapped_creators      r'   r(   zDistributedTable.__init__  s    ::CC!<>>Ik!n!0!2D+D 55D #D,5NN,<D)'')
))+ *r)   c                 (    |dk(  r
t               | j                  j                  v rT j                  j                  |   t              r fd}|S t	        t
              rS t         j                  |      S t         j                  |      S )Nr  c                       g| i |S r   r  )rD   rE   
attr_valuer#   s     r'   wrapperz-DistributedTable.__getattr__.<locals>.wrapper  s    D24262
2r)   )r  r  __dict__callablerK   r&  r<   )r#   attrr  r  s   `  @r'   r?   zDistributedTable.__getattr__  s     &&t))222--66t<j	*		3 j(+t11488T//66r)   c                 \      fd}|t        j                  g t        j                        fS )Returns a closure to run for a resource handle at call time and its spec.

    This function is called in self.resource_handle to create a placeholder
    which returns a resource handle on some worker or on the coordinator.
    c                      t        j                         } | r6j                  j                  | j                     }| j                  |      }|S j                  j                  S r   )r   r  r  r  r  r  r  resource_handler  s      r'   r  zADistributedTable.resource_handle_call_time_value.<locals>.closure  s_     -IIK	..66))+55lC
 ))999r)   rL  r   
TensorSpecr	   resourcer  s   ` r'   resource_handle_call_time_valuez0DistributedTable.resource_handle_call_time_value  s&    : F%%b@@@r)   c                       j                   5   j                  s% fd} j                  j                  |       _        ddd       y# 1 sw Y   yxY w)ICreate table objects and resources on each worker if hasn't been created.c                  @    j                         } | j                  }|S r   )r  r  )	new_tabler  r#   s     r'   create_copyzDDistributedTable._maybe_build_distributed_table.<locals>.create_copy
  s!    ++-)))#*r)   Nr  r  r  _create_per_worker_resourcesr#   r  s   ` r'   r  z/DistributedTable._maybe_build_distributed_table  sQ    		.	. 	I$$	 ::;G 		I 	I 	I   2A		Ac                 8   t        j                         st        j                         r| j                  j
                  S | j                          | j                         \  }}t        j                         j                  ||| j                  j
                        S )N)default_value)r   rZ  r   r  r  r  r  r  r
   r  r  r  s      r'   r  z DistributedTable.resource_handle  s      "l&B&B&D''777
))+::<mgt""$<<

22BB = D Dr)   c                      y)NTr  r5   s    r'   is_distributed_tablez%DistributedTable.is_distributed_table  s    r)   c                     | j                         \  }}|j                  j                  | j                  j                  ||| j                  j                  |       |j                  j
                  d   S )N)r  r  )r  r   %replace_capture_with_deferred_capturer  r  deferred_external_captures)r#   concrete_functioninternal_capturer  r  s        r'   #__tf_experimental_restore_capture__z4DistributedTable.__tf_experimental_restore_capture__"  sn    88:MGTAA""2200@@$ B & ""==bAAr)   N)r"  r#  r$  r%  r(   r?   r  r  r&  r  r  r  r  r)   r'   r  r    sM     ,78A,I 	D 	D  	Br)   r  c                  B    	 t         j                  S # t        $ r Y y w xY wr   )_local_resource_restore_contextcurrentr  r  r)   r'   *get_current_local_resource_restore_contextr  1  s%    *222	 s    	c              #   t   K   t        t        dd       }t        |       t        _        d  |t        _        y w)Nr  )r<   r  LocalResourceRestoreContextr  )instanceprevious_contexts     r'   #with_local_resource_restore_contextr  8  s3     <iN,G-!),<!)s   68c                       e Zd ZdZd Zy)r  aY  Class holding information of a distributed instance, e.g. StaticHashTable.

  Pairing use with context manager `with_local_resource_restore_context` allows
  operations under this context manager to conveniently gets information of a
  component of the `RestoredDistributedTable` (and other restored distributed
  `CapturableResource` if we're supporting their distribution in the future),
  instead of looking it up from the mapping of the worker-to-resource handle.
  This is especially useful when we know which instance the operations should
  execute with and the mapping is not available yet.
  c                     || _         y r   )r  )r#   r  s     r'   r(   z$LocalResourceRestoreContext.__init__M  s	    DMr)   N)r"  r#  r$  r%  r(   r  r)   r'   r  r  A  s    	r)   r  c                   J     e Zd ZdZ fdZd Z fdZd Zd Zd Z	d Z
 xZS )	RestoredDistributedTablezGA restored and distributed StaticHashTable for ParameterServerStrategy.c                 X    t        j                         | _        t        |   ||       y r   )r  	Condition_has_resource_functionsr  r(   )r#   r$   r  r  s      r'   r(   z!RestoredDistributedTable.__init__T  s#    #,#6#6#8D 	GX/r)   c                 \      fd}|t        j                  dt        j                        fS )r  c                     t        j                         } | rYt               }|r|j                  j                  }n#j
                  j                  | j                     }| j                  |      }|S j                  j                  S r   )
r   r  r  r  r  r  r  r  r  r  )r  local_resource_restore_contextr  r  r#   s       r'   r  zIRestoredDistributedTable.resource_handle_call_time_value.<locals>.closure`  s     -IIK	68 	' *7@@PP, 0088++-, 55lC
 ))999r)   r  )r   r   r  r  s   ` r'   r  z8RestoredDistributedTable.resource_handle_call_time_valueY  s'    :B F%%BfooFFFr)   c                 `    |t         v rt         d      si  _        | j                  |<   t         fdt         D              r/ j                  5   j                  j                          d d d         j                  j                  ||      S t        t           ||      S # 1 sw Y   9xY w)N_restored_functionc              3   :   K   | ]  }|j                   v   y wr   r  .0methodr#   s     r'   	<genexpr>z7RestoredDistributedTable.__setattr__.<locals>.<genexpr>  s$      7 t... 7   )
TRACKABLE_RESOURCE_METHODShasattrr  allr  
notify_allr  __setattr__r  r  )r#   r>   rO   r  s   `  r'   r  z$RestoredDistributedTable.__setattr__  s    )) T/0"$&+dd#	 757 
7)) 	4

&
&
1
1
3	4''33D%@@+T>tUKK		4 	4s   B$$B-c                 6    | j                   j                         S )zEA function that creates a resource handle for a table on coordinator.)r  r   r5   s    r'   r   z)RestoredDistributedTable._create_resource  s    %%6688r)   c                 6    | j                   j                         S )z)A function that initializes the resource.)r  r   r5   s    r'   r   z$RestoredDistributedTable._initialize  s    %%1133r)   c                 6    | j                   j                         S )z&A function that destroys the resource.)r  r   r5   s    r'   r   z*RestoredDistributedTable._destroy_resource  s    %%7799r)   c                       j                   5   j                  s% fd} j                  j                  |       _        ddd       y# 1 sw Y   yxY w)r  c                     j                         } j                  5  t        d      rt        fdt        D              r@j                  j                          t        d      s't        fdt        D              r@d d d        t        d      rt        |       5  j                  j                         D ]  \  }}t        | ||        | j                         }t        j                         s.t        j                  t        j                  j                   |       d d d        | j"                  }|S # 1 sw Y   xY w# 1 sw Y   #xY w)Nr  c              3   :   K   | ]  }|j                   v  y wr   r  r  s     r'   r  z_RestoredDistributedTable._maybe_build_distributed_table.<locals>.create_copy.<locals>.<genexpr>  s&      A: d555A:r  )r  r  r
  anyr	  waitr  r  itemsrn  r   r   rZ  r
   add_to_collection	GraphKeysTABLE_INITIALIZERSr  )r  r>   tf_functioninit_opr  r#   s        r'   r  zLRestoredDistributedTable._maybe_build_distributed_table.<locals>.create_copy  s,   ++-) ++ 2d$89S A:8A: >: **//1 d$89S A:8A: >:2 T/04Y? Q'+'>'>'D'D'F 6#$	456!--/g..0%%cmm&F&FPQ ))#*2 2Q Qs   AD:*D:"BE:EENr  r  s   ` r'   r  z7RestoredDistributedTable._maybe_build_distributed_table  sQ    		.	. I$$	, ::;G 	1I I Ir  )r"  r#  r$  r%  r(   r  r  r   r   r   r  r  r  s   @r'   r  r  Q  s-    O0
(GTL294:Ir)   r  r!  ):r%  
contextlibr,   r  r  r   tensorflow.python.distributer   r   r   r   (tensorflow.python.distribute.coordinatorr   tensorflow.python.eagerr   tensorflow.python.frameworkr	   r
   r   r   tensorflow.python.opsr   r   r   r   r   rU   tensorflow.python.saved_modelr   tensorflow.python.trackabler   r   tensorflow.python.typesr   tensorflow.python.utilr   r	  BaseResourceVariablerc  r   r   rv  #register_tensor_conversion_functionry  rh  r{  r  r  StaticHashTabler  localr  r  contextmanagerr  objectr  r  r  r)   r'   <module>r,     sk   >      7 9 / 4 H + . + . B + 2 , 7 6 6 9 ( / @O/DD++@OF
m>+@@$++ m>d7 ?  > >577 ?  > >/1  0 0 2k>-BB k>\F-- wBz11 wBt #2)//"3  = =&  rI/ rIr)   