
    BVh                    P   d Z ddlZddlZddlZddlZddlZddlmZmZm	Z	m
Z
mZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlm Z  ddlm!Z! ddlm"Z# ddl$m%Z& ddl$m'Z' ddl$m(Z( ddl$m)Z) ddl*m+Z+ ddl*m,Z, ddl*m"Z- ddl*m.Z. ddl*m/Z/ ddl*m0Z0 ddl*m1Z1 ddl2m3Z3 dd l4m5Z5 dd!l4m6Z6 dd"l4m7Z7 dd#l8m9Z9 dd$l8m:Z: dd%l8m;Z; dd&l8m<Z< dd'l8m=Z= dd(l8m>Z> dd)l8m?Z? dd*l8m@Z@ dd+l8mAZA dd,l8mBZB dd-l8mCZC dd.l8mDZD dd/l8mEZE dd0l8mFZF dd1l8mGZG dd2lHmIZI dd3lHmJZJ dd4lKmLZL dd5lKmMZM dd6lKmNZN dd7lKmOZO dd8lPmQZQ dd9lRmSZT dd:lUmVZV dd;lUmWZW dd<lUmXZX dd=lYmZZZ  e[e+j                  e+j                  f      Z] ej                  d>d?d@g      Z_dAZ`dBZa G dC dDej                        Zc G dE dFed      ZedGeWj                  dHeWj                  fdIZgdJ ZhdKeidLeifdMZj	 d|dNe
e   dKeidOekfdPZl	 d|dQemeiedRef   f   dSeWj                  fdTZn ej                  dUg dV      ZodWeodXe7j                  fdYZqdZedRef   fd[ZrdZedRef   d\e_d]e	e/j                  edRef   f   fd^Ztd_e/j                  d`eefdaZudbej                  dHdfdcZw	 d|dbej                  d`eedQe	eiedRef   f   dde
ei   deexdfexdgexdHeeoe/j                  f   fdhZydiej                  fdjZ{d`eefdkZ|d`eefdlZ}dmej                  fdnZdoe/j                  dpeifdqZ eZdrdrdsgt      	 	 d}dpeidueAj                  fdv       Z	 	 	 d~dueAj                  fdwZ	 	 d}dxeidueAj                  fdyZ	 d|dueAj                  fdzZ	 d|dueAj                  dbej                  fd{Zy)z4Exports a SavedModel from a Trackable Python object.    N)AnyCallableDictListTuple)logging)function_pb2)	graph_pb2)node_def_pb2)versions_pb2)meta_graph_pb2)saved_model_pb2)saved_object_graph_pb2)
checkpoint)checkpoint_options)functional_saver)
graph_view)save_util_v1)util)context)def_function)function)concrete_function)polymorphic_function)saved_model_exported_concrete)saved_model_utils)dtypes)errors)
meta_graph)ops)tensor_util)versions)file_io)	array_ops)control_flow_ops)resource_variable_ops)builder_impl)fingerprinting_utils)function_serialization)path_helpers)pywrap_saved_model)registration)revived_types)save_context)save_options)signature_constants)signature_def_utils)signature_serialization)tag_constants)tracing_utils)
utils_impl)	constants)metrics)asset)base)resource)trackable_utils)trace_saveable_util)core)compat)object_identity)tf_stack)	tf_export_CapturedTensornamer      save_v2c                        e Zd ZdZ fdZdej                  deede	f   ede	f   f   fdZ
 fdZ fdZd	efd
Zdej                   fdZd Z xZS )_AugmentedGraphViewa  An extendable graph which also tracks functions attached to objects.

  Extensions through `add_object` appear in the object graph and any checkpoints
  generated from it, even if they are not dependencies of the node they were
  attached to in the saving program. For example a `.signatures` attribute is
  added to exported SavedModel root objects without modifying the root object
  itself.

  Also tracks functions attached to objects in the graph, through the caching
  `_list_functions` method. Enumerating functions only through this method
  ensures that we get a consistent view of functions, even if object attributes
  create new functions every time they are accessed.
  c                     t         t        |   |       t        j                         | _        t        j                         | _        i | _        g | _        y N)	superrG   __init__r?   ObjectIdentityDictionary_children_cache_serialization_cache_wrapped_functionsuntraced_functions)selfroot	__class__s     R/home/dcms/DCMS/lib/python3.12/site-packages/tensorflow/python/saved_model/save.pyrK   z_AugmentedGraphView.__init__s   sK    	
t-d3 +CCED !0 H H JD !D D    signature_mapwrapped_functions.c                     | j                  | j                         t        j                  }|| j                  | j                     |<   | j
                  j                  |       y)a9  Attach signature to the root object.

    Args:
      signature_map: An object that contains signature functions.
      wrapped_functions: A dictionary mapping functions to functions that are
        guaranteed to not capture cached variables (functions that capture
        cached variables can't be saved).
    N)list_childrenrR   r2   SIGNATURE_ATTRIBUTE_NAMErM   rO   update)rQ   rV   rW   rC   s       rT   set_signaturez!_AugmentedGraphView.set_signature   sO     	tyy!";;D,9D#D)""#45rU   c                 `   t         t        |          \  }}t        j                         t        j                         |D ]U  }t        |t        j                        r||j                  <   t        |t        j                        sG||j                  <   W fd}t        | j                  j                               D ]W  } ||      |ur| j                  |= | j                  |   j                         D ]  \  }} ||      | j                  |   |<    Y t         t        |          S )z6Returns all trackable objects in the SavedObjectGraph.c                     t        | t        j                        r| j                     S t        | t        j
                        r,| j                  v r| j                     S | j                     S | S rI   )
isinstancer8   Asset
asset_pathr   TrackableConstantcapture)xasset_pathsconstant_capturess    rT   _get_merged_trackablezK_AugmentedGraphView._breadth_first_traversal.<locals>._get_merged_trackable   s`    	Au{{	#1<<((	A(::	;99#QYY'
'"199-
-hrU   )rJ   rG   _breadth_first_traversalr?   rL   r_   r8   r`   ra   r   rb   rc   listrM   keysitems)
rQ   trackable_objects_objrg   rC   childre   rf   rS   s
          @@rT   rh   z,_AugmentedGraphView._breadth_first_traversal   s'    	!4AC q "::<K'@@B  -	C	%&)CNN#	C*<<	=),#++&	- D((--/0 G	s	#3	.  %--c288: G+$*?*FS!$'G	G $dDFFrU   c              #   (  K   || j                   vri x}| j                   |<   t        t        |   |t        j
                  j                  | j                        D ]5  \  }}t        |t        j                        r| j                  |      }|||<   7 t        |t        j                        r'|s%| j                  j                  |j                          | j                   |   j#                         D ]  \  }}t	        j$                  ||        yw)z'Lists children of `obj` for SavedModel.)	save_typecacheN)rM   rJ   rG   rY   r9   SaveType
