a
    /Sic5}                     @   s  d Z ddl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gZedgddddZdddZdd ZG dd dejZ G dd dZ!G dd de Z"dS )z0Provides templates which allow variable sharing.    N)
checkpoint)context)function)ops)variable_scope)
tf_logging)base)object_identity)tf_contextlib)tf_decorator)
deprecated)	tf_exportmake_template)v1Fc                 K   s   t | ||||fddi|S )a  Given an arbitrary function, wrap it so that it does variable sharing.

  @compatibility(TF2)
  `tf.compat.v1.make_template` is a legacy API that is only compatible
  with eager execution enabled and `tf.function` if you combine it with
  `tf.compat.v1.keras.utils.track_tf1_style_variables`. See the model mapping
  migration guide section on `make_template` for more info:

  https://www.tensorflow.org/guide/migrate/model_mapping#using_tfcompatv1make_template_in_the_decorated_method

  Even if you use legacy apis for `variable_scope`-based variable reuse,
  we recommend using
  `tf.compat.v1.keras.utils.track_tf1_style_variables` directly and not using
  `tf.compat.v1.make_template`, as it interoperates with eager execution in a
  simpler and more predictable fashion than `make_template`.

  The TF2 API approach would be tracking your variables using
  `tf.Module`s or Keras layers and models rather than relying on
  `make_template`.
  @end_compatibility

  This wraps `func_` in a Template and partially evaluates it. Templates are
  functions that create variables the first time they are called and reuse them
  thereafter. In order for `func_` to be compatible with a `Template` it must
  have the following properties:

  * The function should create all trainable variables and any variables that
     should be reused by calling `tf.compat.v1.get_variable`. If a trainable
     variable is
     created using `tf.Variable`, then a ValueError will be thrown. Variables
     that are intended to be locals can be created by specifying
     `tf.Variable(..., trainable=false)`.
  * The function may use variable scopes and other templates internally to
      create and reuse variables, but it shouldn't use
      `tf.compat.v1.global_variables` to
      capture variables that are defined outside of the scope of the function.
  * Internal scopes and variable names should not depend on any arguments that
      are not supplied to `make_template`. In general you will get a ValueError
      telling you that you are trying to reuse a variable that doesn't exist
      if you make a mistake.

  In the following example, both `z` and `w` will be scaled by the same `y`. It
  is important to note that if we didn't assign `scalar_name` and used a
  different name for z and w that a `ValueError` would be thrown because it
  couldn't reuse the variable.

  ```python
  def my_op(x, scalar_name):
    var1 = tf.compat.v1.get_variable(scalar_name,
                           shape=[],
                           initializer=tf.compat.v1.constant_initializer(1))
    return x * var1

  scale_by_y = tf.compat.v1.make_template('scale_by_y', my_op, scalar_name='y')

  z = scale_by_y(input1)
  w = scale_by_y(input2)
  ```

  As a safe-guard, the returned function will raise a `ValueError` after the
  first call if trainable variables are created by calling `tf.Variable`.

  If all of these are true, then 2 properties are enforced by the template:

  1. Calling the same template multiple times will share all non-local
      variables.
  2. Two different templates are guaranteed to be unique, unless you reenter the
      same variable scope as the initial definition of a template and redefine
      it. An examples of this exception:

  ```python
  def my_op(x, scalar_name):
    var1 = tf.compat.v1.get_variable(scalar_name,
                           shape=[],
                           initializer=tf.compat.v1.constant_initializer(1))
    return x * var1

  with tf.compat.v1.variable_scope('scope') as vs:
    scale_by_y = tf.compat.v1.make_template('scale_by_y', my_op,
    scalar_name='y')
    z = scale_by_y(input1)
    w = scale_by_y(input2)

  # Creates a template that reuses the variables above.
  with tf.compat.v1.variable_scope(vs, reuse=True):
    scale_by_y2 = tf.compat.v1.make_template('scale_by_y', my_op,
    scalar_name='y')
    z2 = scale_by_y2(input1)
    w2 = scale_by_y2(input2)
  ```

  Depending on the value of `create_scope_now_`, the full variable scope may be
  captured either at the time of first call or at the time of construction. If
  this option is set to True, then all Tensors created by repeated calls to the
  template will have an extra trailing _N+1 to their name, as the first time the
  scope is entered in the Template constructor no Tensors are created.

  Note: `name_`, `func_` and `create_scope_now_` have a trailing underscore to
  reduce the likelihood of collisions with kwargs.

  Args:
    name_: A name for the scope created by this template. If necessary, the name
      will be made unique by appending `_N` to the name.
    func_: The function to wrap.
    create_scope_now_: Boolean controlling whether the scope should be created
      when the template is constructed or when the template is called. Default
      is False, meaning the scope is created when the template is called.
    unique_name_: When used, it overrides name_ and is not made unique. If a
      template of the same scope/unique_name already exists and reuse is false,
      an error is raised. Defaults to None.
    custom_getter_: Optional custom getter for variables used in `func_`. See
      the `tf.compat.v1.get_variable` `custom_getter` documentation for more
      information.
    **kwargs: Keyword arguments to apply to `func_`.

  Returns:
    A function to encapsulate a set of variables which should be created once
    and reused. An enclosing scope will be created either when `make_template`
    is called or when the result is called, depending on the value of
    `create_scope_now_`. Regardless of the value, the first time the template
    is called it will enter the scope with no reuse, and call `func_` to create
    variables, which are guaranteed to be unique. All subsequent calls will
    re-enter the scope and reuse those variables.

  Raises:
    ValueError: if `name_` is None.
  create_graph_function_F)make_template_internal)name_func_create_scope_now_unique_name_custom_getter_kwargs r   Z/var/www/html/django/DPS/env/lib/python3.9/site-packages/tensorflow/python/ops/template.pyr   "   s     c                 K   s\   |rt |tj|fi |}t rH|dur6tdt| ||||dS t| |||||dS )a  Make a template, optionally compiling func_ into a graph function.

  See `make_template` for full documentation.

  Args:
    name_: A name for the scope created by this template. If necessary, the name
      will be made unique by appending `_N` to the name.
    func_: The function to wrap.
    create_scope_now_: Boolean controlling whether the scope should be created
      when the template is constructed or when the template is called. Default
      is False, meaning the scope is created when the template is called.
    unique_name_: When used, it overrides name_ and is not made unique. If a
      template of the same scope/unique_name already exists and reuse is false,
      an error is raised. Defaults to None. If executing eagerly, must be None.
    custom_getter_: Optional custom getter for variables used in `func_`. See
      the `tf.compat.v1.get_variable` `custom_getter` documentation for more
      information.
    create_graph_function_: When True, `func_` will be executed as a graph
      function. This implies that `func_` must satisfy the properties that
      `function.defun` requires of functions: See the documentation of
        `function.defun` for details. When executing eagerly, setting this flag
        to True can improve performance. Regardless of whether eager execution
        is enabled, enabling this flag gives the caller access to graph-function
        semantics, i.e., accesses to variables are totally ordered and
        side-effecting ops are not pruned.
    **kwargs: Keyword arguments to apply to `func_`.

  Returns:
    A function to encapsulate a set of variables which should be created once
    and reused. An enclosing scope will be created either when `make_template`
    is called or when the result is called, depending on the value of
    `create_scope_now_`. Regardless of the value, the first time the template
    is called it will enter the scope with no reuse, and call `func_` to create
    variables, which are guaranteed to be unique. All subsequent calls will
    re-enter the scope and reuse those variables.

  Raises:
    ValueError: if `name_` is None.
    ValueError: if `unique_name_` is not None and eager execution is enabled.
  Nz<unique_name_ cannot be used when eager execution is enabled.)create_scope_nowcustom_gettercreate_graph_function)r   unique_namer   r   )	r   make_decorator	functoolspartialr   executing_eagerly
