a
    /Sic0<                 	   @   s  d Z ddlZddlZddlZddlZddlm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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dl"m+Z+ ddl"m,Z, ddl"m-Z- ddl"m.Z. dd l/m0Z0 dd!l/m1Z1 dd"l/m2Z2 dd#l/m3Z3 dd$l/m4Z4 dd%l/m5Z5 dd&l6m7Z8 dd'l9m:Z: dd(l;m<Z= dd)l>m?Z? dd*l@mAZA dd+l@mBZB dd,l@mCZC dd-l@mDZD dd.l@mEZE dd/l@mFZF dd0l@mGZG dd1l@mHZH dd2l@mIZI dd3lJmKZK eDLd4eM d5ZNeDLd6eM d7ZOd8ZPd9ZQd:ZRd;ZSeTd<d=ZUd>d? ZVd@dA ZWdBdC ZXddEdFZYdGdH ZZG dIdJ dJe[Z\e] Z^dKdL Z_dMdN Z`dOdP ZadQZbdRZcdSZddTdU ZedVdW ZfdXdY ZgG dZd[ d[e[ZhG d\d] d]e[Zid^d_ ZjG d`da dae[ZkeldbdcZmG ddde dee[ZnG dfdg dgenZoG dhdi dienZpG djdk dke[Zqe[ ZrG dldm dme?jse=jtZseAudne+jv eAudoe+jw eAudpe*jx G dqdr dre[Zydsdt Zzdudv Z{dwdx Z|ddzd{Z}eKd|g d}dd~dZ~G dd de[Zdd ZG dd de[ZG dd de[Zdd Zdd ZdS )z2Defun decorator for defining graph-mode functions.    N)List)map)attr_value_pb2)function_pb2)function_cache)
pywrap_tfe)pywrap_tf_session)backprop)backprop_util)context)execute)forwardprop_util)function_context)function_saved_model_utils)function_spec)
monitoring)tape)graph_placeholder)
c_api_util)composite_tensor)dtypes)error_interpolation)errors)
func_graph)indexed_slices)ops)tensor_shape)tensor_spec)	type_spec)	array_ops)default_gradient)functional_ops)gradients_util)handle_data_util)resource_variable_ops)
tf_logging)trace)base)core)_pywrap_utils)compat)function_utils)lazy_loader)memory)nest)object_identity)tf_decorator)
tf_inspect)	tf_exportag_ctxz'tensorflow.python.autograph.core.ag_ctx	np_arraysz)tensorflow.python.ops.numpy_ops.np_arraysforward_function_nameZbackward_function_name_implementsZshared_rendezvousz6/tensorflow/core/tf_function/graph_building_time_usecsz+Time for tf.function to build a graph (us).c                 C   sF   t | tjrt| j| jS t | tjr,| S t | t	j
r>| jS | S dS )zDReturns a TypeSpec for `x`, or `x` if `x` doesn't have a TensorSpec.N)
isinstancer   Tensorr   
TensorSpecshapedtyper   TypeSpecr   CompositeTensor
_type_specx rA   \/var/www/html/django/DPS/env/lib/python3.9/site-packages/tensorflow/python/eager/function.py_type_spec_fora   s    rC   c                 C   s   t | tjr| || kS dS )zHReturns true if `b` is a subset of type `a` (or if a is not a TypeSpec.)T)r7   r   r<   most_specific_compatible_type)abrA   rA   rB   _is_type_subsetp   s    rG   c                 C   s
  | d  u r|  krdu r8n nt d|  d| d| du rDdS t| tjsdtdt|  dt|tjstdt| d| j|jks| jdu rtdS g }t| j|jD ]H\}}||kst	|du st	|du r|
d q|
t	| qt|S )z>Find a `TensorShape` that is compatible with both `x` and `y`.NzXCannot find a common shape when LHS shape is None but RHS shape is not (or vice versa): z vs. .z$`x` must be a TensorShape, got type z$`y` must be a TensorShape, got type )RuntimeErrorr7   r   TensorShape	TypeErrortyperankzipdimsdimension_valueappend)r@   yrO   dim_xdim_yrA   rA   rB   common_shapew   s4    "
rU   Fc              	   C   sv   zt j| |dd W n ttfy,   Y dS 0 |rrt j| dd}t j|dd}tdd t||D rjdS ||kS dS )zECheck two structures for equality, optionally of types and of values.Texpand_compositesFc                 s   s"   | ]\}}t |t |kV  qd S NrL   ).0f1f2rA   rA   rB   	<genexpr>       z$is_same_structure.<locals>.<genexpr>)r.   assert_same_structure
ValueErrorrK   flattenanyrN   )Z
structure1Z
structure2check_valuesZ
flattened1Z
flattened2rA   rA   rB   is_same_structure   s    rd   c                 C   s   i }|   D ]\}}t|tjr*|||< qt|trFtj|d||< qt|trbtj|d||< qt|tr~tj|d||< qt|ttt	j
frtjt|d||< qtd| dt| dq|S )a  Convert the keyword arguments into function_def attributes.

  Currently only support primitive types: bool, int, float and string.

  Args:
    attributes: the dictionary of attributes.
  Returns:
    A dict of attributes where the key is the name of attribute and the value
      is the AttrValue proto.
  Raises:
    ValueError: If the kwargs contains unallowlisted name or unsupported value
      types.
  )rF   )i)f)sz
Attribute z5 must be bool, int, float, string, or AttrValue. Got rH   )itemsr7   r   	AttrValueboolintfloatstrbytessix	text_typer*   as_bytesr`   rL   )
attributesattrskeyvaluerA   rA   rB   _parse_func_attrs   s     




rv   c                   @   s.   e Zd ZdZdgZdd Zdd Zdd Zd	S )
_InterpolateFunctionErrorzFContext Manager that interpolates the exception from 'top_level_func'._funcc                 C   s
   || _ d S rX   )rx   )selfZtop_level_funcrA   rA   rB   __init__   s    z"_InterpolateFunctionError.__init__c                 C   s   d S rX   rA   ry   rA   rA   rB   	__enter__   s    z#_InterpolateFunctionError.__enter__c           
      C   s   |rt |tjsdS t|j}t|\}}}d }|D ]J}|jt	| j
jkrZ| j
j}q8|r8||j}	|	d ur8t |	tr8|	j}q8|rt|||_dS )NF)r7   r   OpErrorr*   as_textmessager   parse_messagenameas_strrx   graph_get_function_EagerDefinedFunctioninterpolate_message)
ry   typexctbr   _	func_tagsgZfunc_tag	next_funcrA   rA   rB   __exit__   s"    
z"_InterpolateFunctionError.__exit__N)__name__
__module____qualname____doc__	__slots__rz   r|   r   rA   rA   rA   rB   rw      s
   rw   c                 C   s   t |  dS )a  Add a callback function for Function creation.

  The callback function has the signature:

    `def function_callback(function, name, graph, inputs, outputs):`

  where:
  - `function`: _EagerDefinedFunction being created before finalizing the graph.
      Do not modify the function directly but instead modify the graph.
  - `name`: name of the function.
  - `graph`: Graph of the function.
  - `inputs`: `tuple` of tensors used as inputs to the function.
  - `outputs`: `tuple` of tensors used as outputs from the function.

  The callback is at the top of the `_EagerDefinedFunction` construction, giving
  callback an opportunity to make the last edits to the graph. Do not make
  changes to `graph, inputs`, and `outputs` manually, but, instead, set the
  `graph` as the default then define ops.

  Repeated registration of the same callback function is idempotent.
  After a callback is added, it can be removed with the
  `remove_function_callback()` method.

  Args:
    function_callback: The callback to add.
  N)_function_callbacksaddfunction_callbackrA   rA   rB   add_function_callback   s    r   c                 C   s   t |  dS )zRemove an already-added function callback.

  See the doc string of `add_function_callback()` for more information.

  Args:
    function_callback: The callback to remove.
  N)r   remover   rA   rA   rB   remove_function_callback  s    r   c                   C   s   t   dS )z9Clear all function callbacks, if any have been regisered.N)r   clearrA   rA   rA   rB   clear_function_callbacks  s    r   Z
__forward_Z__backward_Z__inference_c                 C   s   dt | t f S )z.The name of a generated forward defun named n.%s%s_%s)_FORWARD_PREFIXr   uidnrA   rA   rB   _forward_name  s    r   c                 C   s   dt | t f S )z/The name of a generated backward defun named n.r   )_BACKWARD_PREFIXr   r   r   rA   rA   rB   _backward_name  s    r   c                 C   s   dt | t f S )z4The name of a forward-but-no-gradient defun named n.r   )_INFERENCE_PREFIXr   r   r   rA   rA   rB   _inference_name"  s    r   c                   @   s&   e Zd ZdZdgZdd Zdd ZdS )_EagerDefinedFunctionDeleterz'Unregister function from eager context.r   c                 C   s
   || _ d S rX   r   )ry   r   rA   rA   rB   rz   ,  s    z%_EagerDefinedFunctionDeleter.__init__c                 C   s8   zt | j W n" ty"   Y n ty2   Y n0 d S rX   )r   remove_functionr   rK   AttributeErrorr{   rA   rA   rB   __del__/  s    z$_EagerDefinedFunctionDeleter.__del__N)r   r   r   r   r   rz   r   rA   rA   rA   rB   r   '  s   r   c                   @   sd   e Zd ZdZdd Zedd Zedd Zdd	 ZdddZ	edd Z
edd ZdddZd
S )r   ar  Callable with the interface of `framework.function._DefinedFunction`.

  `_EagerDefinedFunction` encapsulates a function definition and its properties,
  and it provides a method for calling the encapsulated function. Some Ops
  take functions as attributes, which have type `func`; an instance of this
  class may be provided as the value of these `func` attributes.
  c                    s<  t D ]}|| ||t|t| qtdd |D fdd| D }|j  durt fdd|D r fdd|D }tt|t|krg }ng }|j d}	t	
|	t|dd	d |D d
d |D dd |D |dd |jD g dtd}
W d   n1 s0    Y  t|
|| _| D ]&\}}| }t	|
t|| q4|  j}t|j| _t > t rt  t|
 t| j| _ d| _!W d   n1 s0    Y  t|j"| _#dd |j"D | _$dd |D | _%|j&| _'t(|| _)d| _*d| _+d| _,|| _-tdd |D | _.dS )a  Initializes an eager defined function.

    Args:
      name: str, the name for the created function.
      graph: Graph, the graph containing the operations in the function
      inputs: the tensors in the graph to be used as inputs to the function
      outputs: the tensors in the graph which will be outputs from the function
      attrs: dict mapping names of attributes to their AttrValue values
    c                 s   s   | ]}|j V  qd S rX   )oprZ   argrA   rA   rB   r]   X  r^   z1_EagerDefinedFunction.__init__.<locals>.<genexpr>c                    s   g | ]}| vr|qS rA   rA   rZ   r   )	input_opsrA   rB   
<listcomp>Y  r^   z2_EagerDefinedFunction.__init__.<locals>.<listcomp>Nc                 3   s   | ]}t | v V  qd S rX   r   	tensor_idrZ   tgraph_output_namesrA   rB   r]   ]  r^   c                    s    g | ]}t  t| qS rA   )r*   rq   r   r   r   r   rA   rB   r   ^  s   Fc                 S   s   g | ]
}|j qS rA   _c_oprZ   orA   rA   rB   r   l  r^   c                 S   s   g | ]}|  qS rA   _as_tf_outputr   rA   rA   rB   r   m  r^   c                 S   s   g | ]}|  qS rA   r   r   rA   rA   rB   r   n  r^   c                 S   s   g | ]
}|j qS rA   r   r   rA   rA   rB   r   p  r^    Tc                 S   s   g | ]
}|j qS rA   rY   r   rA   rA   rB   r     r^   c                 S   s   g | ]
}|j qS rA   r:   r   rA   rA   rB   r     r^   c                 s   s   | ]}|j r|V  qd S rX   )_is_statefulr   rA   rA   rB   r]     r^   )/r   tuplesetget_operationsZ_output_namesalllen_c_graphgetr   TF_GraphToFunction_wrapperr*   r   Zcontrol_outputsr   ScopedTFFunction_c_funcrh   SerializeToStringTF_FunctionSetAttrValueProto_get_definition	signaturerq   r   _namer   
init_scoper   executing_eagerlyensure_initializedadd_functionr   _function_deleterZ_registered_on_context
output_arg_num_outputs_output_types_output_shapesZcontrol_captures_control_captureslist_func_graph_outputsgrad_func_namepython_grad_func
_grad_funcr   _stateful_ops)ry   r   r   inputsoutputsrs   r   
operationsoutput_namesc_graphfn
attr_value
serializedr   rA   )r   r   rB   rz   K  sh    

$



&
z_EagerDefinedFunction.__init__c                 C   s,   z| j W S  ty$   | jj| _ Y n0 | j S rX   )
_signaturer   
definitionr   r{   rA   rA   rB   r     s
    z_EagerDefinedFunction.signaturec                 C   s,   z| j W S  ty$   |  | _ Y n0 | j S rX   )_definitionr   r   r{   rA   rA   rB   r     s
    z _EagerDefinedFunction.definitionc              	   C   s   t  P}| j }t|| W d    n1 s60    Y  t|}W d    n1 s^0    Y  t }|	t
| |S rX   )r   	tf_bufferr   r   r   TF_FunctionToFunctionDefTF_GetBufferr   FunctionDefParseFromStringr*   rq   )ry   buffer_func
proto_datafunction_defrA   rA   rB   r     s    
*(z%_EagerDefinedFunction._get_definitionNc                 C   sp   |s.t  r.t   }|| jsl|| j n>|| jsD||  | jj	
 D ]}||jsP|| qPdS )zAdd the function to the current context or a graph, if supplied.

    Args:
      g: the graph to add the function to. If not supplied, the function will
        be added to the current context.
    N)r   r   has_functionr   add_function_defr   _is_function_add_functionr   
_functionsvalues)ry   r   ctxrf   rA   rA   rB   add_to_graph  s    
z"_EagerDefinedFunction.add_to_graphc                 C   s   | j S rX   )r   r{   rA   rA   rB   r     s    z_EagerDefinedFunction.namec                 C   s   | j S rX   )r   r{   rA   rA   rB   stateful_ops  s    z"_EagerDefinedFunction.stateful_opsc                 C   s  t |t | jjkr:tdt t| jj dt | d|j}|jdu rTt }n|j}|j	pbd}|
 }d|d|f}|rt| X |du rtjt| jj| j|||d}	n tjt| jj| j||||d	}	W d   n1 s0    Y  |	pd}	nt|  t| jR t ( tj|| | j|||d
}	W d   n1 sF0    Y  W d   n1 sf0    Y  W d   n1 s0    Y  t| jD ]\}
}t||	|
  q|r|	S t| jD ]\}
}|	|
 | q|	S dS )a  Calls this function with `args` as inputs.

    `ConcreteFunction` execution respects device annotations only if the
    function won't be compiled with xla.

    Args:
      ctx: a Context object
      args: a list of arguments to supply this function with.
      cancellation_manager: a `CancellationManager` object that can be used to
        cancel function execution.

    Returns:
      The outputs of the function call.

    Raises:
      ValueError: if the number of arguments is incorrect.
      FunctionAlreadyGarbageCollectedError: if the function is no longer
        available to be called because it has been garbage collected.
    zSignature specifies z arguments, got: rH   Nr   executor_typeconfig_proto)num_outputsr   rs   r   )r   r   rs   r   cancellation_manager)argsrf   Ztoutr   configr   )r   r   	input_argr`   r   function_call_optionsconfig_proto_serializedr+   get_disabled_rewriter_configr   r   rw   r   rm   r   r   execute_with_cancellationr   control_dependenciesr   r   stop_recordingr!   partitioned_callr   	enumerater   r#   copy_handle_datar   	set_shape)ry   r   r  r  r  r  r   r   rs   r   re   func_graph_outputr:   rA   rA   rB   call  sd    