SAVEDMODELrN   r_   defunConcreteFunction _maybe_uncache_variable_capturesr   FunctionrP   appendrC   rk   TrackableReference)rQ   rn   childrenrC   ro   rS   s        rT   rY   z!_AugmentedGraphView.list_children   s     
$&&&-//h%%c*2DG
MM,,)) H + +$ eU33477>% 
C..	/&&sxx0++C0668 1e##D%001s   DDrC   c                 &    | j                   |   |   S rI   )rM   )rQ   rn   rC   s      rT   	get_childz_AugmentedGraphView.get_child   s    $T**rU   r   c                     || j                   v r| j                   |   S |j                  D ]E  }t        |d      s|| j                   vst        j                  |      x}| j                   |<   |c S  |S )N_cached_variable)rO   captured_inputshasattrr)   wrap_cached_variables)rQ   r   rc   wrappeds       rT   rw   z4_AugmentedGraphView._maybe_uncache_variable_captures   s     D333$$%677$44 	,	-D$;$;;$::;LM'D++,=> . rU   c              #     K   || j                   vri }n| j                   |   }|j                  |      j                         D ]@  \  }}t        |t        j
                        st        dt        |       d| d      ||f B yw)a  Yields `Trackables` that must be loaded before `obj`.

    Dependencies and children are both dictionaries of `Trackables`. Children
    define the object graph structure (used in both checkpoints and SavedModel),
    while dependency defines the order used to load the SavedModel

    Args:
      obj: A `Trackable` object

    Yields:
      Tuple of dependency names and trackable objects.

    Raises:
      TypeError: if any of the returned dependencies are not instances of
        `Trackable`.
    zThe dependency of type z is not an instance `Trackable`, and can't be saved to SavedModel. Please check the implementation of `_deserialization_dependencies` in the parent object .N)rM   _deserialization_dependenciesrk   r_   r9   	Trackable	TypeErrortype)rQ   rn   r{   rC   deps        rT   list_dependenciesz%_AugmentedGraphView.list_dependencies   s     " $&&&h%%c*h66x@FFH 	cT^^,%d3i[ 1 U! 	
 #Ios   BB)__name__
__module____qualname____doc__rK   r2   _SignatureMapr   r   r   r\   rh   rY   strr}   cfrv   rw   r   __classcell__)rS   s   @rT   rG   rG   d   sv    ! 6,::6 hsCx0(382DDE6&!GF1(+ +!22rU   rG   c                       e Zd ZdZdedej                  fdZd Zd Z	e
d        Ze
d        Zd	ej                  fd
Zd Zd Zd Zy)_SaveableViewa  Provides a frozen view over a trackable root.

  This class helps to create a single stable view over an object to save. The
  saving code should access properties and functions via this class and not via
  the original object as there are cases where an object construct their
  trackable attributes and functions dynamically per call and will yield
  different objects if invoked more than once.

  Changes to the graph, for example adding objects, must happen in
  `augmented_graph_view` (an `_AugmentedGraphView`) before the `_SaveableView`
  is constructed. Changes after the `_SaveableView` has been constructed will be
  ignored.
  augmented_graph_viewoptionsc           
         || _         || _        t        j                  | j                         \  | _        | _        | _        | _        | _        | j                   j                  }|rNt        j                  ddj                  |dt               t        t        t        |            t        |             | j!                          | j#                          t%        j&                         | _        y)zInitializes a SaveableView.

    Args:
      augmented_graph_view: A GraphView object.
      options: A SaveOptions instance.
    zFound untraced functions such as %s while saving (showing %d of %d). These functions will not be directly callable after loading.z, N)r   r   checkpoint_util(objects_ids_and_slot_variables_and_paths_trackable_objects
node_pathsnode_ids_slot_variablesobject_namesrP   r   infojoin_NUM_DISPLAY_UNTRACED_FUNCTIONSminlen&_initialize_save_and_restore_functions(_initialize_nodes_and_concrete_functionsr?   rL   captured_tensor_node_ids)rQ   r   r   rP   s       rT   rK   z_SaveableView.__init__  s     !5DDL 
	A	A&&
(.Tdot}	4, 22EEllJ
))&'G(GH
I
-s3E/F
G
 
!# 	//1113$3$L$L$ND!rU   c                    t        j                  | j                        \  }}t        j                         | _        |j                         D ])  \  }}|j                         D ]  }|| j
                  |<    + t        |      | _	        y)a  Generates all checkpoint save/restore functions.

    The save and restore functions are generated in the eager context (or in the
    user's Graph/Session) before being copied to the exported GraphDef. These
    functions record the ops for saving/restoring the entire object or
    individual objects (e.g. variables and hash tables).

    The global save and restore functions are generated for compatibility with
    TF1 and loading from C++, and is saved in the `MetaGraphDef.saver_def`.

    The individual functions are generated for the Python TF2 use case, where
    users use the loaded SavedModel as-is, or compose new models using parts
    of the object loaded from the SavedModel. These functions are recorded in
    the `saveable_objects` map in the `SavedObject` proto.
    N)
r   !get_checkpoint_factories_and_keysr   r?   rL   _obj_to_registered_saverrk   values_gen_save_and_restore_functions_saveable_objects_map)rQ   checkpoint_factory_mapregistered_savers
saver_name
trackables	trackables         rT   r   z4_SaveableView._initialize_save_and_restore_functions.  s    " 	66t7H7HI .-$3$L$L$ND!"3"9"9"; >
J!((* >)3=%%i0>> 	((>? 	rU   c                 P   t        | j                        | _        g | _        g | _        | j                  D ]  }|| j
                  v s| j
                  |   j                         D ]  \  }}t        | j                        | j                  |<   | j                  j                  |       t        | j                        | j                  |<   | j                  j                  |         | j                  D cg c]  }t        |t        j                        s|! c}| _        yc c}w )zCreates graph with nodes for trackable objects and functions.

    Adds functions for each trackable object to `self.nodes` and associated
    concrete functions to `self.concrete_functions` for serialization.
    N)ri   r   nodesgradient_functionsgradient_defsr   r   r   r   ry   r_   ru   rv   concrete_functions)rQ   rn   save_fn
restore_fns       rT   r   z6_SaveableView._initialize_nodes_and_concrete_functionsG  s     d--.DJ DDzz (	**	*#'#=#=c#B#I#I#K 	(GZ#&tzz?$--
 
**

G
$&)$**o$--

#
**

J
'	(( zzZU5K5K%LD s   6D#D#c                 4    | j                   | j                  z   S rI   )r   r   rQ   s    rT   concrete_and_gradient_functionsz-_SaveableView.concrete_and_gradient_functions^  s    ""T%<%<<<rU   c                      | j                   d   S )Nr   )r   r   s    rT   rR   z_SaveableView.rootb  s    ::a=rU   protoc                    t        | j                        D ]  \  }}| j                  |   |k(  sJ |j                  j                         }|j                  j                  | j                  j                  |d             t        |t              r{| j                  j                  |      D ]K  }|j                  j                         }| j                  |j                     |_        |j                  |_        M | j                  j#                  |      D ]:  \  }}|j$                  j                         }| j                  |   |_        ||_        < || j&                  v rv|| j(                  vsJ d       | j&                  |   j+                         D ]?  \  }	\  }
}|j,                  |	   }| j                  |
   |_        | j                  |   |_        A || j(                  v s| j(                  |   |_         y)zFPopulate the nodes, children and slot_variables of a SavedObjectGraph. z>Objects can't have both SaveableObjects and a registered saverN)	enumerater   r   addslot_variablesextendr   getr_   rB   r   rY   r{   refnode_idrC   
local_namer   dependenciesr   r   rk   saveable_objectssave_functionrestore_functionregistered_saver)rQ   r   r   nodeobject_protoro   child_protorC   r   r   r   r   saveable_object_protos                rT   fill_object_graph_protoz%_SaveableView.fill_object_graph_protof  s    #4::. L]]4 G+++[[__&l!!(()=)=)A)A$)KL	D/	*,,::4@ ,%"++//1"mmEII6!&, 00BB4H &)$"//335"mmC0!%&
 
++	+4888 	NL	N8 &&t,224	M-J-*"."?"?
"K
04g0F

-37==3L

0		M 4000(,(E(Ed(K%5LrU   c                    t        j                         rJ t        j                         }t        j                         }t	        g t        j                         i i       }t        |       D ]|  }| j                  |   }|j                  ||| j                        }t        |t        j                        rt        ||||j                            |sg|D ]  }|| j                  |<    ~ |||fS )a?  Makes new resource handle ops corresponding to existing resource tensors.

    Creates resource handle ops in the current default graph, whereas
    `accessible_objects` will be from an eager context. Resource mapping adds
    resource handle ops to the main GraphDef of a SavedModel, which allows the
    C++ loader API to interact with resources.

    Returns:
      A tuple of (object_map, tensor_map, asset_info):
        object_map: A dictionary mapping from object in `accessible_objects` to
          replacement objects created to hold the new resource tensors.
        tensor_map: A dictionary mapping from resource tensors extracted from
          `accessible_objects` to newly created resource tensors.
        asset_info: An _AssetInfo tuple describing external assets referenced
          from accessible_objects.
    