ValueErrorEagerTemplateTemplate)r   r   r   r   r   r   r   r   r   r   r      s0    0r   c                 C   s@   t t| |D ]$\}\}}||kr| |d   S q| dd S )zGSkips items that the target stacktrace shares with the base stacktrace.N)	enumeratezip)Z
stacktraceZ	base_caseitracer   r   r   r   _skip_common_stack_elements   s    r*   c                   @   s   e Zd ZdZd&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ed"d#d$d% ZdS )'r$   a  Wrap a function to aid in variable sharing.

  Templates are functions that create variables the first time they are called
  and reuse them thereafter. See `make_template` for full documentation.

  Note: By default, the full variable scope is captured at the time of first
  call. If `create_scope_now_` is passed as True to the constructor, the full
  scope will be captured there, but no variables will created until the first
  call.
  FNc                 C   s   |rt || _n|| _t dd | _|| _|| _|| _|du rLt	d|rt
j| jpdt
| j| jd}|| _W d   q1 s0    Y  nd| _d| _d| _dS )a'  Creates a template for the given function.

    Args:
      name: A name for the scope created by this template. The name will be made
        unique by appending `_N` to the it (see how
        `tf.compat.v1.variable_scope` treats the `default_name` for details).
      func: The function to apply each time.
      create_scope_now: Whether to create the scope at Template construction
        time, rather than first call. Defaults to false. Creating the scope at
        construction time may be more convenient if the template is to passed
        through much lower level code, and you want to be sure of the scope name
        without knowing exactly where it will be first called. If set to True,
        the scope will be created in the constructor, and all subsequent times
        in `__call__`, leading to a trailing numeral being added to the names of
        all created Tensors. If set to False, the scope will be created at the
        first call location.
      unique_name: When used, it overrides `name` and is not made unique. If a
        template of the same scope/unique_name already exists and reuse is
        false, an error is raised. Defaults to None.
      custom_getter: optional custom getter to pass to `variable_scope()`
      create_graph_function: When True, `func` will be executed as a graph
        function. Enabling this flag gives the caller access to graph-function
        semantics, i.e., accesses to variables are totally ordered and
        side-effecting ops are not pruned.

    Raises:
      ValueError: if `name` is None.
    Nzname cannot be None.r   FT)r   defun_func	tracebackformat_stack_stacktrace_name_unique_name_custom_getterr"   r   _pure_variable_scope_get_unique_variable_scope_variable_scope_variables_created_first_call)selfnamefuncr   r   r   r   vsr   r   r   __init__  s(    #
