
    BVhT                        d Z ddlZddlZddlmZ ddlmZ ddlmZ ddl	m
Z
 ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ dZ G d de      Z G d de      Z G d de      Z  G d de      Z! G d dejD                        Z#	 	 	 	 	 	 	 	 	 dEdZ$d Z%d  Z&dFd!Z'd" Z(d# Z)d$ Z*d% Z+d& Z,d' Z-d( Z.d) Z/i ej`                  d*ejb                  d+ejd                  d,ejf                  d-ejh                  d.ejj                  d/ejl                  d0ejn                  d1ejp                  d2ejr                  d.ejt                  d3ejv                  d4ejx                  d5ejz                  d6ej|                  d7ej~                  d8ej                  d9ej                  d:ej                  d;ej                  d<ej                  d=ej                  d>ej                  d?ej                  d@ej                  dAej                  dBej                  dCej                  dDiZLy)GzPython front-end supports for functions.

NOTE: At this time, functions are experimental and subject to change!. Proceed
with caution.
    N)attr_value_pb2)function_pb2)pywrap_tf_session)context)
c_api_util)dtypes)graph_to_function_def)ops)tensor)	array_ops)resource_variable_ops)variable_scope)compat)function_utils)tf_contextlib)
tf_inspectTc                       e Zd ZdZd Zd Zy)Defunu  Obsolete. Slated for deletion. Please use tf.function instead.

  Known feature gaps while migrating to tf.function (could be outdated):
  - tf.function doesn’t support Send/Recv capability since it doesn’t share
    rendezvous with the main graph but always creates a new one.
  - tf.function doesn’t support custom gradient function directly, instead you
    need to define the function inside a tf.custom_gradient wrapper together
    with the gradient function.
  - Unlike Defun, Keras layers used inside a tf.function need to be created only
    once to avoid variable recreation.
  - Defun respects the device assignments and applies them to the function body
    but tf.function needs it to be done manually.
  - Defun might prune out unused ops automatically but tf.function doesn't.

  Limitations of Defun:
  - Original source locations are not preserved so errors do not include
    full/valid stack traces.
  - Only supports linear sequence of arguments and return values, putting the
    burden on the caller to pack/unpack everything across a Defun boundary into
    tuples (as opposed to passing list and dict-like structures directly).
  - Does not support overloading or late-bound specializations.
  - Has its own way for defining gradient overrides which does not follow
    current conventions.
  - Cannot support imperative control flow or automatic control dependencies.
  - Does not reflect statefulness in the graph and has a calling convention that
    differs from how more modern tools interact.
  - Is only compatible with graph building mode.

  Decorator used to define TensorFlow functions.

  Use this decorator to make a Python function usable directly as a TensorFlow
  function.

  The decorated function must add ops to the default graph and return zero or
  more `Tensor` objects.  Call the decorator with named arguments, one for each
  argument of the function to decorate, with the expected type of the argument
  as value.

  For example if the function to decorate accepts two `tf.float32` arguments
  named `x` and `y`, call the decorator with:

      @Defun(tf.float32, tf.float32)
      def foo(x, y):
        ...

  When you call the decorated function, it adds the `call` ops to the
  default graph. In addition, it adds the definition of the function into the
  default graph. Because the addition of the function into the graph
  is deferred, the decorator can be used anywhere in the program.

  Any variables created inside of the function are hoisted into the outer graph.
  Note that the variables are created in the variable scope that was active
  during the first call to the function. Subsequent function calls will refer to
  the same set of variables.

  Definitions of functions in a graph are frozen as soon as the graph is used to
  create a session. However, new functions and new calls to existing functions
  may be added to the graph, with the new functions themselves becoming
  immediately frozen.

  Example, but also see the [How To on functions](link_needed).

  ```python
  # Defining the function.
  @tf.Defun(tf.float32, tf.float32)
  def MyFunc(x, y):
    return x + y, x - y

  # Building the graph.
  a = tf.constant([1.0])
  b = tf.constant([2.0])
  c, d = MyFunc(a, b, name='mycall')
  ```
  c                     || _         |j                  dd      | _        |j                  dd      | _        |j                  dd      | _        |j                  dd      | _        || _        y)a  Create a `Defun` decorator.

    Args:
      *input_types: A list of `tf.DType`
      **kwargs: Optional keyword arguments, including
         func_name - (optional).  A python string, the name to use to
           declare this `Function` in the graph.

         grad_func - (optional).  A function implementing the gradient
           of the function-to-register.  This is must be a
           `_DefinedFunction` object. The gradient
           function must satisfy the criterion defined in
           function.proto:GradientDef.

         python_grad_func - (optional).  A function implementing the
           gradient of the function python-side. This function must
           take the current op and the gradients w.r.t. its outputs,
           and return the gradients w.r.t. the inputs. That is it must
           implement the interface expected by `tf.RegisterGradient`).
           This will be called by tf.gradients to add the gradient ops
           to the graph. At most one of grad_func and python_grad_func
           can be specified.

         out_names = (optional). A list of strings, one per output
           tensor.

         shape_func - (optional). A function taking the op and returning a list
           of static shapes to set for the function's outputs.
    	func_nameN	grad_funcpython_grad_func	out_names)_input_typespop
_func_name
_grad_func_python_grad_func
_out_names_extra_kwargs)selfinput_typeskwargss      T/home/dcms/DCMS/lib/python3.12/site-packages/tensorflow/python/framework/function.py__init__zDefun.__init__y   s^    < $Djjd3DOjjd3DO#ZZ(:DADjjd3DOD    c                    t        |      st        d| d      t        j                  |      }|j                  s|j
                  r)t        d| d|j
                   d|j                   d      t        |j                        }|}|j                  rd}|j                  }t        j                  |      r