asset_defsasset_initializers_by_resourceasset_filename_mapasset_index)
object_map
tensor_mapr   )r   executing_eagerlyr?   rL   
_AssetInfo_dependency_sorted_node_idsr   _export_to_saved_model_graphr   r_   r8   r`   _add_asset_infora   r   )rQ   r   r   
asset_infor   rn   tensorstensors           rT   map_resourcesz_SaveableView.map_resources  s    $ ((*** !99;J 99;J'6'O'O'Q	J /t4 	:JJwc00J 1 g 
C	%ZCNN)CD	 	:F29$
'
'
/	:	: z:--rU   c                     t        | j                        }| j                  j                  |       || j                  |<   || j                  |<   || j                  |<   |S rI   )r   r   ry   r   r   )rQ   rc   r   r   s       rT   add_capture_and_nodez"_SaveableView.add_capture_and_node  sR    $**oGJJd$DMM'!DMM$-4D!!'*NrU   c                     g }| j                   D ]V  }t        |t        j                        s|j	                  | j
                  j                  |d      j                                X |S )N_initialize)r   r_   r:   CapturableResourcery   r   r}   get_concrete_function)rQ   concrete_initializersrn   s      rT   "get_concrete_resource_initializersz0_SaveableView.get_concrete_resource_initializers  sc    zz =	C44	5$$%%//]$$9$9$;	==
 ! rU   N)r   r   r   r   rG   r/   SaveOptionsrK   r   r   propertyr   rR   r   SavedObjectGraphr   r   r   r   r   rU   rT   r   r      s    O/O ''OBA2. = =  L)::L@(.T!rU   r   r   returnc                 r   t        j                         }| j                         D ]  \  }}t        j                  |      s|s|d   j
                  t        j                  k(  r9t        |      dk(  sJ t        j                  t        j                  |      i||<   wt        j                  ||      ||<    |S )a  Generates global and individual save/restore concrete functions.

  The global functions records the ops to save and restore the entire object to
  a file prefix, while the individual functions save and restore value tensors
  for resources.

  This function is intended to run on the output of
  `save_util_v1.get_checkpoint_factories_and_keys(object_names)`,
  which returns the generated a map of `_CheckpointFactoryData`.

  Args:
    checkpoint_factory_map: A dictionary mapping trackable objects to
      a list of `_CheckpointFactoryData`.

  Returns:
    Tuple of (
      saveable_fn_map: Maps obj -> factory name -> (concrete save, restore)
      )
  r      )r?   rL   rk   r&   is_resource_variablerC   r;   SERIALIZE_TO_TENSORS_NAMEr   r4   trace_save_and_restorer<   trace_save_restore_function_map)r   saveable_fn_maprn   factory_data_lists       rT   r   r     s    0 $<<>/ 6 < < > 'c11#6>O  O$M$MM"#q(((-GG

.
.s
36oc
 
=
=$& c' 
rU   c                 |    | j                         D ci c]  \  }}|t        j                  |       c}}S c c}}w rI   )rk   r5   build_tensor_info_internal)tensor_dictkeyvalues      rT   _tensor_dict_to_tensorinfor     sA     $))+

#u 
:0077
  
s    8signature_keyuser_input_namec                     dj                  | |      }t        j                  d|      r|S t        j                  dd|      }t        j                  dd|      S )aw  Creates a sanitized name scope from user signature and input names.

  Concatenates signature and input names, sanitizing as needed to be a valid
  scope name.

  Args:
    signature_key: The user-provided key for the signature.
    user_input_name: The user-provided name for the input placeholder.

  Returns:
    A name scope that is safe to be used in tf.name_scope().
  z{}_{}z^[A-Za-z0-9.][A-Za-z0-9_.\\-]*$z^[^A-Za-z0-9.]* z[^A-Za-z0-9_.\\-]rm   )formatrematchsub)r   r   
name_scopeinvalid_prefix_strippeds       rT   _to_safe_name_scoper    sR     ~~m_=*XX0*=FF#5r:F	$c+B	CCrU   function_argumentsfunction_namec           
         i }g }| D ]2  }t        j                  |j                  j                  d            }||j                  j                  k7  r(t        d| dt        j                  |       d| d      |j                  |i       j                  |      }|Qt        j                  |j                         |j                  t        ||            }	|	||<   |j                  |	       t        j                  |j                  |j                  t        ||            }
|
||<   |j                  |
       5 ||fS )a  Creates exterior placeholders in the exported graph for function arguments.

  Functions have two types of inputs: tensors captured from the outside (eager)
  context, and arguments to the function which we expect to receive from the
  user at each call. `_map_captures_to_created_tensors` replaces
  captured tensors with stand-ins (typically these are resource dtype tensors
  associated with variables). `_map_function_inputs_to_created_inputs` runs over
  every argument, creating a new placeholder for each which will belong to the
  exported graph rather than the function body.

  Args:
    function_arguments: A list of argument placeholders in the function body.
    signature_key: The name of the signature being exported, for error messages.
    function_name: The name of the function, for error messages.
    defaults: A dictionary mapping signature_key to dictionary of
      user_specified_name to Tensor representing default values.

  Returns:
    A tuple of (mapped_inputs, exterior_placeholders)
      mapped_inputs: A list with entries corresponding to `function_arguments`
        containing all of the inputs of the function gathered from the exported
        graph (both captured resources and arguments).
      exterior_argument_placeholders: A dictionary mapping from argument names
        to placeholders in the exported graph, containing the explicit arguments
        to the function which a user is expected to provide.

  Raises:
    ValueError: If argument names are not unique.
  _user_specified_namezAGot non-flat/non-unique argument names for SavedModel signature 'z': more than one argument to 'z' was named 'a%  '. Signatures have one Tensor per named input, so to have predictable names Python functions used to generate these signatures should avoid *args and Tensors in nested structures unless unique names are specified for each. Use tf.TensorSpec(..., name=...) to provide a name for a Tensor input.)inputshaperC   )r  dtyperC   )r>   
as_str_anyopget_attrrC   
ValueErrorr   r$   placeholder_with_defaultnumpyr  r  ry   placeholderr  )r	  r   r
  defaultsexterior_argument_placeholdersmapped_inputsr  r   default_valuer  arg_placeholders              rT   )_map_function_arguments_to_created_inputsr  	  sd   R $& -' (,k '' 679O +..--- _ ./ 0 	
 
 LL377HM !*!C!C##%!!"=/B"
 9Q$_534!--!!!!"=/Bo
 9H$_5?+Q(,R 
6	66rU   signature_functions.r   c                    i }t        | j                               D ]6  \  }}|j                  j                  r8|j                  j                  dt        |j                  j                          }n|j                  j                  }t        |||j                  |      \  }}t        t        ||   j                  j                  d   j                                     }	 ||   di t        |	|      D 
ci c]  \  }
}|
|
 c}}
}t        j                  t        |      t        |      t         j"                  |j%                  |d            ||<   9 |S c c}}
w )a  Validates and calls `signature_functions` in the exported graph.

  Args:
    signature_functions: A dictionary mapping string keys to concrete TensorFlow
      functions (e.g. from `signature_serialization.canonicalize_signatures`)
      which will be used to generate SignatureDefs.
    object_map: A dictionary that contains mappings from signature functions to
      concrete functions in the exported graph.
    defaults: A dictionary mapping signature_key to dictionary of
      user_specified_name to Tensor representing default values.

  Returns:
    Each function in the `signature_functions` dictionary is called with
    placeholder Tensors, generating a function call operation and output
    Tensors. The placeholder Tensors, the function call operation, and the
    output Tensors from the function call are part of the default Graph.

    This function then returns a dictionary with the same structure as
    `signature_functions`, with the concrete functions replaced by SignatureDefs
    implicitly containing information about how to call each function from a
    TensorFlow 1.x Session / the C++ Loader API. These SignatureDefs reference
    the generated placeholders and Tensor outputs by name.

    The caller is expected to include the default Graph set while calling this
    function as a MetaGraph in a SavedModel, including the returned
    SignatureDefs as part of that MetaGraph.
  Nr   )method_namer  r   )sortedrk   graphcapturesinputsr   r  rC   ri   r   structured_input_signaturerj   zipr1   build_signature_defr   r0   PREDICT_METHOD_NAMEr   )r  r   r  
signaturesr   r   argument_inputsr  r  kwarg_names
kwarg_namemapped_inputoutputss                rT   _generate_signaturesr.  `  sS   @ *!'(;(A(A(C!D mX~~ --.LHNN4K4K0L/LMo --o1]HMM8	
 2M1
 x ))DDQGLLN	PQK #j" (+K(G&$J 	L & G !4 G G"#AB"7+';;mT2	!J}#. 