&zTemplate.__init__c              
   C   s  z| j rtttjj}tttjj}| j|i |}ttjj}|t|krntd||d  f ttjj}|t|krt	
d||d   n|| jr
d| _z@tj| d  | j|i |}W d    n1 s0    Y  W n   d| _ Y n0 d| _ n| j|i |}|W S  ty } zl|j}|sBd}	n|d }	dt| jt }
d|	|
f }	|	g}||d	d   t||_ W Y d }~n
d }~0 0 d S )
NTrainable variable created when calling a template after the first time, perhaps you used tf.Variable when you meant tf.get_variable: %sNew variables created when calling a template after the first time, perhaps you used tf.Variable when you meant tf.get_variable: %sFtemplateT r   %s

originally defined at:
%s   )r8   lenr   get_collection_ref	GraphKeysGLOBAL_VARIABLESTRAINABLE_VARIABLESr.   r"   logginginfor9   trackable_utilcapture_dependencies	Exceptionargsjoinr*   r1   r/   r0   extendtupler:   rP   r   Zvars_at_startZtrainable_at_startresulttrainable_variables	variablesexcZarg0r)   new_argsr   r   r   
_call_funcJ  s`    
2
zTemplate._call_funcc                 O   s   | j rHtj| j | j d | ||W  d    S 1 s<0    Y  nHtj| j| j| jd"}|| _ | ||W  d    S 1 s0    Y  d S N)reuser,   )r7   r   r9   rZ   r3   r2   r4   r:   rP   r   r=   r   r   r   __call__  s    
,zTemplate.__call__c                 C   s   | j S )z(Returns the name given to this Template.)r2   r:   r   r   r   r;     s    zTemplate.namec                 C   s   | j S )z(Returns the func given to this Template.)r.   r_   r   r   r   r<     s    zTemplate.funcc                 C   s   | j S z;Returns the variable scope object created by this Template.r7   r_   r   r   r   r     s    zTemplate.variable_scopec                 C   s.   | j r*| j j}|r|d dkr"|S |d S dS )z9Returns the variable scope name created by this Template.r%   /N)r7   r;   )r:   r;   r   r   r   variable_scope_name  s
    zTemplate.variable_scope_namec                 C   s   | j | j S )zGReturns the list of global and local variables created by the Template.)global_variableslocal_variablesr_   r   r   r   rW     s    zTemplate.variablesc                 C   s    | j rttjj| jS g S dS )@Returns the list of trainable variables created by the Template.N)r8   r   get_collectionrH   rJ   rc   r_   r   r   r   rV     s
    
zTemplate.trainable_variablesc                    s"   | j }t| j  fdd|D S )DReturns the list of non-trainable variables created by the Template.c                    s   g | ]}| vr|qS r   r   ).0xrV   r   r   
<listcomp>      z4Template.non_trainable_variables.<locals>.<listcomp>)rd   setrV   )r:   rd   r   rk   r   non_trainable_variables  s    
z Template.non_trainable_variablesc                 C   s    | j rttjj| jS g S dS =Returns the list of global variables created by the Template.N)r8   r   rg   rH   rI   rc   r_   r   r   r   rd     s
    
zTemplate.global_variablesc                 C   s    | j rttjj| jS g S dS rp   )r8   r   rg   rH   LOCAL_VARIABLESrc   r_   r   r   r   re     s
    
zTemplate.local_variablesc                 C   s   | j S )z2List of weights/variables created by the Template.)rW   r_   r   r   r   weights  s    zTemplate.weightsc                 C   s   | j S )z<List of trainable weights/variables created by the Template.rk   r_   r   r   r   trainable_weights  s    zTemplate.trainable_weightsc                 C   s   | j S )z@List of non-trainable weights/variables created by the Template.)ro   r_   r   r   r   non_trainable_weights  s    zTemplate.non_trainable_weightsz
2017-02-21zbThe .var_scope property is deprecated. Please change your code to use the .variable_scope propertyc                 C   s   | j S r`   ra   r_   r   r   r   	var_scope  s    zTemplate.var_scope)FNNF)__name__
__module____qualname____doc__r>   rZ   r^   propertyr;   r<   r   rc   rW   rV   ro   rd   re   rs   rt   ru   r   rv   r   r   r   r   r$      sJ       
>@