|dz  }|dd  }| j                  rt        | j                        }||k  s||kD  rt        d	| d
| d| d| d	      t        ||| j                  | j                  | j                  | j                  fd| j                  i| j                   S |dk(  rJ|dk(  rEt        |g g | j                  | j                  | j                  fd| j                  i| j                   S t#        ||| j                  | j                  | j                  fd| j                  i| j                   S )N	Function z must be a callable.zJFunctions with argument defaults or keywords arguments are not supported. z has defaults z and keywords .i@B    zVThe number of tf.function input types is not compatible with the allowed arguments of z. The tf.function have z7 input types, while the python function allows minimum z and maximum z arguments.r   r   )callable
ValueErrorr   
getargspeckeywordsdefaultslenargsvarargsismethodr   _DefinedFunctionr   r   r   r   r    _OverloadedFunction)r!   funcargspecmin_argsmax_argsargnamesnums          r$   __call__zDefun.__call__   s   D>4&(<=>> ##D)G7++v^G,<,<+=^a!" " 7<< HHh||H4 !mh!"h !!"c	x3>$$(6)@ F??Gj Ij-. 	.
 





//
//

 
   OO      1}Q
B
//
//

 
 	 
 OO       // 

 r&   N)__name__
__module____qualname____doc__r%   r<    r&   r$   r   r   -   s    IV# J?r&   r   c                   "    e Zd ZdZdgZd Zd Zy)_DefinedFunctionDeleterz'Unregister function from eager context.namec                     || _         y NrD   )r!   rD   s     r$   r%   z _DefinedFunctionDeleter.__init__   s	    DIr&   c                 v    	 t        j                  | j                         y # t        $ r Y y t        $ r Y y w xY wrF   )r   remove_functionrD   	TypeErrorAttributeErrorr!   s    r$   __del__z_DefinedFunctionDeleter.__del__   s8    dii(   
s   " 	888N)r=   r>   r?   r@   	__slots__r%   rM   rA   r&   r$   rC   rC      s    /h)r&   rC   c                       e Zd ZdZ	 	 	 	 	 	 	 	 ddZed        Zed        Zed        Zed        Z	d Z
ed	        Zed
        Zed        Zed        Zed        Zd Zd Zd Zd Zd Zd Zy)r4   a  _DefinedFunction encapsulates a function definition and its properties.

  Attributes:
    name: The function name.
    definition: The definition of this function. A FunctionDef proto.
    cached_definition: Same as definition. Needed to match AtomicFunction API.
    grad_func_name: If not None, the name of this function's gradient function.
    python_grad_func: A python callable implementing the gradient of
      the function python-side.
  Nc                 4   || _         || _        || _        || _        || _        || _        || _        |	| _        |
| _        | j                  t               | _        || _
        || _        d| _        d| _        d| _        i | _        t!        j"                         j$                  }|r|d   nd| _        d| _        t+        |t,        t.        f      sJ || _        t3        t5        |            D cg c]  }|t5        |      k  r||   nd|z   c}| _        yc c}w )a4  Creates _DefinedFunction.

    Args:
      func:  A python callable which constructs a tf function body.
      argnames: A list of strings for function argument names.
      input_types: The function's argument types. Can be a tuple, list of
        tf data types.
      func_name: The function name. Defaults to None, in which derives from
        'func'.
      grad_func: This function's gradient function, if not None. Defaults
        to None.
      python_grad_func: A python callable implementing the gradient of
        the function python-side.
      out_names: An optional list of strings for the function return value
        names.
      shape_func: An optional function mapping an op to a list of static
        output shapes.
      capture_by_value: Boolean (defaults to False). If True, captured values
        will be copied into the function body.
      allowlisted_stateful_ops: A set of ops that if stateful we ignore and
        copy into the function body, when `capture_by_value` is True.
      capture_resource_var_by_value: Boolean (defaults to True). If False,
        captured resource variable returns the handle instead of value.
      **kwargs: The keyword arguments. **kwargs is passed to every call
        site of this function.

    Raises:
      ValueError: The function definition is invalid.

    Nzarg%d)_funcr   r   r   r   r   _shape_func_capture_by_value_allowlisted_stateful_opsset_capture_resource_var_by_valuer    _definition_c_func_function_deleter_sub_functionsr
   get_default_graph _device_functions_outer_to_inner_caller_device_op_def
isinstancelisttuple
_arg_typesranger0   
_arg_names)r!   r6   r:   r"   r   r   r   r   
shape_funccapture_by_valueallowlisted_stateful_opscapture_resource_var_by_valuer#   device_funcsis                  r$   r%   z_DefinedFunction.__init__  s   V DJ#DDODO-DDO!D-D%=D"%%-'*ud$*GD'DDDL!DD((*KKL /;,r*D DLkD%=111!DO %c+&6 79 '(#h-&7x{gkJ 9DO 9s   -Dc                 :    | j                          | j                  S )zFunction name.)_create_definition_if_neededr   rL   s    r$   rD   z_DefinedFunction.nameT  s     	%%'??r&   c                     | j                   S rF   )
definitionrL   s    r$   cached_definitionz"_DefinedFunction.cached_definitionZ  s    ??r&   c                    | j                          | j                  rt        j                         5 }| j                  j	                         5 }t        j                  ||       t        j                         }t        j                  |      }|j                  t        j                  |             t        j                         5  t        j                          r9t        j"                  |       t%        |j&                  j(                        | _        ddd       ddd       ddd       S | j,                  S # 1 sw Y   'xY w# 1 sw Y   +xY w# 1 sw Y   S xY w)zFunction definition proto.N)rm   rY   r   	tf_buffergetc_apiTF_FunctionToFunctionDefr   FunctionDefTF_GetBufferParseFromStringr   as_bytesr
   
init_scoper   executing_eagerlyadd_c_functionrC   	signaturerD   rZ   rX   )r!   bufr6   fdef
proto_datas        r$   ro   z_DefinedFunction.definition^  s    	%%'||! 
'S\\ 		'4

(
(s
3))+$))#.*