$


fz_EagerDefinedFunction.call)N)N)r   r   r   r   rz   propertyr   r   r   r   r   r   r  rA   rA   rA   rB   r   B  s   L




r   c           	      C   st   t |j}t| }|td tt|i}|| t||d}tt	|ji}|| t
|||j|j|}||fS )z@Creates forward and backward functions from the function graphs.N)rs   )r   r   dictpopIMPLEMENTS_ATTRIBUTE_NAMErv   FORWARD_FUNCTION_ATTRIBUTE_NAMEupdateConcreteFunction BACKWARD_FUNCTION_ATTRIBUTE_NAMEr   r   r   )	rs   forward_graphbackwards_graphr5   Zcommon_attributesZbackward_function_attrbackward_functionZforward_function_attrforward_functionrA   rA   rB   #_create_forward_backward_with_graph$  s(    


r  c                   @   sT   e Zd ZdZdd ZdddZdd Zd	d
 Zdd ZdddZ	dd Z
dd ZdS ) _DelayedRewriteGradientFunctionszACaches forward/backward functions with a delayed forward rewrite.c                 C   sT   i | _ || _tt| jj| j| jj| jj|| _|| _d| _	t
| jj| _|| _dS )z6Construct an inference function and initialize caches.N)_cached_function_pairs_func_graphr   r   r   r   r   _inference_function_attrsZ_gradient_namer   _num_inference_outputs_func_graph_deleter)ry   r   rs   func_graph_deleterrA   rA   rB   rz   A  s    z)_DelayedRewriteGradientFunctions.__init__Nc                 C   sJ   |du r| j }| j|}|dur&|S | |\}}||f| j|< ||fS )z9A possibly-cached pair of forward and backward functions.N)r#  r  r   _construct_forward_backward)ry   num_doutputsforward_backwardforwardbackwardrA   rA   rB   r(  R  s    z1_DelayedRewriteGradientFunctions.forward_backwardc              	      s  dd  j jd| D g }D ]}|tjt|  q" fdd} j   t	t
 j j}tj|j|g i ||d |j} fdd|D }t j j}|D ]$}	|	|vr||	  j j|	 qt j j |\}
}|
|fW  d   S 1 s0    Y  dS )aC  Constructs a pair of forward and backward functions.

    Args:
      num_doutputs: The constructed backprop function will take output gradients
        for the first `num_doutputs` outputs of the forward function. Defaults
        to the number of outputs for the inference function, but when
        higher-order gradients are computed this will increase to include side
        outputs.

    Returns:
      A pair of (forward_function, backward_function):
        forward_function: A re-generated inference function (an
          _EagerDefinedFunction) to account for new side outputs, if any extra
          were required when building the backward pass.
        backward_function: A ConcreteFunction that Takes `num_doutputs`
          arguments and returns gradients with respect to inputs of the forward
          function.
    c                 S   s   g | ]}t |r|qS rA   r
   IsTrainablerZ   outputrA   rA   rB   r   p  s   
zP_DelayedRewriteGradientFunctions._construct_forward_backward.<locals>.<listcomp>Nc                     sF   t d ( tj jj|  jdW  d    S 1 s80    Y  d S )Ngrad_ysZ	src_graph)r   devicer"   _GradientsHelperr   r   )r0  ry   trainable_outputsrA   rB   _backprop_functiony  s    zX_DelayedRewriteGradientFunctions._construct_forward_backward.<locals>._backprop_function)r   Zpython_funcr  kwargsr   r   c                    s(   g | ] }t |tjs|j ju r|qS rA   r7   r   EagerTensorr   r   rZ   cr{   rA   rB   r     s   )r   r   rQ   r   r9   r    shape_and_dtype
as_defaultfunc_graph_module	FuncGraphr   r   func_graph_from_py_funcexternal_capturesr/   ObjectIdentitySetr   r  r"  )ry   r'  r   r   r5  r  Zbackwards_graph_capturescaptures_from_forwardexisting_outputscapturer  r  rA   r3  rB   r&  ]  sF    



z<_DelayedRewriteGradientFunctions._construct_forward_backwardc                    sL  |  t|\}}|js|jS ||j |d|j |d|j	 |
|j	t|jd |jt|jd  tt|jD ] }|j| }t||j|  qttdd | jjD |j  fdd|jD }g }t|| jjD ]X\}	}
t|
rt|	tjr|t|	 q|	dur.||	 q|t|
 q|||S )zCAdd outputs to the forward call and feed them to the grad function.rf   ToutNc                 s   s   | ]}t |V  qd S rX   r   r   rA   rA   rB   r]     r^   zV_DelayedRewriteGradientFunctions._rewrite_forward_and_call_backward.<locals>.<genexpr>c                    s   g | ]}  t||qS rA   r   r   r   rZ   rD  capture_mappingrA   rB   r     s   zW_DelayedRewriteGradientFunctions._rewrite_forward_and_call_backward.<locals>.<listcomp>)r(  r   r   structured_outputsr   r   _set_func_attrr   _set_type_list_attrr   _add_outputsr   ranger   r#   r  r  rN   r   captured_inputsr
   r,  r7   r   IndexedSlicesrQ   r   convert_to_tensorr    
zeros_like
_call_flat)ry   r   Zdoutputsr  Zbackwards_functionre   r  remapped_capturesZcleaned_doutputsdoutputplaceholderrA   rH  rB   "_rewrite_forward_and_call_backward  s<    



zC_DelayedRewriteGradientFunctions._rewrite_forward_and_call_backwardc                 C   s   | j S )a  Returns gradient function.

    The gradient rewrites an inference call op to a forward call op, but does
    not modify a pre-existing forward call op. It then computes the gradient
    from the output's gradients and the side outputs of the forward op.
    )rW  r{   rA   rA   rB   get_gradient_function  s    z6_DelayedRewriteGradientFunctions.get_gradient_functionc                 C   s   ~|rt d| jS )a!  A forward function with only user-specified outputs.

    The call operation for the returned inference function can be rewritten into
    a forward function. This only happens if the backward function (from the
    `backward` method) ends up being used to compute gradients.

    This approach avoids constructing unnecessary graphs, but it only works if
    we are calling this function when not executing eagerly.

    Args:
      inference_args: A flat list of Tensors, arguments to the inference
        function. Unused, but taken for compatibility with
        _TapeGradientFunctions.
      input_tangents: A flat list of Tensors, jvps associated with
        `inference_args`. Unused; if required, tape functions must be used
        instead.

    Returns:
      An _EagerDefinedFunction.
    zVunexpectedly got forwardprop information in a class that does not support forwardprop.)r   InternalErrorr!  ry   inference_argsinput_tangentsrA   rA   rB   r)    s    
z(_DelayedRewriteGradientFunctions.forwardc                    s    fdd}| fS )zBFetch a backward function for `outputs` from the forward function.c                     s    d j }j|g| R  S )Nr   )r   rW  )r  Zcall_opr   ry   rA   rB   _backward_function  s    
zF_DelayedRewriteGradientFunctions._backward.<locals>._backward_functionrA   )ry   r   r^  rA   r]  rB   	_backward  s    z*_DelayedRewriteGradientFunctions._backwardc                 C   s,   |  |\}}t| jjj||| | dS )a<  Record the function call operation.

    _DelayedRewriteGradientFunctions supports only first-order backprop tape
    gradients (and then only when graph building). It does not work with
    higher-order tape gradients or forward autodiff, but does work with
    higher-order symbolic gradients (tf.gradients).

    Args:
      flat_outputs: The result of running `forward`.
      inference_args: A flat list of Tensors with inference inputs to the
        operation.
      input_tangents: A flat list of Tensors with input tangents consumed by the
        operation.
    N)r_  r   record_operationr!  r   r   ry   flat_outputsr[  r\  r  Z	to_recordrA   rA   rB   record  s
    z'_DelayedRewriteGradientFunctions.record)N)NN)r   r   r   r   rz   r(  r&  rW  rX  r)  r_  rc  rA   rA   rA   rB   r  >  s   
=,	
r  _ForwardWrapperr   r   output_indicesoutput_tangentsc                   @   sP   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd ZdS )_TapeGradientFunctionsa6  Caches forward and backward functions compatible with eager gradients.

  In contrast to the delayed-rewrite approach in
  `_DelayedRewriteGradientFunctions` which only works with delayed execution,
  the forward function generated by this class has a fixed set of outputs which
  may be preserved by a tape in order to compute gradients later.

  This class is abstract; its child classes differ in how many side outputs of
  the forward function their backward function accepts gradients for, which
  determines whether higher-order tape gradients are possible.
  c                 C   st   || _ d | _|| _d | _d | _t|j| _|| _|| _	d | _
d| _t|j| _tdd |jD | _|| _|| _d S )Nr   c                 S   s   g | ]}t |r|qS rA   r+  r   rA   rA   rB   r   3  r^   z3_TapeGradientFunctions.__init__.<locals>.<listcomp>)r   _forward_graphr"  _forwardr_  r   r   r   r$  _forwardprop_input_indices_forwardprop_output_indices_num_forwardprop_outputsr#   _num_trainable_inference_outputs_delayed_rewrite_functions_need_gradients_for_jvpsry   r   rs   r%  forwardprop_input_indicesdelayed_rewrite_functionsneed_gradients_for_jvpsrA   rA   rB   rz   $  s     z_TapeGradientFunctions.__init__c                    s   j j}g }g }t|D ]6\}}t|r|t||}|| || qt	t
 j j}	|	  g }
|D ]2}t|\}}t||}t|| |
| qttd( tj| j j|
 j d}W d   n1 s0    Y  |rtdd |} fdd|	jD }t j j}|D ](}||vr$||  j j| q$W d   n1 sd0    Y  |