r$   c                   @   sN   e Zd ZdZdd Zdd Zejdd Zdd	 Z	d
d Z
dd Zdd ZdS )_EagerTemplateVariableStorezDWrapper around EagerVariableStore to support nesting EagerTemplates.c                 C   s6   || _ t }|jr"t|| _n
t | _d| _d S )NF)_variable_scope_namer   _get_default_variable_store_store_eager_variablesEagerVariableStore_eager_variable_store
_used_once)r:   rc   defaultr   r   r   r>     s    
z$_EagerTemplateVariableStore.__init__c                 C   s
   || _ d S N)r}   )r:   rc   r   r   r   set_variable_scope_name  s    z3_EagerTemplateVariableStore.set_variable_scope_namec              	   c   s   zx| j s$t }|jr|| j_d| _ | j  d V  W d    n1 sJ0    Y  W | jd u rhtdt	 
| j n$| jd u rtdt	 
| j 0 d S )NTzPA variable scope must be set before an _EagerTemplateVariableStore object exits.)r   r   r~   r   r   _store
as_defaultr}   RuntimeErrorget_variable_scope_storeclose_variable_subscopes)r:   r   r   r   r   r     s$    &	

z&_EagerTemplateVariableStore.as_defaultc                    s$    j d u rtd fdd|D S )Nz>A variable scope must be set before variables can be accessed.c                    s"   g | ]}|j  jd  r|qS )rb   )r;   
startswithr}   )ri   vr_   r   r   rl   #  s   zC_EagerTemplateVariableStore._variables_in_scope.<locals>.<listcomp>)r}   r   )r:   variable_listr   r_   r   _variables_in_scope  s    