vz:
;~~ '((*$$T*'>..%%('d$'		'
' k' '		' 		'
' ks=   EA8EAD9EE9E>EE	
EEc                 :    | j                          | j                  S rF   )rm   r_   rL   s    r$   
_signaturez_DefinedFunction._signatureq  s    %%'<<r&   c                 R    | j                   rJ t        |t              sJ || _         y)z1Specifies the gradient function of this function.N)r   r`   r4   )r!   r   s     r$   set_grad_funcz_DefinedFunction.set_grad_funcv  s'    i!1222DOr&   c                 J    | j                   r| j                   j                  S dS )z*Returns the name of the gradient function.N)r   rD   rL   s    r$   grad_func_namez_DefinedFunction.grad_func_name|  s     $(??4??<<r&   c                     | j                   S )z"Python gradient function callable.)r   rL   s    r$   r   z!_DefinedFunction.python_grad_func  s     !!!r&   c                     | j                   S )z;Returns the list of data types of explicit declared inputs.)r   rL   s    r$   declared_input_typesz%_DefinedFunction.declared_input_types       r&   c                 :    | j                          | j                  S )z/Returns the list of implicitly captured inputs.)rm   _extra_inputsrL   s    r$   captured_inputsz _DefinedFunction.captured_inputs  s     	%%'r&   c                 :    | j                          | j                  S )zuReturns the list of stateful ops in function definition.

    Returns:
      A list of (op.name, op.type) pairs.
    )rm   _stateful_opsrL   s    r$   stateful_opsz_DefinedFunction.stateful_ops  s     	%%'r&   c                 v    t        j                         5  | j                          ddd       y# 1 sw Y   yxY w)z8Creates the function definition if it's not created yet.N)r   
graph_mode!_create_definition_if_needed_implrL   s    r$   rm   z-_DefinedFunction._create_definition_if_needed  s/    				 /
,,./ / /s   /8c                 v
   | j                   | j                  yg }|j                  t        j                  j
                         |j                  t        j                         t        j                         }|D ci c]  }||j                  |       }}t        | j                  | j                  | j                  | j                  | j                   | j"                  || j$                  | j&                  	      }|j(                  | _        |j,                  | _        | j                  r| j                  }nGt1        j2                  | j                        }| j4                  r|d| j4                  j6                  z  z  }t9        |fi | j:                  }|j<                  st?        j>                  ||jA                         |jB                  |jD                  | jF                        | _         |D ]-  }| j                   jH                  |   jK                  ||          / | jM                  | j                   jN                  jP                  | j                   jN                  jR                  | j                   jT                        | _+        | j                  s"djY                  || jV                  g      | _        | j                  | j                   jN                  _        | j                  jZ                  r/| j                  jZ                  | j                   jN                  _.        | j                   jN                  | _/        n| jF                  r-| jF                  D 	cg c]  }	ta        jb                  |	       c}	ng }
| j                  jZ                  xs d}|j<                  je                         5 }tg        jh                  ||| j                  du d|jB                  D cg c]  }|jk                          c}|jD                  D cg c]  }|jk                          c}|
g g d|      }ddd       tm        jn                  |      | _        | jq                  |       | jr                  jN                  | _/        | j                  r%| j                  | j^                  j6                  k(  s0J ta        jt                  | j^                  j6                        | _        |jA                         D cg c]&  }|jv                  r|j6                  |jx                  f( c}| _=        yc c}w c c}	w c c}w c c}w # 1 sw Y   
xY wc c}w )z<This is not what you want, see _create_definition_if_needed.N)collections_refrh   ri   z_%s)r   _)>rX   rY   extendr
   	GraphKeys_VARIABLE_COLLECTIONSappendvs_VARSTORE_KEYr\   get_collection_reffunc_graph_from_py_funcrR   re   rc   r   rT   r^   rU   rW   extra_inputsr   
_functionsr[   r   get_func_namer   rD   _parse_kwargs_as_attrsr    _c_graphr	   get_operationsinputsoutputsr   attrCopyFrom_create_hash_strr}   	input_arg
output_argnode_def	_hash_strjoinr@   descriptionr_   r   ry   rs   rt   TF_GraphToFunction_wrapper_as_tf_outputr   ScopedTFFunction_set_c_attrsro   as_str_is_statefultyper   )r!   variable_keysparent_graphkeyr   
temp_graphbase_func_namekwargs_attrkxoutput_namesr   c_graphtc_funcops                   r$   r   z2_DefinedFunction._create_definition_if_needed_impl  s-   #t||'?
 M<<=))*((*L=JL69\,,S11LO L )

'!%!?!?&*&I&I	KJ $00D$//D n%33DJJ?n	54??#7#778(N4;M;MNK .DD


#
#
%





OO%d  :!a ))+a.9: ,,



$
$
.
.



$
$
/
/1A1A1J1JLdn __((NDNN#CD(,d  %			151C1C"".%%//dl  48??Cavq)C.0 JJ&&.$k""$ 11OOt#(2(9(9:1Q__:(2(:(:;1Q__;  00Hdl
$ __..dl	$,,"3"3333 --(9(9: %/$=$=$?. __ 77BGG, .DiLp D ;; 0.s<   <TT).T)T.T)>T$T)!+T6
T))T3c                    |j                         D ]b  \  }}|j                         }| j                  j                         5 }t	        j
                  |t        j                  |      |       ddd       d y# 1 sw Y   oxY w)zSets `attrs` as attributes of self._c_func.

    Requires that self._c_func is not None.

    Args:
      attrs: a dictionary from attribute name to attribute proto value
    N)itemsSerializeToStringrY   rs   rt   TF_FunctionSetAttrValueProtor   r   )r!   attrsrD   
attr_value
serializedr6   s         r$   r   z_DefinedFunction._set_c_attrs  sx     "KKM 7j//1j << 7**4t1D+5	77 7	77 7s   +A77B 	c                 >  	
 t        j                         fd		fd
	