|	j |	_|	jdd tj |d	d
D  ||	_!t" j# j |	\}}|s| j |ddfS  $||||} %||
|\}} &|}t" j#|j'|\}}t(|t(| t(|j'jkrht)*dt(|j'j dt(|t(|  dt(| dt(| d	||j'||j+t(|j,fS )zFForward+backward functions where the backward function sees `outputs`.Nr/  c                 S   s   | d urt | S d S rX   )r   rQ  r?   rA   rA   rB   <lambda>^  r^   zE_TapeGradientFunctions._build_functions_for_outputs.<locals>.<lambda>c                    s(   g | ] }t |tjs|j ju r|qS rA   r7  r9  r{   rA   rB   r   `  s   zG_TapeGradientFunctions._build_functions_for_outputs.<locals>.<listcomp>c                 s   s   | ]}|d ur|V  qd S rX   rA   )rZ   gradrA   rA   rB   r]   p  s   zF_TapeGradientFunctions._build_functions_for_outputs.<locals>.<genexpr>TrV   r   zThe forward graph had z inputs, but we expected  (z inference inputs and z input tangents).)-r   Zvariable_capturesr  r
   r,  r   idrQ   r=  r>  r   r   r<  r    r;  r   r#   r  r   r1  r"   r2  r   r.   map_structurer@  r/   rA  r   r   internal_capturesextendra   rJ  r  r"   _wrap_forward_function_with_jvps)_wrap_backward_function_with_jvp_backprop_shuffle_forward_outputsr   r   r   rY  rf  rg  )ry   r   r[  r\  Zhandles_to_variablesr4  Ztrainable_indicesindexr.  r  gradients_wrt_outputsgradient_shapegradient_dtypeZgradient_placeholdergradients_wrt_inputsrB  rC  rD  r  r  forward_wrapperwrapped_backwards_graphZwrapped_forward_functionZwrapped_backward_functionrA   r{   rB   _build_functions_for_outputs7  s    




$


2



z3_TapeGradientFunctions._build_functions_for_outputsc                    s  t t| jj   l t 
 dd | jjD }t	| jj
D ]d\}}tj|j|jd}|t|}	|	dur |	| |	jtjkrt|	| qH j
| qHt j
|D ](\}
}tjd|
g|gdd dd d	 qt|}| jD ]}|D ]\}} j
| }t j
|kr:td
| dt j
 dt |\}}t!||}|||  } || t"#|j$|j tjd|g|gdd dd d	 qq j
d| }| j%j&}t' (||d2 |)t** |}t+|tj,rg }W d   n1 s0    Y  | -| j||\}}W d   n1 s:0    Y  t.|j/j|||d t01|\}} fdd|D }W d   n1 s0    Y  t2 |||dS )z2Adds inline JVP computation to a forward function.c                 S   s   i | ]\}}t ||qS rA   r   )rZ   ZexternalinternalrA   rA   rB   
<dictcomp>  s   zK_TapeGradientFunctions._wrap_forward_function_with_jvps.<locals>.<dictcomp>)r;   r:   NZcaptured_valuec                 S   s   | gS rX   rA   r?   rA   rA   rB   ru    r^   zI_TapeGradientFunctions._wrap_forward_function_with_jvps.<locals>.<lambda>c                 S   s   | gS rX   rA   r?   rA   rA   rB   ru    r^   )r  r  z	Expected z forward graph inputs, got rH   c                 S   s   | gS rX   rA   r?   rA   rA   rB   ru    r^   c                 S   s   | gS rX   rA   r?   rA   rA   rB   ru    r^   PartitionedCallStatefulPartitionedCallc                    s   g | ]}  |qS rA   )rD  r   Zforward_wrapper_graphrA   rB   r     s   zK_TapeGradientFunctions._wrap_forward_function_with_jvps.<locals>.<listcomp>re  )3r=  r>  r   r   r   r<  r   Zpush_forwardprop_statecapturesr  r   r   rV  r;   r:   r   r   r   Zadd_capturer   resourcer#   r  rQ   rN   r   r`  r   rk  r   rY  r    r;  r   r   rJ   assert_is_compatible_withro  rW  get_default_graph_override_gradient_functionr  r   r7   	Operation_wrap_backward_function!record_operation_forwardprop_onlyr   r   TFE_Py_PackJVPsrd  )ry   r  r  r[  r\  Zforward_capturesinput_indexZ
real_inputinput_placeholderrD  inpr   Znum_inference_inputsZtape_indicesZ	jvp_indexr  r  Zjvp_placeholderZexternal_jvpZforward_inputsgradient_functionZforward_outputspy_backwardr   rf  rg  rA   r  rB   r|    s    






$(

&z7_TapeGradientFunctions._wrap_forward_function_with_jvpsc              	      sx  t t| jj}|  | | j| j\}}d}g }g }	|D ]L}
t	|
r|| }t
|j|j}|	| || |d7 }qD|	d qD||	 }t j j }d}g }g } j} j}| jr|t|kr||d D ]0}
t|
\}}t
||}|| || qt|}td( tj| jj| jd}W d   n1 sZ0    Y  dd t||D }||t|d   fdd|jD }|D ]&}||vr||  j| qt ! j\}} fdd|D }|D ]}|| qqW d   n1 s0    Y  |d| j" | || j"d  |j# |_||_$d	d |D |_| j%||d
fS )z8Wraps `backward_function` to include gradients for JVPs.r      Nr/  c                 S   s.   g | ]&\}}|d us|d urt ||fqS rX   )r	   Z"aggregate_indexed_slices_gradients)rZ   existingnewrA   rA   rB   r   "  s   zT_TapeGradientFunctions._wrap_backward_function_with_jvp_backprop.<locals>.<listcomp>c                    s(   g | ] }t |tjs|j ju r|qS rA   r7   r   r8  r   r9  r  rA   rB   r   '  s   c                    s   g | ]} j |qS rA   )r   rD  r   r  rA   rB   r   1  s   c                 S   s   g | ]}|d ur|qS rX   rA   r   rA   rA   rB   r   ;  r^   )rf  rg  )&r=  r>  r   r   r   r<  r  r   r
   r,  r   r;   r:   rQ   r/   rA  rg  rf  rp  r   r    r;  r   r1  r"   r2  r   r   rN   r{  r@  r   r   pack_tangentsrn  rz  rJ  _replace)ry   r  r  r  r  r  recorded_outputsZtrainable_indexZforward_doutputsZdoutput_argsr.  rU  Zdoutput_placeholderZdinputsrC  Znum_processed_output_tangentsZgradients_wrt_output_tangentsZtangent_doutputsrg  rf  r  r  rV  r  rB  rD  r   rA   r  rB   r}    s    








&




0z@_TapeGradientFunctions._wrap_backward_function_with_jvp_backpropc                    sR    fdd}t | j} jdj  j  jjd   j_ j|dS )z/Reorders function outputs so captures are last.c                    s>   | j k r| S | t jkr0| t j j  S | t j S rX   )r#  r   r   rg  )originalr  ry   rA   rB   
_index_mapB  s    
zC_TapeGradientFunctions._shuffle_forward_outputs.<locals>._index_mapN)rf  )r.   ry  rf  r   r#  rg  r   r  )ry   r  r  rf  rA   r  rB   r~  @  s    z/_TapeGradientFunctions._shuffle_forward_outputsc                 C   s0   | j du r*| ||\| _ | _| _| _| _| j S )a  Construct or fetch a forward function with side-outputs.

    When graph building without a tape active, symbolic gradients rely on
    regenerating the backward function for higher-order gradients (to account
    for new side outputs of the rewritten forward function call). Thus there is
    no fixed backward function for this case. However, when a tape is active
    (eager or graph building), we generate fixed backward and forward functions
    at forward function call time.

    This difference between the tape and non-tape cases is to avoid building
    unneeded backward functions while graph building (where we may or may not
    eventually need gradients).

    Args:
      inference_args: A flat list of Tensors, arguments to the inference
        function.
      input_tangents: A flat list of Tensors, jvps associated with
        `inference_args`.

    Returns:
      A forward _EagerDefinedFunction.
    N)rj  _forward_and_backward_functionsri  r_  rl  rm  rZ  rA   rA   rB   r)  Q  s
    

z_TapeGradientFunctions.forwardc                    s:  t tdd jD | j}fdd|D tfddD rlfddD }td| di t jt| g }d	}g | j	r| j
s|d
| j || j| j	 d
  }n|}t|D ]R\}	}
|k r||
 t|
r|d7 }n
|	 |
jtjkrt|
|	< qʇ fdd}||fS )zECreate a backward function given `outputs` from the forward function.c                 s   s   | ]}t |V  qd S rX   r   r   rA   rA   rB   r]   q  r^   zA_TapeGradientFunctions._wrap_backward_function.<locals>.<genexpr>c                    s   g | ]}  t||qS rA   rF  rG  rH  rA   rB   r   s  s   zB_TapeGradientFunctions._wrap_backward_function.<locals>.<listcomp>c                 3   s$   | ]}t |tjs|j u V  qd S rX   r  r   r  rA   rB   r]   w  s   c                    s&   g | ]}t |tjs|j ur|qS rA   r  r   r  rA   rB   r   y  s   
zTFailed to map all backward graph captures to the forward graph. Incorrectly mapped: rH   r   Nr  c                     s    j s jS g }d}t| D ]~\}}t|tjr:t|}|v rDq|du r| j| }|j	t
jkrl| }ntjt| }|| |d7 }|kr qq |S )z8Process output gradients and call the backward function.r   Nr  )r   rJ  r  r7   r   rP  r   rQ  r   r;   r   variantr   zerosr    r;  rQ   rS  )r  Zprocessed_argsr  output_indexr   r  )r*  backward_function_inputsrT  skip_positionsvariant_zeros_likerA   rB   _backward_function_wrapper  s2    


zR_TapeGradientFunctions._wrap_backward_function.<locals>._backward_function_wrapper)r  rN   r   rO  rb   r   rY  r   r   rm  rp  r#  r  rQ   r
   r,  r;   r   r  r    rR  )ry   r  r*  r   rO  Zincorrect_mappingr  Ztrainable_recorded_outputsZrelevant_outputsr  r.  r  rA   )r*  r  rI  r  rT  r  r  rB   r  n  sF    





