
    BVh              	       v   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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% e&ddg      Z' e&ddg      Z(e'jS                  e(      Z* G d d ejV                  dg d             Z, G d! d" ejV                  d"d#d$g            Z- G d% d& ejV                  d&d'd(g            Z. G d) d*e/      Z0 G d+ d,e0      Z1 G d- d.e0      Z2 G d/ d0e2      Z3 G d1 d2e2      Z4 G d3 d4e2      Z5 G d5 d6e2      Z6 G d7 d8e2      Z7 G d9 d:e2      Z8 G d; d<e2      Z9 G d= d>e9      Z: G d? d@e9      Z; G dA dBe9      Z< G dC dDe9      Z= G dE dFe0      Z> G dG dHe/      Z? G dI dJe?      Z@ G dK dLe@      ZA G dM dNe@      ZB G dO dPe?      ZCdQ ZDdR ZEdS ZFdT ZG	 	 d^dUZH	 	 d^dVZI	 	 d^dWZJ	 	 d_dXZK e!j                  ddYZ       e$d[g\      	 	 d_d]              ZMy)`z<Helpers to convert variables to constants in TensorFlow 2.0.    N)attr_value_pb2)	graph_pb2)tensor_shape_pb2)variable_pb2)
config_pb2)meta_graph_pb2)rewriter_config_pb2)context)wrap_function)dtypes)errors)
graph_util)ops)tensor_util)tf_optimizer)	array_ops)	variables)
tf_logging)export_meta_graph)deprecation)object_identity)	tf_exportextra_var_assign_opsIfStatelessIfWhileStatelessWhilec                   $    e Zd ZdZdZed        Zy)_TensorDataz5Data about a tensor that was converted to a constant. c                 B    t        j                  | j                        S )N)type)r   	AttrValuedtypeselfs    `/home/dcms/DCMS/lib/python3.12/site-packages/tensorflow/python/framework/convert_to_constants.py
dtype_attrz_TensorData.dtype_attr8   s    ##44    N)__name__
__module____qualname____doc__	__slots__propertyr(   r    r)   r'   r   r   3   s    =)5 5r)   r   numpyr$   indexc                       e Zd ZdZdZd Zy)	_EndPointzAn endpoint in a graph.r    c                 N    dj                  | j                  | j                        S )Nz{}[{}])formatconvertibler2   r%   s    r'   __str__z_EndPoint.__str__A   s    ??4++TZZ88r)   Nr*   r+   r,   r-   r.   r8   r    r)   r'   r4   r4   =   s    )9r)   r4   r7   r2   c                       e Zd ZdZdZd Zy)_EdgezA directed graph edge.r    c                 N    dj                  | j                  | j                        S )Nz{} -> {})r6   sourcedestinationr%   s    r'   r8   z_Edge.__str__I   s    T[[$*:*:;;r)   Nr9   r    r)   r'   r;   r;   E   s    )<r)   r;   r=   r>   c                   N    e Zd ZdZd Zd Zd Zd Zd Ze	d        Z
e	d        Zy	)
_Convertiblez9An entity that can have variables converted to constants.c                 .    || _         g | _        d | _        y N)_enclosing_graph_outgoing_edges_converted_self)r&   enclosing_graphs     r'   __init__z_Convertible.__init__P   s    +DDDr)   c                     t         )am  A copy of this Convertible to be modified during conversion.

    Returns:
      Implementations should return the copied instance, which in turn should
      be contained in converted_enclosing_graph(). This instance is the one that
      will be modified during conversion. Its main use will be in the
      implementations of convert_variable_to_constant().
    NotImplementedErrorr%   s    r'   converted_selfz_Convertible.converted_selfU   s
     r)   c                     t         )a  Converts a variable in this Convertible and its dependencies.

    This method should make sure that a converted copy of itself is present in
    the converted graph, and that all Convertibles depending on this one also go
    through the same process.

    Args:
      incoming_edge: The graph edge into this Convertible that is being
        converted to a constant.
      tensor_data: The tensor representing the constant.
    rI   r&   incoming_edgetensor_datas      r'   convert_variable_to_constantz)_Convertible.convert_variable_to_constant`   s
     r)   c                     t         )a,  Calls add_outgoing_edge for all edges known to this Convertible.

    This is used to build the graph dependencies, so that conversion of
    variables to constants can be properly propagated through the graph. Usually
    this method will call add_outgoing_edge() to all the Convertible inputs.
    rI   r%   s    r'   create_edgesz_Convertible.create_edgesn   s
     r)   c                 :    | j                   j                  |       y)zAdds an outgoing edge to the Convertible's list of edges.

    Args:
      edge: The outgoing edge (its source should be 'self').
    N)rD   append)r&   edges     r'   add_outgoing_edgez_Convertible.add_outgoing_edgew   s     	%r)   c                 6    | j                   j                         S )zThe graph being converted.)rC   rK   r%   s    r'   converted_enclosing_graphz&_Convertible.converted_enclosing_graph   s       //11r)   c                     | j                   S )z/The list of edges starting at this Convertible.)rD   r%   s    r'   outgoing_edgesz_Convertible.outgoing_edges   s     r)   N)r*   r+   r,   r-   rG   rK   rP   rR   rV   r/   rX   rZ   r    r)   r'   r@   r@   M   sF    A 
	& 2 2    r)   r@   c                   Z     e Zd ZdZ fdZd Zed        Zed        Zd Z	d Z
