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dd Zdd ZdS )z&Optional helper for gradient handling.    N)dtypes)ops)	array_ops)variable_scope)	variables)
tf_logging)tpu_opsc                 C   s:   |  }| ||}dd |D }tt| |}|S )a  Compute gradients to send to TPU embedding.

  Args:
    optimizer: a subclass of optimizer.Optimizer, usually CrossShardOptimizer.
      Used to call compute_gradients().
    loss: a Tensor to call optimizer.compute_gradients() on.
    activations: an OrderedDict mapping feature_name to Tensors of activations.

  Returns:
    An OrderedDict mapping from feature name Strings to Tensors of gradients of
      the loss wrt the activations of the features.
  c                 S   s   g | ]\}}|qS  r	   ).0Zgrad_r	   r	   m/home/www/facesmatcher.com/pyenv/lib/python3.10/site-packages/tensorflow/python/tpu/tpu_embedding_gradient.py
<listcomp>+   s    z;get_gradients_through_compute_gradients.<locals>.<listcomp>)valuesZcompute_gradientscollectionsOrderedDictzipkeys)Z	optimizerZlossactivationsZactivation_listZgrads_and_varsZgradsfeature_to_gradient_dictr	   r	   r   'get_gradients_through_compute_gradients   s   r   c              	   C   s   t  }t| jD ]?\}}tjd|tjdgdddgd||< t	
 }|d|}|r5td|t| j| }|dd	 t|D  q	|tj| d
dfS )a  Create dummy embedding table variables.

  The sole purpose of these dummy variables are to trigger gradient
  calculation wrt them so that the gradients wrt activation can be captured
  and later sent to TPU embedding.

  Args:
    tpu_embedding: TPUEmbedding, dummy table variables will be created for use
      with tpu_embedding.

  Returns:
    A tuple of dummy variables and their initializer.

  Raises:
    RuntimeError: if collection to store gradients already exists and is not
    empty.
  z%tpu_embedding_dummy_table_variable_{}   TZ#tpu_embedding_dummy_table_variables)ZdtypeshapeZuse_resourceZ	trainabler    tpu_embedding_gradients_table_{}z.tpu_embedding_gradients_table_{} is not empty.c                 S   s   g | ]}d qS Nr	   )r
   r   r	   r	   r   r   [   s    z0create_dummy_table_variables.<locals>.<listcomp>Z(tpu_embedding_dummy_table_variables_init)name)r   r   	enumeratetable_to_features_dictr   Zget_variableformatr   Zfloat32r   get_default_graphZget_collection_refRuntimeErrorlenextendranger   Zvariables_initializerr   )tpu_embeddingdummy_table_variablestable_idtablegtable_gradientsZnum_featuresr	   r	   r   create_dummy_table_variables1   s6   r)   c                 C   sX   t  }|D ]#}| j| j}tj|| || t| j|| j	| |d||< q|S )a  Have activations depend on dummy table variables for gradient intercept.

  Args:
    tpu_embedding: TPUEmbedding, activations and dummy_table_variables are from
      tpu_embedding.
    activations: An OrderedDict of feature name String to activation tensors.
    dummy_table_variables: An OrderedDict of table name String to dummy table
      variables.

  Returns:
    An OrderedDict of feature name String to activation tensors, which can be
      used just as the activations input.
  )r%   Z	lookup_id)
r   r   feature_to_config_dictr%   r   Ztpu_embedding_activationslisttable_to_config_dictindexr   )r#   r   r$   Znew_activationsfeaturer&   r	   r	   r   )hook_dummy_table_variables_to_activationsc   s   r/   c                 C   s  t  }d}t| jD ])\}}|d|}tdd |D r)td|| |p3tdd |D }q|s<td t	
 }t| jD ]G\}}|d|}t| j| |D ]2\}}|durf|||< qY| j| j}	| j}
| j| j}|rt|
||	g||< qYt|
|	g||< qYqE|S )	a  Get gradients wrt the activations of each feature.

  Args:
    tpu_embedding: TPUEmbedding, create dummy table variable to be used with
      tpu_embedding.

  Returns:
    An OrderedDict mapping feature name to gradient.

  Raises:
    ValueError: if some gradients are not defined.
  Fr   c                 s   s    | ]}|d u V  qd S r   r	   r
   gradientr	   r	   r   	<genexpr>   s    z>get_gradients_through_dummy_table_variables.<locals>.<genexpr>a  Table {} with id {} has undefined gradients: this is probably because the model asked TPUEmbedding to compute activations that were not used, or tf.stop_gradient() is applied. Gradients of zeros are sent back to TPUEmbedding instead. Gradients of zeros and no gradients are equivalent for SGD, AdaGrad, FTRL, etc, but might differ for other optimizers due to implementation of TPU embedding optimizers.c                 s   s    | ]}|d uV  qd S r   r	   r0   r	   r	   r   r2      s    
zAll tables have undefined gradients: this is probably because the model asked TPUEmbedding to compute activations that were not used. If all TPUEmbedding features have stop_gradients, consider using the INFERENCE mode instead.N)r   r   r   r,   Zget_collectionr   anyloggingwarnr   r   r   r   	dimensionZbatch_size_per_corer*   max_sequence_lengthr   Zzeros)r#   r'   Zgradients_foundr%   r&   r(   r   r.   r1   r6   Z
batch_sizer7   r	   r	   r   +get_gradients_through_dummy_table_variables}   sR   





r8   )__doc__r   Ztensorflow.python.frameworkr   r   Ztensorflow.python.opsr   r   r   Ztensorflow.python.platformr   r4   Ztensorflow.python.tpu.opsr   r   r)   r/   r8   r	   r	   r	   r   <module>   s   2