fd}|D ]  } 
|j                                 |D ]  } 
|j                                 t        |d       D ]  } 
|j                          
|j
                          ||j                          	t        |j                               t        |j                        D ]-  } 
|        
|j                  |   j                                /  j                         dd S )a  Creates an 8-character string unique to this input.

    Args:
      input_arg: the input_arg field of an OpDef
                 (e.g. self._definition.signature.input_arg)
      output_arg: the output_arg field of an OpDef
                 (e.g. self._definition.signature.output_arg)
      node_def: the node_def field of a FunctionDef
                (e.g. self._definition.node_def)

    Returns:
      The unique string for this input
    c                 T    j                  t        j                  d| z               y )Nz%x)updater   ry   )nhashers    r$   
update_numz5_DefinedFunction._create_hash_str.<locals>.update_num%  s    mmFOOD1H-.r&   c                 p     t        |              j                  t        j                  |              y rF   )r0   r   r   ry   )sr   r   s    r$   
update_strz5_DefinedFunction._create_hash_str.<locals>.update_str(  s$    QmmFOOA&'r&   c                 F     t        |              | D ]
  } |        y rF   )r0   )slistr   r   r   s     r$   update_strsz6_DefinedFunction._create_hash_str.<locals>.update_strs,  s%    U !1r&   c                     | j                   S rF   rG   )r   s    r$   <lambda>z3_DefinedFunction._create_hash_str.<locals>.<lambda>7  s
    AFF r&   )r   N   )
hashlibsha1r   sortedrD   r   inputr0   r   	hexdigest)r!   r   r   r   r   adefr   r   r   r   r   s           @@@r$   r   z!_DefinedFunction._create_hash_str  s     \\^F/(
  +'')*+  +'')*+ H"23 2!''QVVaff~ 2!1166!9..0122 bq!!r&   c                 z   | j                          t        j                         r.t        j                         j                  | j                         n|j                  |        | j                  j                         D ]  }|j                  |        | j                  r| j                  j                  |       yy)z$Adds this function into the graph g.N)rm   r   r{   add_function_defro   _add_functionr[   values_add_function_recursiver   add_to_graph)r!   gfs      r$   r   z_DefinedFunction.add_to_graphC  s    %%'   "oo((9ood   '') #"# 
oo""1% r&   c           
         | j                  t        j                                |D cg c]  }t        j                  |       c}| j                  z   }t        | j                  g|i |\  }}t        |t        j                        sJ t        |d|        | j                  | j                  |      }t        |      t        |j                        k7  r<t        d| j                   dt        |      ddt        |j                         d      t        |j                  |      D ]  \  }}|j                  |        |S c c}w )N__defunzshape_func z
 produced dz shapes, which does not match z	 outputs.)r   r
   r\   convert_to_tensorr   _callr   r`   	OperationsetattrrS   r0   r   r,   zip	set_shape)	r!   r1   r#   r   retr   shapesr   shapes	            r$   r<   z_DefinedFunction.__call__W  s"   c++-..23C!!!$3d6H6HHDDOO5d5f5GC b#--(((B	4 ##f	VBJJ	';t'7'7&8
K?*H

O,I7 8 	8 BJJ/ *1e	EJ! 4s   E)NNNNNFNT)r=   r>   r?   r@   r%   propertyrD   rp   ro   r   r   r   r   r   r   r   rm   r   r   r   r   r<   rA   r&   r$   r4   r4      s   	  $ %(,-1N9`  
    $    = = " "    
  /
c.J7 ,"\&(r&   r4   c                   ,    e Zd ZdZ	 	 	 	 ddZd Zd Zy)r5   z_OverloadedFunction encapsulates an overloaded function.

  _OverloadedFunction maintains a mapping from input types to
  instantiated _DefinedFunction in self._overload.

  Nc                     || _         || _        || _        |t        |t              sJ || _        || _        || _        || _        i | _	        y)a  Creates _DefinedFunction.

    Args:
      func:  A python callable which constructs a tf function body.
      argnames: A list of strings for function argument names.
      func_name: The function name. Defaults to None, in which derives from
        'func'.
      grad_func: This function's gradient function, if not None. Defaults
        to None.
      python_grad_func: A python callable implementing the gradient of
        the function python-side.
      out_names: A list of strings for the function return value names.
      **kwargs: The keyword arguments. **kwargs is passed to every call
        site of this function.

    Raises:
      ValueError: The function definition is invalid.

    N)
rR   	_argnamesr   r`   r5   r   r   r   r    	_overload)r!   r6   r:   r   r   r   r   r#   s           r$   r%   z_OverloadedFunction.__init__t  sT    6 DJDNDO
96I JJJDO-DDODDNr&   c                 @   t        |      }| j                  j                  |      }|s| j                  }|dj	                  ||g      }t        | j                  | j                  ||d| j                  fd| j                  i| j                  }|j                  }| j                  rc|j                  j                  D cg c]!  }t        j                   |j"                        # }}| j                  j%                  ||z         |_        || j                  |<   |S c c}w )zInstantiate this function given input argument types.

    Args:
      input_types: A list of data types for the inputs.

    Returns:
      _DefinedFunction for the given input types.

    Nr   r   )_type_list_to_strr   rs   r   r   r4   rR   r   r   r   r    rD   r   r   r   r   DTyper   instantiate)r!   r"   r   definedrD   r   output_typess          r$   r   z_OverloadedFunction.instantiate  s    K
(Cnn  %G__d		xxs$ 
**
..




 
   OO   g ,,a	
 +2*<*<*G*G
%&FLL 
 
 "__889E:F G $dnnSN
s   ?&Dc           	      D   g }t        |      }t        |      D ]o  \  }}t        j                  |      }t	        |t
        j                        st        d| dt        |       d      |j                  |j                         |||<   q  | j                  |      |i |S )NzExpected a Tensor but got z with type r)   )ra   	enumerater
   r   r`   