d Z xZS )		_FunctionzA library function Convertible.

  Edges into functions are edges from node _inputs_ into function _inputs_:
  Functions get their input from their callers, not from node outputs, and the
  callers in turn get those values as inputs.
  c           	          t         t        |   |       || _        |j                  D ci c]%  }|j
                  t        j                  || |      ' c}| _        y c c}w )NnodefunctionrF   )	superr\   rG   	_functionnode_defname_Nodenew_nodes)r&   r`   rF   n	__class__s       r'   rG   z_Function.__init__   s^    	)T#O4DN ""  	
		q4	I	JDK s   *Ac                 B    | j                   j                  j                  S rB   )r`   	signaturerd   r%   s    r'   r8   z_Function.__str__   s    ==""'''r)   c                     | j                   S rB   )rb   r%   s    r'   r`   z_Function.function   s    >>r)   c                     | j                   S rB   rg   r%   s    r'   nodesz_Function.nodes       ;;r)   c                    | j                   s| j                  j                  j                  }| j                  j
                  |   }| j                  j                  ||       | j                  j                  |   | _         | j                   S )a  The Function copy to be converted.

    The copy will be renamed according to the graph's converted_function_name
    map, to ensure the name does not match anything currently in TensorFlow's
    function cache.

    Returns:
      The function instance to be converted.
    )	rE   r`   rk   rd   rC   converted_function_namesrX   rename_function	functions)r&   old_namenew_names      r'   rK   z_Function.converted_self   sv     #((--h&&??Ih
$$44XxH!;;EEhOdr)   c                    |j                   j                  }| j                  D ]B  }|j                  j                  |k(  s|j                   j                  j                  ||       D | j                         j                  }|j                  |j                  j                  |   _        d|j                  v r^d|j                  d   j                  j                  |   _        |j                  d   j                  j                  |   j                   dd= |j"                  |   j                  }d|v rKd|d   j                  j                  d   _        |d   j                  j                  d   j                   dd= yy)zConverts one function argument into a constant.

    Args:
      incoming_edge: The edge into the argument to be converted.
      tensor_data: The constant value.
    _input_shapesTN_output_shapesr   )r>   r2   rZ   r=   r7   rP   rK   r`   r$   rk   	input_argr"   attrlistshapeunknown_rankdimarg_attr)r&   rN   rO   r2   rU   r`   	arg_attrss          r'   rP   z&_Function.convert_variable_to_constant   sO    %%++E## 			e	#$$AA+	
 ""$--H/:/@/@H  ', (--'FJhmmO$))//6C
--
(
-
-
3
3E
:
>
>q
A!!%(--I9$?Ci !&&,,Q/<
$
%
*
*
0
0
3
7
7
: %r)   c                 b    | j                   j                         D ]  }|j                           y rB   )rg   valuesrR   )r&   rh   s     r'   rR   z_Function.create_edges   s(    [[! nnr)   )r*   r+   r,   r-   rG   r8   r/   r`   ro   rK   rP   rR   __classcell__ri   s   @r'   r\   r\      sI    (     ";4r)   r\   c                   v     e Zd ZdZ fdZd Zed        Zed        Z	ed        Z
d Zd Zd	 Zd
 Zd Z xZS )re   zA Convertible NodeDef.c                 H    t         t        |   |       || _        || _        y rB   )ra   re   rG   _noderb   r&   r_   r`   rF   ri   s       r'   rG   z_Node.__init__   s     	%0DJDNr)   c                 .    | j                   j                  S rB   )r   rd   r%   s    r'   r8   z_Node.__str__   s    ::??r)   c                 |   | j                   dv rt        | ||      S | j                   dk(  rt        | ||      S | j                   dk(  rt        | ||      S | j                   dk(  rt	        | ||      S | j                   dk(  rt	        | ||      S | j                   dk(  rt        | ||      S | j                   dk(  rt        | ||      S | j                   dk(  rt        | ||      S | j                   d	v rt        | ||      S | j                   d
v rt        | ||      S | j                   dv rt        | ||      S t        | ||      S )z/Creates a new _Node base on its operation type.)
VariableV2VarHandleOpPlaceholderCaseMergePartitionedCallStatefulPartitionedCallReadVariableOpResourceGatherResourceGatherNd)r   r   )r   r   )EnterExitIdentityNextIterationSwitch_SwitchN)op
_VarHandle_Case_Merge_PartitionedCall_ReadVariable_ResourceGather_ResourceGatherNd_If_While_Intermediatere   r^   s      r'   rf   z	_Node.new   sK    ww>>h88	F	4?33	G	D(O44	%	%dHo>>	-	-dHo>>	$	$4?;;	$	$T8_==	&	&tX??	)	)x11	/	/D(O44	 L 
L4?;;4?33r)   c                     | j                   S rB   )r   r%   s    r'   r_   z
_Node.node   s    ::r)   c                 r    | j                   | j                   j                  S | j                  j                  S )z2The node container (either a graph or a function).)rb   r`   rC   	graph_defr%   s    r'   	containerz_Node.container  s0     ~~!^^$$$  ***r)   c                     | j                   P| j                  xs | j                  }|j                         j                  | j
                  j                     | _         | j                   S )zThe NodeDef to be converted.

    Returns:
      The NodeDef to be converted, which can come from either a graph for a
      function. Derived classes should call this (via 'super') to make sure the
      node is retrieved from the right place.
    )rE   rb   rC   rK   ro   r   rd   )r&   r=   s     r'   rK   z_Node.converted_self	  sT     #~~6!6!6f#224::4::??Kdr)   c                      y rB   r    rM   s      r'   rP   z"_Node.convert_variable_to_constant  s    r)   c           
          t        | j                  j                        D ]N  \  }}|d   dk(  r| j                  |      }|j                  j                  t        |t        | |                   P y )Nr   ^)	enumerater   inputresolve_inputr7   rV   r;   r4   )r&   r2   rd   r=   s       r'   rR   z_Node.create_edges  sg     !1!12 1t	aC!!$'f**
	$.
