o
    2h                    @   sJ  d Z ddlZddlm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 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/Z0 dd l-m1Z1 d!d" Z2d#d$ Z3G d%d& d&e0j4Z4G d'd( d(e4Z5G d)d* d*e4ej6e0j7Z7dRd,d-Z8e9e7e8 G d.d/ d/ej:Z;e'<e'=e;ej>j? G d0d1 d1e5e0j@Z@G d2d3 d3eAZBG d4d5 d5e1jCZDG d6d7 d7e5e%jEe.jFZGG d8d9 d9e,jHZIG d:d; d;e,jHZJG d<d= d=eGe@ZKG d>d? d?e,jHZLG d@dA dAeGZM			+dRdBdCZNe9eGeN dRdDdEZOe9eKeO dRdFdGZPe9e@eP dRdHdIZQe9eMeQ G dJdK dKeAZRG dLdM dMeRZSG dNdO dOeRZTG dPdQ dQZUdS )Sz0Various classes representing distributed values.    N)Optional)
struct_pb2)device_util)distribute_lib)packed_distributed_variable)reduce_util)values_util)context)record)composite_tensordevice)dtypes)ops)tensor)tensor_conversion_registry)tensor_shape)tensor_util)	type_spec)	array_ops)control_flow_ops)math_ops)resource_variable_ops)variable_scope)	variables)nested_structure_coder)base)saveable_object)core)
distribute)tracec                    s   j tjjkr  |fi |S t j sEj tjj	kr-j
js-t|r-tdt|j }t  t j |f|ddS  fdd}t j||f|dS )zCUpdates variables with ON_WRITE synchronization in replica context.Cannot update non-float variables with tf.VariableAggregation.MEAN aggregation in replica context. Either change the variable dtype to float or update it in cross-replica context.Targskwargsgroupc                    s\   j tjjkrjjst|trtd| j	ksJ t
| |j }j |fi |S )zCAggregate values and update all variables in cross replica context.r!   )aggregationvsVariableAggregationMEANdtypeis_floating
isinstance
PerReplica
ValueErrordistribute_strategyr   apply_aggregation_update_cross_replica)strategyvaluer$   v	update_fnvar ^/var/www/html/chatgem/venv/lib/python3.10/site-packages/tensorflow/python/distribute/values.pymerge_fnR   s   	z*_on_write_update_replica.<locals>.merge_fn)r#   r$   )r&   r'   r(   NONE_get_on_device_or_primaryr   get_strategyextended_use_merge_callr)   r*   r+   r   
is_tf_typer.   !apply_aggregation_replica_contextr   mark_as_unsaveableget_replica_context_update
merge_call)r7   r6   r3   r$   aggregated_valuer:   r8   r5   r9   _on_write_update_replica4   s4   	rG   c                    sn   t | tr	tdt| s| S |tjjkr& fdd}t	 j
|| fdS tj|}t j|| }|S )zBAggregate `value` to `destinations` as specified by `aggregation`.zDCannot use DistributedValues to update variables in replica context.c                    s   | j j| |d  dS )Nr   destinations)r>   broadcast_toexperimental_local_results)r2   r3   rH   r8   r9   r:   v   s   z3apply_aggregation_replica_context.<locals>.merge_fn)r#   )r,   DistributedValues	TypeErrorr   r@   r'   r(   ONLY_FIRST_REPLICAr   rC   rE   r   ReduceOpfrom_variable_aggregationr=   r>   _replica_ctx_all_reduce)r3   r&   rI   r:   	reduce_oprF   r8   rH   r9   rA   k   s    


rA   c                   @   sX   e Zd ZdZdd Zdd Zdd Zdd	 Zed
d Z	edd Z
dd Zdd ZdS )rL   z/Base class for representing distributed values.c                 C   s   t || _dS )z+Should only be called by subclass __init__.Ntuple_values)selfvaluesr8   r8   r9   __init__      zDistributedValues.__init__c                 C   s"   t  }|du r|  S | j| S z@Returns the value for the current device or raises a ValueError.N)r   get_current_replica_id_as_int_get_cross_replicarU   rV   
replica_idr8   r8   r9   _get   s   
zDistributedValues._getc                 C      t dt|  )Nz}DistributedValues._get_cross_replica should be implemented by sub-classes which support cross-replica accesses. Type name is NotImplementedErrortyperV   r8   r8   r9   r\      s
   z$DistributedValues._get_cross_replicac                 C   sR   t  }|du r$tt }| jD ]}t|j|kr |  S q| jS | j| S )GReturns value in same replica or device if possible, else the _primary.N)r   r[   r   canonicalizecurrentrU   r   _primary)rV   r^   current_devicer3   r8   r8   r9   r<      s   

z+DistributedValues._get_on_device_or_primaryc                 C   s
   | j d S )z#Returns a representative component.r   rU   rd   r8   r8   r9   rh      s   
zDistributedValues._primaryc                 C   s   t dd | jD S )Nc                 s       | ]}|j V  qd S Nr   .0r4   r8   r8   r9   	<genexpr>       z-DistributedValues._devices.<locals>.<genexpr>rS   rd   r8   r8   r9   _devices   s   zDistributedValues._devicesc                 C   *   d dd t| jD }d| jj|f S )N,
c                 s        | ]\}}d ||f V  qdS )z  %d: %sNr8   rn   ir4   r8   r8   r9   ro          
z,DistributedValues.__str__.<locals>.<genexpr>	%s:{
%s
}join	enumeraterU   	__class____name__)rV   	debug_strr8   r8   r9   __str__      
zDistributedValues.__str__c                 C   rr   )Nrs   c                 s   rt   )z  %d: %rNr8   ru   r8   r8   r9   ro      rw   z-DistributedValues.__repr__.<locals>.<genexpr>rx   ry   )rV   
debug_reprr8   r8   r9   __repr__   r   zDistributedValues.__repr__N)r}   
__module____qualname____doc__rX   r_   r\   r<   propertyrh   rq   r   r   r8   r8   r8   r9   rL      s    

rL   c                       s6  e Zd ZdZ fddZedd Zdd Zdd	 Zd
d Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zd d! Zd"d# Zd$d% Zd&d' Zd(d) Zd*d+ Zd,d- Zd.d/ Zd0d1 Zd2d3 Zd4d5 ZdId7d8Zd9d: Z d;d< Z!d=d> Z"d?d@ Z#dAdB Z$dCdD Z%dEdF Z&dGdH Z'  Z(S )JDistributedDelegatezAA map from device to values; acts as the same type as the values.c                    s>   | ds	|dv rtt| |S |dkrt t|  |S )N_self_)_use_resource_variables_attribute_sentinel_distributed_containerrU   )
startswithsuperr   __getattr__AttributeErrorgetattrr_   rV   namer|   r8   r9   r      s
   