&s   4Er   r   r   mapped_path_variablec                 4   | j                   }t        j                  |      }	 t        |j	                  t                    }t        j                  ||j                        }||j                  |<   t        j                         }||_        |j                  j                  |j                  _        |j                  j!                  |       |j"                  |j$                  |<   t'        |j                        dz
  |j(                  | <   y# t
        $ r Y w xY w)z&Add `trackable_asset` to `asset_info`.)asset_filepathr   r   N)ra   r!   constant_valuer   astypeAttributeErrorr'   get_asset_filename_to_addr   r   AssetFileDeffilenameinitial_valuerC   tensor_infor   ry   initializerr   r   r   )trackable_assetr   r/  original_path_tensororiginal_pathpath	asset_defs          rT   r   r     s     )33,,-AB-	,,S12M
 
	/	/"#66
8$ )6*%))+))3AAFF)y)&& ++,@A,/
0E0E,F,J*) 
 		s   D 	DDfnc              #   P  K   t        | t        j                        rB| j                  j                  D ](  }|j
                  d   j                  }|st        d       y| j                  j                         D ]  }	 |j                  d      }||f  y# t        $ r Y )w xY ww)zHIterates through each op in the function and returns the op type and op._gradient_op_typezUnable to save gradient functions when exporting a _DefinedFunction (generally created through graph freezing utils or through V1 graph importers). Please save with `options=tf.SaveOptions(experimental_custom_gradients=False)`N)r_   framework_fn_DefinedFunction
definitionnode_defattrsr  r!  get_operationsr  )r@  r   op_typer  s       rT   _iterate_op_typesrK    s     L112&& M		-.00g	LM 	MM hh%%' ++12 RK  s0   AB&*B&=B	B&	B# B&"B##B&rc   func_graph_mapc                    | }|t        |t        j                        s|j                  |j                  ur&|j	                  |j                  j
                        }nd	 |j                  j                  j                  |      }|j                  j                  |   }|j	                  |j                  j
                        }|t        |t        j                        s||fS # t        $ r Y ||fS w xY w)zETries to find the original captured tensor if capture more than once.)
r_   r    EagerTensorr!  r   outer_graphinternal_capturesindexr  external_captures)r@  rc   rL  outer_fncapture_indexs        rT   _get_outer_most_capturerU    s     (Z%I}}HNN*##HNN$>$>?h 88>>wG 00?g##HNN$>$>?h 	Z%I 
7	   
7	s   %C" "	C10C1r!  saveable_viewc                    t        | j                  j                               }|D ci c]  }t        |d      s|j                  | }}t               }|D ]  }t        |      D ]  \  }}||v r|j                  |       	 t        j                  j                  |      }		  t        j                  |	      j                  dg|j                   }
| j+                         5  g }|
j,                  D ]U  }|j.                  t0        v rt3        |||      \  }}|t5        |t        j6                        r:||j8                  vrt'        d| d      |j8                  |   |j8                  |<   }|j                  |j                  u r|j(                  }t5        |t:        j<                        rV	 |j                  j                  j?                  |      }|j@                  jB                  jD                  |   j(                  dz   }tG        ||j(                        }|jI                  ||       ;|jK                  |j(                         X |s|
jM                  |        nt'        d| d	| d
|       	 ddd       |jN                  jK                  |
       |
||
j                  <   tQ        jR                         }|
j(                  |_*        ||_+        |jX                  jK                  |         yc c}w # t        $ r Y w xY w# t         $ r?}t#        j$                          t'        d|j(                   d|j                         |d}~ww xY w# t&        $ r Y ]w xY w# 1 sw Y   xY w)z?Traces gradient functions and records them in the SaveableView.r!  NaN  Error when tracing gradients for SavedModel.

Check the error log to see the error that was raised when converting a gradient function to a concrete function. You may need to update the custom gradient, or disable saving gradients with the option tf.saved_model.SaveOptions(experimental_custom_gradients=False).
	Problematic op name: z
	Gradient inputs: zFound invalid capture z when saving custom gradients.z:0zCannot save custom gradient z called in function z@ because SavedModel is unable to serialize the captured inputs: )-ri   
_functionsr   r   r!  setrK  r   r    gradient_registrylookupLookupErrorr   r   r   r#  	Exception	traceback	print_excr  rC   
as_defaultr   r  _UNCOPIABLE_DTYPESrU  r_   rN  r   ru   AtomicFunctionrQ  cached_definition	signature	input_argrB   r   ry   add_to_graphr   r	   RegisteredGradientgradient_funcregistered_op_typer   )r!  rV  	functionsfrL  seen_op_typesr@  rJ  r  custom_gradientgrad_fnexcbad_capturesrc   rS  outer_capturecapture_name	arg_indexr   grad_defs                       rT   _trace_gradient_functionsru    su   5##**,-)(1I1WQ5HAGGQJI.I%- W3b(, V3	M	! //66w?%HL!!/2HH"yy" 	  4 .. '	.G]]00
 %<'>%
!(M M3??!KM$J$JJ*=/ :- - 
 66}E 227; ""hnn4(--L (E$8$89	$NN1177F	..88BB!d  #<?D..w=-O'	.P 


u
%,WI5I" N%(  &]4l &&--g6&-nW]]#002h&||h$+h!!!((2mV3W3 J    
%) *,	1Fyyk "%	%
%d   M4 4sg   K5K5K:$0L
$C
M%/AMA0M%:	LL
	M:MM	M"M%!M""M%%M.meta_graph_defc                    dt         j                  ddfddt         j                  ddfddt        dt        fddt        dt        fddt         j                  ddffd	}| j                  j                  D ]
  } ||        | j                  j
                  j                  D ]  }|j                  D ]
  } ||         y)
a\  An experimental function to remove debug nodes from the final graph.

  This function removes all Assert and CheckNumerics nodes from the meta_graph.
  It strips the operators in both the nodes and in all of the function defs,
  with the Assert ops being replaced by `NoOp`s and the CheckNumerics ops being
  transformed into `Identity` ops. In addition to this, it creates control
  inputs for the nodes that are not relevant for the op. For more information
  about control inputs please see go/how-tensors-flow#control-dependencies.

  Args:
   meta_graph_def: The meta_graph that will be exported.
  r   r   Nc                     | j                   j                         D cg c]  }|j                  d      s| }}|D ]  }| j                   j                  |        yc c}w )zErases regular node attributes.rm   N)rG  rj   
startswithpop)r   	attributeattributes_to_removes      rT   erase_regular_node_attributesz9_strip_debug_nodes.<locals>.erase_regular_node_attributes\  sa     )##C( 	 
 * 	