/11r)   c                 ^   |j                  d      }|d   }|d   dk(  r|dd }d}t        |      dkD  r!|d   j                         rt        |d         }| j                  #t        | j                  j                  |   |      S |dk7  s|| j                  j                  v r#t        | j                  j                  |   |      S | j                  j                  j                  j                  D cg c]  }|j                   }}t        | j                  |j                  |            S c c}w )a#  Resolves an input into its _EndPoint.

    A NodeDef's input name can refer to either global NodeDefs (in the
    GraphDef's node list), a NodeDef in a function's node list, or a Function
    (in the GraphDef's function library). The name can also carry semantic
    information, depending on whether it starts with "^". This method handles
    all that logic in order to find the object to which the input name refers
    to.

    Args:
      input_name: The input name to resolve.

    Returns:
      The object referred to by 'input_name'.
    :r   r      N)splitlen	isnumericintrb   r4   rC   ro   r`   rk   rz   rd   r2   )r&   
input_name	name_eltssource_namesource_indexiinputss          r'   r   z_Node.resolve_input"  s   2   %IA,K1~OkL
9~im5572'l~~t,,22;?NNqK4>>+?+??t~~++K8,GG"nn55??IIJaffJFJT^^V\\+%>?? Ks   0D*c                 N   | j                   j                  |   }d}|j                  d      r,|j                  j                  }t        |      }||kD  r&|||<   y|j                  d      rd}|dk(  r||_        yt        d|dd| j                   j                   d	| d
|dd	      )zChanges the type of a given input.

    Args:
      attr_name: The NodeDef attribute containing the type to change.
      index: The index of the input type to change.
      dtype: The type to change to.
    r   r|   Nr"   r   z`index` dz is out of range for node(z).attr(z), which has z
 elements.)r   r{   HasFieldr|   r"   r   
ValueErrorrd   )r&   	attr_namer2   r$   r{   	num_typestypess          r'   update_dtypez_Node.update_dtypeL  s     ::??9%DI }}Viinnee*i	U	e	v	i	!	
xay )!ZZ__-WYK}!!}J0 1 1r)   )r*   r+   r,   r-   rG   r8   staticmethodrf   r/   r_   r   rK   rP   rR   r   r   r   r   s   @r'   re   re      sg    
 4 48   + + 	1(@T1r)   re   c                       e Zd ZdZd Zy)r   z,Specialization of _Node to intermediate ops.c                 R   | j                         }|j                  d|j                  j                  |j                         d|j
                  j                  v r|j
                  j                  d= | j                  D ](  }|j                  j                  j                  ||       * y )NTry   )
rK   r   r>   r2   r$   r_   r{   rZ   r7   rP   )r&   rN   rO   r_   rU   s        r'   rP   z*_Intermediate.convert_variable_to_constantk  s     Dc=44::K<M<MN499>>)
))..)
*## 
""??
r)   Nr*   r+   r,   r-   rP   r    r)   r'   r   r   h  s
    4r)   r   c                   "     e Zd ZdZ fdZ xZS )r   z%Specialization of _Node to Merge ops.c           	          t         t        |   t        |j                  t        |j
                  j                  d            |       y )Nr   )ra   r   rP   r;   r=   r>   r7   )r&   rN   rO   ri   s      r'   rP   z#_Merge.convert_variable_to_constantx  s>     
&$4m""M--991=	?@KMr)   )r*   r+   r,   r-   rP   r   r   s   @r'   r   r   u  s    -M Mr)   r   c                       e Zd ZdZd Zy)r   z'Specialization of _Node to VarHandleOp.c                 (   t        j                  |j                  |j                  |j                  j                        }| j                         j                  }|j                          | j                  j                  |_	        d|_
        |j                  d   j                  |j                         |j                  d   j                  j                  |       | j                  D ](  }|j                   j"                  j%                  ||       * y )NConstr$   value)r   make_tensor_protor1   r$   r}   rK   r_   Clearr   rd   r   r{   CopyFromr(   tensorrZ   r>   r7   rP   )r&   rN   rO   tensor_protor_   rU   s         r'   rP   z'_VarHandle.convert_variable_to_constant  s    001B1B1<1B1B1<1B1B1H1HJL  %%DJJL

DIDGIIg 6 67IIg&&|4## 
""??
r)   Nr   r    r)   r'   r   r     s
    /r)   r   c                       e Zd ZdZd Zy)r   z*Specialization of _Node to ResourceGather.c                    | j                   y | j                  j                  d   j                  dk7  rGt	        d| j                  j
                   d| j                  j                  d   j                   d      | j                  j
                  dz   }| j                  j                  d   }t        j                  | j                  j                  d   j                        }| j                  j                         }||j                  vrQt        j                  |j                  j                  j                         | j                   |      |j                  |<   |j                  |   j                  }||_        d	|_        |j                  d
   j#                  |       t%        j&                  ||j(                  |j*                        }|j                  d   j,                  j#                  |       | j                         j                  }	|	j/                          | j                  j
                  |	_        d|	_        |	j0                  j3                  | j                  j0                  d   | j                  j0                  d   |g       |	j                  d   j#                  | j                  j                  d
          |	j                  d   j#                  | j                  j                  d          |	j                  d   j#                  |       d| j                  j                  v r6|	j                  d   j#                  | j                  j                  d          y y )N
batch_dimsr   z4batch_dims must be 0 for freeze_graph, but got node(z).attr('batch_dims') = .z/axisTindicesr^   r   r$   )r$   r}   r   GatherV2r   TparamsTaxis_class)rb   r   r{   r   r   rd   nparrayrC   rK   ro   re   rf   r   r_   addr   r   r   r   r"   r}   r   r   r   extend)
r&   rN   rO   axis_node_name
axis_dtype	axis_dataconverted_graphoutput_axis_noder   output_nodes
             r'   rP   z,_ResourceGather.convert_variable_to_constant  s   ~~!zz|$&&!+ #zz//F**//,799:!= > > ZZ__w.N,J6889I++::<O_222.3ii((--113>>) /8 /+oN+ ',,^<AA*!'"++J7**	AF'"))226:%%',,KzzKKN			!	djj..q1>BDY(()ABZ ))$**//**EFW&&z24::??"x ))$**//(*CD #r)   Nr   r    r)   r'   r   r     s    2$Er)   r   c                       e Zd ZdZd Zy)r   z,Specialization of _Node to ResourceGatherNd.c                    | j                         j                  }|j                          | j                  j                  |_        d|_        |j                  j                  | j                  j                  d   | j                  j                  d   g       |j                  d   j                  | j                  j                  d          |j                  d   j                  | j                  j                  d          d| j                  j                  v r6|j                  d   j                  | j                  j                  d          y y )NGatherNdr   r   r   r$   r   r   )
rK   r_   r   r   rd   r   r   r   r{   r   )r&   rN   rO   r   s       r'   rP   z._ResourceGatherNd.convert_variable_to_constant  s    %%',,KzzKKNdjj..q14::3C3CA3FGHY(()ABZ ))$**//**EF4::??"x ))$**//(*CD #r)   Nr   r    r)   r'   r   r     s    4	Er)   r   c                       e Zd ZdZd Zy)r   z*Specialization of _Node to ReadVariableOp.c                    | j                         j                  }|j                          | j                  j                  |_        d|_        |j                  j                  | j                  j                  d          |j                  d   j                  | j                  j                  d          d| j                  j                  v r5|j                  d   j                  | j                  j                  d          | j                  | j                  D ]  }|j                  j                  }|j                  j                  j                         }t        |t               sN|j                  j                  |   j#                  d      }t%        |      dkD  s|d   dk(  sd	|d<   dj'                  |      |j                  j                  |<    y y )
Nr   r   r   r$   r   r   r   r   output)rK   r_   r   r   rd   r   r   rT   r{   r   rb   rZ   r>   r2   r7   
isinstancere   r   r   join)r&   rN   rO   r_   rU   r2   destinput_name_partss           r'   rP   z*_ReadVariable.convert_variable_to_constant  sj    %%DJJL

DIDGJJdjj&&q)*IIcNDJJOOG454::??"
ii""4::??8#<=
 ~~!%% @$  &&++::<dE"!YY__U399#>
!"Q&+;A+>'+I"*Q%(XX.>%?DIIOOE"@ "r)   Nr   r    r)   r'   r   r     s    2@r)   r   c                   <     e Zd ZdZ fdZ fdZd Z fdZ xZS )_FunctionCallerz7A base class for Convertibles that reference functions.c                 Z    t         t        |   |||       || _        || _        || _        y)a  Initializes a _FunctionCaller.

    Args:
      node: As in _Node.
      function: As in _Node.
      enclosing_graph: As in _Node.
      first_function_input: The index of the first NodeDef input that is tied to
        the function inputs. It is assumed that the rest of the NodeDef inputs
        map one to one to function inputs.
      type_attribute: The name of the NodeDef attribute that defines the input
        types. It is assumed that the types listed here map one-to-one with the
        function inputs (that is, they do _not_ specify types for inputs that
        are not passed to functions).
      function_attributes: The names of the NodeDef attributes containing
        references to functions.
    N)ra   r   rG   _first_function_input_type_attribute_function_attributes)r&   r_   r`   rF   first_function_inputtype_attributefunction_attributesri   s          r'   rG   z_FunctionCaller.__init__  s0    $ 