zDistributedDelegate.__getattr__c                 C      | j S zReturns the per replica values.rj   rd   r8   r8   r9   rW         zDistributedDelegate.valuesc                 C      |   S )a  Returns the value for operations for the current device.

    Some implementations, e.g. `TPUMirroredVariable`, are not able to return the
    value type within a replica context. They can, however, return a value that
    can be used by the operations below.
    )r_   rd   r8   r8   r9   _get_as_operand   s   z#DistributedDelegate._get_as_operandc                 C   s   |   | S rl   r   rV   or8   r8   r9   __add__      zDistributedDelegate.__add__c                 C   s   ||    S rl   r   r   r8   r8   r9   __radd__   r   zDistributedDelegate.__radd__c                 C   s   |   | S rl   r   r   r8   r8   r9   __sub__   r   zDistributedDelegate.__sub__c                 C   s   ||    S rl   r   r   r8   r8   r9   __rsub__   r   zDistributedDelegate.__rsub__c                 C   s   |   | S rl   r   r   r8   r8   r9   __mul__   r   zDistributedDelegate.__mul__c                 C   s   ||    S rl   r   r   r8   r8   r9   __rmul__   r   zDistributedDelegate.__rmul__c                 C   s   |   | S rl   r   r   r8   r8   r9   __truediv__  r   zDistributedDelegate.__truediv__c                 C   s   ||    S rl   r   r   r8   r8   r9   __rtruediv__  r   z DistributedDelegate.__rtruediv__c                 C   s   |   | S rl   r   r   r8   r8   r9   __floordiv__	  r   z DistributedDelegate.__floordiv__c                 C   s   ||    S rl   r   r   r8   r8   r9   __rfloordiv__  r   z!DistributedDelegate.__rfloordiv__c                 C   s   |   | S rl   r   r   r8   r8   r9   __mod__  r   zDistributedDelegate.__mod__c                 C   s   ||    S rl   r   r   r8   r8   r9   __rmod__  r   zDistributedDelegate.__rmod__c                 C   s   |   |k S rl   r   r   r8   r8   r9   __lt__  r   zDistributedDelegate.__lt__c                 C   s   |   |kS rl   r   r   r8   r8   r9   __le__  r   zDistributedDelegate.__le__c                 C   s   |   |kS rl   r   r   r8   r8   r9   __gt__  r   zDistributedDelegate.__gt__c                 C   s   |   |kS rl   r   r   r8   r8   r9   __ge__  r   zDistributedDelegate.__ge__c                 C   s   |   |@ S rl   r   r   r8   r8   r9   __and__!  r   zDistributedDelegate.__and__c                 C   s   ||   @ S rl   r   r   r8   r8   r9   __rand__$  r   zDistributedDelegate.__rand__c                 C   s   |   |B S rl   r   r   r8   r8   r9   __or__'  r   zDistributedDelegate.__or__c                 C   s   ||   B S rl   r   r   r8   r8   r9   __ror__*  r   zDistributedDelegate.__ror__c                 C   s   |   |A S rl   r   r   r8   r8   r9   __xor__-  r   zDistributedDelegate.__xor__c                 C   s   ||   A S rl   r   r   r8   r8   r9   __rxor__0  r   zDistributedDelegate.__rxor__c                 C   s   |   | S rl   r   r   r8   r8   r9   __getitem__3  r   zDistributedDelegate.__getitem__Nc                 C   s   t |  ||S rl   powr   )rV   r   modulor8   r8   r9   __pow__6     zDistributedDelegate.__pow__c                 C   s   t ||  S rl   r   r   r8   r8   r9   __rpow__9     zDistributedDelegate.__rpow__c                 C   s
   |    S rl   r   rd   r8   r8   r9   
__invert__<     
zDistributedDelegate.__invert__c                 C   s
   |    S rl   r   rd   r8   r8   r9   __neg__?  r   zDistributedDelegate.__neg__c                 C   s   t |  S rl   )absr   rd   r8   r8   r9   __abs__B  r   zDistributedDelegate.__abs__c                 C   (   z|   |W S  ty   t Y S w rl   )r   __div__r   NotImplementedr   r8   r8   r9   r   E  
   zDistributedDelegate.__div__c                 C   r   rl   )r   __rdiv__r   r   r   r8   r8   r9   r   L  r   zDistributedDelegate.__rdiv__c                 C   r   rl   )r   
__matmul__r   r   r   r8   r8   r9   r   S  r   zDistributedDelegate.__matmul__c                 C   r   rl   )r   __rmatmul__r   r   r   r8   r8   r9   r   Z  r   zDistributedDelegate.__rmatmul__rl   ))r}   r   r   r   r   r   rW   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   __classcell__r8   r8   r   r9   r      sL    


r   c                   @   s(   e Zd ZdZedd Zedd ZdS )r-   z2Holds a map from replica to unsynchronized values.c                 C   s   t dd | jD  S )Nc                 s   s    | ]}t |V  qd S rl   )r   type_spec_from_valuerm   r8   r8   r9   ro   k  s    z(PerReplica._type_spec.<locals>.<genexpr>)PerReplicaSpecrU   rd   r8   r8   r9   
_type_spech  s   zPerReplica._type_specc                 C   r   r   rj   rd   r8   r8   r9   rW   m  r   zPerReplica.valuesN)r}   r   r   r   r   r   rW   r8   r8   r8   r9   r-   d  s    
r-   Fc                 C   sb   ~|dur| | jstd|j| jj|rtdt s$t s(tdt	
 }| j| S )z&Converts a `PerReplica` to a `Tensor`.NzMIncompatible type conversion requested to type {!r} for variable of type {!r}z5PerReplica doesn't support being used as a reference.zIt looks like you are using a PerReplica object while not inside a replica context, which is not supported. Try running your op or function inside a replica context by using `strategy.run`)is_compatible_withr*   r.   formatr   rb   r   in_cross_replica_contexthas_strategyr   r[   rW   )r7   r*   r   as_refr^   r8   r8   r9   _per_replica_to_tensors  s    
r   c                   @   sN   e Zd ZdZdgZedd Zdd Zdd Zed	d
 Z	dd Z
dd ZdS )r   z&Type specification for a `PerReplica`._value_specsc                 C   s   t S rl   r-   rd   r8   r8   r9   <lambda>  s    zPerReplicaSpec.<lambda>c                 G   s   t || _d S rl   )rT   r   )rV   value_specsr8   r8   r9   rX     r   zPerReplicaSpec.__init__c                 C   r   rl   r   rd   r8   r8   r9   
_serialize     zPerReplicaSpec._serializec                 C   r   rl   r   rd   r8   r8   r9   _component_specs     zPerReplicaSpec._component_specsc                 C   s(   t  }|d ur|jdkrtd|jS )N   zJFlattening a PerReplica to components is not supported in replica context.)r   rC   num_replicas_in_syncr.   rU   )rV   r3   replica_contextr8   r8   r9   _to_components  s   zPerReplicaSpec._to_componentsc                 C   s   t |S rl   r   )rV   tensor_listr8   r8   r9   _from_components     zPerReplicaSpec._from_componentsN)r}   r   r   r   	__slots__r   
value_typerX   r   r   r   r   r8   r8   r8   r9   r     s    
r   c                   @   (   e Zd ZdZdd Zdd Zdd ZdS )	Mirroredz:Holds a map from replica to values which are kept in sync.c                 C   r   rl   r<   rd   r8   r8   r9   r\     r   zMirrored._get_cross_replicac                 C   s*   |   }t|dd }|rt|r| S |S )N_as_graph_element)r_   r   callable)rV   objconv_fnr8   r8   r9   r     s
   zMirrored._as_graph_elementc                 C      dS NTr8   rd   r8   r8   r9   _is_mirrored     zMirrored._is_mirroredN)r}   r   r   r   r\   r   r   r8   r8   r8   r9   r     s
    r   c                   @   r   )	DistributedVarOpz'A class that looks like `tf.Operation`.c                 C   s   || _ || _|| _|| _d S rl   )r   graph	tracebackrc   )rV   r   r   r   typr8   r8   r9   rX     s   