iimmIs   Ac                     d| j                   v r?| j                   d   }| j                  d       | j                   d   j                  |       y| j                  d       y)z'Prunes all attributes that are not `T`.TrG  N)rG  
ClearFieldCopyFrom)r   t_values     rT   prune_all_non_t_attributesz6_strip_debug_nodes.<locals>.prune_all_non_t_attributesf  sI    
dii		#g
oof
iing&
oofrU   rC   c                     | xr | d   dk(  S )z4Returns whether or not the input is a control input.r   ^r   rC   s    rT   is_control_inputz,_strip_debug_nodes.<locals>.is_control_inputo  s    "DGsN"rU   c                 0    d| j                  d      d   z   S )z*Returns the input as a control dependency.r  :r   )splitr  s    rT   as_control_depz*_strip_debug_nodes.<locals>.as_control_deps  s    C###rU   c                 V   | j                   dk(  s| j                   dk(  rd| _          |        g }| j                  D ]3  } |      s|j                   |             #|j                  |       5 | j                  d       | j                  j	                  |       y	| j                   dk(  s| j                   dk(  rld| _          |        t        dt        | j                              D ]:  } | j                  |         r | j                  |         | j                  |<   < y	y	)
a  Strips the graph from Assert and CheckNumerics ops.

    For Assert ops, this function also rewrites all of the inputs to the nodes
    that were transformed by making them into control dependencies. It also
    removes all of the regular node attributes, that is all node attributes
    that do not start with `_`.

    For CheckNumerics ops, this function turns the op into an Identity op,
    which will be pruned later (according to the original implementation in
    grappler's `debug_stripper.cc`. Then, since Identity ops only take one
    input, it leaves the first input as is while transforming the other ones
    into control dependencies.

    Args:
      node: The node to potentally strip.
    AssertPrintV2NoOpr  CheckNumericsPrintIdentityr   N)r  r  ry   r  r   ranger   )r   
new_inputsinpir  r}  r  r  s       rT   maybe_do_stripz*_strip_debug_nodes.<locals>.maybe_do_stripw  s   " ww(dgg2dg#D)j !#$


N3/
0


C
 	!
 oog
jj
#	O	#tww''9dg & QDJJ( 8!

1.(A7$**Q-8 (:rU   )r   NodeDefr   	graph_defr   libraryr   rF  )rv  r  r   funcr  r}  r  r  s       @@@@rT   _strip_debug_nodesr  N  s    ,*>*> 4 |';';  #S #S #$3 $3 $$8<// $8D $8 $8N &&++ d4 &&..77 d TrU   namespace_whitelistsave_custom_gradientscreate_saverenable_debug_stripperc                 ~
   |j                         }t        j                         }	g }
