o
    ?e                    @   s2  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  Z/d!d" Z0G d#d$ d$e-j1Z1G d%d& d&e1Z2G d'd( d(e1ej3e-j4Z4dPd*d+Z5e6e4e5 G d,d- d-ej7Z8e$9e$:e8ej;j< G d.d/ d/e2e-j=Z=G d0d1 d1e>Z?G d2d3 d3e.j@ZAG d4d5 d5e2e"jBe+jCZDG d6d7 d7e)jEZFG d8d9 d9e)jEZGG d:d; d;eDe=ZHG d<d= d=e)jEZIG d>d? d?eDZJ			)dPd@dAZKe6eDeK dPdBdCZLe6eHeL dPdDdEZMe6e=eM dPdFdGZNe6eJeN G dHdI dIe>ZOG dJdK dKeOZPG dLdM dMeOZQG dNdO dOZRdS )Qz0Various classes representing distributed values.    N)Optional)
struct_pb2)device_util)distribute_lib)packed_distributed_variable)reduce_util)values_util)context)record)composite_tensor)dtypes)ops)tensor)tensor_conversion_registry)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   Zapply_aggregation_update_cross_replica)strategyvaluer!   v	update_fnvar d/home/www/facesmatcher.com/pyenv/lib/python3.10/site-packages/tensorflow/python/distribute/values.pymerge_fnP   s   	z*_on_write_update_replica.<locals>.merge_fn)r    r!   )r#   r$   r%   NONE_get_on_device_or_primaryr   get_strategyextendedZ_use_merge_callr&   r'   r(   r   
is_tf_typer+   !apply_aggregation_replica_contextr   mark_as_unsaveableget_replica_context_update
merge_call)r3   r2   r/   r!   aggregated_valuer6   r4   r1   r5   _on_write_update_replica2   s4   	rB   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:   Zbroadcast_toZexperimental_local_results)r.   r/   rC   r4   r5   r6   t   s   z3apply_aggregation_replica_context.<locals>.merge_fn)r    )r)   DistributedValues	TypeErrorr   r;   r$   r%   ONLY_FIRST_REPLICAr   r>   r@   r   ReduceOpfrom_variable_aggregationr9   r:   _replica_ctx_all_reduce)r/   r#   rD   r6   Z	reduce_oprA   r4   rC   r5   r<   i   s    


r<   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 )rE   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valuesr4   r4   r5   __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_replicarM   rN   
replica_idr4   r4   r5   _get   s   
zDistributedValues._getc                 C      t d)NzoDistributedValues._get_cross_replica should be implemented by sub-classes which support cross-replica accesses.NotImplementedErrorrN   r4   r4   r5   rT         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   rS   r   canonicalizecurrentrM   device_primary)rN   rV   current_devicer/   r4   r4   r5   r8      s   

z+DistributedValues._get_on_device_or_primaryc                 C   s
   | j d S )z#Returns a representative component.r   rM   r[   r4   r4   r5   ra      s   
