o
    i e}                     @   s$  d 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 G dd deZdd Zdd Z e!dg dZ"dd Z#dd Z$d d! Z%dS )"z7Logic for restoring checkpointed values for Trackables.    N)checkpoint_view)functional_saver)save_util_v1)saveable_compat)context)ops)	array_ops)
gen_io_ops)io_ops)
tf_logging)registration)base)	constants)python_state)trackable_utils)saveable_object_util)object_identityc                   @   s   e Zd ZdZg dZdd Zd0ddZdd	 Zd
d Zd0ddZ	dd Z
dd Zdd Zd0ddZedd Zedd Zedd Zedd Zedd Zd d! Zd"d# Zd$d% Zd&d' Zd(d) Zd*d+ Zd0d,d-Zd.d/ ZdS )1CheckpointPositionz>Indicates a position within a `_CheckpointRestoreCoordinator`._checkpoint	_proto_idskip_restorec                 C   s   || _ || _d| _dS )zSpecify an object within a checkpoint.

    Args:
      checkpoint: A _CheckpointRestoreCoordinator object.
      proto_id: The index of this object in TrackableObjectGraph.nodes.
    FNr   )self
checkpointproto_id r   S/var/www/myenv/lib/python3.10/site-packages/tensorflow/python/checkpoint/restore.py__init__+   s   
zCheckpointPosition.__init__Nc                 C   sr   t  + | |r| |}|r'| j| W d   dS W d   dS W d   dS 1 s2w   Y  dS )z$Restore this value into `trackable`.N)r   
init_scopebind_object_restore_descendantsr   new_restore_ops)r   	trackablereaderrestore_opsr   r   r   restore8   s   


"zCheckpointPosition.restorec                 C   sl   | j }|j| |j| jd}|j| j |du r$||j| j< dS ||ur4td| d| d dS )a\  Set a checkpoint<->object correspondence.

    Args:
      trackable: The object to record a correspondence for.

    Returns:
      True if this is a new assignment, False if this object has already been
      mapped to a checkpointed `Object` proto.
    Raises:
      AssertionError: If another object is already bound to the `Object` proto.
    NTa&  Inconsistent references when loading the checkpoint into this object graph. For example, in the saved checkpoint object, `model.layer.weight` and `model.layer_copy.weight` reference the same variable, while in the current object these are two different variables. The referenced variables are:(z and z).F)	r   all_python_objectsaddobject_by_proto_idgetr   matched_proto_idsloggingwarning)r   r"   r   current_assignmentr   r   r   r   B   s    zCheckpointPosition.bind_objectc                 C   s.   | j j}t|dko|d jtjko| j j S )zEDetermine whether this value is restorable with a Tensor initializer.   r   )object_proto
attributeslennamer   VARIABLE_VALUE_KEYchildren)r   r0   r   r   r   is_simple_variabled   s   z%CheckpointPosition.is_simple_variablec           
   
   C   s   i }| j jD ]k}|j}| jj| }|j}| jjjpd}t	 J t
|- |dur5|j|v r5||j }nd}tj| jj|g|g|gd|jf d\}	W d   n1 sUw   Y  t|	||j< W d   n1 slw   Y  q|S )a  Create value `Tensor`s for this object's attributes.

    Does not require that the Python object has been created. Used for
    restore-on-create when executing eagerly.

    Args:
      shape_and_slices: A dict mapping from object attribute names to a shape
        and slice string that will be passed to a RestoreV2 op. If the dict is
        None or if an object attribute is not in the dict, the full tensor will
        be restored.

    Returns:
      A dictionary mapping from object attribute names to `Tensor`s.
    zcpu:0N z%s_checkpoint_read)prefixtensor_namesshape_and_slicesdtypesr2   )r/   r0   checkpoint_keyr   	dtype_map
base_dtypeoptionsexperimental_io_devicer   r   devicer2   r
   
restore_v2save_path_tensorr   identity)
r   r9   value_tensorsserialized_tensorr;   dtype	base_type	io_deviceshape_and_slicevaluer   r   r   rD   k   s0   



z CheckpointPosition.value_tensorsc           
      C   s  |   }| jjs|sg i g i fS g }i }g }tt}t| j}t	 | j}|r9| j