z/_EagerTemplateVariableStore._variables_in_scopec                 C   s   |  | j S r   )r   r   rW   r_   r   r   r   rW   (  s    z%_EagerTemplateVariableStore.variablesc                 C   s   |  | j S r   )r   r   rV   r_   r   r   r   rV   +  s    z/_EagerTemplateVariableStore.trainable_variablesc                 C   s   |  | j S r   )r   r   ro   r_   r   r   r   ro   /  s    z3_EagerTemplateVariableStore.non_trainable_variablesN)rw   rx   ry   rz   r>   r   r
   contextmanagerr   r   rW   rV   ro   r   r   r   r   r|     s   
	r|   c                       sn   e Zd ZdZd f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  ZS )r#   a  Wrap a function to aid in variable sharing in Eager mode.

  Templates are functions that create variables the first time they are called
  and reuse them thereafter. See `make_template` for full documentation.

  Note: By default, the full variable scope is captured at the time of first
  call. If `create_scope_now` is passed as True to the constructor, the full
  scope will be captured there, but no variables will be created until the first
  call.
  FNc                    s`   t  stdt| tt| |||d|| | jdurH| jj	}nd}t
|| _d| _dS )a  Creates a template for the given function.

    Args:
      name: A name for the scope created by this template. The name will be made
        unique by appending `_N` to the it (see how
        `tf.compat.v1.variable_scope` treats the `default_name` for details).
      func: The function to apply each time.
      create_scope_now: Whether to create the scope at Template construction
        time, rather than first call. Defaults to false. Creating the scope at
        construction time may be more convenient if the template is passed
        through much lower level code, and you want to be sure of the scope name
        without knowing exactly where it will be first called. If set to True,
        the scope will be created in the constructor, and all subsequent times
        in `__call__`, leading to a trailing numeral being added to the names of
        all created Tensors. If set to False, the scope will be created at the
        first call location.
      custom_getter: optional custom getter to pass to `variable_scope()`
      create_graph_function: When True, `func` will be executed as a graph
        function. Enabling this flag allows the caller to reap the performance
        benefits associated with executing graphs, at the cost of sacrificing
        debuggability; however, not all Python functions can be compiled into
        graph functions. See the documentation for `function.defun` for details.

    Raises:
      RuntimeError: if eager execution is not enabled.
    zc{} objects can only be used when eager execution is enabled, use tf.Template for graph constructionN)r   r!   r   formattypesuperr#   r>   r7   r;   r|   _template_store_variable_scope_context_manager)r:   r;   r<   r   r   r   rc   	__class__r   r   r>   @  s     


zEagerTemplate.__init__c              
   C   s|  z| j  }| j  }| jr.| j|i |}n<tj| d  | j|i |}W d    n1 s`0    Y  | jr| j  }t|t|krtdt	t
|t
|  | j  }t|t|krtdt	t
|t
|  nd| _|W S  tyv } zl|j}|sd}	n|d }	dt| jt }
d|	|
f }	|	g}||dd   t||_ W Y d }~n
d }~0 0 d S )	NrA   r?   r@   TrC   r   rD   rE   )r   rW   rV   r8   r.   rM   rN   rF   r"   listr	   ObjectIdentitySetrK   rL   rO   rP   rQ   r*   r1   r/   r0   rR   rS   rT   r   r   r   rZ   o  s\    

.



zEagerTemplate._call_funcc              	   O   s"  | j r| js tj| j tjd| _| jT | j * | ||W  d    W  d    S 1 sb0    Y  W d    n1 s0    Y  ntj| j| j| j	dj}|| _ | j
|j | j * | ||W  d    W  d    S 1  s0    Y  W d    n1 s0    Y  d S r[   )r7   r   r   
AUTO_REUSEr   r   rZ   r3   r2   r4   r   r;   r]   r   r   r   r^     s"    XzEagerTemplate.__call__c                 C   s   | j s
g S | j S )z6Returns the list of variables created by the Template.)r8   r   rW   r_   r   r   r   rW     s    zEagerTemplate.variablesc                 C   s   | j s
g S | j S )rf   )r8   r   rV   r_   r   r   r   rV     s    z!EagerTemplate.trainable_variablesc                 C   s   | j s
g S | j S )rh   )r8   r   ro   r_   r   r   r   ro     s    z%EagerTemplate.non_trainable_variablesc                 C   s   | j s
g S | jS rq   )r8   rW   r_   r   r   r   rd     s    zEagerTemplate.global_variablesc                 C   s   g S r   r   r_   r   r   r   re     s    zEagerTemplate.local_variables)FNF)rw   rx   ry   rz   r>   rZ   r^   r{   rW   rV   ro   rd   re   __classcell__r   r   r   r   r#   4  s"      /;



r#   )FNN)FNNF)#rz   r   r/   tensorflow.python.checkpointr   rM   tensorflow.python.eagerr   r   tensorflow.python.frameworkr   tensorflow.python.opsr   tensorflow.python.platformr   rK   tensorflow.python.trackabler   	trackabletensorflow.python.utilr	   r
   r   "tensorflow.python.util.deprecationr    tensorflow.python.util.tf_exportr   __all__r   r   r*   	Trackabler$   r|   r#   r   r   r   r   <module>   s>   
        
F tA