"z._TapeGradientFunctions._wrap_backward_functionc                 C   sp   |  | j| j|\}}| jrRt| jjj||| t	| jjj||| || j nt
| jjj||| | dS )a  Record the function call operation.

    For backprop, indicates the backward function to use and which new Tensors
    must be watched. For forwardprop from eager, the function call itself will
    have produced tangents which need to be recorded.

    Args:
      flat_outputs: The result of running `forward`.
      inference_args: A flat list of Tensors with inference inputs to the
        operation.
      input_tangents: A flat list of Tensors with input tangents consumed by the
        operation.
    N)r  ri  r_  rl  r   record_operation_backprop_onlyrj  r   r   r  r`  ra  rA   rA   rB   rc    s&    
z_TapeGradientFunctions.recordN)r   r   r   r   rz   r  r|  r}  r~  r)  r  rc  rA   rA   rA   rB   rh    s   _^LNrh  c                       s(   e Zd ZdZ fddZdd Z  ZS ) _FirstOrderTapeGradientFunctionsz9Caches tape-friendly functions for first-order gradients.c                    s*   t t| |||||| || _|| _d S rX   )superr  rz   r$  rk  rq  	__class__rA   rB   rz     s    
z)_FirstOrderTapeGradientFunctions.__init__c                 C   s    | j jd| j }| |||S )ay  Shortcut for when only first-order gradients are required.

    The returned backward function does not accept gradients with respect to
    side output of forward_function. This is fine as long as the user can't
    possibly request second order tape gradients, as when they've used a single
    non-persistent GradientTape. Since we don't need the backward function to
    take gradients with respect to side outputs, we can skip some potentially
    slow graph building.

    Args:
      inference_args: A flat list of Tensors, arguments to the inference
        function.
      input_tangents: A flat list of Tensors, jvps associated with
        `inference_args`.

    Returns:
      A tuple of (forward_function, backward_function):
        forward_function: Takes the same inputs as the inference function, but
          returns side outputs used by backward_function in addition to the
          inference function's outputs.
        backward_function: Takes side outputs from forward_function and
          gradients with respect to the "real" outputs of forward_function and
          returns gradients with respect to the inputs.
    N)r   r   r#  r  )ry   r[  r\  r   rA   rA   rB   r    s    z@_FirstOrderTapeGradientFunctions._forward_and_backward_functions)r   r   r   r   rz   r  __classcell__rA   rA   r  rB   r    s   	r  c                   @   s   e Zd ZdZdd ZdS )!_HigherOrderTapeGradientFunctionsz:Caches tape-friendly functions for higher-order gradients.c                 C   sL  g }d}t |t | jjk rtdd | jjt |d D r|d7 }|dkr|d dkrd}d}| jjt |d D ]}t|rv|d7 }|j}qvtd	| jj
||| t| jj}| ||| q| |||\}}	}
}}t | jjt |kr>td	d | jjt |d D r>td
| jjt |d  d||	|
||fS )a  Forward and backward functions suitable for higher-order gradients.

    Unlike in `_FirstOrderTapeGradientFunctions`, the backward function built by
    this method accepts gradients for all of the outputs of the returned forward
    function, including side outputs.

    Args:
      inference_args: A flat list of Tensors, arguments to the inference
        function.
      input_tangents: A flat list of Tensors, jvps associated with
        `inference_args`.

    Returns:
      A tuple of (forward_function, backward_function):
        forward_function: Takes the same inputs as the inference function, but
          returns side outputs used by backward_function in addition to the
          inference function's outputs.
        backward_function: Takes side outputs from forward_function and
          gradients with respect to all of its outputs, real and side. Returns
          gradients with respect to the inputs.
    r   c                 s   s   | ]}t |V  qd S rX   r+  r-  rA   rA   rB   r]   5  s   zT_HigherOrderTapeGradientFunctions._forward_and_backward_functions.<locals>.<genexpr>Nr        a  Determining side outputs for the function '{}' is taking longer than expected ({} iterations, typically this converges in 5 or so). This could indicate that a gradient registration is adding new ops to the forward pass every time gradients are generated. {} new trainable output(s) were added this iteration, one from the following op:
 {}
This may indicate a TensorFlow bug, or an issue in a tf.custom_gradient.c                 s   s   | ]}t |V  qd S rX   r+  r-  rA   rA   rB   r]   S  s   z\Unexpectedly added new outputs to the forward function when building the backward function: rH   )r   r   r   rb   r
   r,  r   loggingwarningformatr   r   r  r   rY  )ry   r[  r\  r   Ziteration_countZnew_op_with_trainable_outputZnum_new_trainable_outputsr.  r  r  r  rf  Znum_output_tangentsrA   rA   rB   r    sV    
zA_HigherOrderTapeGradientFunctions._forward_and_backward_functionsN)r   r   r   r   r  rA   rA   rA   rB   r    s   r  c                   @   s0   e Zd ZdZg dZdd Zdd Zdd Zd	S )
_ForwardBackwardCallzCHolds the state of a function call between execution and recording.r   _inference_args_input_tangents_tape_watchingc                 C   s   || _ || _|| _|| _dS )a  Collects information about the function call.

    Args:
      functions: An object which produces forward and backward functions, either
        a _DelayedRewriteGradientFunctions or a _TapeGradientFunctions object.
      inference_args: A flat list of Tensors, arguments to the inference
        function.
      input_tangents: A flat list of Tensors, jvps associated with
        `inference_args`.
      tape_watching: Boolean, with True indicating that recording is necessary.
    Nr  )ry   	functionsr[  r\  tape_watchingrA   rA   rB   rz   d  s    z_ForwardBackwardCall.__init__c                 C   s"   | j | j| j}|| j| j fS )z5Builds or retrieves a forward function for this call.)r   r)  r  r  )ry   r  rA   rA   rB   r)  u  s    z_ForwardBackwardCall.forwardc                 C   s2   | j r.t|tjs.|dur.| j|| j| j dS )zEGiven outputs from the execution of `forward`, records the operation.N)r  r7   r   r  r   rc  r  r  )ry   rb  rA   rA   rB   rc  {  s    

z_ForwardBackwardCall.recordN)r   r   r   r   r   rz   r)  rc  rA   rA   rA   rB   r  ]  s
   r  c                   @   s  e Zd ZdZdZddZdd Zdd	 Zed
d Zdd Z	edd Z
dd Zd[ddZdd Zdd Zdd Zdd Zdd Zdd Zd\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d0d1 Zd]d2d3Zed4d5 Zed6d7 Zed8d9 Zed:d; Z d^d<d=Z!d_d>d?Z"d@dA Z#dBdC Z$dDdE Z%edFdG Z&d`dIdJZ'dKdL Z(dadMdNZ)dOdP Z*dQdR Z+dbdTdUZ,dVdW Z-dXdY Z.dS )cr  zFA `tf.types.experimental.ConcreteFunction` created from `tf.function`.NTc                 C   s   d| _ d| _|| _| jj| jj | _| | |r~t|v r~tdd | j	D }t|| jfr~J dj
|jt|t | j	| jdtdd | jjD | _t|pi | _|rd| _n
t|| _t|| j| j| _i | _i | _| j | _dS )a  Initialize a `ConcreteFunction`.

    Args:
      func_graph: An instance of FuncGraph: the function body to wrap.
      attrs: (optional) dict mapping names of attributes to their AttrValue
        values. Attributes in `attrs` will be included in this function's
        definition.
     shared_func_graph: If False, the ConcreteFunction takes ownership of
       `func_graph` and will break reference cycles when it is deleted. This
       makes the FuncGraph inoperable.
     spec: FunctionSpec for the original function.  If not specified,
       then this ConcreteFunction may only be called using the flat signature.

    Raises:
      ValueError: If number of input_placeholders is not equal to the number
        of function inputs.
    Nc                 s   s   | ]}|j tjkV  qd S rX   )r;   r   r  )rZ   r  rA   rA   rB   r]     s   z,ConcreteFunction.__init__.<locals>.<genexpr>aQ  Function {name} has "{attr}={value}" attribute and thus can not depend on any tensors outside of its signature or modify variables. 

Note: variables are always captured and cause function re-tracing for every variable called.
  inputs: {inputs}
  captures: {captured}

To pass a variable to such function use  use variable.read_value().)r   attrru   r   capturedc                 s   s   | ]}|j V  qd S rX   r   r-  rA   rA   rB   r]     s   )_arg_keywords_num_positional_argsr   r@  Zdeferred_external_captures_captured_inputs_set_function_specr  rb   r   r  r   r   r   r   rv   r"  _garbage_collector ConcreteFunctionGarbageCollectorr  ro  _first_order_tape_functions_higher_order_tape_functionsr)  r!  )ry   r   rs   shared_func_graphspecZhas_resource_varsrA   rA   rB   rz     s>    
	


zConcreteFunction.__init__c                 C   s   d| _ || _|   dS )z5Enables the structured signature by supplying a spec.N)_function_spec_pre_initialized_function_spec_initialize_function_spec)ry   r  rA   rA   rB   r    s    z#ConcreteFunction._set_function_specc              	   C   s   | j du rdS | jrJ d| j }|jj}| j\}}tt|jt|}tj	t
|dd |D  ddtgt| t
t|tdd |D |jjd}tj||j|j|j| jjd| _dS )	a  Updates `self._function_spec` to include varargs and bound variables.

    Adds new positional arguments for any varargs (i.e., for args that are
    in `structured_input_signature`, but not in the original fullargspec.args).

    Replaces `defaults` and `kwonlydefaults` with the `_BOUND_VALUE`, for
    all args and kwargs in `structured_input_signature`.

    Sets `varkw` and `varargs` to None.
    Nzalready initializedc                 S   s   g | ]}d  |d qS )<arg{}>r  r  rZ   re   rA   rA   rB   r     r^   z>ConcreteFunction._initialize_function_spec.<locals>.<listcomp>c                 s   s   | ]}|t fV  qd S rX   )_BOUND_VALUE)rZ   krA   rA   rB   r]     r^   z=ConcreteFunction._initialize_function_spec.<locals>.<genexpr>)r  varargsvarkwdefaults
kwonlyargskwonlydefaultsannotationsr   )r  r  fullargspecr  structured_input_signaturerN  r   	arg_namesr1   FullArgSpecr   r  sortedr  r  r   FunctionSpec	is_methodinput_signatureis_purer   r   )ry   r  r  	arg_specskwarg_specsZvararg_indicesr  rA   rA   rB   r    s.    


z*ConcreteFunction._initialize_function_specc                 C   s   t | jjS )z(Sequence of variables for this function.)r   r   	variablesr{   rA   rA   rB   r    s    zConcreteFunction.variablesc                 C   s   || j _d S rX   )r   r  )ry   r  rA   rA   rB   set_variables
  s    zConcreteFunction.set_variablesc                 C   s   t | jjS )z2Sequence of trainable variables for this function.)r   r   trainable_variablesr{   rA   rA   rB   r    s    z$ConcreteFunction.trainable_variablesc                 O   s   |  ||S )a5  Executes the wrapped function.

    ConcreteFunctions have two signatures:

    * The signature of the original function wrapped by this ConcreteFunction.
    * A flat signature, where each argument accepts a single Tensor.

    The original function signature is generally preferred, but the flat input
    signature is supported for backward compatibility.

    ### Original Function Signature

    When calling a ConcreteFunction with the signature of the original function,
    each argument must match the type or value that was used when the
    ConcreteFunction's graph was traced.  In particular:

    * Tensor arguments (including CompositeTensors, such as RaggedTensor) must
      have matching `TypeSpec`s.
    * Non-Tensor arguments (such as booleans or ints) must have equal values.
    * Nested arguments (such as lists, tuples, or dictionaries) must have the
      same nesting structure; and each nested value must have a matching type
      or value.

    The default value for any arguments that were traced with non-Tensor values
    is the value that was used in the trace.  Arguments that were traced with
    tensor arguments do not have a default value (even if the original function
    had a default value for that argument).

    ### Flat Signature

    When calling a ConcreteFunction with the flat signature, the arguments
    correspond to the flattened component tensors of the arguments that were
    used to construct the ConcreteFunction.  Parameter names are assigned based
    on `TensorSpec.name` (when specified) or the original argument names (with
    suffixes automatically added for nested arguments or composite tensors with
    multiple components).

    Args:
      *args: Positional arguments to the concrete function.
      **kwargs: Keyword arguments to the concrete function.

    Returns:
      The result of applying the TF function on the given Tensors.

    Raises:
      AssertionError: If this `ConcreteFunction` was not created through
        `get_concrete_function`.
      TypeError: If the arguments do not match the function's signature.
    
_call_impl)ry   r  r6  rA   rA   rB   __call__  s    2zConcreteFunction.__call__c                 C   s   t j| jjdd | jdurz| |||W W  d   S  ty } zNz*| |||W W  Y d}~W  d   S  ty   |Y n0 W Y d}~n
d}~0 0 | |||W  d   S 1 s0    Y  dS )zSee `__call__` for details.concrete)tf_function_callN)r&   Tracer   r   r  _call_with_structured_signaturerK   _call_with_flat_signature)ry   r  r6  r  Zstructured_errrA   rA   rB   r  F  s    
  zConcreteFunction._call_implc              
   C   s  t || jkr2t|   d| j dt | dt|}t|}| jt |d D ]}z||t	
| W qT ty   t| jdt | t|  }tt| jt| }t|   dd| dY qT0 qT|rFt| jdt | }|D ]$}||v rt|   d| dqt|   d	dt| dt|D ]H\}	}
t|
tjtjfsNt|   d
|	 dt|
j d|
 dqN| || j|S )a  Executes the wrapped function with the flat signature.

    Args:
      args: Positional arguments to the concrete function.
      kwargs: Keyword arguments to the concrete function.
      cancellation_manager: A `CancellationManager` that can be used to cancel
        function invocation.

    Returns:
      The result of applying the function on the Tensors/Variables contained in
      `args` and `kwargs`.
    Raises:
      TypeError: if `args` and `kwargs` do not match the flat signature of this
        `ConcreteFunction`.
     takes z positional arguments, got rH   N missing required arguments: , z got two values for 'z'.# got unexpected keyword arguments: z: expected argument #z!(zero-based) to be a Tensor; got rw  ).)r   r  rK   _flat_signature_summaryr   r  r  rQ   r  r*   r   KeyErrorkeysr  r   joinr  r7   r   r8   r$   BaseResourceVariablerL   r   rS  rO  )ry   r  r6  r  keywordZspecified_keywordsZmissing_required_argsZpositional_arg_keywords
unused_keyre   r   rA   rA   rB   r  X  sT     
z*ConcreteFunction._call_with_flat_signaturec                 C   sN   | j j|i |\}}}| || | || | || | j|| j|dS )a$  Executes the wrapped function with the structured signature.

    Args:
      args: Positional arguments to the concrete function.
      kwargs: Keyword arguments to the concrete function.
      cancellation_manager: A `CancellationManager` that can be used to cancel
        function invocation.

    Returns:
      The result of applying the function on the Tensors/Variables contained in
      `args` and `kwargs`.
    Raises:
      TypeError: if `args` and `kwargs` do not match the structured signature
        of this `ConcreteFunction`.
    )rO  r  )r  canonicalize_function_inputs(_structured_signature_check_missing_args+_structured_signature_check_unexpected_args%_structured_signature_check_arg_typesrS  rO  )ry   r  r6  r  filtered_flat_argsrA   rA   rB   r    s    z0ConcreteFunction._call_with_structured_signaturec           
      C   s   | j \}}g }tt||D ].\}\}}|tu rt|r|| jj|  q| D ]&\}	}|tu rTt||	 rT||	 qT|rt	| 
  ddt| ddS )z+Raises a TypeError if any args are missing.r  r  rH   N)r  r  rN   r  _contains_type_specrQ   r  r  rh   rK   _structured_signature_summaryr  r  )