s8| jjj}| j|| |< nJ|rH| jjd j| ji||< n;t| jtjrU||  n.| tjhkre| |\}}n|ro| |\}}n| jjD ]}	| jj| jg |	j qs||||fS )zLooks up or creates SaveableObjects which don't have cached ops.

    Returns:
      A tuple of (
          existing_restore_ops: list,
          named_saveables: dict,
          python_positions: list,
          registered_savers: dict)
    r   )get_registered_saver_namer/   r0   collectionsdefaultdictdictr   saveable_objects_from_trackabler"   r   r   registered_saverobject_namer;   
isinstancer   PythonStateappendkeysr   SERIALIZE_TO_TENSORS_NAME$_create_serialize_to_tensor_saveable#_create_saveables_by_attribute_namer   unused_attributes
setdefaultr   r2   )
r   recorded_registered_saverexisting_restore_opsnamed_saveablespython_positionsregistered_saverssaveable_factories
saver_namer2   rE   r   r   r   gather_ops_or_named_saveables   sJ   



z0CheckpointPosition.gather_ops_or_named_saveablesc                 C   s   t | jpd}t| jjd j| }t s=| j	j
|d}|dur(|gi fS | j	j| ji }||v r=g ||| ifS |tj |d}t sM|||< g ||ifS )z9Creates a saveable using the _serialize_to_tensor method.r6   r   Nr2   )r   get_saveable_namer"   _extract_saveable_namer/   r0   r;   r   executing_eagerlyr   restore_ops_by_namer)   saveables_cacherZ   r   rV   )r   r`   suffixsaveable_nameexisting_oprh   saveabler   r   r   rW      s.   
z7CheckpointPosition._create_serialize_to_tensor_saveablec           	         s6  i }g }t  }| jjD ] t rd}n	| jj jd}|dur'|	| qt
 fdd|D r3q| jj}|du r>d}n|| ji  jd}t|dkrT|\}nd}|durf j|jvrfd}|| j= |du rt| |}|du r| jj| jg 	 j q|dur|g|| ji  j< || j< q||fS )a+  Creates or caches SaveableObjects by matching the attribute names.

    The attribute name keys in the `saveable_factories` is used to find the
    corresponding attribute in the object proto. Attributes contain checkpoint
    keys which are passed to the factory function to generate the
    SaveableObject.

    Args:
      saveable_factories: a dict mapping attribute name to a callable factory
        function that produces a SaveableObject.

    Returns:
      A tuple of (
          existing_restore_ops: list,
          named_saveables: dict)
    Nc                 3   s    | ]	} j |V  qd S N)r2   
startswith).0r2   rE   r   r   	<genexpr>  s    zICheckpointPosition._create_saveables_by_attribute_name.<locals>.<genexpr>rm   r.   )setr/   r0   r   rf   r   rg   r)   r;   rT   anyrh   r"   r2   r1   _get_saveable_from_factoryrY   rZ   r   )	r   r`   r]   r\   created_compat_namesrk   rh   rl   saveable_listr   rp   r   rX      sj   

z6CheckpointPosition._create_saveables_by_attribute_namec                 C   s<   |   rtd|  \}}}}|| jj|||d |S )aj  Create or fetch restore ops for this object's attributes.

    Requires that the `Trackable` Python object has been bound to an object
    ID in the checkpoint.

    Args:
      reader: A `CheckpointReader`. If None, a new instance will be created.

    Returns:
      A list of operations when graph building, or an empty list when executing
      eagerly.
    zOUnable to run individual checkpoint restore for objects with registered savers.r#   )_has_registered_saver
ValueErrorrb   extendr   restore_saveables)r   r#   r$   tensor_saveablesr^   _r   r   r   r$   C  s   zCheckpointPosition.restore_opsc                 C      | j S rm   )r   r   r   r   r   r   Z     zCheckpointPosition.checkpointc                 C   s   | j j| j S rm   )r   r(   r   r   r   r   r   r"   ^  s   zCheckpointPosition.trackablec                 C   s   | j jj| j S rm   )r   object_graph_protonodesr   r   r   r   r   r/   b  s   zCheckpointPosition.object_protoc                 C   r~   rm   )r   r   r   r   r   r   f  r   zCheckpointPosition.proto_idc                 C   s   | j jS rm   )r   restore_uidr   r   r   r   r   j  s   zCheckpointPosition.restore_uidc                 C   s
   t | jS rm   )reprr/   r   r   r   r   __repr__n  s   