zDistributedVarOp.__init__c                 C   s@   t || jst| j|jko| j|jko| j|jko| j|jkS rl   )r,   r|   rb   r   r   r   rc   r   r8   r8   r9   __eq__  s   

zDistributedVarOp.__eq__c                 C   s   t | j| jt| j| jfS rl   )hashr   r   rT   r   rc   rd   r8   r8   r9   __hash__  s   zDistributedVarOp.__hash__N)r}   r   r   r   rX   r   r   r8   r8   r8   r9   r     s
    r   c                   @   s^   e Zd ZdZdd Zdd Zdd Zdd	d
Zdd Zdd Z	de
fddZdefddZdS )DistributedVariableTraceTypez)TraceType of DistributedVariable objects.c                 C   s    || _ t|j |jf| _d S rl   )distributed_variablerT   shapeas_listr*   
components)rV   r   r8   r8   r9   rX     s   
z%DistributedVariableTraceType.__init__c                 C   s   | |kS rl   r8   rV   otherr8   r8   r9   is_subtype_of  r   z*DistributedVariableTraceType.is_subtype_ofc                    s   t  fdd|D r S d S )Nc                 3   s    | ]} |kV  qd S rl   r8   )rn   r   rd   r8   r9   ro     s    zNDistributedVariableTraceType.most_specific_common_supertype.<locals>.<genexpr>)all)rV   othersr8   rd   r9   most_specific_common_supertype  s   z;DistributedVariableTraceType.most_specific_common_supertypeNc                 C   r   rl   )r   )rV   placeholder_contextr8   r8   r9   placeholder_value  r   z.DistributedVariableTraceType.placeholder_valuec                 C   s   g S rl   r8   )rV   r3   r8   r8   r9   
to_tensors  r   z'DistributedVariableTraceType.to_tensorsc                 C   s   |S rl   r8   )rV   r3   _r8   r8   r9   cast  r   z!DistributedVariableTraceType.castreturnc                 C   s
   t | jS rl   )r   r   rd   r8   r8   r9   r     r   z%DistributedVariableTraceType.__hash__c                 C   s   t |tsdS | j|jkS NF)r,   r   r   r   r8   r8   r9   r     s   
z#DistributedVariableTraceType.__eq__rl   )r}   r   r   r   rX   r   r   r  r  r  intr   boolr   r8   r8   r8   r9   r     s    
r   c                       s  e Zd ZdZd fdd	Zdd Zdd Zdd	d
Zedd Z	dd Z
dd Zedd Zedd Zedd Zedd Zedd Zedd Zedd Zedd  Zed!d" Zed#d$ Zed%d& Zed'd( Zed)d* Zdd+d,Zed-d. Zd/d0 Zd1d2 Zed3d4 Zed5d6 Zed7d8 Zd9e j!fd:d;Z"dd<d=Z#ed9e$j%fd>d?Z&ed@dA Z'dBdC Z(dDdE Z)dFdG Z*dHdI Z+dJdK Z,dLdM Z-ddPdQZ.ddRdSZ/ddTdUZ0ddVdWZ1ddXdYZ2ddZd[Z3dd\d]Z4dd^d_Z5dd`daZ6ddbdcZ7ddde Z8dfdg Z9dhdi Z:djdk Z;dldm Z<dndo Z=dpdq Z>drds Z?ddtduZ@		ddveAeBjC dweAeD d9eEjFfdxdyZG			ddzd{ZHd|d} ZId~d ZJedd ZKdd ZL  ZMS )DistributedVariablez&Holds a map from replica to variables.Nc           	         s  |t jjkr|d jjstd|| _|| _tt	| 
| | jjdd | _|D ]}t|tjr?t|dr?t| |j_q*t| |_q*t rt|ddrd| j }t|d drwtjtd	d
 |D g |d}|D ]}||_qmd | _ntj||d| _nd | _d| _d | _|| _ d S )Nr   zcreating distributed tf.Variable with aggregation=MEAN and a non-floating dtype is not supported, please use a different aggregation or dtype:handle%_enable_packed_variable_in_eager_modeFz
%s/packed/_varsc                 s   rk   rl   )r  )rn   r3   r8   r8   r9   ro      rp   z/DistributedVariable.__init__.<locals>.<genexpr>r   )!variables_libr(   r)   r*   r+   r.   _distribute_strategy_aggregationr   r	  rX   rh   r   split_common_namer,   r   CompositeTensorhasattrweakrefrefr  r   r   #executing_eagerly_outside_functionsr   packedPackedDistributedVariablesum_packed_var_keras_initialized_initializer_op_policy)	rV   r2   rW   r&   
var_policyr4   r   
packed_varr3   r   r8   r9   rX     s@   



zDistributedVariable.__init__c              
   C   s   t | j/ g }| jD ]!}t|j |t|| W d   n1 s(w   Y  qW d   n1 s8w   Y  t	| | j|| j
t| j|d}||t| < |S )ab  Perform a deepcopy of the `DistributedVariable`.

    Unlike the deepcopy of a regular tf.Variable, this keeps the original
    strategy and devices of the `DistributedVariable`.  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 `DistributedVariable`
    within its originating strategy scope.

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

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

    Raises:
      RuntimeError: If trying to deepcopy into a different strategy.
    N)r2   rW   r&   r   )r   enter_or_assert_strategyr  rU   r   r   appendcopydeepcopyrc   r  r  id)rV   memo
new_valuesr3   copied_variabler8   r8   r9   __deepcopy__9  s"   
z DistributedVariable.__deepcopy__c                 C   s   | j d uo	t  S rl   )r  r   is_saving_non_distributedrd   r8   r8   r9   _use_packed_variable\  s   
z(DistributedVariable._use_packed_variablec                 C   sp   t  r	| j S |  r| j S | j }| jdd D ]
}t|| }qtj|| jd  |d}|S )zIdentifies if all the component variables are initialized.

    Args:
      name: Name of the final `logical_and` op.

    Returns:
      The op that evaluates to True or False depending on if all the
      component variables are initialized.
    r   r  )	r   r+  rh   is_initializedr,  r  rU   r   logical_and)rV   r   resultr4   r8   r8   r9   r.  b  s   



z"DistributedVariable.is_initializedc                 C   s>   t  r| jjS | jr| j}|S ttdd | jD }|S )Nc                 s   rk   rl   )initializerrm   r8   r8   r9   ro     rp   z2DistributedVariable.initializer.<locals>.<genexpr>)	r   r+  rh   r1  r  r   r%   rT   rU   )rV   init_opr8   r8   r9   r1  {  s   zDistributedVariable.initializerc                 C      |    S rl   )r<   initialized_valuerd   r8   r8   r9   r4    r   z%DistributedVariable.initialized_valuec                 C   s   | j d uo	| j  S rl   )r  r   rd   r8   r8   r9   r        z DistributedVariable._is_mirroredc                 C   
   |   jS rl   )r<   initial_valuerd   r8   r8   r9   r7       