/4)$/J!5D)D 3Dr)   c                 z   | j                   "t        t        |          j                  }| j
                  j                  }| j                  D ]  }|j                  |   }|j                  d      rX| j
                  j                  |j                  j                        r)||j                  j                     |j                  _        {|j                  d      s|j                  j                  D ]<  }| j
                  j                  |j                        s)||j                     |_        >  | j                   S )Nfuncr|   )rE   ra   r   rK   r_   rC   rr   r   r{   r   is_converted_functionr   rd   r|   )r&   r_   converted_namesr   r{   r   ri   s         r'   rK   z_FunctionCaller.converted_self  s    #?D8:??d--FFo00 	5)yy#==--CC		 *499>>:$)).]]6"iinn 5d$$::499E)$))4di5	5 r)   c                    |j                   j                  }| j                  D ]U  }|j                   j                  }|j                  j                  |k(  s3t        |t              sD|j                  ||       W | j                         }|| j                  k\  r5|j                  | j                  || j                  z
  |j                         y y rB   )r>   r2   rZ   r7   r=   r   r\   rP   rK   r   r   r   r$   )r&   rN   rO   r2   rU   r   r_   s          r'   rP   z,_FunctionCaller.convert_variable_to_constant  s    %%++E ## =))d			e	#
4(C))$<=
  D***
,, : ::K<M<MO +r)   c                 x   t         t        |           | j                  D ]  }| j                  j
                  |   }|j                  d      r| j                  j                  |j                  j                     }t        t        | j                  j                        | j                  z
        D ]>  }| j                  t!        t#        | || j                  z         t#        ||                   @ |j                  d      s|j$                  j                  D ]  }| j                  j                  |j                     }t        t        | j                  j                        | j                  z
        D ]>  }| j                  t!        t#        | || j                  z         t#        ||                   @   y)zCreates edges related to a function caller.

    Edges from a function caller to its called functions are always edges from
    _inputs_ to _inputs_: a FunctionDef input is given by the caller, based on
    its own inputs.
    r   r|   N)ra   r   rR   r   r   r{   r   rC   rt   r   rd   ranger   r   r   rV   r;   r4   r|   )r&   r   r{   r`   r2   r   ri   s         r'   rR   z_FunctionCaller.create_edges+  sl    
/4-/.. 1	ZZ__Y'd	v	((22499>>B3tzz//043M3MMN 	/E

 
 D%$*D*D"DEHe,./	/
 == IINN 	1D**44TYY?($**""#d&@&@@B 1e""dED,F,F$FGh.011	11r)   )	r*   r+   r,   r-   rG   rK   rP   rR   r   r   s   @r'   r   r     s     ?4.  O.1 1r)   r   c                   "     e Zd ZdZ fdZ xZS )r   z.Specialization of _Node to If-like operations.c           	      <    t         t        |   |||ddddg       y )Nr   Tinthen_branchelse_branchr   r   r   )ra   r   rG   r   s       r'   rG   z_If.__init__J  s.    	#t*M:  <r)   r*   r+   r,   r-   rG   r   r   s   @r'   r   r   G  s    6< <r)   r   c                   "     e Zd ZdZ fdZ xZS )r   z0Specialization of _Node to Case-like operations.c                 :    t         t        |   |||dddg       y )Nr   r  branchesr
  )ra   r   rG   r   s       r'   rG   z_Case.__init__W  s+    	%'L   *r)   r  r   s   @r'   r   r   T  s    8* *r)   r   c                   "     e Zd ZdZ fdZ xZS )r   z;Specialization of _Node to PartitionedCall-like operations.c                 :    t         t        |   |||dddg       y )Nr   r  fr
  )ra   r   rG   r   s       r'   rG   z_PartitionedCall.__init__d  s,    	
D* E + #r)   r  r   s   @r'   r   r   a  s    C# #r)   r   c                   ,     e Zd ZdZ fdZ fdZ xZS )r   z1Specialization of _Node to While-like operations.c           	      <    t         t        |   |||ddddg       y )Nr   r   bodycondr
  )ra   r   rG   r   s       r'   rG   z_While.__init__q  s.    	&$ #V, ! .r)   c           
      4   t         t        |   ||       | j                         }|j                  j
                  d   j                  j                  r|j                  j
                  d   j                  j                  |j                  j                     j                  t        j                  |j                  j                  D cg c]"  }t        j                  j                  |      $ c}             | j                  j
                  d   j                   j"                  }| j$                  j&                  |   j                         j(                  }|j*                  |j,                  j.                  |j                  j                     _        y c c}w )Noutput_shapes)size)r   r  )ra   r   rP   rK   r_   r{   r|   r}   r>   r2   r   r   TensorShapeProtor1   Dimr   r   rd   rC   rt   r`   r$   rk   
output_argr"   )r&   rN   rO   r_   r   	body_namer  ri   s          r'   rP   z#_While.convert_variable_to_constantz  s5   	&$4]KP Dyy~~o&++11
iinn_%**00

#
#
)
)++38//(..445 #3377S7A5 , 