zDistributedValues._primaryc                 C   s   t dd | jD S )Nc                 s       | ]}|j V  qd S N)r`   .0r0   r4   r4   r5   	<genexpr>       z-DistributedValues._devices.<locals>.<genexpr>rK   r[   r4   r4   r5   _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: %sNr4   rg   ir0   r4   r4   r5   rh          
z,DistributedValues.__str__.<locals>.<genexpr>	%s:{
%s
}join	enumeraterM   	__class____name__)rN   Z	debug_strr4   r4   r5   __str__      
zDistributedValues.__str__c                 C   rk   )Nrl   c                 s   rm   )z  %d: %rNr4   rn   r4   r4   r5   rh      rp   z-DistributedValues.__repr__.<locals>.<genexpr>rq   rr   )rN   Z
debug_reprr4   r4   r5   __repr__   rx   zDistributedValues.__repr__N)rv   
__module____qualname____doc__rP   rW   rT   r8   propertyra   rj   rw   ry   r4   r4   r4   r5   rE      s    

rE   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 )NZ_self_)Z_use_resource_variablesZ_attribute_sentinel_distributed_containerrM   )
startswithsuperr~   __getattr__AttributeErrorgetattrrW   rN   nameru   r4   r5   r      s
   
zDistributedDelegate.__getattr__c                 C      | j S zReturns the per replica values.rc   r[   r4   r4   r5   rO         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.
    )rW   r[   r4   r4   r5   _get_as_operand   s   z#DistributedDelegate._get_as_operandc                 C   s   |   | S re   r   rN   or4   r4   r5   __add__      zDistributedDelegate.__add__c                 C   s   ||    S re   r   r   r4   r4   r5   __radd__   r   zDistributedDelegate.__radd__c                 C   s   |   | S re   r   r   r4   r4   r5   __sub__   r   zDistributedDelegate.__sub__c                 C   s   ||    S re   r   r   r4   r4   r5   __rsub__   r   zDistributedDelegate.__rsub__c                 C   s   |   | S re   r   r   r4   r4   r5   __mul__   r   zDistributedDelegate.__mul__c                 C   s   ||    S re   r   r   r4   r4   r5   __rmul__   r   zDistributedDelegate.__rmul__c                 C   s   |   | S re   r   r   r4   r4   r5   __truediv__   r   zDistributedDelegate.__truediv__c                 C   s   ||    S re   r   r   r4   r4   r5   __rtruediv__  r   z DistributedDelegate.__rtruediv__c                 C   s   |   | S re   r   r   r4   r4   r5   __floordiv__  r   z DistributedDelegate.__floordiv__c                 C   s   ||    S re   r   r   r4   r4   r5   __rfloordiv__  r   z!DistributedDelegate.__rfloordiv__c                 C   s   |   | S re   r   r   r4   r4   r5   __mod__  r   zDistributedDelegate.__mod__c                 C   s   ||    S re   r   r   r4   r4   r5   __rmod__  r   zDistributedDelegate.__rmod__c                 C   s   |   |k S re   r   r   r4   r4   r5   __lt__  r   zDistributedDelegate.__lt__c                 C   s   |   |kS re   r   r   r4   r4   r5   __le__  r   zDistributedDelegate.__le__c                 C   s   |   |kS re   r   r   r4   r4   r5   __gt__  r   zDistributedDelegate.__gt__c                 C   s   |   |kS re   r   r   r4   r4   r5   __ge__  r   zDistributedDelegate.__ge__c                 C   s   |   |@ S re   r   r   r4   r4   r5   __and__  r   zDistributedDelegate.__and__c                 C   s   ||   @ S re   r   r   r4   r4   r5   __rand__   r   zDistributedDelegate.__rand__c                 C   s   |   |B S re   r   r   r4   r4   r5   __or__#  r   zDistributedDelegate.__or__c                 C   s   ||   B S re   r   r   r4   r4   r5   __ror__&  r   zDistributedDelegate.__ror__c                 C   s   |   |A S re   r   r   r4   r4   r5   __xor__)  r   zDistributedDelegate.__xor__c                 C   s   ||   A S re   r   r   r4   r4   r5   __rxor__,  r   zDistributedDelegate.__rxor__c                 C   s   |   | S re   r   r   r4   r4   r5   __getitem__/  r   zDistributedDelegate.__getitem__Nc                 C   s   t |  ||S re   powr   )rN   r   Zmodulor4   r4   r5   __pow__2     zDistributedDelegate.__pow__c                 C   s   t ||  S re   r   r   r4   r4   r5   __rpow__5     zDistributedDelegate.__rpow__c                 C   s
   |    S re   r   r[   r4   r4   r5   
__invert__8     
zDistributedDelegate.__invert__c                 C   s
   |    S re   r   r[   r4   r4   r5   __neg__;  r   zDistributedDelegate.__neg__c                 C   s   t |  S re   )absr   r[   r4   r4   r5   __abs__>  r   zDistributedDelegate.__abs__c                 C   (   z|   |W S  ty   t Y S w re   )r   __div__r   NotImplementedr   r4   r4   r5   r   A  
   zDistributedDelegate.__div__c                 C   r   re   )r   __rdiv__r   r   r   r4   r4   r5   r   H  r   zDistributedDelegate.__rdiv__c                 C   r   re   )r   
__matmul__r   r   r   r4   r4   r5   r   O  r   zDistributedDelegate.__matmul__c                 C   r   re   )r   __rmatmul__r   r   r   r4   r4   r5   r   V  r   zDistributedDelegate.__rmatmul__re   ))rv   rz   r{   r|   r   r}   rO   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__r4   r4   r   r5   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 re   )r   Ztype_spec_from_valuerf   r4   r4   r5   rh   g  s    z(PerReplica._type_spec.<locals>.<genexpr>)PerReplicaSpecrM   r[   r4   r4   r5   
_type_specd  s   zPerReplica._type_specc                 C   r   r   rc   r[   r4   r4   r5   rO   i  r   zPerReplica.valuesN)rv   rz   r{   r|   r}   r   rO   r4   r4   r4   r5   r*   `  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`)Zis_compatible_withr'   r+   formatr   rZ   r   in_cross_replica_contextZhas_strategyr   rS   rO   )r3   r'   r   as_refrV   r4   r4   r5   _per_replica_to_tensoro  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 re   r*   r[   r4   r4   r5   <lambda>  s    zPerReplicaSpec.<lambda>c                 G   s   t || _d S re   )rL   r   )rN   Zvalue_specsr4   r4   r5   rP     r   zPerReplicaSpec.__init__c                 C   r   re   r   r[   r4   r4   r5   
_serialize     zPerReplicaSpec._serializec                 C   r   re   r   r[   r4   r4   r5   _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   r>   Znum_replicas_in_syncr+   rM   )rN   r/   replica_contextr4   r4   r5   _to_components  s   zPerReplicaSpec._to_componentsc                 C   s   t |S re   r   )rN   Ztensor_listr4   r4   r5   _from_components     zPerReplicaSpec._from_componentsN)rv   rz   r{   r|   	__slots__r}   Z
value_typerP   r   r   r   r   r4   r4   r4   r5   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   re   r8   r[   r4   r4   r5   rT     r   zMirrored._get_cross_replicac                 C   s*   |   }t|dd }|rt|r| S |S )N_as_graph_element)rW   r   callable)rN   objZconv_fnr4   r4   r5   r     s
   zMirrored._as_graph_elementc                 C      dS NTr4   r[   r4   r4   r5   _is_mirrored     zMirrored._is_mirroredN)rv   rz   r{   r|   rT   r   r   r4   r4   r4   r5   r     s
    r   c                   @   r   )	DistributedVarOpz'A class that looks like `tf.Operation`.c                 C   s   || _ || _|| _|| _d S re   )r   graph	tracebacktype)rN   r   r   r   typr4   r4   r5   rP     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 re   )r)   ru   rZ   r   r   r   r   r   r4   r4   r5   __eq__  s   

zDistributedVarOp.__eq__c                 C   s   t | j| jt| j| jfS re   )hashr   r   rL   r   r   r[   r4   r4   r5   __hash__  s   zDistributedVarOp.__hash__N)rv   rz   r{   r|   rP   r   r   r4   r4   r4   r5   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 re   )distributed_variablerL   shapeas_listr'   
components)rN   r   r4   r4   r5   rP     s   
z%DistributedVariableTraceType.__init__c                 C   s   | |kS re   r4   rN   otherr4   r4   r5   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 re   r4   )rg   r   r[   r4   r5   rh     s    zNDistributedVariableTraceType.most_specific_common_supertype.<locals>.<genexpr>)all)rN   Zothersr4   r[   r5   most_specific_common_supertype  s   z;DistributedVariableTraceType.most_specific_common_supertypeNc                 C   r   re   )r   )rN   Zplaceholder_contextr4   r4   r5   placeholder_value  r   z.DistributedVariableTraceType.placeholder_valuec                 C   s   g S re   r4   )rN   r/   r4   r4   r5   _to_tensors  r   z(DistributedVariableTraceType._to_tensorsc                 C   s   |S re   r4   )rN   r/   _r4   r4   r5   _cast  r   z"DistributedVariableTraceType._castreturnc                 C   s
   t | jS re   )r   r   r[   r4   r4   r5   r     r   z%DistributedVariableTraceType.__hash__c                 C   s   t |tsdS | j|jkS NF)r)   r   r   r   r4   r4   r5   r     s   
z#DistributedVariableTraceType.__eq__re   )rv   rz   r{   r|   rP   r   r   r   r   r   intr   boolr   r4   r4   r4   r5   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d9d: Z dd;d<Z!ed=d> Z"ed?d@ Z#dAdB Z$dCdD Z%dEdF Z&dGdH Z'dIdJ Z(dKdL Z)ddOdPZ*ddQdRZ+ddSdTZ,ddUdVZ-ddWdXZ.ddYdZZ/dd[d\Z0dd]d^Z1dd_d`Z2ddadbZ3dcdd Z4dedf Z5dgdh Z6didj Z7dkdl Z8dmdn Z9dodp Z:dqdr Z;ddsdtZ<		ddue=e>j? dve=e@ dweAjBfdxdyZC			ddzd{ZDd|d} ZEed~d ZFdd ZG  ZHS )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 | _qt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:handleZ%_enable_packed_variable_in_eager_modeFz
%s/packed/_varsc                 s   rd   re   )r   )rg   r/   r4   r4   r5   rh     ri   z/DistributedVariable.__init__.<locals>.<genexpr>r   )!variables_libr%   r&   r'   r(   r+   _distribute_strategy_aggregationr   r   rP   ra   r   split_common_namer)   r   CompositeTensorhasattrweakrefrefr   r   r   Z#executing_eagerly_outside_functionsr   packedZPackedDistributedVariablesum_packed_varZ_keras_initialized_initializer_op_policy)	rN   r.   rO   r#   
var_policyr0   r   Z
packed_varr/   r   r4   r5   rP     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)r.   rO   r#   r  )r   enter_or_assert_strategyr   rM   r   r`   appendcopydeepcopyr   r   r  id)rN   memo
new_valuesr/   Zcopied_variabler4   r4   r5   __deepcopy__5  s"   
z DistributedVariable.__deepcopy__c                 C   s   | j d uo	t  S re   )r  r   is_saving_non_distributedr[   r4   r4   r5   _use_packed_variableX  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  ra   is_initializedr  r  rM   r   logical_and)rN   r   resultr0   r4   r4   r5   r  ^  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   rd   re   )initializerrf   r4   r4   r5   rh     ri   z2DistributedVariable.initializer.<locals>.<genexpr>)	r   r  ra   r  r  r   r"   rL   rM   )rN   Zinit_opr4   r4   r5   r  w  s   zDistributedVariable.initializerc                 C      |    S re   )r8   initialized_valuer[   r4   r4   r5   r    r   z%DistributedVariable.initialized_valuec                 C   s   | j d uo	| j  S re   )r  r   r[   r4   r4   r5   r        z DistributedVariable._is_mirroredc                 C   
   |   jS re   )r8   initial_valuer[   r4   r4   r5   r       
z!DistributedVariable.initial_valuec                 C      | j jS re   )ra   
constraintr[   r4   r4   r5   r       zDistributedVariable.constraintc                 C   r  re   )ra   r   r[   r4   r4   r5   r     r  zDistributedVariable.graphc                 C   r   re   )r   r[   r4   r4   r5   _shared_name  r   z DistributedVariable._shared_namec                 C   r  re   )ra   
_unique_idr[   r4   r4   r5   r     r  zDistributedVariable._unique_idc                 C   r  )z7Lets Optimizers know which graph this variable is from.)ra   
_graph_keyr[   r4   r4   r5   r!    s   zDistributedVariable._graph_keyc                 C   r  re   )ra   r   r[   r4   r4   r5   r     r  zDistributedVariable.namec                 C   r  re   )ra   r'   r[   r4   r4   r5   r'     r  zDistributedVariable.dtypec                 C   r  re   )ra   r   r[   r4   r4   r5   r     r  zDistributedVariable.shapec                 C   r  re   )ra   synchronizationr[   r4   r4   r5   r"    r  z#DistributedVariable.synchronizationc                 C   r   re   r   r[   r4   r4   r5   r#     r   zDistributedVariable.aggregationc                 C   s   |   r| jS d S re   )r  r  r[   r4   r4   r5   _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  ra   r   rS   r+   r  r  rM   rU   r4   r4   r5   r     s   zDistributedVariable.handlec                 C   s   |   |S re   )r8   eval)rN   sessionr4   r4   r5   r%    r   zDistributedVariable.evalc                 C   r  re   )ra   _save_slice_infor[   r4   r4   r5   r'    r  z$DistributedVariable._save_slice_infoc                 C   
   | j  S re   )ra   _get_save_slice_infor[   r4   r4   r5   r)    r   z(DistributedVariable._get_save_slice_infoc                 C   s   | j D ]}|| qd S re   )rM   _set_save_slice_info)rN   Zsave_slice_infor0   r4   r4   r5   r*    s   