z!DistributedVariable.initial_valuec                 C      | j jS rl   )rh   
constraintrd   r8   r8   r9   r:       zDistributedVariable.constraintc                 C   r9  rl   )rh   r   rd   r8   r8   r9   r     r;  zDistributedVariable.graphc                 C   r   rl   )r  rd   r8   r8   r9   _shared_name  r   z DistributedVariable._shared_namec                 C   r9  rl   )rh   
_unique_idrd   r8   r8   r9   r=    r;  zDistributedVariable._unique_idc                 C   r9  )z7Lets Optimizers know which graph this variable is from.)rh   
_graph_keyrd   r8   r8   r9   r>    s   zDistributedVariable._graph_keyc                 C   r9  rl   )rh   r   rd   r8   r8   r9   r     r;  zDistributedVariable.namec                 C   r9  rl   )rh   r*   rd   r8   r8   r9   r*     r;  zDistributedVariable.dtypec                 C   r9  rl   )rh   r   rd   r8   r8   r9   r     r;  zDistributedVariable.shapec                 C   r9  rl   )rh   synchronizationrd   r8   r8   r9   r?    r;  z#DistributedVariable.synchronizationc                 C   r   rl   r  rd   r8   r8   r9   r&     r   zDistributedVariable.aggregationc                 C   s   |   r| jS d S rl   )r,  r  rd   r8   r8   r9   _packed_variable  s   z$DistributedVariable._packed_variablec                 C   sD   t  r| jjS t  }|d u rtd|  r| jjS | j| jS )NztDistributedVariable.handle is not available outside the replica context or a `tf.distribute.Strategy.update()` call.)	r   r+  rh   r  r[   r.   r,  r  rU   r]   r8   r8   r9   r    s   zDistributedVariable.handlec                 C   s   |   |S rl   )r<   eval)rV   sessionr8   r8   r9   rB    r   zDistributedVariable.evalc                 C   r9  rl   )rh   _save_slice_inford   r8   r8   r9   rD    r;  z$DistributedVariable._save_slice_infoc                 C   
   | j  S rl   )rh   _get_save_slice_inford   r8   r8   r9   rF    r   z(DistributedVariable._get_save_slice_infoc                 C   s   | j D ]}|| qd S rl   )rU   _set_save_slice_info)rV   save_slice_infor4   r8   r8   r9   rG    s   
z(DistributedVariable._set_save_slice_infoc                 C   r6  rl   )r<   r   rd   r8   r8   r9   r     r8  zDistributedVariable.devicec                 C   r9  rl   )rh   	trainablerd   r8   r8   r9   rI    r;  zDistributedVariable.trainablec                 C   r   rl   )r  rd   r8   r8   r9   r/     r   z'DistributedVariable.distribute_strategyr  c                 C   rE  rl   )rh   	get_shaperd   r8   r8   r9   rJ    r   zDistributedVariable.get_shapec                 C   s   | j j|dS )N)export_scope)rh   to_proto)rV   rK  r8   r8   r9   rL    r   zDistributedVariable.to_protoc                 C   sH   t  r| jjS t rt| jjj| jjj| jjj	| jjj
S |  jS rl   )r   r+  rh   opr   r   r   r   r   r   rc   r_   rd   r8   r8   r9   rM    s   
zDistributedVariable.opc                 C   r9  rl   )rh   _in_graph_moderd   r8   r8   r9   rN    r;  z"DistributedVariable._in_graph_modec                 C   s$   | j | }|  r| j|jS |S )z8Returns the value on a device with the given replica_id.)rU   r,  r  	on_devicer   )rV   r^   r3   r8   r8   r9   _get_replica  s   
z DistributedVariable._get_replicac                 C   s0   t  r| jS t  }|du r|  S | |S rZ   )r   r+  rh   r[   r\   rP  r]   r8   r8   r9   r_     s   
zDistributedVariable._getc                 C   sr   t  r| jS t  }|du r4tt }t| jD ]\}}t|j	|kr.| 
|  S q| 
dS | 
|S )re   Nr   )r   r+  rh   r[   r   rf   rg   r{   rU   r   rP  )rV   r^   ri   rv   r3   r8   r8   r9   r<     s   

z-DistributedVariable._get_on_device_or_primaryc                 C   sP   t  r	| j S t| j t| 	 W  d    S 1 s!w   Y  d S rl   )
r   r+  rh   
read_valuer   r"  r  r   identityr_   rd   r8   r8   r9   rQ     s
   
$zDistributedVariable.read_valuec                 C   s0   t  r	| j S | jr| j| S |   S rl   )r   r+  rh   r3   r  r<   rd   r8   r8   r9   r3   &  s
   
zDistributedVariable.valuec                 C   s   t  r
|   S td)NzNDistributedVariable.numpy() is only available when eager execution is enabled.)r	   executing_eagerlyrQ  numpyrb   rd   r8   r8   r9   rT  -  s   zDistributedVariable.numpyFTc                 C   J   t  r| j||||S | jr| jj| ||||dS t j| ||||dS Nuse_lockingr   rQ  )r   r+  rh   
assign_subr  on_write_assign_subrV   r3   rX  r   rQ  r8   r8   r9   rY  4     
zDistributedVariable.assign_subc                 C   rU  rV  )r   r+  rh   
assign_addr  on_write_assign_addr[  r8   r8   r9   r]  A  r\  zDistributedVariable.assign_addc                 C   rU  rV  )r   r+  rh   assignr  on_write_assignr[  r8   r8   r9   r_  N  r\  zDistributedVariable.assignc                 C   D   t  r| j|||S | jr| jj| |||dS t j| |||dS NrX  r   )r   r+  rh   scatter_subr  rV   sparse_deltarX  r   r8   r8   r9   rd  [     zDistributedVariable.scatter_subc                 C   ra  rb  )r   r+  rh   scatter_addr  re  r8   r8   r9   rh  d  rg  zDistributedVariable.scatter_addc                 C   ra  rb  )r   r+  rh   scatter_mulr  re  r8   r8   r9   ri  m  rg  zDistributedVariable.scatter_mulc                 C   ra  rb  )r   r+  rh   scatter_divr  re  r8   r8   r9   rj  v  rg  zDistributedVariable.scatter_divc                 C   ra  rb  )r   r+  rh   scatter_minr  re  r8   r8   r9   rk    rg  zDistributedVariable.scatter_minc                 C   ra  rb  )r   r+  rh   scatter_maxr  re  r8   r8   r9   rl    rg  zDistributedVariable.scatter_maxc                 C   ra  rb  )r   r+  rh   scatter_updater  re  r8   r8   r9   rm    rg  z"DistributedVariable.scatter_updatec                 C   s   t | S rl   )r   rV   r  r8   r8   r9   __tf_tracing_type__  r   z'DistributedVariable.__tf_tracing_type__c                        j f fdd	}tj|iS )zOverrides Trackable method.

    This allows both name-based and object-based save and restore of
    DistributedVariables.

    Returns:
      A dictionary mapping attribute names to `SaveableObject` factories.
    c                       t   j| S rl   )_DistributedVariableSaveablerh   r  rd   r8   r9   _saveable_factory  r   zODistributedVariable._gather_saveables_for_checkpoint.<locals>._saveable_factoryr  	trackableVARIABLE_VALUE_KEYrV   rs  r8   rd   r9    _gather_saveables_for_checkpoint     