ry   r  r6  r  r  Zmissing_argumentsre   r   r  r   rA   rA   rB   r    s    
z9ConcreteFunction._structured_signature_check_missing_argsc                 C   s   | j \}}t|t|krDt|   dt| jj dt| dt|t|krt|t| }t|   dd| ddS )z/Raises a TypeError if there are any extra args.r  z positional arguments but got rH   r  r  N)r  r   rK   r  r  r  r   r  )ry   r  r6  r  r  
extra_argsrA   rA   rB   r     s    


z<ConcreteFunction._structured_signature_check_unexpected_argsc           	      C   sh   | j \}}tt||D ]&\}\}}| jj| }| ||| q| D ]\}}| ||| | qHdS )z3Raises a TypeError if any args have the wrong type.N)r  r  rN   r  r  $_structured_signature_check_arg_typerh   )	ry   r  r6  r  r  re   r   r  r   rA   rA   rB   r    s    
z6ConcreteFunction._structured_signature_check_arg_typesc                 C   s  |t u rdS ztj||dd W n ttfy   ztj||dd || }}W n( ttfyx   t|t| }}Y n0 t|   d| d| d| Y n0 tj|dd}tj|dd}t||D ]\}}	t	|	t
jr"tjtjf}
t	||
st|   d| d	t|j d
| dq|t urzt||	k}W n, ttfyf   tjdddd d}Y n0 |std|   dt|	j d
|	 d| dt|j d
| dqdS )z5Raise TypeError if `arg`'s type doesn't match `spec`.NTrV   Fz: argument z  had incorrect type
  expected: z
       got: z expected a Tensor in z
, but got z value rH   r  zError matching value with spec)exc_infozConcreteFunction z was constructed with z in z, but was called with )r  r.   r_   r`   rK   _structure_summaryr  ra   rN   r7   r   	DenseSpecr   r8   r$   r  rL   r   rj   r  vlog)ry   r   r  r   expectedgotZ
arg_piecesZspec_piecesZ	arg_pieceZ
spec_pieceZtensor_typesZarg_matches_specrA   rA   rB   r    sd    
z5ConcreteFunction._structured_signature_check_arg_typec              
   C   sN  t   }| }t }|jr4| jjs4|| jj t	
 sFt|dr^| jjD ]}t| qNg }tg }	t|D ]\}
}t|tjrt|j|	v rqrt| ||j |	t|j qrt|tjr|| qrt|
dd| dt| d| jj dqr|st|D ]t\}
}|jtjks|jtjkr8qt | jj!|
 j"}|#|j"std| d| jj!|
 j" d	|j" d
q|| }t$%|}|t$j&kr|r| '| j(j)|||dS | *|||}|+ \}}|r|j)|||d}nF|,| - | - d |)||}W d   n1 s00    Y  |.| | '|S )a  Executes the wrapped function.

    Args:
      args: a list of Tensors or Variables. Arguments from the Python function
        should be filtered before calling this method: objects aside from
        Tensors, CompositeTensors, and Variables are ignored. Any
        CompositeTensors should be expanded before calling this method.
      captured_inputs: the captured inputs that are also part of the input args
        to the actual execution. By default, it should be self._captured_inputs.
      cancellation_manager: (Optional.) A `CancellationManager` that can be
        used to cancel function invocation.

    Returns:
      The result of applying the TF function to `args`.

    Raises:
      ValueError: If `args` contains anything other than Tensors or Variables.
    watch_variabledz
-th input z must be a Tensor, got z when calling rH   zTensor zP is not compatible with the shape this function was traced with. Expected shape z, but got shape z.

If you called get_concrete_function, you may need to pass a tf.TensorSpec(..., shape=...) with a less specific shape, having None on axes which can vary.r  r  N)/r   r   r   r  building_functionr   saveableZmark_as_unsaveablesaving_errorsr   could_possibly_recordhasattrr  r$   variable_accessedr   r  r7   r  rx  handlerQ   r   r8   r`   rL   r   r;   r   r  r  r   rJ   r   r:   is_compatible_withr"   ZPossibleTapeGradientTypesZPOSSIBLE_GRADIENT_TYPES_NONE_build_call_outputsr!  r  &_select_forward_and_backward_functionsr)  r  _get_gradient_functionrc  )ry   r  rO  r  r   r   default_graphvtensor_inputsZvariables_usedre   r   Ztensor_inputZgraph_input_shapepossible_gradient_typer(  r  Zargs_with_tangentsrb  rA   rA   rB   rS    s    



,
zConcreteFunction._call_flatc                    s    fdd}|S )a  Returns a callable that invokes a cancellable version of this function.

    Args:
      cancellation_manager: A `CancellationManager` object that can be used to
        cancel function invocation.

    Returns:
      A callable with the same signature as this concrete function.
    c                     s   j | | dS )Nr  r  )r  r6  r  ry   rA   rB   cancellable_callc  s    zRConcreteFunction._experimental_with_cancellation_manager.<locals>.cancellable_callrA   )ry   r  r   rA   r  rB   '_experimental_with_cancellation_managerX  s    z8ConcreteFunction._experimental_with_cancellation_managerc                 C   s   | j  jS )z`ConcreteFunction` name.)ro  r)  r   r{   rA   rA   rB   r   i  s    zConcreteFunction.namec                 C   s   | j S )z;Returns the graph from which this function was constructed.r   r{   rA   rA   rB   r   n  s    zConcreteFunction.graphc                 C   s   | j jS )z;Returns tensors in `self.graph` corresponding to arguments.)r   r   r{   rA   rA   rB   r   s  s    zConcreteFunction.inputsc                 C   s   | j jS )a  Returns structured signature for this concrete function.

    Returns:
      A tuple `(args, kwargs)`, where:

        * `args` is a tuple that specifies the expected type or value each for
          positional argument.
        * `kwargs` is a dictionary that specifies the expected type or value
          for each keyword-only argument.

      The type or value for each argument is specified using one of the
      following:

        * A `tf.TypeSpec`, indicating that a Tensor or other TensorFlow-native
          value is expected.
        * A Python value, such as an integer, indicating that an equal value
          is expected.
        * A nested structure of `tf.TypeSpec`s and Python values, indicating
          that a corresponding nested structure is expected.
    )r   r  r{   rA   rA   rB   r  x  s    z+ConcreteFunction.structured_input_signaturec                 C   s   | j jS )zBReturns tensors in `self.graph` corresponding to returned tensors.)r   r   r{   rA   rA   rB   r     s    zConcreteFunction.outputsc                 C   s   | j jS )zEReturns outputs in `self.graph` as returned by the original function.)r   rJ  r{   rA   rA   rB   rJ    s    z#ConcreteFunction.structured_outputsc                 C   s
   || _ dS )a  Updates the function capture values.

    The new values must have tensor types and shapes consistent with the
    original captures of the concrete function, but it is allowed to change a
    value captured with a deferred one and vice-versa.

    Args:
      captures: A list of tensors or closures. Tensors are value captures, and
        closures are call-time (deferred captures).
    N)r  )ry   r  rA   rA   rB   set_external_captures  s    z&ConcreteFunction.set_external_capturesc           	      C   s   d}t | jD ] \}}t|t|kr|} q0q|du rf|du rPtd| d| jt| j |  }||s||std| d| d| d| jj|||||d |dur|| j|< dS )	a	  Replaces existing capture `tensor` with a deferred capture `closure`.

    This API replaces the capture `tensor` from the concrete function's captured
    inputs list, and places the deferred capture `closure` in
    its spot so the order of captured inputs is preserved. This is important
    because the old `tensor` and the new `closure` will have the same internal
    placeholder, which can be passed through the `placeholder` argument, or
    skipped, in which case we find the placeholder from internal inputs by
    indexing `tensor` in the external captured inputs list. Thus, it is
    important that the new deferred capture has output spec (specified by the
    `spec` argument) compatible with the internal placeholder (`placeholder`)
    and the original capture (`tensor`).

    For example,

    ```python
    bool_captured_tensor = tf.constant(True)
    float_captured_tensor = tf.constant([3.], dtype=tf.float32)
    value = tf.constant([2.], dtype=tf.float32)

    @tf.function
    def fn():
      deferred_tensor = ops.get_default_graph().capture_call_time_value(
          lambda: value,
          tf.TensorSpec(shape=(1,), dtype=tf.float32))
      if bool_captured_tensor:
        return deferred_tensor
      else:
        return deferred_tensor + float_captured_tensor

    concrete_fn = fn.get_concrete_function()
    print(concrete_fn())  # tf.Tensor([2.], shape=(1,), dtype=float32)

    new_bool_captured_tensor = constant_op.constant(False)
    def bool_closure():
      return new_bool_captured_tensor

    concrete_fn.replace_capture_with_deferred_capture(
        bool_captured_tensor,
        bool_closure,
        spec=tensor_spec.TensorSpec(shape=(), dtype=dtypes.bool))

    print(concrete_fn())  # tf.Tensor([5.], shape=(1,), dtype=float32)
    ```

    Args:
      tensor: Tensor already captured. This `tensor` should be listed in
        concrete_function.captured_inputs except when it's empty such as when
        the concrete function is restored from SavedModel.
      closure: function which takes no arguments, to be evaluated at function
        call time, returning a nest of tensors compatible with `spec`.
      spec: nest of TypeSpec for the value to capture.
      placeholder: optional. The internal placeholder corresponding to the
        captured `tensor` and the new `closure`.
      default_value: optional value to use in environments that cannot safely
        evaluate closure.
    NzDid not find `tensor` argument z in the ConcreteFunction's captured inputs list, and did not receive a placeholder argument. Thus we're unable to infer the internal placeholder. z+Attempting to substitute closure with spec z/ that's incompatible with the original capture z or the internal placeholder rH   )tensorclosurer  rV  default_value)	r  r  rx  r`   r   r   r  r   %replace_capture_with_deferred_capture)	ry   r$  r%  r  rV  r&  Zcapture_indexre   rD  rA   rA   rB   r'    s<    ?

z6ConcreteFunction.replace_capture_with_deferred_capturec                 C   s   t jdd | jD ddS )zReturns external Tensors captured by this function.

    self.__call__(*args) passes `args + self.captured_inputs` to the function.
    c                 S   s   g | ]}t |r| n|qS rA   )callablerZ   r@   rA   rA   rB   r     r^   z4ConcreteFunction.captured_inputs.<locals>.<listcomp>TrV   )r.   ra   r  r{   rA   rA   rB   rO    s    z ConcreteFunction.captured_inputsc                 C   s   | j  jS )z:Returns a `FunctionDef` object representing this function.)ro  r)  r   r{   rA   rA   rB   r     s    zConcreteFunction.function_defc                 C   s   t jdd t| jjddS )zThe function's output shapes.c                 S   s   t | dtd S )Nr:   )getattrr   rJ   r?   rA   rA   rB   ru    r^   z0ConcreteFunction.output_shapes.<locals>.<lambda>FrV   r.   ry  r   "replace_composites_with_componentsr   rJ  r{   rA   rA   rB   output_shapes  s    zConcreteFunction.output_shapesc                 C   s   t jdd t| jjddS )Nc                 S   s   | d ur| j S d S rX   )r;   r?   rA   rA   rB   ru  (  r^   z0ConcreteFunction.output_dtypes.<locals>.<lambda>FrV   r+  r{   rA   rA   rB   output_dtypes$  s    zConcreteFunction.output_dtypesc                 C   s(   t  s|st }| j | dS )zRegisters the function, adds it to the graph g or default graph.

    Args:
      g: If specified, registers the function with this graph. Defaults to the
        current context (either the default graph or the eager context).
    N)r   r   r   r  ro  r)  r   )ry   r   rA   rA   rB   r   -  s    zConcreteFunction.add_to_graphc                 C   sJ   t  s|st }| j | | j \}}|| || dS )zCAdd forward/backward functions to graph `g` or the current context.N)r   r   r   r  ro  r)  r   r(  )ry   r   r  r  rA   rA   rB   add_gradient_functions_to_graph=  s    