z(DistributedVariable._set_save_slice_infoc                 C   r  re   )r8   r`   r[   r4   r4   r5   r`     r  zDistributedVariable.devicec                 C   r  re   )ra   	trainabler[   r4   r4   r5   r+    r  zDistributedVariable.trainablec                 C   r   re   )r   r[   r4   r4   r5   r,     r   z'DistributedVariable.distribute_strategyc                 C   r(  re   )ra   	get_shaper[   r4   r4   r5   r,    r   zDistributedVariable.get_shapec                 C   s   | j j|dS )N)export_scope)ra   to_proto)rN   r-  r4   r4   r5   r.    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 re   )r   r  ra   opr   r   r   r   r   r   r   rW   r[   r4   r4   r5   r/    s   
zDistributedVariable.opc                 C   r  re   )ra   _in_graph_moder[   r4   r4   r5   r0    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.)rM   r  r  Z	on_devicer`   )rN   rV   r/   r4   r4   r5   _get_replica  s   
z DistributedVariable._get_replicac                 C   s0   t  r| jS t  }|du r|  S | |S rR   )r   r  ra   rS   rT   r1  rU   r4   r4   r5   rW     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 )r]   Nr   )r   r  ra   rS   r   r^   r_   rt   rM   r`   r1  )rN   rV   rb   ro   r/   r4   r4   r5   r8     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 re   )
r   r  ra   
read_valuer   r  r   r   identityrW   r[   r4   r4   r5   r2    s
   
$zDistributedVariable.read_valuec                 C   s0   t  r	| j S | jr| j| S |   S re   )r   r  ra   r/   r  r8   r[   r4   r4   r5   r/   "  s
   
zDistributedVariable.valuec                 C   s   t  r
|   S td)NzNDistributedVariable.numpy() is only available when eager execution is enabled.)r	   Zexecuting_eagerlyr2  numpyrZ   r[   r4   r4   r5   r4  )  s   zDistributedVariable.numpyFTc                 C   J   t  r| j||||S | jr| jj| ||||dS t j| ||||dS Nuse_lockingr   r2  )r   r  ra   
assign_subr  on_write_assign_subrN   r/   r8  r   r2  r4   r4   r5   r9  0     
zDistributedVariable.assign_subc                 C   r5  r6  )r   r  ra   
assign_addr  on_write_assign_addr;  r4   r4   r5   r=  =  r<  zDistributedVariable.assign_addc                 C   r5  r6  )r   r  ra   assignr  on_write_assignr;  r4   r4   r5   r?  J  r<  zDistributedVariable.assignc                 C   D   t  r| j|||S | jr| jj| |||dS t j| |||dS Nr8  r   )r   r  ra   scatter_subr  rN   sparse_deltar8  r   r4   r4   r5   rD  W     zDistributedVariable.scatter_subc                 C   rA  rB  )r   r  ra   scatter_addr  rE  r4   r4   r5   rH  `  rG  zDistributedVariable.scatter_addc                 C   rA  rB  )r   r  ra   scatter_mulr  rE  r4   r4   r5   rI  i  rG  zDistributedVariable.scatter_mulc                 C   rA  rB  )r   r  ra   scatter_divr  rE  r4   r4   r5   rJ  r  rG  zDistributedVariable.scatter_divc                 C   rA  rB  )r   r  ra   scatter_minr  rE  r4   r4   r5   rK  {  rG  zDistributedVariable.scatter_minc                 C   rA  rB  )r   r  ra   scatter_maxr  rE  r4   r4   r5   rL    rG  zDistributedVariable.scatter_maxc                 C   rA  rB  )r   r  ra   scatter_updater  rE  r4   r4   r5   rM    rG  z"DistributedVariable.scatter_updatec                 C   s   t | S re   )r   rN   r   r4   r4   r5   __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 re   )_DistributedVariableSaveablera   r   r[   r4   r5   _saveable_factory  r   zODistributedVariable._gather_saveables_for_checkpoint.<locals>._saveable_factoryr   	trackableZVARIABLE_VALUE_KEYrN   rS  r4   r[   r5    _gather_saveables_for_checkpoint     

z4DistributedVariable._gather_saveables_for_checkpointc                 C   s,   t  r	| j S | jr| j| S td)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.)r   r  ra   r   r  rZ   r[   r4   r4   r5   r     s   
z%DistributedVariable._as_graph_elementc                 C   s(   t  r| jS | jr| j| S td)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.)r   r  ra   r  rT   rZ   r[   r4   r4   r5   rT     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   r=   r,   r:   updaterN   r2   r/   r!   r4   r4   r5   r-     s   z)DistributedVariable._update_cross_replicac                 K   s&   | j r| j j| ||fi |S td)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.)r  _update_replicarZ   rZ  r4   r4   r5   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  ra   r   r  r,   r   Zget_update_replica_idr1  r-   Zassert_replica_contextr[  )rN   r2   r/   r!   Zupdate_replica_idZreplica_valuer4   r4   r5   r?     s   
$zDistributedVariable._updatec                 C   r   )z6Pass resource_variable_ops.is_resource_variable check.Nr4   r[   r4   r4   r5    _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_tensorra   r   r  r   rW   rN   r'   r   r   r4   r4   r5   _dense_var_to_tensor	  s   
$z(DistributedVariable._dense_var_to_tensorr'   r   r   c                 C   s   |  ||S re   rb  )rN   r'   r   r4   r4   r5   __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 r4   )ra   rf   r[   r4   r5   
<listcomp>#  s    zDDistributedVariable._export_to_saved_model_graph.<locals>.<listcomp>r4   )
ra   _export_to_saved_model_graphrM   Zexperimental_variable_policyZ_expand_distributed_variablesextendr   r  r  Zpacked_handle)rN   re  rf  rg  r!   Zresource_listr0   r4   r[   r5   ri    s@   

z0DistributedVariable._export_to_saved_model_graphc                 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   Z(write_object_proto_for_resource_variabler   Zwrite_object_proto)rN   protorg  r4   r4   r5   _write_object_proto9  s   z'DistributedVariable._write_object_protoc                 C   r   r   r4   r[   r4   r4   r5   is_distributed_variableQ  r]  z+DistributedVariable.is_distributed_variablec                 C   s6   |j }|| | tjd|g| gdd dd d | S )NZcaptured_valuec                 S      | gS re   r4   xr4   r4   r5   r   \      zIDistributedVariable.__tf_experimental_restore_capture__.<locals>.<lambda>c                 S   rn  re   r4   ro  r4   r4   r5   r   ]  rq  )Zbackward_functionZforward_function)r   Zreplace_capturer
   Zrecord_operation)rN   Zconcrete_functionZinternal_capturer   r4   r4   r5   #__tf_experimental_restore_capture__U  s   
z7DistributedVariable.__tf_experimental_restore_capture__re   FNTFNNNF)NN)NNN)Irv   rz   r{   r|   rP   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/  r0  r1  rW   r8   r2  r/   r4  r9  r=  r?  rD  rH  rI  rJ  rK  rL  rM  rO  rW  r   rT   r-   r[  r?   r\  rb  r   r   ZDTypestr
tensor_libTensorrd  ri  rl  rm  rr  r   r4   r4   r   r5   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  rP   )rN   r   primary_variabler   r   specr   r4   r5   rP   k  s   z%_DistributedVariableSaveable.__init__c                 C   s   |\}| j j| j |S z*Restore the same value into all variables.)rz  r  get_restore_opsrN   Zrestored_tensorsZrestored_shapesr   r4   r4   r5   restorew  s   z$_DistributedVariableSaveable.restorerv   rz   r{   r|   rP   r  r   r4   r4   r   r5   rR  h  s    rR  c                       ry  )_MirroredSaveablez5Class for defining how to restore a MirroredVariable.c                    s2   || _ t| j ||\}}tt| ||| d S re   )_mirrored_variabler   get_on_write_saveabler   r  rP   )rN   Zmirrored_variabler|  r   r   r}  r   r4   r5   rP     s
   z_MirroredSaveable.__init__c                 C   s   |\}t | j|S r~  )r   get_on_write_restore_opsr  r  r4   r4   r5   r    s   z_MirroredSaveable.restorer  r4   r4   r   r5   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 re   )r   r   r[   r4   r4   r5   r     r   zMirroredVariable._is_mirroredc                 K   s   t | ||fi |S re   )rB   rZ  r4   r4   r5   r[    r  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  Zop_namer#   )r   r  ra   rK  r   r$   r%   rG   r7   rZ   scatter_error_msgr   r   r  rN   r    r!   r   r4   r5   rK       zMirroredVariable.scatter_minc                    r  )NrL  r  )r   r  ra   rL  r   r$   r%   rG   r7   rZ   r  r   r   r  r  r   r4   r5   rL    r  zMirroredVariable.scatter_maxc                    r  )NrM  r  )r   r  ra   rM  r   r$   r%   rG   r7   rZ   r  r   r   r  r  r   r4   r5   rM    r  zMirroredVariable.scatter_updatec                 C   s   t t| S re   )r   r3  r   rT   r[   r4   r4   r5   rT     s   z#MirroredVariable._get_cross_replicac                 C   r  re   r8   r   r[   r4   r4   r5   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  re   )r  ra   r   r[   r4   r5   rS    r   zLMirroredVariable._gather_saveables_for_checkpoint.<locals>._saveable_factoryrT  rV  r4   r[   r5   rW    rX  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`  rW   ra  r4   r4   r5   rb    s   z%MirroredVariable._dense_var_to_tensorru  )rv   rz   r{   r|   r   r[  rK  rL  rM  rT   r   rW  rb  r   r4   r4   r   r5   r    s    


r  c                       ry  )_SyncOnReadSaveablez7Class for defining how to restore a SyncOnReadVariable.c                    s2   || _ t||j|\}}tt| ||| d S re   )_sync_on_read_variabler   get_on_read_saveablera   r   r  rP   )rN   Zsync_on_read_variabler   r   r}  r   r4   r5   rP     s
   z_SyncOnReadSaveable.__init__c                 C   s   |\}t | j|| jjS r~  )r   get_on_read_restore_opsr  r#   r  r4   r4   r5   r    s
   z_SyncOnReadSaveable.restorer  r4   r4   r   r5   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 re   r   rZ  r4   r4   r5   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  rW   r[   r   r4   r5   rW     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r2  )r   r  ra   r9  r   r  r   r   in_replica_update_contextr=    on_read_assign_sub_cross_replicar   r  r;  r   r4   r5   r9        $zSyncOnReadVariable.assign_subc                    r  r  )r   r  ra   r=  r   r  r   r   r  r=    on_read_assign_add_cross_replicar   r  r;  r   r4   r5   r=    r  zSyncOnReadVariable.assign_addc                    r  r  )r   r  ra   r?  r   r  r   r   r  r=   on_read_assign_cross_replicar   r  r;  r   r4   r5   r?    s   $zSyncOnReadVariable.assignc                 C      t d| d)Nz:Variables with `synchronization=ON_READ` doesn't support ``rY   rN   methodr4   r4   r5   _scatter_not_implemented)  s   