z4DistributedVariable._gather_saveables_for_checkpointc                 C   s6   t  r	| j S | jr| j| S tdt|  )NzDistributedVariable._as_graph_element requires a valid VariablePolicy. Please set the policy via the `var_policy` argument in the constructor, or override this method in sub-classes which support cross-replica accesses. Type name is )r   r+  rh   r   r  rb   rc   rd   r8   r8   r9   r     s   
z%DistributedVariable._as_graph_elementc                 C   s2   t  r| jS | jr| j| S tdt|  )NzDistributedVariable._get_cross_replica requires a valid VariablePolicy. Please set the policy via the `var_policy` argument in the constructor, or override this method in sub-classes which support cross-replica accesses. Type name is )r   r+  rh   r  r\   rb   rc   rd   r8   r8   r9   r\     s   z&DistributedVariable._get_cross_replicac                 K   s"   t   | jjj| ||f|ddS )ag  Applies updates across replicas.

    Args:
      update_fn: A callable to pass to `strategy.extended.update` to update the
        variable. It should has the same signature as `Variable.assign()`.
      value: value to be passed to `update_fn`.
      **kwargs: remaining arguments to `update_fn`.

    Returns:
      Updated variable or `tf.Operation`.
    Tr"   )r   rB   r/   r>   updaterV   r6   r3   r$   r8   r8   r9   r1     s   z)DistributedVariable._update_cross_replicac                 K   s0   | j r| j j| ||fi |S tdt|  )a@  Applies updates in one replica.

    Args:
      update_fn: A callable to update the variable. It should has the same
        signature as `Variable.assign()`.
      value: value to be passed to `update_fn`.
      **kwargs: remaining arguments to `update_fn`.

    Returns:
      Updated variable or `tf.Operation`.
    zDistributedVariable._update_replica requires a valid VariablePolicy. Please set the policy via the `var_policy` argument in the constructor, or override this method in sub-classes which support cross-replica accesses. Type name is )r  _update_replicarb   rc   r{  r8   r8   r9   r|    s   z#DistributedVariable._update_replicac                 K   s   t  r|| j|fi |S t| jJ t rGt }|dur6| |}|||fi |W  d   S | j	||fi |W  d   S t 
| j | j||fi |W  d   S 1 saw   Y  dS )a  Applies updates depending on the context.

    The method calls `_update_replica` in replica context,
    `_update_cross_replica` in cross replica context, and `update_fn` in update
    context.

    If `read_value` is True, the method returns the updated Variable. If
    `read_value` is False, the method returns the update `tf.Operation`.

    Args:
      update_fn: A callable to pass to `strategy.extended.update` to update the
        variable. It should have the same signature as `Variable.assign()`.
      value: value to be passed to `update_fn`.
      **kwargs: keyword arguments to `update_fn`.

    Returns:
      Updated variable or `tf.Operation`.

    N)r   r+  rh   r   r"  r/   r   get_update_replica_idrP  r1   assert_replica_contextr|  )rV   r6   r3   r$   update_replica_idreplica_valuer8   r8   r9   rD     s   
$zDistributedVariable._updatec                 C   r   )z6Pass resource_variable_ops.is_resource_variable check.Nr8   rd   r8   r8   r9    _should_act_as_resource_variable     z4DistributedVariable._should_act_as_resource_variablec                 C   sb   t  rtj| j|||dS t| j tj|  |||dW  d   S 1 s*w   Y  dS ) Converts a variable to a tensor.r*   r   r   N)	r   r+  r   convert_to_tensorrh   r   r"  r  r_   rV   r*   r   r   r8   r8   r9   _dense_var_to_tensor  s   
$z(DistributedVariable._dense_var_to_tensorr*   r   c                 C   s   |  ||S rl   r  )rV   r*   r   r8   r8   r9   __tf_tensor__  s   z!DistributedVariable.__tf_tensor__c              	      s    j jd|||d|} fdd jD D ]-}|j r.||jd|||d| q| j  ||< | j j ||j< ||j q| j  | < | j j | < |   jd uro| j j | jj	< | jj	 |S )N)
object_map
tensor_mapoptionsc                    s   g | ]	}| j kr|qS r8   )rh   rm   rd   r8   r9   
<listcomp>-  s    zDDistributedVariable._export_to_saved_model_graph.<locals>.<listcomp>r8   )
rh   _export_to_saved_model_graphrU   experimental_variable_policy_expand_distributed_variablesextendr  r#  r  packed_handle)rV   r  r  r  r$   resource_listr4   r8   rd   r9   r  !  s@   

z0DistributedVariable._export_to_saved_model_graphc              	   C   s   | |vr<t j| jjddd }t| tj| j	| j
| j| j| j| jd}W d   n1 s3w   Y  ||| < ||  }t|j ||   W d   dS 1 sYw   Y  dS )zFor implementing `Trackable`.CPUr   )device_typedevice_index)rI  r   r*   r   r/   r&   N)pydev
DeviceSpecfrom_stringr   replace	to_stringr   r   UninitializedVariablerI  r   r*   r<  r  r  r_  rQ  )rV   r  	op_devicenew_vardestination_varr8   r8   r9   _copy_trackable_to_cpuC  s*   "z*DistributedVariable._copy_trackable_to_cpuc                 C   s    t | || t| || dS )a  Update a SavedObject proto for the caller.

    If a DistributedVariable object supports this method, it will be called when
    saving with a pre-built `SavedObject` proto representing the object, plus an
    instance of `SaveOptions`. This method is then free to modify that proto
    instance.

    `DistributedVariable` with `AUTO` or `ON_WRITE` synchronization optionally
    write out information about their components to the
    `experimental_distributed_variable_components` field of a
    `SavedVariable` (depending on the `SaveOptions` variable policy).

    Args:
      proto: A pre-built `SavedObject` proto for this object. It is assumed this
        will be a `SavedVariable` instance.
      options: A `SaveOptions` instance.
    N)r   (write_object_proto_for_resource_variabler   write_object_proto)rV   protor  r8   r8   r9   _write_object_protoX  s   z'DistributedVariable._write_object_protoc                 C   r   r   r8   rd   r8   r8   r9   is_distributed_variablep  r  z+DistributedVariable.is_distributed_variablec                 C   s6   |j }|| | tjd|g| gdd dd d | S )Ncaptured_valuec                 S      | gS rl   r8   xr8   r8   r9   r   {      zIDistributedVariable.__tf_experimental_restore_capture__.<locals>.<lambda>c                 S   r  rl   r8   r  r8   r8   r9   r   |  r  )backward_functionforward_function)r   replace_capturer
   record_operation)rV   concrete_functioninternal_capturer   r8   r8   r9   #__tf_experimental_restore_capture__t  s   
z7DistributedVariable.__tf_experimental_restore_capture__rl   FNTFNNNF)NN)NNN)Nr}   r   r   r   rX   r*  r,  r.  r   r1  r4  r   r7  r:  r   r<  r=  r>  r   r*   r   r?  r&   rA  r  rB  rD  rF  rG  r   rI  r/   r   TensorShaperJ  rL  r   	OperationrM  rN  rP  r_   r<   rQ  r3   rT  rY  r]  r_  rd  rh  ri  rj  rk  rl  rm  ro  rx  r   r\   r1   r|  rD   r  r  r   r   DTypestr
tensor_libTensorr  r  r  r  r  r  r   r8   r8   r   r9   r	    s    ;#



























	
	
	
	
	
		!