zCheckpointPosition.__repr__c                 C   s0   | j jD ]}|jtjkr| jj|j   S qdS )zoThe shape of the VARIABLE_VALUE tensor.

    Returns:
      If found a TensorShape object, otherwise None.
    N)r/   r0   r2   r   r3   r   	shape_mapr;   )r   rE   r   r   r   value_shapeq  s
   zCheckpointPosition.value_shapec                 C   s   t | jjjS rm   )boolr/   rP   r2   r   r   r   r   rx   |     z(CheckpointPosition._has_registered_saverc              
   C   sf   |   r1| jjj}z
t| j| W |S  ty0 } zt|r"|d| _	W Y d}~|S d}~ww dS )z<Returns the registered saver name defined in the Checkpoint.TN)
rx   r/   rP   r2   r   validate_restore_functionr"   ry   get_strict_predicate_restorer   )r   ra   er   r   r   rK     s   

z,CheckpointPosition.get_registered_saver_namec                 C   s<   t | j|d}|j|||d}|dur||r||fS dS )a  Generates CheckpointPosition for a slot variable.

    Args:
      optimizer_object: Optimizer that owns the slot variable.
      variable: Variable associated with the slot variable.
      slot_variable_id: ID of the slot variable.
      slot_name: Name of the slot variable.

    Returns:
      If there is a slot variable in the `optimizer_object` that has not been
      bound to the checkpoint, this function returns a tuple of (
        new `CheckpointPosition` for the slot variable,
        the slot variable itself).
    r   r   )slot_variable_positionvariable	slot_nameN)NN)r   r    _create_or_restore_slot_variabler   )r   optimizer_objectr   slot_variable_idr   r   slot_variabler   r   r   create_slot_variable_position  s   z0CheckpointPosition.create_slot_variable_positionc                 C   s   t | j|dS )Nr   )r   r   )r   node_idr   r   r   create_child_position  r   z(CheckpointPosition.create_child_positionc                 C   s   t | | jfg}g }i }g }t t}|rO| \}}| \}	}
}}||	 ||
 || |	 D ]\}}|| | q7t
|| t|| |s||jj||||d |S )z?Restore the bound Trackable and dependencies (may be deferred).rw   )rL   dequer"   rM   rN   popleft_single_restorerz   updateitems_queue_children_for_restoration_queue_slot_variablesr   r{   )r   r#   visit_queuer$   r|   r^   r_   current_positionr}   r!   new_tensor_saveablesnew_python_positionsnew_registered_saversra   trackable_mapr   r   r   r      s6   





z'CheckpointPosition._restore_descendantsc                 C   sV   | j }|  | j}|j|jkr|  \}}}}|j|_nd}i }d}i }||||fS )zRestores the trackable.r   )r"   _maybe_initialize_trackabler   r   _update_uidrb   )r   r"   r   r$   r|   r^   r_   r   r   r   r     s   

z"CheckpointPosition._single_restorerm   )__name__
__module____qualname____doc__	__slots__r   r%   r   r5   rD   rb   rW   rX   r$   propertyr   r"   r/   r   r   r   r   rx   rK   r   r   r    r   r   r   r   r   r   &   s<    