z+SyncOnReadVariable._scatter_not_implementedc                 O   (   t  r| jj|i |S | d d S NrD  )r   r  ra   rD  r  r  r4   r4   r5   rD  -     zSyncOnReadVariable.scatter_subc                 O   r  NrH  )r   r  ra   rH  r  r  r4   r4   r5   rH  2  r  zSyncOnReadVariable.scatter_addc                 O   r  NrI  )r   r  ra   rI  r  r  r4   r4   r5   rI  7  r  zSyncOnReadVariable.scatter_mulc                 O   r  NrJ  )r   r  ra   rJ  r  r  r4   r4   r5   rJ  <  r  zSyncOnReadVariable.scatter_divc                 O   r  NrK  )r   r  ra   rK  r  r  r4   r4   r5   rK  A  r  zSyncOnReadVariable.scatter_minc                 O   r  NrL  )r   r  ra   rL  r  r  r4   r4   r5   rL  F  r  zSyncOnReadVariable.scatter_maxc                 O   r  NrM  )r   r  ra   rM  r  r  r4   r4   r5   rM  K  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_contextrZ   r   r  ra   r/   r  r   r   r  r   r$   r%   rG   r1  rT   r8   r[   r4   r4   r5   r/   P  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  rZ   r   r2  r[   r   r4   r5   r2  a  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   )Zaxis)r   r$   r%   rG   r1  SUMr   r=   r   r  r   reducer   rH   rI   r[   r4   r4   r5   rT   h  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 re   )r   r  ra   r   r   r  r   r   r   r`  rT   rW   r[   r4   r4   r5   r   u  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 re   )r  r   r[   r4   r5   rS    r   zNSyncOnReadVariable._gather_saveables_for_checkpoint.<locals>._saveable_factoryrT  rV  r4   r[   r5   rW  ~  rX  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`  ra   r   r  r   r>   r  r   r$   r%   rG   r1  r  r=   r.   r:   rJ   r   rH   rI   rW   r2  )rN   r'   r   r   r   Zreducedr4   r4   r5   rb    s>   