tensor_libTensorr,   r   r   dtyper   )r!   r1   r#   r"   rk   r   s         r$   r<   z_OverloadedFunction.__call__  s    K:DD/ A



"a:,,-5aSDG9ANOO!d1g )4K($9&99r&   )NNNN)r=   r>   r?   r@   r%   r   r<   rA   r&   r$   r5   r5   l  s&      $#J(T	:r&   r5   c                        e Zd ZdZ fdZed        Zej                  d        Z		 	 	 	 	 	 	 ddZ
	 	 	 	 	 	 d fd	ZddZed        Zdd	Zd
 Zdej"                  fdZ xZS )
_FuncGrapha  A helper for constructing a function.

  _FuncGraph overrides ops.Graph's create_op() so that we can keep
  track of all inputs into every op created inside the function.  If
  any input is from other graphs, we keep track of it in self.capture
  and substitute the input with a place holder.

  Each captured input's corresponding place holder is converted into a
  function argument and the caller passes in the captured tensor.
  c                 `   t        t        | 
  |i | || _        || _        || _        d| _        t        j                         | _	        t        j                         | _        | j                  j                  | _        || _        g | _        g | _        i | _        g | _        g | _        g | _        y )NT)superr  r%   rT   rU   rW   _building_functionr
   r\   _outer_graphr   get_variable_scope_vscopecustom_getter_old_custom_getterrD   r   r   	_capturedr   
extra_args
extra_vars)r!   rD   rg   rh   ri   r1   r#   	__class__s          r$   r%   z_FuncGraph.__init__  s    	*d$d5f5-D%=D"*GD'"D--/D((*DL"ll88D DI DK DLDN D DO DOr&   c                     | j                   S )z2The graph active when this _FuncGraph was created.)r	  rL   s    r$   outer_graphz_FuncGraph.outer_graph  r   r&   c              #     K   | j                   }t        j                         5  t        j                         j                   }ddd       	 || _         t        j                         5  |t        j                         _         ddd       | j                    || _         t        j                         5  t        j                         _         ddd       y# 1 sw Y   xY w# 1 sw Y   axY w# 1 sw Y   yxY w# || _         t        j                         5  t        j                         _         ddd       w # 1 sw Y   w xY wxY ww)a  Returns a context manager that specifies the resource container to use.

    Overridden from `tf.Graph` to update both the init_scope container
    and the present inner container. This is necessary to make sure setting
    containers applies correctly both to created variables and to stateful
    ops.

    Args:
      container_name: container name string.

    Returns:
      A context manager for defining resource containers for stateful ops,
        yields the container name.
    N)
_containerr
   rz   r\   )r!   container_nameoriginal_containeroriginal_init_containers       r$   	containerz_FuncGraph.container  s      		 C # 5 5 7 B BCE&do>> <-;*<OO*do>> E-D*E EC C< <
E E +do>> E-D*E E Es|   !ECEC8 &C  C8 E1C,	ECE C)%C8 ,C51E8ED7.	E7E <EEc
                    | j                   j                         5  | j                  j                  t	        j
                         ||||||||		      }| j                  j                  |       t        |t        j                        r%| j                  r|j                         cddd       S |cddd       S # 1 sw Y   yxY w)zA custom variable getter.)r   r  initializerreuse	trainablecollectionsuse_resourceN)r	  
as_defaultr  get_variabler   _get_default_variable_storer  r   r`   r   BaseResourceVariablerW   value)r!   getterrD   r   r  r  r  r  r  r  r#   vars               r$   getvarz_FuncGraph.getvar#  s    ( 
			%	%	' LL%%

(
(
*
!!# & 	%c ooS!
S/DD
E

-
-
 yy{' ( )  s   BB7,B77C c	           
          t        |      D ]B  \  }	}