z0ConcreteFunction.add_gradient_functions_to_graphc                 C   s   | j jS )zCReturns gradient function. It will be lazily created at first call.)ro  rW  r{   rA   rA   rB   r  G  s    z'ConcreteFunction._get_gradient_functionc                 C   s  |rt |}nt  }t|j}||jf}|tjkr|jsB|r| j	
|d}|du rt| j| j| j|j| j|d}|| j	|< t|||jddS t| j||jddS n\|tjkr| j
|d}|du rt| j| j| j|j| j|d}|| j|< t|||jddS t| j||jddS )a`  Selects forward and backward functions based on the calling context.

    The forward function computes the "real" function outputs, `self._outputs`,
    and any extra values needed by the corresponding backward function.

    Args:
      args: A flat list of Tensors with all of the inputs to the forward
        function (including user-specified and captured inputs).
      possible_gradient_type: One of gradients_util.POSSIBLE_GRADIENT_TYPES_*.
      executing_eagerly: Boolean, the value of context.executing_eagerly().

    Returns:
      An object with a `forward` method returning a tuple of (forward_function :
      _EagerDefinedFunction, augmented_arguments : List), and a corresponding
      `record` method which takes outputs from the forward function and records
      the operation. forward_function should be called with augmented_arguments.
    N)rr  rs  rt  T)r  F)r   r  ZTangentInfor   should_record_backproptangentsindicesr"   Z#POSSIBLE_GRADIENT_TYPES_FIRST_ORDERr  r   r  r   r"  r  ro  r  Z$POSSIBLE_GRADIENT_TYPES_HIGHER_ORDERr  r  )ry   r  r  r   r\  rt  	cache_keyr  rA   rA   rB   r  K  s`    







z7ConcreteFunction._select_forward_and_backward_functionsc                 C   s   | j jdu r|S tj| j jdd}d}t|D ]:\}}|dur.t| j| ||  || ||< |d7 }q.tj| j j|dd}|S )zMaps the fdef output list to actual output structure.

    Args:
      result: Output lists defined by FunctionDef.
    Returns:
      The actual call output.
    NTrV   r   r  )	r   rJ  r.   ra   r  r#   r  r   pack_sequence_as)ry   resultZoutputs_listjre   r   retrA   rA   rB   r    s    	

z$ConcreteFunction._build_call_outputsc                 C   s6   t j| jd}| j D ]\}}|j| | q|S )z4Returns a `NameAttrList` representing this function.r   )r   NameAttrListr   r"  rh   r  CopyFrom)ry   r7  r   ru   rA   rA   rB   _as_name_attr_list  s    z#ConcreteFunction._as_name_attr_listFc           	      C   s   | j dusJ | j\}}t| j j}|dt| }|rptt|D ]*}t|| sD||  d|| 7  < qD|r|d |	 D ]4\}}|| |rt|s|d  d|7  < q| j
j dd| d}|S )zReturns a string summarizing this function's structured signature.

    Args:
      default_values: If true, then include default values in the signature.

    Returns:
      A `string`.
    Nz={}*(r  ))r  r  r   r  r   rN  r  r  rQ   rh   r   r   r  )	ry   default_valuesr  r  r  re   r   r  r   rA   rA   rB   r    s     


z.ConcreteFunction._structured_signature_summaryc                 C   sj   | j dusJ | jdusJ | j }| jt|krP|dd tt|| jD  | jj dd| dS )z<Returns a string summarizing this function's flat signature.Nc                 s   s   | ]}d  |d V  qdS )r  r  Nr  r  rA   rA   rB   r]     s   z;ConcreteFunction._flat_signature_summary.<locals>.<genexpr>r=  r  r>  )r  r  r   r{  rN  r   r   r  )ry   r  rA   rA   rB   r    s    
z(ConcreteFunction._flat_signature_summaryc              	      s  |s| j ddS  fdd | j ddg}| j\}}t| jj}g }t|dt| t|D ]&\}}t|r^|d	| | q^|rt
|D ]*}	||	 }t|r|d	|	 | q|r|d || |d d	d
 }
|d	 t|
| j d|S )zEReturns a string summarizing the signature of this concrete function.T)r?  c                    s   t | tjrd| jj| jS t| rtj	| dd}dd t
t|D }t| |}tj|dd}t||D ]\}}|d| |7 }qp|S t| S d	S )
z;Returns a string describing the spec for a single argument.z{} Tensor, shape={}FrV   c                 S   s   g | ]}t d |d qS )z<{}>r  )_Markerr  r  rA   rA   rB   r     r^   zXConcreteFunction.pretty_printed_signature.<locals>.pretty_print_spec.<locals>.<listcomp>i'  )widthz
      {}: {}N)r7   r   r9   r  r;   r   r:   r.   	is_nestedra   rN  r   r4  pprintpformatrN   repr)r  piecesmarkers	structurer5  markerpiecepretty_print_specrA   rB   rL    s    
zDConcreteFunction.pretty_printed_signature.<locals>.pretty_print_specNz
    {}: {}z  Args:z
  Returns:c                 S   s   t | tjr| S t| S rX   )r7   r   r<   type_spec_from_valueru   rA   rA   rB   spec_from_value	  s    zBConcreteFunction.pretty_printed_signature.<locals>.spec_from_valuez    {}
)r  r  r   r  r  rN   r   r  rQ   r  r  r{  r.   ry  rJ  r  )ry   verboselinesr  r  namesZarg_detailsr   r  kwargrO  rA   rK  rB   pretty_printed_signature  s8    

"


z)ConcreteFunction.pretty_printed_signaturec                 C   sX   | j d ur"d| jddt| S | jd u sJ| jd u sJd|  t| S t| S d S )Nz<ConcreteFunction {} at 0x{:X}>F)rQ  )	r  r  rU  rx  r  r  r  object__repr__r{   rA   rA   rB   rW  +	  s    
zConcreteFunction.__repr__c                 C   s$   | j d urd|  S |  S d S )NzConcreteFunction {})r  r  rU  rW  r{   rA   rA   rB   __str__5	  s    
zConcreteFunction.__str__
checkpointc                 K   sX   |dkri S i }t | jjD ]6\}\}}|jtjtjfvrt|s||d| < q|S )zImplements `Trackable`.rY  Zcapture_)	r  r   r  r;   r   r  r  r$   is_resource_variable)ry   	save_typer6  Zcaptured_trackablesr   rD  r   rA   rA   rB   _trackable_children;	  s    z$ConcreteFunction._trackable_childrenc                 C   s   |S rX   rA   )ry   childrenrA   rA   rB   _deserialization_dependenciesT	  s    z.ConcreteFunction._deserialization_dependenciesc                 K   sD   | j js(td| j dd| j j |   t| ||| < g S )NzUnable to save function z for the following reason(s):
rP  )	r   r  r`   r   r  r  r   r   ZExportedConcreteFunction)ry   
object_map
tensor_mapunused_kwargsrA   rA   rB   _export_to_saved_model_graphW	  s    z-ConcreteFunction._export_to_saved_model_graph)NTN)N)N)NN)N)N)F)T)rY  )/r   r   r   r   rz   r  r  r  r  r  r  r  r  r  r  r  r   r  r  rS  r!  r   r   r   r  r   rJ  r#  r'  rO  r   r-  r.  r   r/  r  r  r  r:  r  r  rU  rW  rX  r\  r^  rb  rA   rA   rA   rB   r    sz      
O!

4
1
0
_





  
_
	





R

$
>

r  r8   r8  rP  c                   @   s   e Zd ZdZd"ddZdd Zed	d
 Zedd Zedd Z	edd Z
dd Zdd Zdd Zdd Zee dddZdd Zdd Zd d! ZdS )#Functiona  Wrapper class for the graph functions defined for a Python function.

  See the documentation for `defun` for more information on the semantics of
  defined functions.

  `Function` class is thread-compatible meaning that minimal usage of defuns
  (defining and calling) is thread-safe, but if users call other methods or
  invoke the base `python_function` themselves, external synchronization is
  necessary.
  In addition, Function is not reentrant, so recursive functions need to call
  the wrapped function, not the wrapper.
  NTFc                 C   s   || _ |ot|v }tjj||||
d| _|| _|| _|| _|| _	t
 | _|pPi | _|| _d| _t | _t | _t | _|	| _|
| _dS )a  Initializes a `Function`.

    Args:
      python_function: the function to be wrapped.
      name: the name given to it.
      input_signature: a possibly nested sequence of `TensorSpec` objects
        specifying the input signature of this function. If `None`, a separate
        function is instantiated for each inferred input signature.
      attributes: dict, extra keyword arguments that will be added as attribute
        of the function.
      autograph: whether to use autograph to compile
        `python_function`. See https://www.tensorflow.org/guide/autograph for
        more information.
      autograph_options: Experimental knobs to control behavior
        `when autograph=True`. See https://www.tensorflow.org/guide/autograph
        for more information.
      reduce_retracing: When True, `tf.function` uses
        `tf.types.experimental.TraceType` to trace supertypes of arguments to
        reduce the number of traces.
      capture_by_value: Experimental. Whether to capture resource variables by
        value or reference. If None, will inherit from a parent context or
        default to False.
      jit_compile: Force-compile the function with XLA, cf.
        def_function.Function doc on jit_compile.
      experimental_follow_type_hints: See the documentation for `tf.function`.

    Raises:
      ValueError: if `input_signature` is not None and the `python_function`'s
        argspec has keyword arguments.
    )r  experimental_follow_type_hintsr   N)_python_functionr  r   r  from_function_and_signaturer  r   
_autograph_autograph_options_reduce_retracingr   ZFunctionCache_function_cache_function_attributes_capture_by_valuetracing_countr=  ZCapturesContainer_captures_container	threadingRLock_lockweakrefWeakKeyDictionary_descriptor_cache_jit_compile_experimental_follow_type_hints)ry   python_functionr   r  rr   	autographautograph_optionsreduce_retracingcapture_by_valuejit_compilerd  Zpure_functionrA   rA   rB   rz   x	  s*    )




zFunction.__init__c                 O   sF   | j   | ||\}}W d   n1 s,0    Y  |j||jdS )z1Calls a graph function specialized to the inputs.N)rO  )rq  _maybe_define_functionrS  rO  )ry   r  r6  graph_functionr  rA   rA   rB   r  	  s    
zFunction.__call__c                 C   s   | j S )z$Returns the wrapped Python function.)re  r{   rA   rA   rB   rw  	  s    zFunction.python_functionc                 C   s   | j S rX   )r  r{   rA   rA   rB   r   	  s    zFunction.function_specc                 C   s   | j jS )zReturns the input signature.)r  r  r{   rA   rA   rB   r  	  s    zFunction.input_signaturec                 C   s   | j jS )z&Returns the flattened input signature.)r  flat_input_signaturer{   rA   rA   rB   r  	  s    zFunction.flat_input_signaturec                 O   sH   | j rd\}}| j  | ||\}}W d   n1 s:0    Y  |S )z?Returns a concrete function which cleans up its graph function.NNN)r  rq  r}  )ry   r  r6  r~  r   rA   rA   rB   1_get_concrete_function_internal_garbage_collected	  s
    .z:Function._get_concrete_function_internal_garbage_collectedc                 O   s   | j |i |}|j  |S )z6Bypasses error checking when getting a graph function.)r  r  releasery   r  r6  r~  rA   rA   rB   _get_concrete_function_internal	  s    
z(Function._get_concrete_function_internalc                 O   s  | j r|r"td| d| j  d|rt| j |sJtd| d| j  dtj|dd}tdd	 |D rrtd
tdd	 t| j|D rtd| d| j  dd\}}| j | 	||\}}t
 }t|jj}g |_i }d}	|jjD ]z}
|
|v r qj|	d7 }	t|
jd}|}||v rR||d}d||}|d ||< q || |j| q|	|_|W  d   S 1 s0    Y  dS )a  Returns a `ConcreteFunction` specialized to inputs and execution context.

    Unlike `get_concrete_function(...)`, the graph will be deleted when the
    returned function is deleted.  It's useful to avoid creating a reference
    cycle when you know for sure that the graph will be no longer used without
    the returned function.

    Args:
      *args: inputs to specialize on.
      **kwargs: inputs to specialize on.
    zCannot define a TensorFlow function from a Python function with keyword arguments when input_signature is provided, got keyword arguments (z) with input_signature (r  zLStructure of Python function inputs does not match input_signature: inputs (z), input_signature (TrV   c                 s   s&   | ]}t |tjtjtjf V  qd S rX   )r7   r   r8   r   r	  r$   r  r   rA   rA   rB   r]   
  s   zDFunction._get_concrete_function_garbage_collected.<locals>.<genexpr>zWhen input_signature is provided, all inputs to the Python function must be Tensors, Variables, tf.TensorSpec or tf.VariableSpec objects.c                 s   s   | ]\}}| | V  qd S rX   )r  )rZ   r  otherrA   rA   rB   r]   	
  s   z9Python inputs incompatible with input_signature: inputs (r  r   r  Z_user_specified_namez{}_{}N)r  r`   rd   r.   ra   rb   rN   r  rq  r}  r   r/   rA  r   rz  r  r   r*   r   r   get_attrr   r  r   rQ   r  )ry   r  r6  flat_inputsr~  r   Z