$z'SyncOnReadVariable._dense_var_to_tensorrs  ru  )rv   rz   r{   r|   r[  rW   r9  r=  r?  r  rD  rH  rI  rJ  rK  rL  rM  r/   r2  rT   r   rW  rb  r   r4   r4   r   r5   r    s*    	r  c                 C      | j |||dS Nr_  rc  r3   r'   r   r   r4   r4   r5   "_tensor_conversion_distributed_var  s   r  c                 C   r  r  rc  r  r4   r4   r5   _tensor_conversion_mirrored  r   r  c                 C   s   t j|  |||dS r  )r   r`  rW   )r/   r'   r   r   r4   r4   r5   _tensor_conversion_mirrored_val  s   r  c                 C   r  r  rc  r  r4   r4   r5   _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 re   r#  )rN   r#   r4   r4   r5   rP     r   zVariablePolicy.__init__c                 C   rX   )Nz8VariablePolicy.value should be overriden by sub-classes.rY   r[   r4   r4   r5   r/     r\   zVariablePolicy.valuec                 C   rX   )Nz?VariablePolicy._is_mirrored should be overriden by sub-classes.rY   r[   r4   r4   r5   r     r\   zVariablePolicy._is_mirroredc                 C   rX   )NzDVariablePolicy._as_graph_element should be overriden by sub-classes.rY   rN  r4   r4   r5   r     r\   z VariablePolicy._as_graph_elementc                 C   rX   )NzEVariablePolicy._get_cross_replica should be overriden by sub-classes.rY   rN   r3   r4   r4   r5   rT     r\   z!VariablePolicy._get_cross_replicac                 K   rX   )NzBVariablePolicy._update_replica should be overriden by sub-classes.rY   rN   r3   r2   r/   r!   r4   r4   r5   r[    r\   zVariablePolicy._update_replicaN)
rv   rz   r{   r|   rP   r/   r   r   rT   r[  r4   r4   r4   r5   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   r4   r[   r4   r4   r5   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%   rG   r1  r/   rT   r8   r  r4   r4   r5   r/      s   
$zOnReadPolicy.valuec                 C   s\   t |j t  rt| W  d    S W d    n1 s#w   Y  |  S re   )	r   r  r,   r   r   r`  rT   rW   r   r  r4   r4   r5   r   
  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%   rG   r1  r  r   r=   r   r  r,   r  r   rH   rI   r  r4   r4   r5   rT     s   
$zOnReadPolicy._get_cross_replicac                 K   s   ||  |fi |S re   r   r  r4   r4   r5   r[    r  zOnReadPolicy._update_replicac                 C   r  )Nz#ON_READ variables doesn't support `z` in cross replica contextrY   r  r4   r4   r5   r    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  Nr7  )	r   r  r,   r   r   r  r=   r  r:  rN   r3   r/   r8  r   r2  r4   r4   r5   r9  "  "   $zOnReadPolicy.assign_subc                 C   r  )zAdds a value to this variable.r  Nr7  )	r   r  r,   r   r   r  r=   r  r>  r  r4   r4   r5   r=  7  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  r7  )	r   r  r,   r   r   r  r=   r  r@  r  r4   r4   r5   r?  L  s"   $zOnReadPolicy.assignc                 O      ~~|  d d S r  r  r  r4   r4   r5   rD  [     zOnReadPolicy.scatter_subc                 O   r  r  r  r  r4   r4   r5   rH  _  r  zOnReadPolicy.scatter_addc                 O   r  r  r  r  r4   r4   r5   rI  c  r  zOnReadPolicy.scatter_mulc                 O   r  r  r  r  r4   r4   r5   rJ  g  r  zOnReadPolicy.scatter_divc                 O   r  r  r  r  r4   r4   r5   rK  k  r  zOnReadPolicy.scatter_minc                 O   r  r  r  r  r4   r4   r5   rL  o  r  zOnReadPolicy.scatter_maxc                 O   r  r  r  r  r4   r4   r5   rM  s  r  zOnReadPolicy.scatter_updatec                 C      t |||S )z0Create a saveable object for the given variable.)r   r  rN   r3   Zprimary_varr   r4   r4   r5   r{  w  rQ   zOnReadPolicy.get_saveablec                 C   s   t ||| jS r~  )r   r  r   rN   r3   r   r4   r4   r5   r  {  s   zOnReadPolicy.get_restore_opsrs  )rv   rz   r{   r|   r   r/   r   rT   r[  r  r9  r=  r?  rD  rH  rI  rJ  rK  rL  rM  r{  r  r4   r4   r4   r5   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   r4   r[   r4   r4   r5   r     r   zOnWritePolicy._is_mirroredc                 C      |   S re   )r8   r/   r  r4   r4   r5   r/     r   zOnWritePolicy.valuec                 C   r  re   r  r  r4   r4   r5   r     r   zOnWritePolicy._as_graph_elementc                 C   s   t | S re   )r   r3  r8   r  r4   r4   r5   rT     s   z OnWritePolicy._get_cross_replicac                 K   s8   |j tjjkr|| |fi |S t|||fi |S re   )r#   r   r%   r7   r8   rB   r  r4   r4   r5   r[    s   zOnWritePolicy._update_replicaFNTc                 C      t j|||||dS r6  )r   r@  r  r4   r4   r5   r?    s   
zOnWritePolicy.assignc                 C   r  r6  )r   r>  r  r4   r4   r5   r=       
zOnWritePolicy.assign_addc                 C   r  r6  )r   r:  r  r4   r4   r5   r9    r  zOnWritePolicy.assign_subc                 C      t j||||dS rB  )r   rD  rN   r3   rF  r8  r   r4   r4   r5   rD       zOnWritePolicy.scatter_subc                 C   r  rB  )r   rH  r  r4   r4   r5   rH    r  zOnWritePolicy.scatter_addc                 C   r  rB  )r   rI  r  r4   r4   r5   rI    r  zOnWritePolicy.scatter_mulc                 C   r  rB  )r   rJ  r  r4   r4   r5   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%   rG   r7   rZ   r   r  r   rK  r  r4   r4   r5   rK       zOnWritePolicy.scatter_minc                 C   r  )NrL  r  rC  )
r   r$   r%   rG   r7   rZ   r   r  r   rL  r  r4   r4   r5   rL    r  zOnWritePolicy.scatter_maxc                 C   r  )NrM  r  rC  )
r   r$   r%   rG   r7   rZ   r   r  r   rM  r  r4   r4   r5   rM    r  zOnWritePolicy.scatter_updatec                 C   r  )z Saveable ops for AUTO variables.)r   r  r  r4   r4   r5   r{    rQ   zOnWritePolicy.get_saveablec                 C   s   t ||S re   )r   r  r  r4   r4   r5   r    r   zOnWritePolicy.get_restore_opsrs  rt  )rv   rz   r{   r|   r   r/   r   rT   r[  r?  r=  r9  rD  rH  rI  rJ  rK  rL  rM  r{  r  r4   r4   r4   r5   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  ZTPUDistributedLookupTabler   )r   Z'distribution_strategy_input_api_counterZget_cellZincrease_by	_strategy_host_to_resources)rN   r.   Zhost_to_resourcesr4   r4   r5   rP     s   
zPerWorkerResource.__init__c                    s&   |dvrt |  |S tt| |S )N)rP   __getattribute__r  r  local_resource)r   r  r   r  r  r   r   r4   r5   r    s   z"PerWorkerResource.__getattribute__c                    s*   |dvrt |  ||S tt| ||S )N)r  r  )setattrr  r   r  __setattr__)rN   r   r/   r   r4   r5   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   r^   r_   Zget_host_for_devicer  getnextiter)rN   rb   Zhost_devicer4   r4   r5   r    s   z PerWorkerResource.local_resource)	rv   rz   r{   r|   rP   r  r  r  r   r4   r4   r   r5   r    s    r  ru  )Sr|   r	  typingr   r   Ztensorflow.core.protobufr   Ztensorflow.python.distributer   r   r   r  r   r   Ztensorflow.python.eagerr	   r
   Ztensorflow.python.frameworkr   r   r   r   rw  r   r   r   Ztensorflow.python.opsr   r   r   r   r   r$   r   r   Ztensorflow.python.saved_modelr   Ztensorflow.python.trackabler   rU  Z!tensorflow.python.training.savingr   Ztensorflow.python.typesr   r   Zds_typesr   rB   r<   rE   r~   r   r*   r   Z#register_tensor_conversion_functionZTypeSpecr   Zregister_codecZBuiltInTypeSpecCodecZTypeSpecProtoZPER_REPLICA_SPECr   objectr   Z	TraceTyper   Variablerx  r   ZSaveableObjectrR  r  r  r  r  r  r  r  r  r  r  r  r  r4   r4   r4   r5   <module>   s   7>  

!    vP >



! e