"
r	  c                       (   e Zd ZdZ fddZdd Z  ZS )rr  z8Class for defining how to restore a DistributedVariable.c                    sB   || _ | j jstd|j|||\}}tt| ||| d S )NzThe VariablePolicy of the argument `distributed_variable` must be set to create a _DistributedVariableSaveable. Please set it via the `var_policy` argument in the constructor of DistributedVariable.)_distributed_variabler  r.   get_saveabler   rr  rX   )rV   r   primary_variabler   r   specr   r8   r9   rX     s   z%_DistributedVariableSaveable.__init__c                 C   s   |\}| j j| j |S z*Restore the same value into all variables.)r  r  get_restore_opsrV   restored_tensorsrestored_shapesr   r8   r8   r9   restore  s   z$_DistributedVariableSaveable.restorer}   r   r   r   rX   r  r   r8   r8   r   r9   rr    s    rr  c                       r  )_MirroredSaveablez5Class for defining how to restore a MirroredVariable.c                    s2   || _ t| j ||\}}tt| ||| d S rl   )_mirrored_variabler   get_on_write_saveabler   r  rX   )rV   mirrored_variabler  r   r   r  r   r8   r9   rX     s
   z_MirroredSaveable.__init__c                 C   s   |\}t | j|S r  )r   get_on_write_restore_opsr  r  r8   r8   r9   r    s   z_MirroredSaveable.restorer  r8   r8   r   r9   r    s    r  c                       sj   e Zd ZdZdd Zdd Z fddZ fdd	Z fd
dZdd Z	dd Z
dd ZdddZ  ZS )MirroredVariablezDHolds a map from replica to variables whose values are kept in sync.c                 C   s
   t | S rl   )r   r   rd   r8   r8   r9   r     r   zMirroredVariable._is_mirroredc                 K   s   t | ||fi |S rl   )rG   r{  r8   r8   r9   r|    r5  z MirroredVariable._update_replicac                    b   t  r| jj|i |S | jtjjkr&| jtjjkr&t	t j
jd| jdtt| j|i |S )Nrk  op_namer&   )r   r+  rh   rk  r  r'   r(   rN   r;   rb   scatter_error_msgr   r   r  rV   r#   r$   r   r8   r9   rk       zMirroredVariable.scatter_minc                    r  )Nrl  r  )r   r+  rh   rl  r  r'   r(   rN   r;   rb   r  r   r   r  r  r   r8   r9   rl    r  zMirroredVariable.scatter_maxc                    r  )Nrm  r  )r   r+  rh   rm  r  r'   r(   rN   r;   rb   r  r   r   r  r  r   r8   r9   rm    r  zMirroredVariable.scatter_updatec                 C   s   t t| S rl   )r   rR  r   r\   rd   r8   r8   r9   r\     s   z#MirroredVariable._get_cross_replicac                 C   r3  rl   r<   r   rd   r8   r8   r9   r     r   z"MirroredVariable._as_graph_elementc                    rp  )zOverrides Trackable method.

    This allows both name-based and object-based save and restore of
    MirroredVariables.

    Returns:
      A dictionary mapping attribute names to `SaveableObject` factories.
    c                    rq  rl   )r  rh   r  rd   r8   r9   rs    r   zLMirroredVariable._gather_saveables_for_checkpoint.<locals>._saveable_factoryrt  rw  r8   rd   r9   rx    ry  z1MirroredVariable._gather_saveables_for_checkpointNFc                 C   s"   |rt dtj|  |||dS )r  zYou may be using variable created under distribute strategy in TF 1.x control flows. Try explicitly converting the variable to Tensor using variable.read_value(), or switch to TF 2.x.r  )r.   r   r  r_   r  r8   r8   r9   r    s   z%MirroredVariable._dense_var_to_tensorr  )r}   r   r   r   r   r|  rk  rl  rm  r\   r   rx  r  r   r8   r8   r   r9   r    s    


r  c                       r  )_SyncOnReadSaveablez7Class for defining how to restore a SyncOnReadVariable.c                    s2   || _ t||j|\}}tt| ||| d S rl   )_sync_on_read_variabler   get_on_read_saveablerh   r   r  rX   )rV   sync_on_read_variabler   r   r  r   r8   r9   rX     s
   z_SyncOnReadSaveable.__init__c                 C   s   |\}t | j|| jjS r  )r   get_on_read_restore_opsr  r&   r  r8   r8   r9   r    s
   z_SyncOnReadSaveable.restorer  r8   r8   r   r9   r    s    r  c                       s   e Zd ZdZdd Z fddZd+ fd	d
	Zd+ fdd	Zd+ fdd	Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd  Z fd!d"Zd#d$ Zd%d& Zd'd( Zd,d)d*Z  ZS )-SyncOnReadVariablezGHolds a map from replica to variables whose values are reduced on save.c                 K   s   ||   |fi |S rl   r   r{  r8   r8   r9   r|       z"SyncOnReadVariable._update_replicac                    s>   t | j tt|  W  d   S 1 sw   Y  dS )a  Returns the value of SyncOnReadVariable based on surrounding context.

    If called under a non-default replica-context, returns the corresponding
    variable on that replica.
    If called under default replica-context or cross-replica context, returns
    the synced value.
    N)r   r"  r  r   r  r_   rd   r   r8   r9   r_     s   $zSyncOnReadVariable._getFNTc                       t  r| j||||S t| j. t r/t  s/t 	  t j
