o
    ?e}                     @   s   d 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 Zdd Zejdd Zejdd Zejdd ZdddZdd ZG dd deZG dd dejZdS )zUtility functions for TPU.    N)packed_distributed_variable)context)def_function)constant_op)ops)resource_variable_ops)tpu_replicationc                   C   s
   t  d S )zEReturns the TPUReplicateContext, which exists inside a tpu.rewrite().r   )enclosing_tpu_context_and_graph r
   r
   f/home/www/facesmatcher.com/pyenv/lib/python3.10/site-packages/tensorflow/python/distribute/tpu_util.pyenclosing_tpu_context   s   
r   c                  C   sZ   t  } | dur+|  }|dur!t|tjr|| fS |j}|dust| dd} | dusdS )z^Returns the TPUReplicateContext which exists inside a tpu.rewrite(), and its associated graph.NZouter_graph)NN)r   Zget_default_graph_get_control_flow_context
isinstancer   ZTPUReplicateContextouter_contextgetattr)graphctxr
   r
   r   r	   !   s   	r	   c                  c   sF    t  \} }| du rdV  dS | }|| j dV  || dS )zOReturns a context manager that skips current enclosing context if there is any.N)r	   r   Z_set_control_flow_contextr   )r   r   Zsaved_contextr
   r
   r   outside_or_skip_tpu_context0   s   

r   c                 c   s^    t  st| tjst rd V  d S | j  d V  W d    d S 1 s(w   Y  d S N)r   Zexecuting_eagerlyr   r   ZEagerTensorZhas_default_graphr   Z
as_default)Ztensorr
   r
   r   _maybe_enter_graph=   s   
"r   c                 c   sP    t | tjr#t| j d V  W d    d S 1 sw   Y  d S d V  d S r   )r   packedZPackedVarAndDevicer   device)varr
   r
   r   _maybe_on_deviceI   s   "
r   Tc                    s   d fdd	}|S )a:  Wrap `raw_assign_fn` with the proper graph context and device scope.

  Args:
    raw_assign_fn: the function to be wrapped.
    use_handle: if True, the `raw_assign_fn` will be applied to the handle of a
      variable; otherwise it will be applied to the variable itself.

  Returns:
    The wrapped function.
  FNTc              
      s  ~r| j n| }t|y t| \  |tj|| jd|d}t|g9 |rGr.|  n|  W  d    W  d    W  d    S |W  d    W  d    W  d    S 1 saw   Y  W d    n1 spw   Y  W d    d S W d    d S 1 sw   Y  d S )N)dtypename)	handler   r   r   convert_to_tensorr   control_dependencies_read_variable_op
read_value)r   valueuse_lockingr   r!   r   opraw_assign_fn
use_handler
   r   	assign_fn_   s    Pz%make_raw_assign_fn.<locals>.assign_fn)FNTr
   )r&   r'   r(   r
   r%   r   make_raw_assign_fnS   s   r)   c                    s   d fdd	}|S )zLWrap `raw_scatter_xxx_fn` so that it can be called w/ and w/o packed handle.FNc              
      s   ~| j }t|\ t| ?  ||jt|j| j|d}t|g | 	 W  d    W  d    W  d    S 1 s@w   Y  W d    n1 sOw   Y  W d    d S W d    d S 1 sgw   Y  d S )Nr   )
r   r   r   indicesr   r   valuesr   r   r    )r   Zsparse_deltar#   r   r   r$   raw_scatter_xxx_fnr
   r   scatter_xxx_fnr   s   Pz/make_raw_scatter_xxx_fn.<locals>.scatter_xxx_fn)FNr
   )r-   r.   r
   r,   r   make_raw_scatter_xxx_fno   s   r/   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	LazyVariableTrackerz,Class to track uninitialized lazy variables.c                 C   s
   g | _ d S r   )_uninitialized_var_listselfr
   r
   r   __init__   s   
zLazyVariableTracker.__init__c                 C   sn   dd }t j|ddd}t  t| jdkr|| j n|| j W d   n1 s-w   Y  g | _dS )z<Initialize all uninitialized lazy variables stored in scope.c              	   S   sn   | D ]/}|j }t|dd }t|d|j}t|j tj||d W d    n1 s,w   Y  qtg S )NZ_packed_varZpacked_handle)resourcer"   )	_initial_valuer   r   r   r   r   ZAssignVariableOpr   Zconstant)Zuninitialized_var_listr   valZ
packed_varr   r
   r
   r   assign_function   s   
z;LazyVariableTracker.initialize_all.<locals>.assign_functionF)Z	autographZjit_compile   N)r   functionr   Z
init_scopelenr1   )r3   r8   Zassign_tf_functionr
   r
   r   initialize_all   s   



z"LazyVariableTracker.initialize_allc                 C   s   | j | d S r   )r1   append)r3   r   r
   r
   r   add_uninitialized_var   s   z)LazyVariableTracker.add_uninitialized_varN)__name__
__module____qualname____doc__r4   r<   r>   r
   r
   r
   r   r0      s
    r0   c                       sJ   e Zd ZdZ fddZd fdd	Zd fdd		Zd fd
d	Z  ZS )TPUUninitializedVariablezUninitializedVariable component for TPU.

  Sometimes user might assign (different values) to a single component of a
  mirrored TPU variable. Thus we need to initialize_all when the assign* or read
  is invoked on a single component.
  c                    s   | j   t  S r   )_lazy_scoper<   superr!   r2   	__class__r
   r   r!      s   

z#TPUUninitializedVariable.read_valueNTc                       | j   t j||||dS N)r#   r   r!   )rD   r<   rE   
assign_subr3   deltar#   r   r!   rF   r
   r   rJ         
z#TPUUninitializedVariable.assign_subc                    rH   rI   )rD   r<   rE   assign)r3   r"   r#   r   r!   rF   r
   r   rN      rM   zTPUUninitializedVariable.assignc                    rH   rI   )rD   r<   rE   
assign_addrK   rF   r
   r   rO      rM   z#TPUUninitializedVariable.assign_add)NNT)	r?   r@   rA   rB   r!   rJ   rN   rO   __classcell__r
   r
   rF   r   rC      s    rC   )T)rB   
contextlibZtensorflow.python.distributer   r   Ztensorflow.python.eagerr   r   Ztensorflow.python.frameworkr   r   Ztensorflow.python.opsr   Ztensorflow.python.tpur   r   r	   contextmanagerr   r   r   r)   r/   objectr0   ZUninitializedVariablerC   r
   r
   r
   r   <module>   s*   



	"