seen_namesr  Zprefix_countsZnum_positionalr   Zuser_arg_nameZproposalr  rA   rA   rB   (_get_concrete_function_garbage_collected	  sf    






z1Function._get_concrete_function_garbage_collectedc                 O   s   | j |i |}|j  |S )aA  Returns a `ConcreteFunction` specialized to inputs and execution context.

    Args:
      *args: inputs to specialize on. Can be concrete values (e.g. 1)
         or `tf.Tensor` or `tf.TensorSpec`.
      **kwargs: keyword inputs to specialize on. Concrete values (e.g. 1)
         or `tf.Tensor` or `tf.TensorSpec`.
    )r  r  r  r  rA   rA   rB   get_concrete_function)
  s    	
zFunction.get_concrete_function)returnc                 C   s
   | j  S rX   )rj  r   r{   rA   rA   rB   _list_all_concrete_functions7
  s    z%Function._list_all_concrete_functionsc                 C   s2   ~|| j vr(|du r| S t| || j |< | j | S )z,Makes it possible to defun instance methods.N)rt  class_method_to_instance_method)ry   instanceownerrA   rA   rB   __get__:
  s    

zFunction.__get__c           	      C   s   |  j d7  _ | jdu r"t|}n
t| j}| jjd| }|t| jj }| jjg| }dd t|D }|| }ttj	| j
| j||| j| j| j|| jd	| j| jdd}|S )z5Create a `ConcreteFunction` from `args` and `kwargs`.r  Nc                 S   s   g | ]\}}d ||f qS )z%s_%drA   )rZ   re   r   rA   rA   rB   r   i
  s   z3Function._create_graph_function.<locals>.<listcomp>)rx  ry  r  r{  F)r  r  )rm  r  r   r  r  Zvararg_namer  r  r=  r?  r   re  rg  rh  rl  rk  r   )	ry   r  r6  arglenZbase_arg_namesZnum_missing_argsZmissing_arg_namesr  r~  rA   rA   rB   _create_graph_function\
  s8    



zFunction._create_graph_functionc              
   C   sb  | j du s|dus|dur4| jj|i |\}}}ng }| j }| j du rbt||f|\}}nt| j|\}}zt| W n. t	y } zt	d|W Y d}~n
d}~0 0 | j
|d}|dur||fS tt n td@ tdd| j| tdd|| | jr tjjntjj}	tj|	| jd	 | jrn| j du rn| j
|}| }
|
d
 \}}| ||}|j j!}| j"| | }| j du rt||f|\}}nt| j|\}}| j
#||| ||fW  d   W  d   W  d   S 1 s0    Y  W d   n1 s40    Y  W d   n1 sT0    Y  dS )a  Gets a function for these inputs, defining it if necessary.

    `args` and `kwargs` can be None if this `Function` was created with an
    `input_signature`.

    Caller must hold self._lock.

    Args:
      args: The varargs for the Python function.
      kwargs: The keyword args for the Python function.

    Returns:
      A graph function corresponding to the input signature implied by args and
      kwargs, as well as filtered flattened inputs (only Tensors and Variables)
      that the object should be called with.

    Raises:
      ValueError: If inputs are incompatible with the input signature.
      TypeError: If the function inputs include non-hashable objects
      RuntimeError: If there's an internal bug (inconsistency) in handling
        shape relaxation retracing.
    NzCArguments supplied to `defun`-generated functions must be hashable.Tztf.function-graph_buildingr  z7Creating new FuncGraph for Python function %r (key: %r)   z1Python function signature [args: %s] [kwargs: %s])statusoptionsr  )$r  r  r  rn  Zget_snapshotr   Zmake_cache_keyr  hashrK   rj  lookupr   MonitoredTimer_graph_building_time_counterget_cellr&   r  r  r
  re  rg  r3   StatusENABLEDDISABLEDZControlStatusCtxrh  ri  Z
generalize_placeholder_valuer  r   Z_capture_func_libr  r   )ry   r  r6  r  r  Zfunc_cache_keyr   er~  Z	ag_statusZplaceholder_dictZgraph_capture_containerr3  Zcache_key_deletion_observerrA   rA   rB   r}  
  sx    




zFunction._maybe_define_function)NNTNFNNF)r   r   r   r   rz   r  r  rw  r   r  r  r  r  r  r  r   r  r  r  r  r}  rA   rA   rA   rB   rc  j	  s6           
C