|	j                         5  |j	                         \  }t        ||      }ddd       |rt        |	|       |	j                         5  |D ]  }g }|j                  j                  D ]2  }j                  j                  |d      }|"|j                  |       4 t        j                  |      5  |   }|
j                   |              ddd        |
j                  j                  j                                t        j                  |
      5  t        j                          }ddd       | j"                  t$        j&                     j(                  j*                  j                  j,                         | j.                  t$        j0                     j3                  t5        j6                  |t$        j0                               ddd       fd}j                         D ]  }|j9                           t;        j<                  |j>                  |	|      \  }}|ret@        jB                  jE                  |||      }|	j                         5  |jG                         }| jH                  j3                  |       ddd       tK        |       |	jM                  dd      \  }}|jN                  jP                  j                  |jR                         tU        ||       | jV                  j3                  |       | jX                  jZ                  j                  t\        j^                         |j`                  jb                  r@|j`                  jb                  D ]'  }| jX                  jZ                  j                  |       ) td        jf                  | jX                  _4        td        jj                  | jX                  _6        d| jX                  _7        | jp                  j                  jr                         ju                         D ]#  \  }}| j.                  |   j3                  |       % tw        jx                  |        tz        j|                  dk(  rt        j                  | dd       |rt        |        | jX                  j                  j                  tw        j                  | jV                               ||	f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   %xY w# 1 sw Y   zxY w)	aj  Generates a MetaGraph which calls `signature_functions`.

  Args:
    meta_graph_def: The MetaGraphDef proto to fill.
    saveable_view: The _SaveableView being exported.
    signature_functions: A dictionary mapping signature keys to concrete
      functions containing signatures to add to the MetaGraph.
    namespace_whitelist: List of strings containing whitelisted op namespaces.
    save_custom_gradients: Whether to save custom gradients.
    create_saver: Whether to add SavedModel's native save and restore ops.
    enable_debug_stripper: Whether to strip the debug nodes from the graph.
    defaults: A dictionary mapping signature_key to dictionary of
      user_specified_name to Tensor representing default values.

  Returns:
    A tuple of (_AssetInfo, Graph) containing the captured assets and
    exported Graph generated from tracing the saveable_view.
  Nc                 N    | v r |    | S  t        j                  |       | S rI   )r   ExportedConcreteFunction)r   argsr   r   s     rT   call_with_mapped_capturesz7_fill_meta_graph_def.<locals>.call_with_mapped_captures  sB    :!Z!4(((AA*#% %rU   )r   r   to_graphr  TF)
add_shapesuse_pybind11_protobiglittle)Er   r    Graphr`  r   r.  ru  r!  rR  r   r   ry   control_dependenciesr   r   r%   no_opcollection_defr6   MAIN_OP_KEY	node_listr   rC   signature_defINIT_OP_SIGNATURE_KEYr  r1   op_signature_def_maybe_initialize_trackabler   frozen_saveables_and_saversr   r   MultiDeviceSaverfrom_saveablesto_proto	saver_defr   _as_graph_defr  registered_gradientsr   _verify_opsr  meta_info_deftagsr3   SERVINGr   
extra_tagsr"   __version__tensorflow_version__git_version__tensorflow_git_versionstripped_default_attrsasset_file_defr   rk   r    strip_graph_default_valued_attrssys	byteorderr5   swap_function_tensor_contentr  stripped_op_list	MergeFromstripped_op_list_for_graph) rv  rV  r  r  r  r  r  r  resource_initializersexported_graphresource_initializer_opsr   r(  resource_initializer_functionasset_dependenciesrc   asset_initializermapped_initializerinit_opr  rn   named_saveable_objectsr   saverr  r  rm   tagr   rd  r   r   s                                  @@rT   _fill_meta_graph_defr    s   < (JJL99;.  " Q)6)D)D)F&J
J%&9:xPJQ  nm<  " O)> 	>%288JJ 7'&EEIIT(

#
#$5
6	7
 ##$67 >'(EF ''(:(<=> >	> ##1188:<		!	!":	; ) &&(g)
 !!)"7"78BBHHOO  !@!@AJJ,,W-6-L-L	NO+O:%   &c##%& .."77!$=	? ,+ --<< 13LE 
	"	"	$ 3.."i''	23 m,--% . 1,)Q((//0K0KLi,-##I.##**=+@+@A%%$$// 4""''..s344<4H4H.1 5 9=.5&&z'<'<=","2"2"4 DmY  /88CD--n=]]e++NE8L~&//99++N,D,DEG	^	##yQ Q > >
) )O Of3 3s[   "S>?T%(T%)TAT%T"B T%,T2>TTT%T"	T%%T/2T<r  c                 $   |yg }t               }g }|j                  t        j                  |              |D ]B  }d|v s|j	                  d      d   }||vs!|j                  |       |j                  |       D |rt        d| d| d      y)aV  Verifies that all namespaced ops in the graph are whitelisted.

  Args:
   graph_def: the GraphDef to validate.
   namespace_whitelist: a list of namespaces to allow. If `None`, all will be
     allowed. If an op does not have a namespace, it will be allowed.

  Raises:
   ValueError: If the graph contains ops that violate the whitelist.
  N>r   zEAttempted to save ops from non-whitelisted namespaces to SavedModel: ae  .
Please verify that these ops should be saved, since they must be available when loading the SavedModel. If loading from Python, you must import the library defining these ops. From C++, link the custom ops to the serving binary. Once you've confirmed this, add the following namespaces to the `namespace_whitelist` argument in tf.saved_model.SaveOptions: r   )rY  r   r   ops_used_by_graph_defr  ry   r   r  )r  r  invalid_opsinvalid_namespacesall_operationsr  	namespaces          rT   r  r  '  s      
+u.
88CD *b
by((3-"i	-	-2y)* 
O- 3
 4F2Fa	IJ J rU   c                 ~   i }| j                   D ]  }| j                  |   }g x}||<   t        |t              r*| j                  j                  |      D ]e  \  }}|| j                  vr4t        j                  | j                  |         }t        d| d| d      |j                  | j                  |          g  	 t        j                  |      S # t        j                  $ r}g }	g }
|j                  j                         D ]|  \  }}t        j                  | j                  | j                   |            }|	j                  d| d| dt        | j                   |          d       |
j                  d| d|        ~ d	j!                  |	      }	d	j!                  |
      }
t        d
|	 d|
       d}~ww xY w)z;Returns topologically sorted nodes, sorted by dependencies.z&Found an untracked dependency. Object z depends on z, but this dependency isn't listed as a child. Please track this child by overriding `_trackable_children` or use `._track_trackable`.z	Node z = z (type )z depends on nodes 
zThere is one or more dependency cycle in the saved Trackable object. Saving cannot continue until this cycle is resolved.
>> Unresolved nodes:
z$
>> Unresolved cyclic dependencies:
N)r   r   r_   rB   r   r   r;   pretty_print_node_pathr   r  ry   order_by_dependencyCyclicDependencyErrorleftover_dependency_maprk   r   r   )rV  dependency_mapr   r   depsrm   r   	node_patherrpretty_printed_nodespretty_printed_dependenciesrd   s               rT   r   r   P  s   .!! /d$$T*G%''D>'"$(44FFtL 	/3	M**	*#::$$T*,	4YK @ **+ 	+
 kk-((-.	// P..~>>		.	. P"$..446 P4!88

"
"=#6#6q#9
:<i!!A3c)GD1D1DQ1G,H+I
KM!((71#5Gv)NOP  99%9:"&)),G"H
	##7"8
01L0M	OP PPs   ?C F<'CF77F<c                    t        j                         }| j                  |       | j                  D ]b  }t	        j
                  |j                        }t        j                  || j                        }|E|j                  |   j                  |       d t        | j                  |j                        D ]'  \  }}t        |||| j                  j                          ) |S )z)Save a SavedObjectGraph proto for `root`.)r   r   r   r   r>   as_textrC   r)   serialize_concrete_functionr   r   r  r%  r   _write_object_protor   rY   )rV  asset_file_def_indexr   r   rC   
serializedrn   	obj_protos           rT   _serialize_object_graphr  x  s     !
1
1
3%''.(HH :>>+001D'CC=AAJ t$--j9: M//= nc9**88	 
,rU   r   c           	         t        | t        j                        r0|j                  j                          ||    |j                  _        nt        j                  |       r(t        j                         }| j                  ||       nt        | t        j                        rO|j                  j                  t        j                  |  ||       D cg c]  }|j                    c}             n/t        | t"        j$                        r/|j&                  j                  t        j(                  |              nt        | t*              r7| j,                  |j.                  _        | j0                  |j.                  _        nt        | t2        j4                        r| j6                  |j2                  _        nit;        j<                  |       }|7t?        j@                  | jB                  tE        jF                  ddg             }|jH                  j                  |       tK        jL                  |       }|r8||_'        | jQ                  |      }||jR                  jU                  |       yyyc c}w )z'Saves an object into SavedObject proto.Nr   )producermin_consumerbad_consumers)
identifierversion)r   )+r_   r8   r`   SetInParentr  r&   r   r.   get_save_optionsr  r   rx   r   r  r)   serialize_functionr   ru   rv   bare_concrete_function serialize_bare_concrete_functionrB   rC   captured_tensorr   r:   r   _resource_devicedevicer-   	serializer   SavedUserObject_object_identifierr   
VersionDefuser_objectr,   get_registered_class_nameregistered_name_serialize_to_protoserialized_user_protoPack)	rn   r   r  list_children_fnr   rd   registered_type_protor
  r  s	            rT   r  r    s    U[[!	KK';C'@EKK$11#6++-GE7+#|,,-	NN11!1#!67A!%%7	9: #u--.	  ))??DF#'!$E.1.C.CE+#x22300ENN)33C8$ 5DD++))q<=
 
45 ::3?/+E333G(!!&&'<= ) - 8s   I0r  
export_dirc                    t        j                         }| j                  D ]J  }| j                  |      }t	        |t
        j                        s/|j                  ||j                         L |j                         }t        j                  t        j                  t        j                  |      t        j                         |j#                  d             y)a1  Exports debug information from graph to file.

  Creates and writes GraphDebugInfo with traces for ops in all functions of the
  exported_graph.

  Args:
    exported_graph: A Graph that has been created by tracing a saveable view.
    export_dir: SavedModel directory in which to write the debug info.
  TdeterministicN)r@   GraphDebugInfoBuilderrX  _get_functionr_   ru   rb  AppendGraphDebugInfograph_debug_infoBuildr#   atomic_write_string_to_filer   r*   get_or_create_debug_dirr6   DEBUG_INFO_FILENAME_PBSerializeToString)r  r  debug_builderfn_namer@  r  s         rT   _export_debug_infor    s     002-** Eg		%	%g	.Bb%../&&w0C0CD	E #((*	%%ll

.
.z
:

*
*, ((t(<	>rU   zsaved_model.savezsaved_model.experimental.save)v1r   c                     t        |t        j                        rt        j                  |      }t	        j
                  t               t        | |||       t	        j                  d       y)a  Exports a [tf.Module](https://www.tensorflow.org/api_docs/python/tf/Module) (and subclasses) `obj` to [SavedModel format](https://www.tensorflow.org/guide/saved_model#the_savedmodel_format_on_disk).

  The `obj` must inherit from the [`Trackable`
  class](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/trackable/base.py#L278).

  Example usage:

  >>> class Adder(tf.Module):
  ...   @tf.function(input_signature=[tf.TensorSpec(shape=[], dtype=tf.float32)])
  ...   def add(self, x):
  ...     return x + x

  >>> model = Adder()
  >>> tf.saved_model.save(model, '/tmp/adder')

  The resulting SavedModel is then servable with an input named "x", a scalar
  with dtype float32.

  _Signatures_

  Signatures define the input and output types for a computation. The optional
  save `signatures` argument controls which methods in `obj` will be
  available to programs which consume `SavedModel`s, for example, serving
  APIs. Python functions may be decorated with
  `@tf.function(input_signature=...)` and passed as signatures directly, or
  lazily with a call to `get_concrete_function` on the method decorated with
  `@tf.function`.

  Example:

  >>> class Adder(tf.Module):
  ...   @tf.function
  ...   def add(self, x):
  ...     return x + x

  >>> model = Adder()
  >>> tf.saved_model.save(
  ...   model, '/tmp/adder',signatures=model.add.get_concrete_function(
  ...     tf.TensorSpec([], tf.float32)))

  If a `@tf.function` does not have an input signature and
  `get_concrete_function` is not called on that method, the function will not
  be directly callable in the restored SavedModel.

  Example:

  >>> class Adder(tf.Module):
  ...   @tf.function
  ...   def add(self, x):
  ...     return x + x

  >>> model = Adder()
  >>> tf.saved_model.save(model, '/tmp/adder')
  >>> restored = tf.saved_model.load('/tmp/adder')
  >>> restored.add(1.)
  Traceback (most recent call last):
  ...
  ValueError: Found zero restored functions for caller function.

  If the `signatures` argument is omitted, `obj` will be searched for
  `@tf.function`-decorated methods. If exactly one traced `@tf.function` is
  found, that method will be used as the default signature for the SavedModel.
  Else, any `@tf.function` attached to `obj` or its dependencies will be
  exported for use with `tf.saved_model.load`.

  When invoking a signature in an exported SavedModel, `Tensor` arguments are
  identified by name. These names will come from the Python function's argument
  names by default. They may be overridden by specifying a `name=...` argument
  in the corresponding `tf.TensorSpec` object. Explicit naming is required if
  multiple `Tensor`s are passed through a single argument to the Python
  function.

  The outputs of functions used as `signatures` must either be flat lists, in
  which case outputs will be numbered, or a dictionary mapping string keys to
  `Tensor`, in which case the keys will be used to name outputs.

  Signatures are available in objects returned by `tf.saved_model.load` as a
  `.signatures` attribute. This is a reserved attribute: `tf.saved_model.save`
  on an object with a custom `.signatures` attribute will raise an exception.

  _Using `tf.saved_model.save` with Keras models_

  While Keras has its own [saving and loading
  API](https://www.tensorflow.org/guide/keras/save_and_serialize),
  this function can be used to export Keras models. For example, exporting with
  a signature specified:

  >>> class Adder(tf.keras.Model):
  ...   @tf.function(input_signature=[tf.TensorSpec(shape=[], dtype=tf.string)])
  ...   def concat(self, x):
  ...      return x + x

  >>> model = Adder()
  >>> tf.saved_model.save(model, '/tmp/adder')

  Exporting from a function without a fixed signature:

  >>> class Adder(tf.keras.Model):
  ...   @tf.function
  ...   def concat(self, x):
  ...      return x + x

  >>> model = Adder()
  >>> tf.saved_model.save(
  ...   model, '/tmp/adder',
  ...   signatures=model.concat.get_concrete_function(
  ...     tf.TensorSpec(shape=[], dtype=tf.string, name="string_input")))

  `tf.keras.Model` instances constructed from inputs and outputs already have a
  signature and so do not require a `@tf.function` decorator or a `signatures`
  argument. If neither are specified, the model's forward pass is exported.

  >>> x = tf.keras.layers.Input((4,), name="x")
  >>> y = tf.keras.layers.Dense(5, name="out")(x)
  >>> model = tf.keras.Model(x, y)
  >>> tf.saved_model.save(model, '/tmp/saved_model/')

  The exported SavedModel takes "x" with shape [None, 4] and returns "out"
  with shape [None, 5]

  _Variables and Checkpoints_

  Variables must be tracked by assigning them to an attribute of a tracked
  object or to an attribute of `obj` directly. TensorFlow objects (e.g. layers
  from `tf.keras.layers`, optimizers from `tf.train`) track their variables
  automatically. This is the same tracking scheme that `tf.train.Checkpoint`
  uses, and an exported `Checkpoint` object may be restored as a training
  checkpoint by pointing `tf.train.Checkpoint.restore` to the SavedModel's
  "variables/" subdirectory.

  `tf.function` does not hard-code device annotations from outside the function
  body, instead of using the calling context's device. This means for example
  that exporting a model that runs on a GPU and serving it on a CPU will
  generally work, with some exceptions:

    * `tf.device` annotations inside the body of the function will be hard-coded
      in the exported model; this type of annotation is discouraged.
    * Device-specific operations, e.g. with "cuDNN" in the name or with
      device-specific layouts, may cause issues.
    * For `ConcreteFunctions`, active distribution strategies will cause device
      placements to be hard-coded in the function.

  SavedModels exported with `tf.saved_model.save` [strip default-valued
  attributes](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/saved_model/README.md#stripping-default-valued-attributes)
  automatically, which removes one source of incompatibilities when the consumer
  of a SavedModel is running an older TensorFlow version than the
  producer. There are however other sources of incompatibilities which are not
  handled automatically, such as when the exported model contains operations
  which the consumer does not have definitions for.

  Args:
    obj: A trackable object (e.g. tf.Module or tf.train.Checkpoint) to export.
    export_dir: A directory in which to write the SavedModel.
    signatures: Optional, one of three types:
      * A `tf.function` with an input signature specified, which will use the
        default serving signature key.
      * The result of `f.get_concrete_function` on a `@tf.function`-decorated
        function `f`, in which case `f` will be used to generate a signature for
        the SavedModel under the default serving signature key.
      * A dictionary, which maps signature keys to either `tf.function`
        instances with input signatures or concrete functions. Keys of such a
        dictionary may be arbitrary strings, but will typically be from the
        `tf.saved_model.signature_constants` module.
    options: `tf.saved_model.SaveOptions` object for configuring save options.

  Raises:
    ValueError: If `obj` is not trackable.

  @compatibility(eager)
  Not well supported when graph building. From TensorFlow 1.x,
  `tf.compat.v1.enable_eager_execution()` should run first. Calling
  tf.saved_model.save in a loop when graph building from TensorFlow 1.x will
  add new save operations to the default graph each iteration.

  May not be called from within a function body.
  @end_compatibility
  2)write_versionN)	r_   osPathLikefspathr7   IncrementWriteApi_SAVE_V2_LABELsave_and_return_nodesIncrementWrite)rn   r  r(  r   s       rT   saver+    sK    v 
BKK(:&J	N+ZW=	s+rU   c                     |xs t        j                         }t        j                         }|j                  j                         }t        | |||      \  }}}	}
}}t        j                  |_	        |sft        j                  |       t        j                  |j                  |j                        }|	j!                  t        j"                  |      |       t%        j&                  |
j(                  |       t+        j,                         r	 t+        j.                          t7        j8                  |       |j:                  rNt=        j>                  tA        jB                  |      d      }tD        jG                  |      jI                  |       npt=        j>                  tA        jB                  |      tA        jB                  t        jJ                              }t=        jL                  ||jO                  d             tQ        jR                  |       |jT                  rtW        ||       tY        jZ                  t]        |             t_        j`                  |       ||fS # t0        j2                  $ r}t5        | d      |d}~ww xY w)	a  Saves a SavedModel while returning all saved nodes and their paths.

  Please see `tf.saved_model.save` for details.

  Args:
    obj: A trackable object to export.
    export_dir: A directory in which to write the SavedModel.
    signatures: A function or dictionary of functions to save in the SavedModel
      as signatures.
    options: `tf.saved_model.SaveOptions` object for configuring save options.
    experimental_skip_checkpoint: If set to `True`, the checkpoint will not be
      written.

  Returns:
    A tuple of (a list of saved nodes in the order they are serialized to the
      `SavedObjectGraph`, dictionary mapping nodes to one possible path from
      the root node to the key node)
  )experimental_io_deviceexperimental_sharding_callback)r   z
 You may be trying to save on a different device from the computational device. Consider setting the `experimental_io_device` option in `tf.saved_model.SaveOptions` to the io_device such as '/job:localhost'.Nsaved_modelTr  )saved_model_path)1r/   r   r   
SavedModelmeta_graphsr   _build_meta_graphr6   SAVED_MODEL_SCHEMA_VERSIONsaved_model_schema_versionr*   get_or_create_variables_dirr   CheckpointOptionsr-  r.  r+  get_variables_pathr'   copy_assets_to_destination_dirr   r   r   
async_waitr   NotFoundErrorFileNotFoundErrorr+   Saveexperimental_image_formatr#   r   r>   as_strproto_splitterSavedModelSplitterwriteSAVED_MODEL_FILENAME_PBr  r  r(   write_fingerprintsave_debug_infor  r7   SetWritePathr   r    dismantle_graph)rn   r  r(  r   experimental_skip_checkpointr/  rv  rm   r  object_saverr   saved_nodesr   ckpt_optionsr  prefixr>  s                    rT   r)  r)    s4   2 1|//1'**,+**..0. Z.A G!^\:{J ** (
 
&,,Z8%77&=='.'M'MOL ''
3\  K--j.K.K.8:
  A *%&&\\j!F %%k288@<<j!i778:D ''k++$+?A((4 ~z2 
J8 n%	j	  G  AE 7 78 >A	AAs   I& &J9JJr7  c                 @   |xs t        j                         }t        j                  j	                  |      }t        | ||      \  }}}}}}t        j                  ||j                  d             |j                  rt        ||       t        j                  |       y)a  Exports the MetaGraph proto of the `obj` to a file.

  This function goes through the same procedures saved_model.save goes to
  produce the given object's MetaGraph, then saves it to the given file. It
  skips saving checkpoint information, and is useful when all one wants is the
  graph defining the model.

  Args:
    obj: A trackable object to build the MetaGraph from.
    filename: The file into which to write the MetaGraph.
    signatures: Optional, either a `tf.function` with an input signature
      specified or the result of `f.get_concrete_function` on a
      `@tf.function`-decorated function `f`, in which case `f` will be used to
      generate a signature for the SavedModel under the default serving
      signature key. `signatures` may also be a dictionary, in which case it
      maps from signature keys to either `tf.function` instances with input
      signatures or concrete functions. The keys of such a dictionary may be
      arbitrary strings, but will typically be from the
      `tf.saved_model.signature_constants` module.
    options: Optional, `tf.saved_model.SaveOptions` object that specifies
      options for saving.
  Tr  N)r/   r   r$  r>  dirnamer3  r#   r  r  rE  r  r    rG  )rn   r7  r(  r   r  rv  r  rm   s           rT   export_meta_graphrO    s    8 1|//1'wwx(*/@	:w0 ,..!Q1 
%%00t0DF ~z2
 n%rU   c           
      F   t        j                         rt        d      t        | t        j
                        st        d|  dt        |        d      |xs t        j                         }t        |       }|t        j                  |      }t        j                  |      \  }}}t        j                  |       t        j                  |      }|j!                  ||       t#        ||      }t%        j&                  |      }	t)        ||||j*                  |j,                  |j.                   |j0                  |      \  }
}|j2                  r|j4                  j2                  }|j2                  j7                         D ]  \  }}t        |t8        j:                        r|||j<                  <   0t        |t>        j@                        r%|jC                         D ]  }|||j<                  <    ot        |tD        jF                  jH                        r)tK        d |D              r|D ]  }|||j<                  <    tM        dt        |       d       tO        ||
jP                        }|jR                  jU                  |       |||	|
|jV                  |jX                  fS )	zHCreates a MetaGraph containing the resources and functions of an object.zy`tf.saved_model.save` is not supported inside a traced @tf.function. Move the call to the outer eagerly-executed context.ztExpected an object of type `Trackable`, such as `tf.Module` or a subclass of the `Trackable` class, for export. Got z with type r   )rv  rV  r  r  r  r  r  r  c              3   P   K   | ]  }t        |t        j                           y wrI   )r_   
types_corerv   ).0rd   s     rT   	<genexpr>z)_build_meta_graph_impl.<locals>.<genexpr>X  s"      >9:*Q
33
4>s   $&zUnsupported type fz. Functions in `function_aliases` should be created by tf.function, or concrete functions, or collections of concrete functions.)-r    inside_functionAssertionErrorr_   r9   r   r  r   r   MetaGraphDefrG   r2   find_function_to_exportcanonicalize_signaturesvalidate_augmented_graph_viewcreate_signature_mapr\   r   r   TrackableSaverr  r  experimental_custom_gradientsexperimental_skip_saverexperimental_debug_stripperfunction_aliasesr  rk   rR  rv   rC   r   rx   _list_all_concrete_functionscollectionsabcIterableallr   r  r   object_graph_defr  r   r   )rn   r(  r   rv  r   rW   r  rV   rV  rI  r   r  r`  aliasr  fdefentryobject_graph_protos                     rT   _build_meta_graph_implrk  $  s    	
	? 
 