t        |
t        j                        s|
j                  | us/| j                  |
      ||	<   D t        t        | #  ||||||||      S )N)r   r"   rD   r   op_defcompute_device)	r   r`   r
   EagerTensorgraphcapturer  r  _create_op_internal)r!   op_typer   r   r"   rD   r   r)  r*  rk   r   r  s              r$   r.  z_FuncGraph._create_op_internalM  sz     &! $1	As	'177$+>LLOq	$ T6% 7 ' 'r&   c                     |j                         | j                  v r| j                  |j                            S | j                  r| j                  |      S | j	                  ||      S )zDAdds the given tensor to this graph and returns the captured tensor.)refr  rT   _add_tensor_and_parents_capture_tensor_as_extra_input)r!   r   rD   s      r$   r-  z_FuncGraph.captured  sV    zz|t~~%^^FJJL))			))&1100>>r&   c                     | j                   j                         D cg c]  \  }}|j                         |f c}}S c c}}w )z%Pairs of tensors and captured tensor.)r  r   deref)r!   r   vs      r$   capturesz_FuncGraph.capturesn  s3     (,~~';';'=>tq!QWWYN>>>s   >c                 B   | j                   j                  |       t        j                  d       5  t	        j
                  |j                  |j                         |      }d d d        t        |t        j                        r|j                  }|rb|j                         }nQ|j                  j                  j                         5 }t        j                   ||j#                               }d d d        rej                  j                  j                         5 }t        j$                  ||j#                         t'        j(                  |             d d d        | j*                  j                         || j,                  |j/                         <   | j0                  j                  |       t3        |      r4t        j                  d       5  t	        j4                  |      cd d d        S |S # 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   y xY w)Nr   rD   )r   r   r
   control_dependenciesr   placeholderr  	get_shaper`   r+  _handle_datar   r,  r   rs   rt   GetHandleShapeAndTyper   SetHandleShapeAndTyper   ry   r   r  r1  r  _is_guaranteed_constguarantee_const)r!   r   rD   phhandle_datar   s         r$   r3  z)_FuncGraph._capture_tensor_as_extra_inputs  s   V$ 
	!	!$	' =  
,,f..0t=b= &#//*''k	!335<<  $$& J'11'282F2F2HJJ 88  " Bg##GR-=-=-?$*OOK$@	BB 	KKr#%DNN6::< OO2F###D) -((,- - i3= =J J
B B- -s/   1G/%G<9H	H/G9<H	HHc                 j    | j                  |j                        }|j                  |j                     S rF   )_add_op_and_parentsr   r   value_index)r!   r   r   s      r$   r2  z"_FuncGraph._add_tensor_and_parents  s+    		!	!&))	,B::f(())r&   r   c                    t        j                  |      }|j                  r4|| j                  vr&t	        d|j
                   d|j                   d      |j                  dv r&t	        d|j
                   d|j                   d      |j                  D cg c]  }| j                  |       }}| j                  |j                  ||j                  D cg c]  }|j                   c}|j
                  |j                  j                  |      }t        |j                  |j                        D ]"  \  }}|| j                  |j!                         <   $ |S c c}w c c}w )Nz%Cannot capture a stateful node (name:z, type:z) by value.)PlaceholderPlaceholderV2z#Cannot capture a placeholder (name:rD   r   r)  )r	   _get_op_defr   rU   r,   rD   r   r   r2  r.  r   r  r   r   r   r  r1  )	r!   r   r)  r   r   ocaptured_opr   
captured_ts	            r$   rE  z_FuncGraph._add_op_and_parents  sM   "..r2F	2T%C%CC>rwwi H!wwi{4 5 5	4	4<RWWI F!wwi{4 5 5 AC		J1t33A6JOJ**
2::6a!''6WWkk + K RZZ)<)<= +: *dnnQUUW+  K 7s   EE)NNNNTNN)NNNNNTrF   )r=   r>   r?   r@   r%   r   r  r   contextmanagerr  r'  r.  r-  r7  r3  r2  r
   r   rE  __classcell__)r  s   @r$   r  r    s    	D   E  EH (\ '.? ? ?@*CMM r&   r  c                    |st        j                  |       }t        |||
|      }|j                         5  t	        j
                  |      5  |||_        |||_        |||_        |	dgt        |      z  }	t        |||	      D ]9  \  }}}t        j                  |||      }|j                  j                  |       ; t        j                   d|j"                        5   | |j                   }ddd       g }n:t%        |t&        t(        f      s|f}t+        d |D              rt-        d| d      |D cg c]  }t	        j.                  |       }}|D cg c]#  }|j0                  |ur|j3                  |      n|% }}||_        ddd       ddd       |S # 1 sw Y   xY wc c}w c c}w # 1 sw Y   )xY w# 1 sw Y   |S xY w)a  Returns a _FuncGraph generated from `func`.

  Args:
    func: A Python callable which constructs a TF function body. The arguments
      must correspond to `arg_types`. Returns a value or list/tuple of values.
      No returned value can be None.
    arg_names: A sequence of strings for the function argument names.
    arg_types: A sequence of the function's argument types.
    name: The function name. If None, the name is derived from `func`.
    capture_by_value: boolean. If True, captured values will be copied into the
      function body.
    device: device name or function.
    colocation_stack: A colocation stack (list) the _FuncGraph should use.
    container: A container name the _FuncGraph should start with.
    collections_ref: A reference to a collections dict the _FuncGraph should
      use internally.
    arg_shapes: A sequence of the function's argument shapes.
    allowlisted_stateful_ops: A set of ops that if stateful we ignore and
      re-create.
    capture_resource_var_by_value: Boolean (defaults to True). If False,
      captured resource variable returns the handle instead of value.

  Returns:
    A _FuncGraph.

  Raises:
    ValueError: if func returns None.
  Nr9   )r  c              3   $   K   | ]  }|d u  
 y wrF   rA   .0r   s     r$   	<genexpr>z*func_graph_from_py_func.<locals>.<genexpr>  s     (1Q$Y(s   r(   z can not return None.)r   r   r  r   r
   device_collectionsr  _colocation_stackr0   r   r   r;  r   r   r   r   r'  r`   ra   rb   anyr,   r   r,  r-  r   )r6   	arg_names	arg_typesrD   rg   rW  colocation_stackr  r   
arg_shapesrh   ri   
func_graphargnameargtypeargshape	argholderr   r   s                      r$   r   r     s   P 
''-D$ 02J79*  )!