| ||dW  d    S tt| ||||W  d    S 1 sDw   Y  d S NrQ  )r   r+  rh   rY  r   r"  r  r   in_replica_update_contextrB    on_read_assign_sub_cross_replicar   r  r[  r   r8   r9   rY  !      $zSyncOnReadVariable.assign_subc                    r  r  )r   r+  rh   r]  r   r"  r  r   r  rB    on_read_assign_add_cross_replicar   r  r[  r   r8   r9   r]  .  r  zSyncOnReadVariable.assign_addc                    r  r  )r   r+  rh   r_  r   r"  r  r   r  rB   on_read_assign_cross_replicar   r  r[  r   r8   r9   r_  ;  s   $zSyncOnReadVariable.assignc                 C      t d| d)Nz:Variables with `synchronization=ON_READ` doesn't support ``rb   rV   methodr8   r8   r9   _scatter_not_implementedH  s   
z+SyncOnReadVariable._scatter_not_implementedc                 O   (   t  r| jj|i |S | d d S Nrd  )r   r+  rh   rd  r  r  r8   r8   r9   rd  L     zSyncOnReadVariable.scatter_subc                 O   r  Nrh  )r   r+  rh   rh  r  r  r8   r8   r9   rh  Q  r  zSyncOnReadVariable.scatter_addc                 O   r  Nri  )r   r+  rh   ri  r  r  r8   r8   r9   ri  V  r  zSyncOnReadVariable.scatter_mulc                 O   r  Nrj  )r   r+  rh   rj  r  r  r8   r8   r9   rj  [  r  zSyncOnReadVariable.scatter_divc                 O   r  Nrk  )r   r+  rh   rk  r  r  r8   r8   r9   rk  `  r  zSyncOnReadVariable.scatter_minc                 O   r  Nrl  )r   r+  rh   rl  r  r  r8   r8   r9   rl  e  r  zSyncOnReadVariable.scatter_maxc                 O   r  Nrm  )r   r+  rh   rm  r  r  r8   r8   r9   rm  j  r  z!SyncOnReadVariable.scatter_updatec                 C   s   t  rtdt r| j S t | j6 t 	 r@t
 s@| jtjjkr5| d W  d    S |  W  d    S |   W  d    S 1 sPw   Y  d S )NzMcall `variable.value()` inside variable_sync_on_read_context is not supportedr   )r    in_variable_sync_on_read_contextrb   r   r+  rh   r3   r"  r  r   r  r  r'   r(   rN   rP  r\   r<   rd   r8   r8   r9   r3   o  s"   

$zSyncOnReadVariable.valuec                    s   t  rtdt  S )NzRcall `variable.read_value()` inside variable_sync_on_read_context is not supported)r   r  rb   r   rQ  rd   r   r8   r9   rQ    s
   
zSyncOnReadVariable.read_valuec                 C   sz   | j tjjkr| dS | j tjjkrt  t	| j
 | j
jtj| j | d dW  d    S 1 s6w   Y  d S Nr   )axis)r  r'   r(   rN   rP  SUMr   rB   r   r"  r  reducer   rO   rP   rd   r8   r8   r9   r\     s   
$z%SyncOnReadVariable._get_cross_replicac                 C   sn   t  r	| j S t| j t r"t	| 
 W  d    S W d    n1 s,w   Y  |   S rl   )r   r+  rh   r   r   r"  r  r   r   r  r\   r_   rd   r8   r8   r9   r     s   
z$SyncOnReadVariable._as_graph_elementc                    rp  )zOverrides Trackable method.

    This allows both name-based and object-based save and restore of
    `SyncOnReadVariable`s.

    Returns:
      A dictionary mapping attribute names to `SaveableObject` factories.
    c                    s
   t  | S rl   )r  r  rd   r8   r9   rs    r   zNSyncOnReadVariable._gather_saveables_for_checkpoint.<locals>._saveable_factoryrt  rw  r8   rd   r9   rx    ry  z3SyncOnReadVariable._gather_saveables_for_checkpointc                 C   s  t  rtj| j|||dS t| je t }|durgt	 rg| j
tjjkr;tj| d|||dW  d   S | j
tjjkrFt   |jjtj| j
|   }tj||||dW  d   S tj|  |||dW  d   S 1 s|w   Y  dS )z*Converts a SyncOnReadVariable to a tensor.r  Nr   )r   r+  r   r  rh   r   r"  r  rC   r  r  r'   r(   rN   rP  r  rB   r2   r>   rQ   r   rO   rP   r_   rQ  )rV   r*   r   r   r   reducedr8   r8   r9   r    s>   

$z'SyncOnReadVariable._dense_var_to_tensorr  r  )r}   r   r   r   r|  r_   rY  r]  r_  r  rd  rh  ri  rj  rk  rl  rm  r3   rQ  r\   r   rx  r  r   r8   r8   r   r9   r    s*    	r  c                 C      | j |||dS Nr  r  r7   r*   r   r   r8   r8   r9   "_tensor_conversion_distributed_var  s   r  c                 C   r  r  r  r  r8   r8   r9   _tensor_conversion_mirrored  r   r  c                 C   s   t j|  |||dS r  )r   r  r_   )r3   r*   r   r   r8   r8   r9   _tensor_conversion_mirrored_val  s   r  c                 C   r  r  r  r  r8   r8   r9   _tensor_conversion_sync_on_read  r   r  c                   @   s@   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dS )VariablePolicya  Policy defining synchronization and aggregation of a distributed variable.

  Given `synchronization` and `aggregation` parameters set on a `tf.Variable`
  during variable creation within `tf.distribute` scope, `tf.distribute` creates
  an appropriate policy object and assigns it to the distributed variable. All
  variable operations are delegated to the respective policy object.
  c                 C   s
   || _ d S rl   r@  )rV   r&   r8   r8   r9   rX     r   zVariablePolicy.__init__c                 C   r`   )NzGVariablePolicy.value should be overridden by sub-classes. Type name is ra   rd   r8   r8   r9   r3     
   zVariablePolicy.valuec                 C   r`   )NzNVariablePolicy._is_mirrored should be overridden by sub-classes. Type name is ra   rd   r8   r8   r9   r     r   zVariablePolicy._is_mirroredc                 C   r`   )NzSVariablePolicy._as_graph_element should be overridden by sub-classes. Type name is ra   rn  r8   r8   r9   r   	  r   z VariablePolicy._as_graph_elementc                 C   r`   )NzTVariablePolicy._get_cross_replica should be overridden by sub-classes. Type name is ra   rV   r7   r8   r8   r9   r\     r   z!VariablePolicy._get_cross_replicac                 K   r`   )NzQVariablePolicy._update_replica should be overridden by sub-classes. Type name is ra   rV   r7   r6   r3   r$   r8   r8   r9   r|    r   zVariablePolicy._update_replicaN)
r}   r   r   r   rX   r3   r   r   r\   r|  r8   r8   r8   r9   r    s    r  c                   @   s   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z				d)ddZ
			d)ddZd)ddZdd Zdd Zdd Zdd Zdd  Zd!d" Zd#d$ Zd%d& Zd'd( ZdS )*OnReadPolicya{  Policy defined for `tf.VariableSynchronization.ON_READ` synchronization.

  This policy is created when `synchronization` is set to
  `tf.VariableSynchronization.ON_READ` and `aggregation` is set to any of the
  values allowed by the `tf.VariableAggregation` enum such as `NONE`, `SUM`,
  `MEAN` or `ONLY_FIRST_REPLICA`when creating a `tf.Variable` in `tf.distribute`
  scope.
  c                 C   r   r  r8   rd   r8   r8   r9   r   &  r   zOnReadPolicy._is_mirroredc                 C   s   t |j6 t  r/t s/| jtjj	kr$|
d W  d    S | W  d    S |  W  d    S 1 s?w   Y  d S )Nr   )r   r"  r/   r   r   r  r  r'   r(   rN   rP  r3   r\   r<   r  r8   r8   r9   r3   )  s   
$zOnReadPolicy.valuec                 C   s\   t |j t  rt| W  d    S W d    n1 s#w   Y  |  S rl   )	r   r"  r/   r   r   r  r\   r_   r   r  r8   r8   r9   r   3  s   zOnReadPolicy._as_graph_elementc                 C   sz   | j tjjkr|dS | j tjjkrt  t	|j
 |j
