a
    Sic%                     @   s   d Z ddlZddlZddlZddlZddlm  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 ed	e d
Zd ddZdd Zdd Zdd Zdd Zdd ZG dd dejZe Zejdd Zdd Z ejdd Z!dS )!zKUtility functions shared between SavedModel saving/loading
implementations.    N)backend)base_layer_utils)control_flow_util)layer_utils)tf_contextlib)
LazyLoadertraining_libzkeras.engine.trainingFc           	         sV   t }t||||\ } fdd}tjjj|||d}rNt|S |S dS )a  Creates fn that adds the losses returned by call_fn & returns the outputs.

    Args:
      layer: A Keras layer object
      call_fn: tf.function that takes layer inputs (and possibly a training
        arg), and returns a tuple of (outputs, list of losses).
      call_spec: The `CallFunctionSpec` for the layer's call function.
      default_training_value: Default value of the training kwarg. If `None`,
        the default is `tf.keras.backend.learning_phase()`.
      return_method: Whether to return a method bound to the layer.

    Returns:
      function that calls call_fn and returns the outputs. Losses returned by
      call_fn are added to the layer losses.
    c                     sX   r| dd }  | i |\}} | t rT D ]}|ur<tjg|_q<|S )zNReturns the outputs from the layer call function, and adds the
        losses.   N)add_losstfexecuting_eagerly_flatten_layersr   REVIVED_LOSS_PLACEHOLDER_eager_losses)argskwargsoutputslossesifnlayerreturn_method Z/var/www/html/django/DPS/env/lib/python3.9/site-packages/keras/saving/saved_model/utils.pyreturn_outputs_and_add_losses;   s    

z7use_wrapped_call.<locals>.return_outputs_and_add_losses)targetdecorator_funcdecorator_argspecN)layer_uses_training_boolmaybe_add_training_argr   __internal__	decoratormake_decoratortypes
MethodType)	r   call_fn	call_specdefault_training_valuer   expects_training_argarg_specr   	decoratedr   r   r   use_wrapped_call#   s    r,   c                 C   s\   | j r
dS | h}t| }|rX| } | |v r.qt| ddr>dS ||  |t|  qdS )zLReturns whether this layer or any of its children uses the training
    arg.T_expects_training_argF)r-   list_all_layerspopgetattraddextend)r   visitedto_visitr   r   r   r   a   s    
r   c                 C   s(   t | tjr| jS t| jdddS d S )NF)include_self	recursive)
isinstancer   Modellayerslistr   )objr   r   r   r.   s   s    r.   c                 C   s.   t | g}|tjdd t| D  |S )Nc                 s   s   | ]}t |V  qd S N)list_all_layers_and_sublayers).0r   r   r   r   	<genexpr>   s   z0list_all_layers_and_sublayers.<locals>.<genexpr>)setupdate	itertoolschainfrom_iterabler.   )r;   sr   r   r   r=   |   s    
r=   c                    s:   |sdfS t  j}t|  fdd}||fS )a  Decorate call and optionally adds training argument.

    If a layer expects a training argument, this function ensures that
    'training' is present in the layer args or kwonly args, with the default
    training value.

    Args:
      call_spec: CallFunctionSpec of the layer.
      wrapped_call: Wrapped call function.
      expects_training_arg: Whether to include 'training' argument.
      default_training_value: Default value of the training kwarg to include in
        the arg spec. If `None`, the default is
        `tf.keras.backend.learning_phase()`.

    Returns:
      Tuple of (
        function that calls `wrapped_call` and sets the training arg,
        Argspec of returned function or `None` if the argspec is unchanged)
    Nc                     s   zj d dd}W n ty,   d}Y n0 |du rLpJt jpJt }t    fddt	
|fddfd	dS )
z<Wrap the `wrapped_call` function, and set training argument.trainingTinputs_in_argsNc                    s&   j d|  dd\}}|i |S )NrF   TrG   )set_arg_value)rF   new_args
new_kwargs)r   r'   r   wrapped_callr   r   replace_training_and_call   s    

zYmaybe_add_training_arg.<locals>.wrap_with_training_arg.<locals>.replace_training_and_callc                      s    dS NTr   r   rM   r   r   <lambda>       zHmaybe_add_training_arg.<locals>.wrap_with_training_arg.<locals>.<lambda>c                      s    dS )NFr   r   rO   r   r   rP      rQ   )get_arg_valueKeyErrorr   call_contextrF   r   learning_phaser:   copyr   
smart_cond)r   r   rF   r'   r(   rL   )r   r   rM   r   wrap_with_training_arg   s(    



z6maybe_add_training_arg.<locals>.wrap_with_training_arg)set_training_arg_specfull_argspecr   CallFunctionSpec)r'   rL   r)   r(   r*   rY   r   rX   r   r       s    
r    c                 C   s   d| j v rv| j d}t| j | }| jdur8t| jng }| jrt| j|kr||  du r||| < | j|dS n<d| jvr| jdg }t| jpi }||d< | j||dS | S )z.Set `training=DEFAULT` argument in an ArgSpec.rF   N)defaults)
kwonlyargskwonlydefaults)	r   indexlenr]   r:   _replacer^   rV   r_   )r*   r(   r`   training_default_indexr]   r^   r_   r   r   r   rZ      s*    


rZ   c                       s   e Zd Z fddZ  ZS )SaveOptionsContextc                    s   t    d| _d S rN   )super__init__save_traces)self	__class__r   r   rf      s    
zSaveOptionsContext.__init__)__name__
__module____qualname__rf   __classcell__r   r   ri   r   rd      s   rd   c                 c   s*   t j}z| t _d V  W |t _n|t _0 d S r<   _save_options_contextrg   )rg   previous_valuer   r   r   keras_option_scope   s
    rr   c                   C   s   t jS )zLWhether to trace layer functions-can be disabled in the save_traces
    arg.ro   r   r   r   r   should_save_traces   s    rs   c                 c   s0   t | dd}d| _zdV  W || _n|| _0 dS )a  A context that disables automatic dependency tracking when assigning attrs.

    Objects that inherit from Autotrackable automatically creates dependencies
    to trackable objects through attribute assignments, and wraps data
    structures (lists or dicts) with trackable classes. This scope may be used
    to temporarily disable this behavior. This works similar to the decorator
    `no_automatic_dependency_tracking`.

    Example usage:
    ```
    model = tf.keras.Model()
    model.arr1 = []  # Creates a ListWrapper object
    with no_automatic_dependency_tracking_scope(model):
      model.arr2 = []  # Creates a regular, untracked python list
    ```

    Args:
      obj: A trackable object.

    Yields:
      a scope in which the object doesn't track dependencies.
    _setattr_trackingTFN)r0   rt   )r;   rq   r   r   r   &no_automatic_dependency_tracking_scope   s
    ru   )NF)"__doc__rV   rB   	threadingr$   tensorflow.compat.v2compatv2r   kerasr   keras.enginer   keras.utilsr   r   r   keras.utils.generic_utilsr   globalsr   r,   r   r.   r=   r    rZ   localrd   rp   contextmanagerrr   rs   ru   r   r   r   r   <module>   s4    
>	@
	