',,11I  **95DDFOOD0;0A0A 	NN!!''))-5s   'F)r*   r+   r,   r-   rG   rP   r   r   s   @r'   r   r   n  s    9.B Br)   r   c                   z     e Zd ZdZ fdZed        Zed        Zed        Zed        Z	d Z
d Zd	 Zd
 Z xZS )	_GraphDefzA convertible GraphDef.c           	         t         t        |   d        || _        |j                  D ci c]%  }|j
                  t        j                  |d |       ' c}| _        |j                  j                  D ci c]$  }|j                  j
                  t        ||       & c}| _        | j                          d | _        y c c}w c c}w )N)rF   r^   )ra   r  rG   
_graph_defr_   rd   re   rf   rg   libraryr`   rk   r\   
_functionsrR   _converted_function_names)r&   r   rh   r  ri   s       r'   rG   z_GraphDef.__init__  s    	)T#D#9DO  	
		q4	FFDK ""++ 	
)At<<DO 	%)D"s   *B>5)Cc                     | j                   S rB   r   r%   s    r'   r   z_GraphDef.graph_def      ??r)   c                     | j                   S rB   rn   r%   s    r'   ro   z_GraphDef.nodes  rp   r)   c                     | j                   S rB   )r"  r%   s    r'   rt   z_GraphDef.functions  r&  r)   c                    | j                   g }| j                  D ]m  }|j                  dd      }t        |      dk(  r7|d   j	                         r$|j                  t        |d         |d   |f       Z|j                  d||f       o t        |      D ci c]+  \  }}}|dj                  |t        j                               - c}}}| _         | j                   S c c}}}w )a:  Map from original to new function names.

    In order to avoid conflicts (two functions with the same name, one converted
    and one not), we need to change the name of every converted function to
    something that is hopefully unique.

    Returns:
      Map from original to new suggested function names.
    _r      r   r   z{}_frozen_{})r#  rt   rsplitr   r   rT   r   sortedr6   r   uid)r&   parsed_namesrd   elementsr*  	base_names         r'   rr   z"_GraphDef.converted_function_names  s     %%-l.. 0$;;sA&x=A(1+"7"7"9


s8A;/!dC
D


r4.
/0 '-\&:( ("q)T %%i;
;(d$
 )))(s   0C c                     | j                   j                  |      }||j                  j                  _        || j                   |<   y rB   )rt   popr`   rk   rd   )r&   ru   rv   r   s       r'   rs   z_GraphDef.rename_function  s6    >>h'D#+DMM #DNN8r)   c                 Z    || j                         j                  vxr || j                  v S rB   )rK   rt   rr   )r&   function_names     r'   r   z_GraphDef.is_converted_function  s1    !4!4!6!@!@@ 86668r)   c                     | j                   ?t        j                         }|j                  | j                         t        |      | _         | j                   S rB   )rE   r   GraphDefr   r   r  )r&   copied_graphs     r'   rK   z_GraphDef.converted_self  sG    #'')lDOO,&|4dr)   c                     | j                   j                         D ]  }|j                           | j                  j                         D ]  }|j                           y rB   )rg   r   rR   r"  )r&   rh   r  s      r'   rR   z_GraphDef.create_edges  sN    [[! nn__##% nnr)   )r*   r+   r,   r-   rG   r/   r   ro   rt   rr   rs   r   rK   rR   r   r   s   @r'   r  r    so    *       * *2$
8
 r)   r  c                   X    e Zd ZdZ	 	 d	dZed        Zed        Zed        Zd Z	d Z
y)
_ConverterDataa  Container for constant conversion supporting data.

  The data includes the graph being converted, and the pre-converted
  tensors. This class will be specialized for ConcreteFunction and Session-based
  conversions, as the means to obtain that data is different for each case.
  Nc                 \    || _         i | _        | j                          || _        || _        y rB   )r   _tensor_data_build_node_defs_list_variable_names_allowlist_variable_names_denylist)r&   r   variable_names_allowlistvariable_names_denylists       r'   rG   z_ConverterData.__init__  s/      DOD %=D"$;D!r)   c                     | j                   S )zThe graph to be converted.r%  r%   s    r'   r   z_ConverterData.graph_def  s     ??r)   c                     | j                   S )zAll the node defs in the graph to be converted.

    Returns:
      A map from node name to the NodeDef for all NodeDefs in the graph, as well
      as all control flow NodeDefs in the functions.
    )
_node_defsr%   s    r'   	node_defsz_ConverterData.node_defs  s     ??r)   c                     | j                   S )z4A map from tensor name to its converted _TensorData.)r=  r%   s    r'   rO   z_ConverterData.tensor_data  s     r)   c                 ~    | j                   du xs || j                   v xr | j                  du xs || j                  vS )z@Checks whether to convert the given variable name to a constant.N)r?  r@  )r&   rd   s     r'   _should_convertz_ConverterData._should_convert  sN    **d2 3D222;--5 :D999;r)   c                    | j                   j                  D ci c]  }|j                  | c}| _        | j                   j                  rv| j                   j                  j
                  D ]R  }| j                  j                  |j                  D ci c]!  }|j                  t        v r|j                  |# c}       T yyc c}w c c}w )a  Builds the list of NodeDefs in the GraphDef.

    This list consists of all NodeDefs in the main graph as well as all control
    flow NodeDefs in the functions.

    The remaining NodeDefs in the functions are not included because the op
    names
    are not unique and the variables are handled differently than the main
    graph.
    The control flow ops need to be extracted because they are need their
    attributes to be updated similar to the control flow ops in the main graph.
    N)