"
'>
Y





)r   c              	   C   s  | du rt dt|tst dt| }| }| D ]0\}}||vs.|jj| du r9t d| d| d|du sCt|t	j
sNt d| d| d	qt }| D ]\}}|jj| j}|jj| }	t|}
|
s|	jst|rt d
| d| d	qWt }t|	jd j||< t|d\}}t|d }t|	jt|krt dt| dt|	j d	t||}| ||< t|| }|r|st d
| d| d	|s|rt d
| d| d| d	t|	jt|| krt dt||  dt|	j d	|
st||  qWt }i ||< |	jD ]}|j}|j}|| | || |< q"t||  qWdS )a  Restores nodes from a dict.

  Requires that the `Trackable` Python object has been bound to an object
  ID in the checkpoint.

  Args:
    save_path: a string represents path to the checkpoint.
    nodes_to_restore: a dict maps `node_id` to `trackable` to be restored.
  Nzsave_path cannot be empty.zDExpecting a dictionary of node_id to Trackable for nodes_to_restore.zThe expected node_id: z to Trackable z- to restore does not exist in the checkpoint.z(Expecting a valid Trackable to node_id: z but got trackable: .z
Trackable z] expects checkpointed values but checkpoint does not contain serialized tensors for node_id: r   z)Size for saveable_objects for Trackable: z? did not match the size for serialized_tensors for checkpoint: zQ does not expect checkpointed values but checkpoint contains serialized tensors: z for node_id: z+Size for serialized_tensors for Trackable: z; did not match size for serialized_tensors for checkpoint: )ry   rR   rN   r   CheckpointViewdescendantsr   _object_graph_protor   r   	Trackabler   ObjectIdentityDictionaryr0   r   !trackable_has_serialize_to_tensorrO   r   extract_object_namer;   r   !get_checkpoint_factories_and_keysgenerate_saveable_objectsr1   SaveableCompatibilityConverter_serialize_to_tensorsr   r   MultiDeviceSaverr%   r2   )	save_pathnodes_to_restore	ckpt_viewckpt_view_descendantsr   r"   serialized_tensorscurrent_trackable ckpt_contains_serialized_tensorsnoder   object_namescheckpoint_factory_mapr}   saveable_objectstrackable_expects_ckpted_valueserialized_tensors_renamed	attributer2   r;   r   r   r   restore_nodes  s   









r   c           
      C   s   | j }| }| jjD ]Y}| jj|jd}|durq| |j}|	|j
|}|j}|du rW|dr9|jj}	nt|jpG|jpG|jpG|d}	|	rV|j|j
g | q|j|drd|||f qdS )z>Queues the restoration of trackable's children or defers them.Nhas_checkpoint_valuesrP   )r"   )r"   _trackable_childrenr/   r4   r   r(   r)   r   r   _lookup_dependency
local_nameHasFieldr   rJ   r   r0   slot_variables_deferred_dependenciesrZ   rT   r   )
checkpoint_positionr   r"   trackable_childrenchildcorrespondencechild_positionlocal_objectchild_proto	has_valuer   r   r   r   P  s@   


r    _DeferredSlotVariableRestorationoriginal_variabler   r   c           	      C   s   | j }| j}|j| jdD ]}| ||j|j|j\}}|dur(|	||f q|j
| jdD ]=}|j|jd}|du rR|j|jg 	t||j|jd q1t|drn| |||j|j\}}|durn|	||f q1dS )z&Queues slot variables for restoration.r   Nr   r   )r"   r   deferred_slot_restorationspopr   r   r   r   r   rT   slot_restorationsr(   r)   optimizer_idrZ   r   hasattr)	r   r   r"   r   deferred_slot_restorationr   r   slot_restorationr   r   r   r   r     sR   

r   c                 C   s$   t jd }| d | |t|  S )N/)r   OBJECT_ATTRIBUTES_NAMEindexr1   )r;   
search_keyr   r   r   re     s   
re   c                 C   s   d}|j }|j}|| v r| | }|du r8|  D ]\}}||r7|dur)td|}t|j| }|| qt|rA||dS |S )z7Returns the saveable generated from the factory method.NzForward compatibility load error: Unable to load checkpoint saved in future version of TensorFlow. Please update your version of TensorFlow to the version in which the checkpoint was saved.rc   )r2   r;   r   rn   ry   re   r'   callable)r`   rE   ru   matched_factoryexpected_factory_namefactory_input_namefactory_namefactoryr   r   r   rt     s*   


rt   )&r   rL   tensorflow.python.checkpointr   r   r   r   tensorflow.python.eagerr   tensorflow.python.frameworkr   tensorflow.python.opsr   r	   r
   tensorflow.python.platformr   r+   tensorflow.python.saved_modelr   tensorflow.python.trackabler   r   r   r   !tensorflow.python.training.savingr   tensorflow.python.utilr   objectr   r   r   
namedtupler   r   re   rt   r   r   r   r   <module>   s>      Fg)(