o
    ?eU)                     @   s   d 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ddZ	dddddZ	dddddZ		dddddZdS )a  Standard functions for creating slots.

A slot is a `Variable` created with the same first m-dimension as a primary
variable or `Tensor`. A slot is always scoped in the namespace of the primary
object and typically has the same device and type.

Slots are typically used as accumulators to track values associated with
the primary object:

```python
# Optimizers can create a slot for each variable to track accumulators
accumulators = {var : create_zeros_slot(var, "momentum") for var in vs}
for var in vs:
  apply_momentum(var, accumulators[var], lr, grad, momentum_tensor)

# Slots can also be used for moving averages
mavg = create_slot(var, var.initialized_value(), "exponential_moving_avg")
update_mavg = mavg.assign_sub((mavg - var) * (1 - decay))
```
    )xla_sharding)distribute_lib)	array_ops)cond)init_ops)ref_variable)resource_variable_ops)variable_scope)variable_v1)	variablesFcopy_xla_shardingc             
   C   s,  t  j}t  d t|r|nd}t| rd}nt| tj	r%d}nd}t j
||d||||d}	t  | t| tjr| jr|	jt| jjd d }
| j}|	jj}|du s_|dkr|	tj|jd |
 |jd| |jd| |jd|  dd	 }|r|| j|	jrtj| |	dd
}	|	S )z-Helper function for creating a slot variable.NTF)initializerZ	trainableuse_resourceshapedtypevalidate_shape/r   c                 S   s    | j d uo|j d uo| j |j kS N)Zrank)Zprimary_shape
slot_shape r   h/home/www/facesmatcher.com/pyenv/lib/python3.10/site-packages/tensorflow/python/training/slot_creator.py_has_same_ranko   s   
z(_create_slot_var.<locals>._has_same_rank)Zuse_sharding_op)r	   Zget_variable_scopeZpartitionerZset_partitionercallabler   Zis_resource_variable
isinstancer   ZRefVariableZget_variabler   VariableZ_save_slice_infonamelenopr   ZndimsZ_set_save_slice_infoZSaveSliceInfoZ	full_nameZ
full_shapeZ
var_offsetZ	var_shaper   Zcopy_sharding)primaryvalscoper   r   r   r   Zcurrent_partitionerr   ZslotZreal_slot_nameZ
slice_infonr   r   r   r   _create_slot_var2   sD   

	r$   Tc                C   s   |   }t| tjr| j}n| jj}td|d | J |rNt	
 }|j|  t| |d|dd|dW  d   W  d   S 1 sHw   Y  nt| |d|dd|dW  d   S W d   dS 1 skw   Y  dS )a  Create a slot initialized to the given value.

  The type of the slot is determined by the given value.

  Args:
    primary: The primary `Variable` or `Tensor`.
    val: A `Tensor` specifying the initial value of the slot.
    name: Name to use for the slot variable.
    colocate_with_primary: Boolean.  If True the slot is located
      on the same device as `primary`.
    copy_xla_sharding: Boolean. If True also copies XLA sharding
      from primary.

  Returns:
    A `Variable` object.
  Nr    r   )	get_shapeis_fully_definedr   r   r   _shared_namer   r   r	   r   get_strategyextendedcolocate_vars_withr$   )r    r!   r   colocate_with_primaryr   r   prefixdistribution_strategyr   r   r   create_slotx   s@   
"r/   c          
      C   s   |  }t| tjr| j}n| jj}td|d | J |rLt	 }	|	j
|  t| |d||||dW  d   W  d   S 1 sFw   Y  nt| |d||||dW  d   S W d   dS 1 siw   Y  dS )aX  Creates a slot initialized using an `Initializer`.

  The type of the slot is determined by the given value.

  Args:
    primary: The primary `Variable` or `Tensor`.
    initializer: An `Initializer`.  The initial value of the slot.
    shape: Shape of the initial value of the slot.
    dtype: Type of the value of the slot.
    name: Name to use for the slot variable.
    colocate_with_primary: Boolean.  If True the slot is located
      on the same device as `primary`.
    copy_xla_sharding: Boolean. If True also copies XLA sharding
      from primary.

  Returns:
    A `Variable` object.
  Nr   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   create_slot_with_initializer   s@   
"r0   Nc             	      s   |du r j }  }| rt }t ||||||dS t tjr7t	
tt  j fdd}nt	
 }t	j||d}t ||||dS )a  Create a slot initialized to 0 with same shape as the primary object.

  Args:
    primary: The primary `Variable` or `Tensor`.
    name: Name to use for the slot variable.
    dtype: Type of the slot variable.  Defaults to the type of `primary`.
    colocate_with_primary: Boolean.  If True the slot is located
      on the same device as `primary`.
    copy_xla_sharding: Boolean. If True also copies XLA sharding
      from primary.

  Returns:
    A `Variable` object.
  N)r,   r   c                      s    j S r   )initial_valuer   r    r   r   <lambda>  s    z#create_zeros_slot.<locals>.<lambda>)r   )r   r&   r'   r   Zzeros_initializerr0   r   r   r   r   r   r   r
   Zis_variable_initializedZ
read_valueZzerosr/   )r    r   r   r,   r   r   r   r!   r   r2   r   create_zeros_slot   s<   	

r4   )T)NT)__doc__Z+tensorflow.python.compiler.xla.experimentalr   Ztensorflow.python.distributer   Ztensorflow.python.opsr   r   r   r   r   r	   r
   r   r$   r/   r0   r4   r   r   r   r   <module>   s4   
I<=