C	(
	>>AU C#YKq	" 
 "B^%@%@%B.,S1(@@J
 55jA ** 778LM)>>zJ-$$]4EF   4g>-**+?@,3#!$!55#AA666#??	 *n %33DD//557 
t	D*55	6&+#d099:557 	.D(-
499
%	.dKOO445# >>B> ;  	/E).
5::
&	/  d -2 2
 	

" /Z++ !!**+=>
 rU   c                 t    t        j                   |      5  t        | |||      cddd       S # 1 sw Y   yxY w)ay  Creates a MetaGraph under a save context.

  Args:
    obj: A trackable object to build the MetaGraph from.
    signatures: Can be a `tf.function` with an input signature specified or the
      result of `f.get_concrete_function` on a `@tf.function`-decorated function
      `f`. `signatures` may also be a dictionary, in which case it maps from
      signature keys to `tf.function` instances. If None, finds signature to
      export from the `@tf.function`-decorated methods in `obj`.
    options: `tf.saved_model.SaveOptions` object that specifies options for
      saving.
    meta_graph_def: Optional, the MetaGraphDef proto fill.

  Raises:
    AssertionError: If `export_meta_graph` is executing inside a `tf.function`.
    ValueError: If `obj` is not trackable.

  Returns:
    meta_graph_def: Filled MetaGraphDef proto
    exported_graph: `tf.Graph` object generated from `obj`.
    object_saver: `checkpoint.TrackableSaver` of the `obj` and its dependencies.
    asset_info: `_AssetInfo` tuple containing external assets in the `obj`.
    saveable_view.nodes: _SaveableView nodes.
    saveable_view.node_paths: _SaveableView paths.
  N)r.   rk  )rn   r(  r   rv  s       rT   r3  r3  q  s:    @   ) L!#z7NKL L Ls   .7rI   )NN)NNF)r   rb  r$  r  r  r^  typingr   r   r   r   r   abslr   tensorflow.core.frameworkr	   r
   r   r   tensorflow.core.protobufr   r   r   tensorflow.python.checkpointr   r   r   r   r   r   r   tensorflow.python.eagerr   r   r   ru   ,tensorflow.python.eager.polymorphic_functionr   r   r   r   r   tensorflow.python.frameworkr   r   rC  r   r    r!   r"   tensorflow.python.lib.ior#   tensorflow.python.opsr$   r%   r&   tensorflow.python.saved_modelr'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   r3   r4   r5   0tensorflow.python.saved_model.pywrap_saved_modelr6   r7   tensorflow.python.trackabler8   r9   r:   r;   !tensorflow.python.training.savingr<   tensorflow.python.typesr=   rR  tensorflow.python.utilr>   r?   r@    tensorflow.python.util.tf_exportrA   	frozensetvariantra  
namedtuplerB   r   r(  ObjectGraphViewrG   objectr   rL   r   r   r   r  bytesr  dictr.  r   ResourceVariabler   rK  r  rU  ru  rW  r  boolr  GraphDefr  r   r  SavedObjectr  r  r   r+  r)  rO  rk  r3  r   rU   rT   <module>r     sh   ;  	 	 
  3 3  2 / 2 2 3 4 ; 3 ; 9 3 5 @ + 0 5 P M V J . . @ 2 + 3 0 , + 2 7 6 > @ 6 < 6 7 6 6 = = A 7 7 4 F D - , 0 7 A 6 ) 2 + 6 @A  )+(():*02E)FH #$  W*44 WtA!F A!H)+DD)--)XDs DS D0 	T7S	T7T7 T7t 8c8CH#5568888v $[##	
KK 0@@K6(38, (c HS#X$667*]3SYY ]3} ]3@V~'B'B Vt VB }$"//}$ }$ c8CH#556}$ c	}$
  }$ }$  }$ :syy !}$@&J9-- &JR%P} %PP 6*>!--*>Z>syy >c >2 ;<> (,	~,~, %%	~,>~,H (,!&V! %%	V!x (,	+&+& %%	+&^ HLJ*66Jb 37	!L %%!L #//	!LrU   