r   r_   rd   rE  r!  r`   updaterc   r   _CONTROL_FLOW_OPS)r&   r_   r   s      r'   r>  z$_ConverterData._build_node_defs_list	  s     48??3G3GH4tyy$HDO//))22 $ 
ww++ IItO 
 	  I 
s   C&C
NN)r*   r+   r,   r-   rG   r/   r   rF  rO   rI  r>  r    r)   r'   r;  r;    sZ     )-'+<      ;r)   r;  c                   4     e Zd ZdZ	 	 d fd	Zd Zd Z xZS )_FunctionConverterDataz5Container for ConcreteFunction-based conversion data.c                 z    || _         t        |||      }t        t        |   |||       | j                          y)az  Creates the conversion data for the given function.

    Args:
      func: ConcreteFunction.
      lower_control_flow: Boolean indicating whether or not to lower control
        flow ops such as If and While.
      aggressive_inlining: Boolean indicating whether or not to do aggressive
        function inlining (might be unsafe if function has stateful ops, not
        properly connected to control outputs).
      variable_names_allowlist: The set of variable names to convert (by
        default, all variables are converted).
      variable_names_denylist: The set of variable names to omit converting to
        constants.
    rA  rB  N)_func_run_inline_graph_optimizationra   rO  rG   _build_tensor_data)r&   r   lower_control_flowaggressive_inliningrA  rB  r   ri   s          r'   rG   z_FunctionConverterData.__init__$  sK    * DJ.t5G/BDI	
 $0!9 7 1 9
 	r)   c                 ,    t        j                  d      )DReturns the value in the tensor. Must be implemented in sub-classes.z;The evaluation method should be implemented in sub-classes.)r   UnimplementedErrorr&   r   s     r'   _evalz_FunctionConverterData._evalD  s    

#
#EG Gr)   c                    i }| j                   j                  j                  D ]>  }t        | j                   j                        D ]  \  }}|j
                  |u s|||<    > @ t        | j                   j                  j                        D ]  \  }\  }}|j                  j                  d      d   }| j                  |      s9||v r| j                  ||         }n[|j                  t        j                  k(  rt        j                  dd|z         t!        j"                  | j                  |            }t%        |t        j&                  |j                        j(                  |      | j*                  |<    | j,                  j/                         D ]3  }	|	j0                  dk(  s| j                  |	j                        s0|	j                  | j2                  vsI| j                   j                  j5                         5  t7        j8                  | j                   j                  j;                  |	j                  dz               }
ddd        | j                   j=                  g 
j                  g             d   }t%        |j?                         |	j@                  d	   jB                  d      | j*                  |	j                  <   6 y# 1 sw Y   xY w)
zBCaches the tensor data for all Placeholders in the given function.r   r   r   z"Skip converting resource tensor %sr0   r   :0Nr$   )"rR  graphr   r   captured_inputshandlecapturesrd   r   rI  r[  r$   r   resourceloggingvlogr   r   r   as_dtypeas_datatype_enumr=  rF  r   r   rO   
as_defaultr   identityas_graph_elementpruner1   r{   r"   )r&   map_index_to_variablevaridxcaptured_input
val_tensorname_tensortensor_namedatar_   identity_nodepruned_graphs               r'   rT  z)_FunctionConverterData._build_tensor_dataI  sf   zz)) !*4::+E+E!F 
#~::''*

$
 +4DJJ4D4D4M4M*N &&j+$$**3/2k!!+.	%	%zz/45v.
,,q>L
M
xx

:./'2

+<<(d$$ %%' 	L	 ##DII.
99D,,,zz**, E%..

  11$))d2BCEME D))"}/A/A.BCEaH,)4 &&(IIg&++*$

DII
&
E Es   AKK	rM  )r*   r+   r,   r-   rG   r[  rT  r   r   s   @r'   rO  rO  !  s    = )-'+@G
(r)   rO  c                       e Zd ZdZd Zy)_FunctionConverterDataInEagerzCContainer for ConcreteFunction-based conversion data in Eager mode.c                 "    |j                         S rX  )r1   rZ  s     r'   r[  z#_FunctionConverterDataInEager._evalw  s    <<>r)   N)r*   r+   r,   r-   r[  r    r)   r'   rv  rv  t  s
    Kr)   rv  c                   0     e Zd ZdZ	 	 	 d fd	Zd Z xZS )_FunctionConverterDataInGraphzCContainer for ConcreteFunction-based conversion data in Graph mode.c                    || _         |j                  t        j                                t	        j
                         j                  t              D ]  }|j                  |        t        t        | +  |||||       y)a  Creates the conversion data for the given function.

    Args:
      func: ConcreteFunction.
      lower_control_flow: Boolean indicating whether or not to lower control
        flow ops such as If and While.
      aggressive_inlining: Boolean indicating whether or not to do aggressive
        function inlining (might be unsafe if function has stateful ops, not
        properly connected to control outputs).
      variable_names_allowlist: The set of variable names to convert (by
        default, all variables are converted).
      variable_names_denylist: The set of variable names to omit converting to
        constants.
      session: Session object.
    N)_sessionrunr   global_variables_initializerr   get_default_graphget_collectionVAR_ASSIGN_COLLECTIONra   rz  rG   )	r&   r   rU  rV  rA  rB  sessionr   ri   s	           r'   rG   z&_FunctionConverterDataInGraph.__init__  ss    , DMKK	6689 ##%445JK kk"o 

'7 !r)   c                 8    | j                   j                  |      S rx  )r|  r}  rZ  s     r'   r[  z#_FunctionConverterDataInGraph._eval  s    ==V$$r)   )NNN)r*   r+   r,   r-   rG   r[  r   r   s   @r'   rz  rz  |  s    K )-'+#!J%r)   rz  c                   (     e Zd ZdZ	 	 d fd	Z xZS )_SessionConverterDataz,Container for Session-based conversion data.c                 0   t        j                  ||      }t        t        |   |||       g }g }| j
                  j                  D ]h  }|j                  dv s|j                  }	| j                  |	      s0|j                  dk(  r|	dz   }	|j                  |       |j                  |	dz          j |rb|j                  |      }
t        ||
      D ]A  \  }}t        ||j                  d   j                  d       | j                   |j                  <   C y y )NrQ  )Variabler   r   r   z/Read/ReadVariableOpr]  r$   r0   )r   extract_sub_graphra   r  rG   r   r_   r   rd   rI  rT   r}  zipr   r{   r"   r=  )r&   r  r   output_node_namesrA  rB  nodes_to_converttensor_names_to_convertr_   rq  converted_tensorstensor_valueri   s               r'   rG   z_SessionConverterData.__init__  s%    ,,Y8IJI	
/!9 7 0 9
  ## ;	=	=ii##K0
77m##&<<+%&&{T'9:; !++&=> #$46G H K
$'2dii&8&=&=T(K$))$K r)   rM  r  r   s   @r'   r  r    s    4 )-'+K Kr)   r  c                    t        j                         }|j                  |        d }|j                  D ]
  } ||        |j                  r4|j                  j
                  D ]  }|j                  D ]
  } ||         |S )zSet '_lower_using_switch_merge' attributes to False.

  Sets the attribute to False in the NodeDefs in the main graph and the NodeDefs
  in each function's graph.

  Args:
    graph_def: GraphDef proto.

  Returns:
    GraphDef
  c                 R    | j                   t        v rd| j                  d   _        y y )NF_lower_using_switch_merge)r   rL  r{   b)r_   s    r'   disable_control_flow_loweringzGdisable_lower_using_switch_merge.<locals>.disable_control_flow_lowering  s&    ww##16dii+,. $r)   )r   r7  r   r_   r!  r`   rc   )r   output_graph_defr  r_   r   s        r'    disable_lower_using_switch_merger    s     '')I&7 ## (d!$'(  ((11 ,-- ,$%d+,, 
r)   c                 H   | j                   j                         }|st        |      }|j                  j                  D ]  }d|j
                  v s|j
                  d=   t        || j                         }dD ]  }g }|j                  d   j                  j                  D ]W  }t        j                         }	|	j                  |       |	j                  d       |j                  |	j                                Y ||j                  |   j                  j                  dd  t!        j"                         }