jtj| j |d dW  d    S 1 s6w   Y  d S r  )r  r'   r(   rN   rP  r  r   rB   r   r"  r/   r  r   rO   rP   r  r8   r8   r9   r\   9  s   
$zOnReadPolicy._get_cross_replicac                 K   s   ||  |fi |S rl   r   r  r8   r8   r9   r|  D  r  zOnReadPolicy._update_replicac                 C   r  )Nz#ON_READ variables doesn't support `z` in cross replica contextr  r  r8   r8   r9   r  G  r   z%OnReadPolicy._scatter_not_implementedFNTc                 C   z   t |j- t  r"t s"t  tj|||dW  d   S tj|||||dW  d   S 1 s6w   Y  dS )z%Subtracts a value from this variable.r  NrW  )	r   r"  r/   r   r   r  rB   r  rZ  rV   r7   r3   rX  r   rQ  r8   r8   r9   rY  K  "   $zOnReadPolicy.assign_subc                 C   r  )zAdds a value to this variable.r  NrW  )	r   r"  r/   r   r   r  rB   r  r^  r  r8   r8   r9   r]  `  r  zOnReadPolicy.assign_addc                 C   sz   t |j- t  r"t s"t  tj|||dW  d    S tj|||||dW  d    S 1 s6w   Y  d S )Nr  rW  )	r   r"  r/   r   r   r  rB   r  r`  r  r8   r8   r9   r_  u  s"   $zOnReadPolicy.assignc                 O      ~~|  d d S r  r  r  r8   r8   r9   rd       zOnReadPolicy.scatter_subc                 O   r  r  r  r  r8   r8   r9   rh    r	  zOnReadPolicy.scatter_addc                 O   r  r  r  r  r8   r8   r9   ri    r	  zOnReadPolicy.scatter_mulc                 O   r  r  r  r  r8   r8   r9   rj    r	  zOnReadPolicy.scatter_divc                 O   r  r  r  r  r8   r8   r9   rk    r	  zOnReadPolicy.scatter_minc                 O   r  r  r  r  r8   r8   r9   rl    r	  zOnReadPolicy.scatter_maxc                 O   r  r  r  r  r8   r8   r9   rm    r	  zOnReadPolicy.scatter_updatec                 C      t |||S )z0Create a saveable object for the given variable.)r   r  rV   r7   primary_varr   r8   r8   r9   r    rY   zOnReadPolicy.get_saveablec                 C   s   t ||| jS r  )r   r  r  rV   r7   r   r8   r8   r9   r    s   zOnReadPolicy.get_restore_opsr  )r}   r   r   r   r   r3   r   r\   r|  r  rY  r]  r_  rd  rh  ri  rj  rk  rl  rm  r  r  r8   r8   r8   r9   r    s4    	



r  c                   @   s   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zd'ddZ				d'ddZ
			d'ddZd(ddZd(ddZd(ddZd(ddZd(ddZd(dd Zd(d!d"Zd#d$ Zd%d& ZdS ))OnWritePolicyaa  Policy defined for `tf.VariableSynchronization.ON_WRITE` synchronization.

  This policy is created when the following `synchronization` and `aggregation`
  parameters are specified when creating a `tf.Variable` in `tf.distribute`
  scope and `synchronization` is equal to `tf.VariableSynchronization.ON_WRITE`
  or `tf.VariableSynchronization.AUTO`.
  c                 C   r   r   r8   rd   r8   r8   r9   r     r   zOnWritePolicy._is_mirroredc                 C      |   S rl   )r<   r3   r  r8   r8   r9   r3     r   zOnWritePolicy.valuec                 C   r  rl   r  r  r8   r8   r9   r     r   zOnWritePolicy._as_graph_elementc                 C   s   t | S rl   )r   rR  r<   r  r8   r8   r9   r\     s   z OnWritePolicy._get_cross_replicac                 K   s8   |j tjjkr|| |fi |S t|||fi |S rl   )r&   r  r(   r;   r<   rG   r  r8   r8   r9   r|    s   zOnWritePolicy._update_replicaFNTc                 C      t j|||||dS rV  )r   r`  r  r8   r8   r9   r_    s   
zOnWritePolicy.assignc                 C   r  rV  )r   r^  r  r8   r8   r9   r]       
zOnWritePolicy.assign_addc                 C   r  rV  )r   rZ  r  r8   r8   r9   rY    r  zOnWritePolicy.assign_subc                 C      t j||||dS rb  )r   rd  rV   r7   rf  rX  r   r8   r8   r9   rd       zOnWritePolicy.scatter_subc                 C   r  rb  )r   rh  r  r8   r8   r9   rh    r  zOnWritePolicy.scatter_addc                 C   r  rb  )r   ri  r  r8   r8   r9   ri    r  zOnWritePolicy.scatter_mulc                 C   r  rb  )r   rj  r  r8   r8   r9   rj    r  zOnWritePolicy.scatter_divc                 C   D   | j tjjkr| j tjjkrttjjd| j dtj	||||dS )Nrk  r  rc  )
r  r'   r(   rN   r;   rb   r   r  r   rk  r  r8   r8   r9   rk       zOnWritePolicy.scatter_minc                 C   r  )Nrl  r  rc  )
r  r'   r(   rN   r;   rb   r   r  r   rl  r  r8   r8   r9   rl    r  zOnWritePolicy.scatter_maxc                 C   r  )Nrm  r  rc  )
r  r'   r(   rN   r;   rb   r   r  r   rm  r  r8   r8   r9   rm    r  zOnWritePolicy.scatter_updatec                 C   r
  )z Saveable ops for AUTO variables.)r   r  r  r8   r8   r9   r    rY   zOnWritePolicy.get_saveablec                 C   s   t ||S rl   )r   r  r  r8   r8   r9   r  
  r   zOnWritePolicy.get_restore_opsr  r  )r}   r   r   r   r   r3   r   r\   r|  r_  r]  rY  rd  rh  ri  rj  rk  rl  rm  r  r  r8   r8   r8   r9   r    s2    



	




	
		r  c                       s<   e Zd ZdZdd Z fddZ fddZdd	 Z  ZS )
PerWorkerResourcea  A per-worker CapturableResource class for non-ParameterServer strategy.

  Resources that populate `host_to_resources` should be instances of classes
  subclassing CapturableResource, although currently it's only used and tested
  for StaticHashTable with TPUStrategy.
  c                 C   s$   t jddd || _|| _d S )Nr  TPUDistributedLookupTabler   )r   'distribution_strategy_input_api_counterget_cellincrease_by	_strategy_host_to_resources)rV   r2   host_to_resourcesr8   r8   r9   rX     s   
zPerWorkerResource.__init__c                    s&   |dvrt |  |S tt| |S )N)rX   __getattribute__r  r  local_resource)r   r   r   r  r  r   r   r8   r9   r    s   z"PerWorkerResource.__getattribute__c                    s*   |dvrt |  ||S tt| ||S )N)r  r  )setattrr   r   r  __setattr__)rV   r   r3   r   r8   r9   r"  "  s   zPerWorkerResource.__setattr__c                 C   s<   t t  }t t |}| j|| jtt| j S )z)Returns the resource on the local worker.)r   rf   rg   get_host_for_devicer  getnextiter)rV   ri   host_devicer8   r8   r9   r   '  s   z PerWorkerResource.local_resource)	r}   r   r   r   rX   r  r"  r   r   r8   r8   r   r9   r    s    r  r  )Vr   r$  typingr   r  tensorflow.core.protobufr   tensorflow.python.distributer   r   r   r  r   r   tensorflow.python.eagerr	   r
   tensorflow.python.frameworkr   r   r  r   r   r   r  r   r   r   r   tensorflow.python.opsr   r   r   r   r   r'   r   r  tensorflow.python.saved_modelr   tensorflow.python.trackabler   ru  !tensorflow.python.training.savingr   tensorflow.python.typesr   r   ds_typesr    rG   rA   rL   r   r  r-   r   #register_tensor_conversion_functionTypeSpecr   register_codecBuiltInTypeSpecCodecTypeSpecProtoPER_REPLICA_SPECr   objectr   	TraceTyper   Variabler  r	  SaveableObjectrr  r  r  r  r  r  r  r  r  r  r  r  r  r8   r8   r8   r9   <module>   s   7@  

!     P >



+ e