6 2 )!" /j'j#%5j" 6C	N*j ),Iy*(M *$'8''xgNiy)* 
		2Z->->	? )j''(g) g $/*	((	(9TF*?@AA189As$$Q'9G9! )*z(Az!!!$qH !G ! JS)! )!T 
1) )( :!O)! )! )!T 
sU   GBF9#F#3AF9>F/F9 (F4	F9G#F,(F99G	>GGc                    t        | t        j                        ry G d dt              }d }t	        g       dt        j
                  ffd}t	        g       } || j                  d      g}|r|j                         }|j                  r. ||j                        rj                  |j                         M|j                  |j                          ||j                        rj                  |j                         |j                   ||j                  d             |j                  j                  D ]4  }|j                  |vs|j                   ||j                  d             6 |r| j                  v S )	ao  Determines whether `tensor` is guaranteed to be a constant.

  A tensor is guaranteed to be a constant if either it was produced by
  a `GuaranteeConst` op or if all of its children are guaranteed to be
  constants.

  Args:
    tensor: The tensor for which to determine const-ness.

  Returns:
    True if `tensor` is guaranteed to be a constant, False otherwise.
  Fc                   ,    e Zd Zdej                  fdZy)"_is_guaranteed_const.<locals>.Workr   c                      || _         || _        y rF   )r   leaving)r!   r   rh  s      r$   r%   z+_is_guaranteed_const.<locals>.Work.__init__  s    dgdlr&   N)r=   r>   r?   r
   r   r%   rA   r&   r$   Workrf    s    3== r&   ri  c                 4    | j                   j                  dk(  S )NGuaranteeConst)r   r   r   s    r$   r   z&_is_guaranteed_const.<locals>.<lambda>"  s    2;;>>5E#E r&   r   c                 \    | j                   xr t        fd| j                   D              S )Nc              3   :   K   | ]  }|j                   v   y wrF   rl  )rU  inp	constantss     r$   rV  zA_is_guaranteed_const.<locals>.all_inputs_const.<locals>.<genexpr>'  s     FSSVVy0Fs   )r   all)r   rp  s    r$   all_inputs_constz._is_guaranteed_const.<locals>.all_inputs_const$  s#     99FFBIIFFFr&   )rh  T)r`   r
   r+  objectrV   r   r   r   rh  addr   r   )	r   ri  is_guaranteed_constrr  visitedstackworkro  rp  s	           @r$   r@  r@    s0    (V  F"g)G3== G
 G'		5)
*%99;D||	$''	"dggKK477#mmDGG 
LLdggt,-ww~~ 2	w	T#&&%012 	  
i	r&   c                    t        |      t        | j                        k7  r0t        dt        | j                        ddt        |      dd      |j                  dd      }t	        j
                         }| j                  }||}t        |fi |}| j                  D cg c]!  }t        j                  |j                        # }}|j                  |t        |      ||||       }	|	j                  rDt        |	j                        dk(  r|	j                  d	   }
|
|	fS t        |	j                        }
|
|	fS |	}
|
|	fS c c}w )
a   Adds a node calling a function.

  This adds a `call` op to the default graph that calls the function
  of signature `sig`, passing the tensors in `inputs` as arguments.
  It returns the outputs of the call, which are one or more tensors.

  `sig` is OpDefArg.a `_DefinedFunction` object.

  You can pass an optional keyword parameter `name=string` to name the
  added operation.

  You can pass an optional keyword parameter `noinline=True|False` to
  instruct the runtime not to inline the function body into the call
  site.

  Args:
    sig: OpDefArg. The signature of the function.
    *inputs: arguments to the function.
    **kwargs: Optional keyword arguments.  Can only contain 'name' or
        'noinline'.

  Returns:
     A 2-element tuple. First element: a Tensor if the function returns a single
     value; a list of Tensors if the function returns multiple value; the
     Operation if the function returns no values. Second element: the Operation.

  Raises:
    ValueError: if the arguments are invalid.
  z	Expected r   z arguments, got r)   rD   NrJ  r*   r   )r0   r   r,   r   r
   r\   rD   r   r   r   r   r   r.  ra   r   rb   )sigr   r#   rD   r   r   r   r   r   r   r   s              r$   r   r   >  s8   < 	[C&&
yS]]!3A 66FFAa) * *	FD	!$	!hh)	\D
 
5f
5%03?1&,,qvv&?,?f|$eC  Q"ZZ
2::!JJqMc
 
b. "**c 
b. C	b. @s   "&E c           	      X   d}| j                   j                  D cg c]  }|j                   }}t        d | j                   j                  D              }| j                   j                  }d}| j                   j                  D cg c]  }|j                   }}t        |||||||      }	t        r&| j                         }
t        j                  |
      }nt        j                  |       }t        j                  ||      |	_        g |	_        | j                   |	_        |	S c c}w c c}w )zCreates a _DefinedFunction initialized from a FunctionDef proto.

  Args:
    fdef: a FunctionDef
    grad_func: a _DefinedFunction or None

  Returns:
    A _DefinedFunction representing fdef
  Nc              3   Z   K   | ]#  }t        j                  |j                         % y wrF   )r   as_dtyper   )rU  args     r$   rV  z#_from_definition.<locals>.<genexpr>  s$      E$'foochhEs   )+)r}   r   rD   rb   r   r4   is_ossr   rt   TF_FunctionImportFunctionDef+TF_FunctionImportFunctionDefNoSerializationr   r   rY   r   r_   )r   r   r6   r~  r:   r"   r   r   r   resultr   r   s               r$   _from_definitionr  r  s
     
$"&..":":;3chh;(; E+/>>+C+CE E+nn!!) #'>>#<#<=Csxx=)=D(KI,i9& '')J//
;F>>tDF..vyA&.&>>&. 
-+ < >s   D"D'c                 
   | j                   s| j                  sg S | j                   D ci c]  }|j                  j                  | c}| j                  D ]T  }|j                  vrt        d|j                   d|        |j                  vs;t        d|j                   d|         t        j                  d       }t        j                  t              }| j                  D ]C  }|j                  ||j                  <   ||j                     j                  |j                         E | j                   D cg c]  }||j                  j                     |  }}|st        d|        i }|ru|j                         }|j                  j                  }|j                  ||         }	||   r|	sJ t        ||	      }
|
||<   |j                  fd||   D               |ru|j                         S c c}w c c}w )a  Creates _DefinedFunctions initialized from a FunctionDefLibrary proto.

  This method handles assigning the correct gradient functions to each
  function.

  Args:
    lib: a FunctionDefLibrary

  Returns:
    A list of _DefinedFunctions

  Raises:
    ValueError: `lib` is invalid
  zFunctionDefLibrary missing 'z' FunctionDef
c                       y rF   rA   rA   r&   r$   r   zfrom_library.<locals>.<lambda>  s    r&   z7FunctionDefLibrary contains cyclic gradient functions!
)r   c              3   (   K   | ]	  }|     y wrF   rA   )rU  r   funcss     r$   rV  zfrom_library.<locals>.<genexpr>  s     7aq7s   )functiongradientr}   rD   function_namer,   gradient_funcr  defaultdictra   r   r   rs   r  r   r   )libr   r   func_to_gradgrad_to_funcsgdefreadyinitializedrD   graddefined_funcr  s              @r$   from_libraryr    s    
cllI 25
>4>>$
>% << .ae#5aoo5F G''*e- . .e#5aoo5F G''*e- . .. ((6,))$/-ll Ad'+'9'9L##$$$$%,,T-?-?@A |||DNN4G4G'H'Pd%  


B3%HJ J +99;D>>D??<-.DDkT#DD9L$K	LL7=#677 	 
			U ?*s   G;=H H c                    t        |t              rt        j                  |      S t        |t              rt        j                  |      S t        |t
              rt        j                  |      S t        |t              r)t        j                  t        j                  |            S t        d|  dt        |       d      ))Creates an AttrValue for a python object.b)rk   )r   r   
Attribute z' must be bool, int, float, or str. Got r)   )r`   boolr   	AttrValueintfloatstrr   ry   r,   r   	attr_namer$  s     r$   _get_experimental_kwarg_as_attrr    s    t##e,,%##e,,%##e,,%##fooe&<==
z) -!!%eQ0 1 1r&   c                     t        |t              r)t        j                  t	        j
                  |            S t        d|  dt        |       d      )r  r  r  z must be str. Got r)   )r`   r  r   r  r   ry   r,   r   r  s     r$   _get_kwarg_as_str_attrr    sE    s##fooe&<==
z),>tE{m1M
NNr&   c                 f   i }|j                  dd      }|"t        j                  t        |            |d<   t        j                  d      |d<   |j                  dd      }|j                  dd      }|t        j                  t        |            |d	<   t        j                  t        |            |d
<   dt	        j
                         j                  v r%t	        j
                         j                  d   |d<   n*t        j                  d| z  j                               |d<   t        |j                               }|D ]I  }|j                  d      rt        |||         ||<   ||= *|dk(  s|dk(  s5t        |||         ||<   ||= K |rt        d|j                          d      |S )z)Parses **kwargs into a node's attributes.noinlineNr  	_noinlineT_disable_call_shape_inferencecompiledseparate_compiled_gradients_XlaCompile_XlaSeparateCompiledGradients	_XlaScopezfunction_%sr  experimental__implements
_referencezUnknown keyword arguments: r)   )r   r   r  r  r
   r\   _attr_scope_mapencodera   keys
startswithr  r  r,   )r   r#   r   r  r  r  kwargs_keysr   s           r$   r   r     s   
%ZZ
D)('11DNCE+ ,:+C+Cd+K%'(ZZ
D)( &

+H$ O)33d8nEE--;-E-E
*
+.-E
)* c++-===002BB;OeK)33Y&..02eK V[[]#+ c
~~o&23sDeCj
+		!4)#vc{;eCj
+ 
26;;=/C
DD	,r&   c                  f    t        j                         } t        | t              r| j                  S g S )zReturns the captured variables by the function.

  Returns:
    If the default graph is being used to define a function, the
    returned list of variables are those created inside the function
    body so far. Otherwise, returns an empty list.
  )r
   r\   r`   r  r  r   s    r$   get_extra_varsr    s+     
!:<<Ir&   c                  f    t        j                         } t        | t              r| j                  S g S )a$  Returns the captured input tensors by the function.

  Returns:
    If the default graph is being used to define a function, the
    returned list of tensors are those accessed inside the function body
    but defined outside the function body so far. Otherwise, returns an
    empty list.
  )r
   r\   r`   r  r   r  s    r$   get_extra_inputsr  *  s+     
!:>>Ir&   c                  f    t        j                         } t        | t              r| j                  S g S )a>  Returns the corresponding function arguments for the captured inputs.

  Returns:
    If the default graph is being used to define a function, the
    returned list of place holders are those used inside the function
    body corresponding those returned by get_extra_inputs(). Otherwise,
    returns an empty list.
  )r
   r\   r`   r  r  r  s    r$   get_extra_argsr  :  s+     
!:<<Ir&   c                     t        d | D              r<| D cg c]  }|t        vs| }}t        d| dt        j                          d      dj	                  d | D              S c c}w )Nc              3   ,   K   | ]  }|t         v  y wrF   _DTYPE_TO_STRrT  s     r$   rV  z$_type_list_to_str.<locals>.<genexpr>K  s     /A-	/s   zUnsupported dtypes z" in `types`. Supported dtypes are r)   rR  c              3   .   K   | ]  }t         |     y wrF   r  rT  s     r$   rV  z$_type_list_to_str.<locals>.<genexpr>P  s     1aq!1s   )rZ  r  r,   r  r   )typestype_unsupported_typess      r$   r   r   J  sy    ///,1P5U-5OPP
*+<*= >6%**,-Q0 1 1 
151	11	 Qs
   A'A'f16f32f64i32i8u16u32u64i16r   c64c128i64r  qi8qu8qi16qu16qi32b16f8e5m2f8e4m3fn
f8e4m3fnuzf8e4m3b11fnuz
f8e5m2fnuzi4u4)	NFNNNNNNTrF   )Mr@   r  r   tensorflow.core.frameworkr   r   tensorflow.python.clientr   rt   tensorflow.python.eagerr   tensorflow.python.frameworkr   r   r	   r
   r   r  tensorflow.python.opsr   r   r   r   tensorflow.python.utilr   r   r   r   r  rs  r   rC   r4   r5   Graphr  r   r@  r   r  r  r  r  r   r  r  r  r   float16float32float64int32uint8uint16uint32uint64int16int8string	complex64
complex128int64r  qint8quint8qint16quint16qint32bfloat16float8_e5m2float8_e4m3fnfloat8_e4m3fnuzfloat8_e4m3b11fnuzfloat8_e5m2fnuzint4uint4r  rA   r&   r$   <module>r     s     4 2 ? + 2 . = + < + 7 6 ) 1 0 -	pF pff 0qv qh`:& `:F_ _J "&-2#'-1&*,0'+59:>Wt0 f1h&R=@1O&R  2
NNE
NNE NNE LL%	
 LL$ MM5 MM5 MM5 LL% KK MM3 e v LL% KK  LL%!" MM5#$ MM6
NNF
MM6
OOU

*
L

L
KK
LL$9r&   