| j$                  | j&                  z   D ]1  }|
j(                  j                  j                  |j*                         3 |j                  d   j-                  |
       t/        j0                         }|j2                  j4                  }d|_        |j8                  j                  d	       |rt:        j<                  j>                  |_         tC        jD                  ||      S )
aG  Apply function inline optimization to the graph.

  Returns the GraphDef after Grappler's function inlining optimization is
  applied. This optimization does not work on models with control flow.

  Args:
    func: ConcreteFunction.
    lower_control_flow: Boolean indicating whether or not to lower control flow
      ops such as If and While. (default True)
    aggressive_inlining: Boolean indicating whether or not to do aggressive
      function inlining (might be unsafe if function has stateful ops not
      properly connected to control outputs).

  Returns:
    GraphDef
  api_implements)r   r^  )r   model_variablestrainable_variableslocal_variablesr   initializer_nameNtrain_opr   r`   )#r^  as_graph_defr  r!  r`   r{   r   collection_def
bytes_listr   r   VariableDefParseFromString
ClearFieldrT   SerializeToStringr   CollectionDefr   outputs	node_listrd   r   r   ConfigProtograph_optionsrewrite_optionsmin_graph_nodes
optimizersr	   RewriterConfig
AGGRESSIVEfunction_optimizationr   OptimizeGraph)r   rU  rV  r   r`   
meta_graphrd   raw_listrawvariablefetch_collectionr   configr  s                 r'   rS  rS    s   $ jj%%')	0;I ##,, *h8==(
--(
)* !9DJJG* 	Cd H((5@@FF 4))+hs#,-ooh0023	4
 ;CJd#..44Q7	C $113{{T\\) 8e$$++EJJ78J'001AB !!#&((88/$&/!##J/((33 )		#	#FJ	77r)   c                 L   | j                   j                  }t        j                  |D cg c]  }||   	 c}      }| j                  D cg c]	  }||vs| }}|D ci c]  }|j
                  | }}|D cg c]  }|j
                   }	}| j                  D cg c]  }|j
                   }
}|j                  j                  D ]q  }t        j                         j                  |j                  j
                        s;t        j                         j                  |j                  j
                         s t        j                  ||	|
      }|j                  D ]*  }|j                  ||j
                     j                          , |S c c}w c c}w c c}w c c}w c c}w )a  Constructs a concrete function from the `output_graph_def`.

  Args:
    func: ConcreteFunction
    output_graph_def: GraphDef proto.
    converted_input_indices: Set of integers of input indices that were
      converted to constants.

  Returns:
    ConcreteFunction.
  )r^  internal_capturesr   ObjectIdentitySetr   rd   r  r!  r`   r
   has_functionrk   remove_functionr   function_from_graph_def	set_shaper}   )r   r  converted_input_indicesinput_tensorsr2   converted_inputsr   not_converted_inputsnot_converted_inputs_mapnew_input_namesnew_output_namesr  new_funcinput_tensors                 r'   _construct_concrete_functionr  )  s    **..-$66)@A}UAC  ;;&8H*Hf  )=$fkk6  0DDVV[[D/D04=ffkk== ##,, :a%%akk&6&67oo''(8(89: 223C3B3CE( oo Nl3L4E4EFLLMN	/1 B E=s#   F	FFF9FF!c                 n   t        | j                        }| j                  j                         D ]$  \  }}|j                  |   j                  d|       & |j                         j                  }| j                  j                         D ch c]  }|j                  |j                   }}||fS c c}w )aV  Replaces variables by constants on a given graph.

  Given a _ConverterData instance with converted variables in its tensor_data
  field, create a new graph where the respective variables are replaced with the
  converted constants.

  Args:
    converter_data: A pre-populated _ConverterData instance.

  Returns:
    The converted graph.
  N)	r  r   rO   itemsro   rP   rK   r   r2   )converter_datainput_graphrq  rO   r   tr  s          r'   _replace_variables_by_constantsr  T  s     .223+"0"<"<"B"B"D k;k"??k  ..0::/ ))002
	
	 gg  
1	11s   B2c                 V    t        | ||      }t        |      \  }}t        | ||      S )a  Replaces all the variables in a graph with constants of the same values.

  TensorFlow 2.0 function for converting all Variable ops into Const ops holding
  the same values. This makes it possible to describe the network fully with a
  single GraphDef file, and allows the removal of a lot of ops related to
  loading and saving the variables. This function runs Grappler's function
  inlining optimization in order to return a single subgraph.

  The current implementation only works for graphs that do not contain any
  control flow or embedding related ops.

  Args:
    func: ConcreteFunction.
    lower_control_flow: Boolean indicating whether or not to lower control flow
      ops such as If and While. (default True)
    aggressive_inlining: Boolean indicating whether or not to do aggressive
      function inlining (might be unsafe if function has stateful ops, not
      properly connected to control outputs). (default False)

  Returns:
    ConcreteFunction containing a simplified version of the original.
  r   rU  rV  r  rv  r  r  )r   rU  rV  r  r  r  s         r'   !convert_variables_to_constants_v2r  r  sE    4 1+-/.
 /N#/%++ 