@"%rc  c                 O   sH   t | ts$td|  dt|  d| j|i |}|  |  |S )a  Register a specialization of a `Function` into the graph.

  This won't actually call the function with the inputs, and only put the
  function definition into graph. Register function with different input param
  will result into multiple version of functions registered in graph.

  Args:
    func: the `Function` instance that generated by a @defun
    *args: input arguments for the Python function.
    **kwargs: input keyword arguments for the Python function.

  Returns:
    a `ConcreteFunction` object specialized to inputs and execution context.

  Raises:
    ValueError: When the input function is not a defun wrapped python function.
  z5Only defun function is allowed to be registered. Got z with type rH   )r7   rc  r`   rL   r  r   r/  )r   r  r6  Zconcrete_funcrA   rA   rB   register
  s    

r  c                 C   sz   t | ttfs"tdt|  dtdd tj| ddD rvdd tj| ddD }td	| d
ttt| dd S )Nz6input_signature must be either a tuple or a list, got rH   c                 s   s   | ]}t |tj V  qd S rX   r7   r   r	  r   rA   rA   rB   r]      s   z%validate_signature.<locals>.<genexpr>TrV   c                 S   s   g | ]}t |tjs|qS rA   r  r   rA   rA   rB   r     s   z&validate_signature.<locals>.<listcomp>z[input_signature must be a possibly nested sequence of TensorSpec objects, got invalid args z with types )	r7   r   r   rK   rL   rb   r.   ra   r   )r   Zbad_argsrA   rA   rB   validate_signature
  s    
r  c                 C   s   t | st|  dd S )Nz is not a callable object.)r(  rK   )rw  rA   rA   rB   validate_python_function	  s    r  Tc                 C   s   t | ||||dS )a>8  Compiles a Python function into a callable TensorFlow graph.

  `defun` (short for "define function") compiles a Python function
  composed of TensorFlow operations into a callable that executes a `tf.Graph`
  containing those operations. The callable produced by `defun` contains only
  the subgraph of TensorFlow operations that were executed when the Python
  function was called with a particular input signature, defined as a list
  of the shapes and dtypes of the Python function's Tensor-valued arguments and
  the values of its non-Tensor Python objects.

  When eager execution is enabled, the ability to create graphs from Python
  functions makes it possible to incrementally trade off debuggability and
  interactivity for performance.  Functions compiled with `defun` cannot be
  inspected with `pdb`; however, executing a graph
  generated by `defun` sometimes takes less time and memory than eagerly
  executing the corresponding Python function, since specifying computations as
  graphs allows for optimizations like automatic buffer reuse and
  parallelization among ops. Note that executing a `defun`-compiled function
  incurs a small constant overhead, so eagerly executing sufficiently small
  Python functions might take less time than executing their corresponding
  `defun`-generated graphs.

  For a Python function to be compatible with `defun`, all of its arguments must
  be hashable Python objects or lists thereof. The function itself may not
  modify the list/map structure of its arguments. Additionally, it must return
  zero or more `tf.Tensor` objects. If the Python function returns
  a `tf.Variable`, its compiled version will return the value of that variable
  as a `tf.Tensor`.

  Executing a graph generated by `defun` respects device annotations (i.e.,
  all `with tf.device` directives present in a Python function will also be
  present in its corresponding graph), but it is not yet possible to execute the
  generated graphs across multiple machines.

  _Example Usage_

  ```python
  import tensorflow as tf

  tf.compat.v1.enable_eager_execution()

  # A simple example.
  def f(x, y):
    return tf.reduce_mean(tf.multiply(x ** 2, 3) + y)

  g = tf.contrib.eager.defun(f)

  x = tf.constant([[2.0, 3.0]])
  y = tf.constant([[3.0, -2.0]])

  # `f` and `g` will return the same value, but `g` will be executed as a
  # TensorFlow graph.
  assert f(x, y).numpy() == g(x, y).numpy()

  # `defun` is capable of compiling Python functions that close over Python
  # objects, including Tensors and Variables.
  @tf.contrib.eager.defun
  def h():
    return f(x, y)

  assert (h().numpy() == f(x, y).numpy()).all()

  # `defun` automatically lifts variables out of the graphs it creates,
  # allowing you to compile the `call` methods of `tf.keras.layers.Layer` and
  # `tf.keras.Model` objects.
  class MyModel(tf.keras.Model):

    def __init__(self, keep_probability=0.2):
      super(MyModel, self).__init__()
      self.dense1 = tf.keras.layers.Dense(4, activation=tf.nn.relu)
      self.dense2 = tf.keras.layers.Dense(5, activation=tf.nn.softmax)
      self.keep_probability = keep_probability

    @tf.contrib.eager.defun
    def call(self, inputs, training=True):
      x = self.dense2(self.dense1(inputs))
      if training:
        return tf.nn.dropout(x, self.keep_probability)
      else:
        return x

  model = MyModel()
  model(x, training=True)  # executes a graph, with dropout
  model(x, training=False) # executes a graph, without dropout

  # `defun`-compiled functions are differentiable.
  optimizer = tf.compat.v1.train.GradientDescentOptimizer(learning_rate=0.01)
  with tf.GradientTape() as tape:
    outputs = model(x)
  gradient = tape.gradient(outputs, model.trainable_variables)
  optimizer.apply_gradients((grad, var) for grad, var in zip(gradient,
                            model.trainable_variables))
  ```

  When using `defun`, there are subtleties regarding inputs, Python control
  flow, and variable creation that one should be aware of. For concreteness, let
  `f` be a Python function that returns zero or more `tf.Tensor` objects and
  let `F = defun(f)`. `F` builds a graph for each unique input signature it
  sees, Python control flow is baked into graphs, and operations related to
  variable initialization are automatically lifted out of the graphs that `F`
  generates and placed in the eager context if executing eagerly or into an
  outer graph otherwise.

  _Input Signatures_

  By default, `F = tf.contrib.eager.defun(f)` instantiates a separate graph
  for every unique sequence of the shapes and dtypes of Tensor arguments and
  the values of Python objects it is invoked with. For example, calling
  `F(tf.random.uniform([2])` will execute a different graph than
  `F(tf.random.uniform([3])` because the two inputs have different shapes.
  The first time that `F(*args, **kwargs)` is called with a particular sequence
  of Tensor shapes and dtypes and Python values, it constructs a graph by
  tracing the execution of `f(*args, **kwargs)`; this graph is bound to an
  input signature inferred from `(*args, **kwargs)` and cached for future reuse.

  NumPy arrays passed as inputs to `F` are converted to `tf.Tensor` objects
  before being passed to `f`, and are treated as Tensors for caching. This
  allows a function to be called multiple times with NumPy arrays having
  different values but the same shape and dtype without re-tracing each time.

  `tf.contrib.eager.defun` caches graphs for your convenience, letting you
  define TensorFlow functions without explicitly specifying their signatures.
  However, this policy is conservative and potentially expensive; for example,
  when different invocations of your function have differently-shaped Tensor
  inputs, this policy might generate more graph functions than necessary. To
  eliminate such costs, `tf.contrib.eager.defun` allows you to supply an
  optional `input_signature` argument specifying the shapes and dtypes of the
  inputs. In particular, the shapes may be partially unspecified, with `None`s
  in the unknown dimensions.  When an input signature is provided,
  `tf.contrib.eager.defun` will only instantiate a single graph for the
  decorated Python function. The following is an example:

  ```python
  import tensorflow as tf

  # The first `TensorSpec` below describes the shape and dtype of `words`,
  # and the second describes the shape and dtype of `another_tensor`. Note that
  # the last dimension of the `words` `TensorSpec` is left unspecified.
  @tf.contrib.eager.defun(input_signature=[
    tf.contrib.eager.TensorSpec(shape=[50, 300, None], dtype=tf.float32),
    tf.contrib.eager.TensorSpec(shape=[300, 100], dtype=tf.float32)
  ])
  def my_sequence_model(words, another_tensor):
    ...

  # Note how the third dimension of the first input can vary freely.
  words = tf.random.uniform(([50, 300, 10])
  second_input = tf.random.uniform([300, 100])
  my_sequence_model(words, second_input)

  words = tf.random.uniform(([50, 300, 20])
  my_sequence_model(words, second_input)

  # Passing an input with an incompatible shape will raise an error.
  words = tf.random.uniform(([50, 100, 20])
  my_sequence_model(words, second_input)  # <---- This will raise an error.

  ```

  Python functions that are compiled with an `input_signature` must only accept
  Tensors as arguments and must not take unnamed keyword arguments (**kwargs).

  _Tracing_

  Be aware that because `F` only logs TensorFlow operations, all the other
  Python code that `f` executes will only shape the _construction_ of the graphs
  that `F` executes: the Python code won't be executed when the graphs
  themselves are executed, though it will be executed every time the Python
  function is traced (and a given Python function might be traced multiple
  times, once for each input signature it is invoked with). For example, whereas
  the Python function

  ```python
  import tensorflow as tf
  import numpy as np

  tf.compat.v1.enable_eager_execution()

  def add_noise():
    return tf.eye(5) + np.random.randn(5, 5)
  ```

  will return a different output everytime it is invoked, the compiled function
  `compiled = tf.contrib.eager.defun(add_noise)` will return the same value
  every time it is called, since a particular random offset generated by NumPy
  will be inserted into the graph as a TensorFlow constant. The solution is to
  replace the call to `np.random.randn` with `tf.random.normal((5, 5))`.

  _Python Side-Effects_

  A corollary of the previous discussion on tracing is the following: If a
  Python function `f` has Python side-effects, then executing `f` multiple times
  will not necessarily be semantically equivalent to executing `F =
  tf.contrib.eager.defun(f)` multiple times; this difference is due to the fact
  that `defun` only captures the subgraph of TensorFlow operations that is
  constructed when `f` is called in a graph-building context.

  _Python Control Flow_

  The structure of many machine learning computations depend upon whether one is
  training or validating, and it is common to nest specialized logic under `if
  training:` blocks. By mapping each input signature to a unique graph, `defun`
  lets users transparently compile such code, as the following code snippet
  demonstrates:

  ```python
  import tensorflow as tf

  tf.compat.v1.enable_eager_execution()

  @tf.contrib.eager.defun
  def lossy_matmul(W, x, training=True):
    outputs = tf.matmul(W, x)
    if training:
      outputs = tf.nn.dropout(outputs, keep_probability=0.2)
    return outputs

  W = tf.random.normal((3, 5))
  x = tf.random.normal((5, 1))

  # Executes a graph that applies dropout.
  lossy_outputs = lossy_matmul(W, x, training=True)

  # Executes a graph that does not apply dropout.
  exact_outputs = lossy_matmul(W, x, training=False)
  ```

  _TensorFlow Control Flow_

  When `autograph` is `True`, data-dependent control flow is allowed as well.
  Control flow statements that depend on `Tensor` values are staged into
  corresponding TensorFlow ops. For example, the following code will work as
  expected:

  ```python
  @tf.contrib.eager.defun
  def dynamic_rnn_loop(cell, seq):
    state, output = cell.zero_state()
    for input in seq:
      state, output = cell(input, state)
    return output
  ```

  For more information see `tf.autograph`.

  _Variables_

  TensorFlow operations related to variable creation and initialization are
  automatically lifted out of the graphs generated by `defun`. In practice, this
  implies that variable creation and initialization only happen the first time
  `F` is called, and that variables are reused every time thereafter. Many
  TensorFlow APIs, like `tf.keras.layers.Layer` objects, create variables the
  first time they are called and reuse them thereafter. Automatic variable
  lifting makes it possible to compile these APIs without extra effort, at the
  cost of introducing a discrepancy between the semantics of executing Python
  functions and their corresponding compiled functions. For example:

  ```python
  import tensorflow as tf

  tf.compat.v1.enable_eager_execution()

  def fn():
    x = tf.Variable(0.0)
    x.assign_add(1.0)
    return x.read_value()

  # `fn` is a Python function, so x is created, initialized, and destroyed upon
  # every invocation
  assert fn().numpy() == fn().numpy() == 1.0

  compiled = tf.contrib.eager.defun(fn)

  # Compiling `fn` with `defun` hoists all variables outside of the generated
  # graph, so initialization happens exactly once.
  assert compiled().numpy() == 1.0
  assert compiled().numpy() == 2.0
  ```

  Finally, because each input signature is bound to a unique graph, if your
  Python function constructs `tf.Variable` objects, then each graph constructed
  for that Python function will reference a unique set of variables. To
  circumvent this problem, we recommend against compiling Python functions that
  create `tf.Variable` objects. Instead, Python functions should either
  lexically close over `tf.Variable` objects or accept them as arguments,
  preferably encapsulated in an object-oriented container. If you must create
  variables inside your Python function and you want each graph generated for it
  to reference the same set of variables, add logic to your Python function that
  ensures that variables are only created the first time it is called and are
  reused for every subsequent invocation; note that this is precisely what
  `tf.keras.layers.Layer` objects do, so we recommend using them to represent
  variable-bearing computations whenever possible.

  Args:
    func: function to be compiled. If `func` is None, returns a
      decorator that can be invoked with a single argument - `func`. The
      end result is equivalent to providing all the arguments up front.
      In other words, defun(input_signature=...)(func) is equivalent to
      defun(func, input_signature=...). The former allows
      the following use case:
        @tf.contrib.eager.defun(input_signature=...)
        def foo(...):
          ...

    input_signature: A possibly nested sequence of
      `tf.contrib.eager.TensorSpec` objects specifying the shapes and dtypes of
      the Tensors that will be supplied to this function. If `None`, a separate
      function is instantiated for each inferred input signature.  If a
      signature is specified, every input to `func` must be a `Tensor`, and
      `func` cannot accept `**kwargs`.
    autograph: Whether `func` should be compiled before
      constructing the graph. See https://www.tensorflow.org/guide/autograph
      for more information.
    experimental_autograph_options: Experimental knobs (in the form of a tuple
      of tensorflow.autograph.Feature values) to control behavior when
      autograph=True.
    reduce_retracing: When True, `tf.function` uses
      `tf.types.experimental.TraceType` to trace supertypes of arguments to
      reduce the number of traces.

  Returns:
     If `func` is not None, returns a callable that will execute the compiled
     function (and return zero or more `tf.Tensor` objects).
     If `func` is None, returns a decorator that, when invoked with a single
     `func` argument, returns a callable equivalent to the case above.

  Raises:
    TypeError: If `input_signature` is neither `None` nor a sequence of
      `tf.contrib.eager.TensorSpec` objects.
  r   r  rx  experimental_autograph_optionsrz  )defun_with_attributesr  rA   rA   rB   defun  s      Qr  z+__internal__.function.defun_with_attributes)v1c           	         s<   durt   fdd}| dur8|| S |S )a  Compiles a Python function into a callable TensorFlow graph.

  This function supports adding extra function attributes. See detailed
  documentation in defun(). Currently this is not exposed in public API since we
  don't expect user to directly use attributes, and attribute won't work by
  itself. This assumption might change in future.

  Args:
    func: function to be compiled.
    input_signature: same as defun()'s input_signature.
    attributes: A dictionary of arguments which will be added to function def as
      attributes. Currently only support primitive types as value, and only
      allowlisted attribute name is allowed. Unallowlisted attribute name or
      unsupported value will result into ValueError. `func_name` is also one of
      the allowlisted argument which is a python string, and sets the name for
      this `ConcreteFunction` in the graph.
    autograph: same as defun()'s autograph.
    experimental_autograph_options: same as defun()'s
      experimental_autograph_options.
    jit_compile: same as defun()'s jit_compile.
    reduce_retracing: same as defun()'s reduce_retracing
    experimental_follow_type_hints: see `tf.function`.

  Returns:
    Same as the return value of defun, with attributes added to the function in
    graph.
  Nc                    sX   z r  d| j}n| j}W n ty4   d}Y n0 t| t| | d	S )N	func_namefunction)r  rr   rx  ry  r|  rz  rd  )r  r   r   r0   make_decoratorrc  )r  r   rr   rx  r  rd  r  r|  rz  rA   rB   	decorated  s(    

z(defun_with_attributes.<locals>.decorated)r  )	r   r  rr   rx  r  r|  rz  rd  r  rA   r  rB   r  e  s    $	r  c                   @   s<   e Zd ZdZdZdd Zedd Zedd Zd	d
 Z	dS )TfMethodTargetz:Binding target for methods replaced by function and defun.)weakrefself_target__weakrefself_func__c                 C   s   || _ t|| _d S rX   )r  rr  refr  )ry   targetZoriginal_python_functionrA   rA   rB   rz     s    zTfMethodTarget.__init__c                 C   s   |   S rX   )r  r{   rA   rA   rB   r    s    zTfMethodTarget.targetc                 C   s    |   }t|r|S |jS d S rX   )r  r1   isclassr  )ry   Z	true_selfrA   rA   rB   target_class  s    
zTfMethodTarget.target_classc                 C   s6   |   }t|rt|}||  g|R i |S rX   )r  r1   ismethodro   get_unbound_functionr  )ry   r  r6  
wrapped_fnrA   rA   rB   r    s    

zTfMethodTarget.callN)
r   r   r   r   r   rz   r  r  r  r  rA   rA   rA   rB   r    s   

r  c                    s   t |t jt j}t ds.J t ds<J t dsJJ t dsXJ d fdd}t |t t	|| j
 j j j jd}t	||}|S )	z.Constructs a new `Function` with `self` bound.r   rg  r  rw  Nc                     sV    }|j }||ju rH j}t|r0t|}| g| R i |S || i |S )zBWraps either a dummy MethodType or a converted AutoGraph function.)__wrapped____original_wrapped__rw  r1   r  ro   r  )r  r6  Zstrong_bound_method_wrapperr  original_functionZweak_bound_method_wrapperZweak_instancerA   rB   bound_method_wrapper  s    


z=class_method_to_instance_method.<locals>.bound_method_wrapper)r   rx  r  rz  r|  )rr  r  	types_lib
MethodTyperw  r  r  rL   r0   r  r   rg  r  ri  ru  )r  r  bound_methodr  Zinstance_funcZwrapped_instance_funcrA   r  rB   r    s0    




r  c                   @   s.   e Zd ZdZdgZdd Zdd Zdd Zd	S )
r  zGCleans up reference cycles when a `ConcreteFunction` goes out of scope.r   c                 C   s
   || _ d S rX   r"  )ry   r   rA   rA   rB   rz     s    z)ConcreteFunctionGarbageCollector.__init__c                 C   s
   d| _ dS )z Call off the FuncGraph deletion.Nr"  r{   rA   rA   rB   r    s    z(ConcreteFunctionGarbageCollector.releasec                 C   s@   t d u std u s| jd u rd S zt | j W n   Y n0 d S rX   )r=  r-   r   dismantle_func_graphr{   rA   rA   rB   r     s    z(ConcreteFunctionGarbageCollector.__del__N)r   r   r   r   r   rz   r  r   rA   rA   rA   rB   r    s
   r  c                   @   s&   e Zd ZdZdgZdd Zdd ZdS )r@  z@Markers used to pretty-print nested args in function signatures._sc                 C   s
   || _ d S rX   )r  )ry   rg   rA   rA   rB   rz   %  s    z_Marker.__init__c                 C   s
   t | jS rX   )rm   r  r{   rA   rA   rB   rW  (  s    z_Marker.__repr__N)r   r   r   r   r   rz   rW  rA   rA   rA   rB   r@     s   r@  c                    s0   dd   fddt | D }tt | |S )z?Displays a summary of the nesting structure of the given value.c                 S   s"   t | tjr| jjS t| jS d S rX   )r7   r   r<   
value_typer   rL   r?   rA   rA   rB   	type_name/  s    z%_structure_summary.<locals>.type_namec                    s   g | ]}t  |qS rA   )r@  )rZ   r  r  rA   rB   r   5  r^   z&_structure_summary.<locals>.<listcomp>)r.   ra   rm   r4  )rH  rG  rA   r  rB   r  ,  s    r  c                 C   s   t dd t| D S )Nc                 s   s   | ]}t |tjV  qd S rX   )r7   r   r<   r)  rA   rA   rB   r]   :  r^   z&_contains_type_spec.<locals>.<genexpr>)rb   r.   ra   rN  rA   rA   rB   r  9  s    r  )F)NNTNF)NNNTNNFF)r   collectionsrC  ro  typesr  typingr   rr  ro   	six.movesr   tensorflow.core.frameworkr   r   Z%tensorflow.core.function.polymorphismr   tensorflow.pythonr   tensorflow.python.clientr   tensorflow.python.eagerr	   r
   r   r   r   r   r   r   r   r   Z&tensorflow.python.eager.graph_only_opsr   tensorflow.python.frameworkr   r   r   r   r   r   r=  r   r   r   r   r   tensorflow.python.opsr   r    r!   r"   r#   r$   tensorflow.python.platformr%   r  tensorflow.python.profilerr&   tensorflow.python.trackabler'   	trackabletensorflow.python.typesr(   tensorflow.python.utilr)   r*   r+   r,   r-   r.   r/   r0   r1    tensorflow.python.util.tf_exportr2   
LazyLoaderglobalsr3   r4   r  r  r   SHARED_RENDEZVOUS_ATTRIBUTE_NAMECounterr  rC   rG   rU   rd   rv   rV  rw   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  
namedtuplerd  rh  r  r  r  r  r  	TrackableRegisterTyper8   r8  rP  rc  r  r  r  r  r  r  r  r  r@  r  r  rA   rA   rA   rB   <module>   s$   
! c L   H*W,       ^  x     
  Y
        O9