&d,<&=
? ?r)   c                     t        j                         }|t        d      t        | |||      }t	        |      \  }}t        | ||      S )a  Replaces all the variables in a graph with constants of the same values.

  This function works as same as convert_variables_to_constants_v2, but it
  should be used in Graph mode. It is a temporary solution when users want to
  integrate their models written in TF2 with infra that requires TF1 mode.

  The current implementation only works for graphs that do not contain any
  control flow or embedding related ops.

  The function must be called in a Session context.

  Args:
    func: ConcreteFunction.
    lower_control_flow: Boolean indicating whether or not to lower control flow
      ops such as If and While. (default True)
    aggressive_inlining: Boolean indicating whether or not to do aggressive
      function inlining (might be unsafe if function has stateful ops, not
      properly connected to control outputs). (default False)

  Raises:
      RuntimeError: If no Session context is present.

  Returns:
    ConcreteFunction containing a simplified version of the original.
  z8The conversion must be carried out in a Session context.)r   rU  rV  r  r  )r   get_default_sessionRuntimeErrorrz  r  r  )r   rU  rV  r  r  r  r  s          r'   #convert_var_to_const_function_in_v1r    so    : ##%'_
BD D 1+-	. /N#/%++ 
&d,<&=
? ?r)   c                 ^    t        | ||      }t        |      \  }}t        | ||      }||fS )ag  Replaces all the variables in a graph with constants of the same values.

  This function works as same as convert_variables_to_constants_v2, but it
  returns the intermediate `GraphDef` as well. This `GraphDef` contains all the
  debug information after all the transformations in the frozen phase.

  Args:
    func: ConcreteFunction.
    lower_control_flow: Boolean indicating whether or not to lower control flow
      ops such as If and While. (default True)
    aggressive_inlining: Boolean indicating whether or not to do aggressive
      function inlining (might be unsafe if function has stateful ops, not
      properly connected to control outputs).

  Returns:
    ConcreteFunction containing a simplified version of the original, and also
    the intermediate GraphDef containing the node debug information for the
    transformations in the frozen phase.
  r  r  r  )r   rU  rV  r  r  r  frozen_funcs          r'   *convert_variables_to_constants_v2_as_graphr    sO    , 1+-/.
 /N#/%++ -T3C-DF+	&	&&r)   c           	      @    t        t        | ||||            \  }}|S )a  Replaces all the variables in a graph with constants of the same values.

  This function works similarly to convert_variables_to_constants_v2, but it
  retrieves the constant values from a Session instead of from a
  ConcreteFunction. This is useful when converting graphs generated from
  TensorFlow V1, where ConcreteFunctions are not available. This also differs
  from graph_util.convert_variables_to_constants in that it supports resource
  variables when V2 control flow constructions are present.

  Args:
    session: Active TensorFlow session containing the variables.
    graph_def: A GraphDef to convert.
    output_node_names: List of name strings for the result nodes of the graph.
    variable_names_allowlist: The set of variable names to convert (by default,
      all variables are converted).
    variable_names_denylist: The set of variable names to omit converting to
      constants.

  Returns:
    An optimized GraphDef.
  r  r   r  rA  rB  r  )r  r  )r  r   r  rA  rB  r*  s         r'   1convert_variables_to_constants_from_session_graphr    s1    6 1*-#;"9;<,)Q 
r)   zThis API was designed for TensorFlow v1. See https://www.tensorflow.org/guide/migrate for instructions on how to migrate your code to TensorFlow v2.)dateinstructionsz)graph_util.convert_variables_to_constants)v1c                 &    t        | ||||      }|S )a  Replaces all the variables in a graph with constants of the same values.

  If you have a trained graph containing Variable ops, it can be convenient to
  convert them all to Const ops holding the same values. This makes it possible
  to describe the network fully with a single GraphDef file, and allows the
  removal of a lot of ops related to loading and saving the variables.

  Args:
    sess: Active TensorFlow session containing the variables.
    input_graph_def: GraphDef object holding the network.
    output_node_names: List of name strings for the result nodes of the graph.
    variable_names_whitelist: The set of variable names to convert (by default,
      all variables are converted).
    variable_names_blacklist: The set of variable names to omit converting to
      constants.

  Returns:
    GraphDef containing a simplified version of the original.

  Raises:
    RuntimeError: if a DT_RESOURCE op is found whose ancestor Variables are both
      denylisted AND whitelisted for freezing.
  r  )r  )sessinput_graph_defr  variable_names_whitelistvariable_names_blacklistrets         r'   convert_variables_to_constantsr    s%    F 	:)76	8# 
*r)   )TFrM  )Nr-   collectionsr1   r   tensorflow.core.frameworkr   r   r   r   tensorflow.core.protobufr   r   r	   tensorflow.python.eagerr
   r   tensorflow.python.frameworkr   r   r   r   r   tensorflow.python.grapplerr   tensorflow.python.opsr   r   tensorflow.python.platformr   rc   tensorflow.python.training.saverr   tensorflow.python.utilr   r    tensorflow.python.util.tf_exportr   r  set_CONDITIONAL_OPS	_LOOP_OPSunionrL  
namedtupler   r4   r;   objectr@   r\   re   r   r   r   r   r   r   r   r   r   r   r   r  r;  rO  rv  rz  r  r  rS  r  r  r  r  r  r  
deprecatedr  r    r)   r'   <module>r     s   C   4 / 6 2 / 3 8 + 1 . . 2 + 3 3 + + < > . 2 6 / m,- *+,	$**95 5K=*EF59&&&{]G4LM 9<"K""7X},EF <: 6 : zI IXO1L O1d
E 
	MU 	M ('Ee 'ETE E@E @8Z1e Z1z
</ 
<
*O 
*
# 
#B_ B>L L^BV BJP^ Pf$: *%$: *%ZKN KD:>8B(V2> :>:?#?N <@<A,?` CGCH 'N " "J 	* :;< =A<@	" ="r)   