o
    i eT                     @   s4  d 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 G dd deZdd Zdd Z dd Z!dd Z"dd  Z#G d!d" d"eZ$d#S )$z8Saves and restore variables inside traced @tf.functions.    )	saver_pb2)checkpoint_options)context)def_function)constant_op)dtypes)ops)tensor_spec)tensor_util)	array_ops)
gen_io_ops)io_ops)
string_ops)registration)trackable_utils)saveable_object)saveable_object_util)nest)object_identityc                   @   s2   e Zd ZdZdgZdd Zd
ddZd
dd	ZdS )_SingleDeviceSaverz7Saves and restores checkpoints from the current device._tensor_slice_dictc                 C   s
   || _ dS )zSpecify a list of `SaveableObject`s to save and restore.

    Args:
      tensor_slice_dict: A dict mapping checkpoint key -> slice_spec -> tensor.
    N)r   )selftensor_slice_dict r   \/var/www/myenv/lib/python3.10/site-packages/tensorflow/python/checkpoint/functional_saver.py__init__+   s   
z_SingleDeviceSaver.__init__Nc                 C   s   |pt  }g }g }g }| j D ];\}}| D ]2\}}	t|	tjr<|	j}
|
dur;||	j	 ||
 ||	j
 q|| ||	 || qq|jp[t|o[t|d j}|p_d}t| t||||W  d   S 1 sxw   Y  dS )%  Save the saveable objects to a checkpoint with `file_prefix`.

    Args:
      file_prefix: A string or scalar string Tensor containing the prefix to
        save under.
      options: Optional `CheckpointOptions` object.
    Returns:
      An `Operation`, or None when executing eagerly.
    Nr   cpu:0)r   CheckpointOptionsr   items
isinstancer   SaveSpectensorappendname
slice_specexperimental_io_devicelenr   set_cpu0devicer   r   save_v2)r   file_prefixoptionstensor_namestensorsslice_specscheckpoint_keytensor_slicesr%   r"   tensor_valuesave_devicer   r   r   save3   s0   



$z_SingleDeviceSaver.savec                 C   s  |pt  }g }g }g }| j D ]0\}}| D ]'\}}	||	j t|	tjr6||	j	 ||	j
 q|| || qq|jpFd}
t|
 t||||}W d   n1 s_w   Y  i }| j D ]\}}|D ]}|d}|||i |< qqqk|S )aJ  Restore the saveable objects from a checkpoint with `file_prefix`.

    Args:
      file_prefix: A string or scalar string Tensor containing the prefix for
        files to read from.
      options: Optional `CheckpointOptions` object.

    Returns:
      A restored tensor dict (maps checkpoint_key -> slice_spec -> tensor).
    r   Nr   )r   r   r   r   r#   dtyper    r   r!   r%   r$   r&   r   r)   r   
restore_v2pop
setdefault)r   r+   r,   r-   tensor_dtypesr/   r0   r1   r%   r"   restore_devicerestored_tensorsrestored_tensor_dictrestored_tensorr   r   r   restoreV   s6   

	
z_SingleDeviceSaver.restoreN)__name__
__module____qualname____doc__	__slots__r   r4   r>   r   r   r   r   r   &   s    
#r   c                 C   s   t | ||S )zAppend sharding information to a filename.

  Args:
    filename_tensor: A string tensor.
    shard: Integer.  The shard for the filename.
    num_shards: An int Tensor for the number of shards.

  Returns:
    A string tensor.
  )r   sharded_filename)filename_tensorshard
num_shardsr   r   r   rE   ~   s   rE   c                 C   s   t | td| gS )N-)r   string_joinr   constant)rF   
saver_namer   r   r   registered_saver_filename   s   rM   c                    R   fdd} du r|S t j|dd}|jtjdtjdd fd	d
}|S )HConverts the function to a python or tf.function with a single file arg.c                        | dS )N)
trackablesr+   r   r+   fnrQ   r   r   save_fn      z/_get_mapped_registered_save_fn.<locals>.save_fnNF	autographr   shaper5   rR   c                        | gS r?   r   rR   call_with_mapped_capturesconcreter   r   save_fn_with_replaced_captures   rV   zF_get_mapped_registered_save_fn.<locals>.save_fn_with_replaced_capturesr   functionget_concrete_functionr	   
TensorSpecr   string)rT   rQ   r]   rU   tf_fnr_   r   r]   r^   rT   rQ   r   _get_mapped_registered_save_fn   s   rg   c                    rN   )rO   c                    rP   )N)rQ   merged_prefixr   rh   rS   r   r   
restore_fn   rV   z5_get_mapped_registered_restore_fn.<locals>.restore_fnNFrW   r   rY   ri   c                    r[   r?   r   ri   r\   r   r   !restore_fn_with_replaced_captures   rV   zL_get_mapped_registered_restore_fn.<locals>.restore_fn_with_replaced_capturesr`   )rT   rQ   r]   rj   re   rk   r   rf   r   !_get_mapped_registered_restore_fn   s   rl   c                  O   s   d S r?   r   )argskwargsr   r   r   <lambda>   s    ro   c                   @   s   e Zd ZdZ		dddZe		dddZdd Zej	e
jd	ejd
fdddd Zej	e
jd	ejd
fdddd ZdddZdddZdS )MultiDeviceSaverzSaves checkpoints directly from multiple devices.

  Note that this is a low-level utility which stores Tensors in the keys
  specified by `SaveableObject`s. Higher-level utilities for object-based
  checkpointing are built on top of it.
  Nc                 C   s4  i | _ i | _i }| D ]X\}}|du rtn|j}| D ]F\}}	t|	ts*d|	i}	|	 D ]4\}
}||
f| j v r=td|| j ||
f< | j|g 	||
f t
|j}|||i |i |
< q.qqdd | D | _i | _|r| D ]\}}tt|||}tt|||}||f| j|< qxdS dS )a  Specify a list of `SaveableObject`s to save and restore.

    Args:
      serialized_tensors: A dictionary mapping `Trackable` to a tensor dict,
        which maps checkpoint_key -> (slice_spec ->) -> Tensor/SaveSpec. The
        `Trackable` key is used to get the `restore_from_tensors` function,
        and may be `None` if the tensor is not meant to be restored.
      registered_savers: A dictionary mapping `registration.RegisteredSaver`
        namedtuples to a dictionary of named Trackables. The keys of the
        Trackable dictionary are string names that uniquely identify the
        Trackable in the checkpoint.
      call_with_mapped_captures: TODO
    N zRecieved multiple tensors with the same checkpoint key and slice spec. This is invalid because one will overwrite the other in the checkpoint. This indicates a bug in the Checkpoint key-generation.c                 S      i | ]	\}}|t |qS r   )r   ).0r)   r   r   r   r   
<dictcomp>   s    z-MultiDeviceSaver.__init__.<locals>.<dictcomp>)_keys_to_restore_fn_restore_fn_to_keysr   _restore_noop_restore_from_tensorsr    dict
ValueErrorr8   r#   r   r(   r)   _single_device_savers_registered_saversrg   r   get_save_functionrl   get_restore_function)r   serialized_tensorsregistered_saversr]   tensors_by_deviceobjtensor_dictrj   r0   maybe_tensorr%   r"   host_deviceregistered_namerQ   rU   r   r   r   r      sT   

zMultiDeviceSaver.__init__c                 C   s:   t  }|D ]}tj||gd}| ||< q| |||S )N)	saveables)r   ObjectIdentityDictionaryr   SaveableCompatibilityConverter_serialize_to_tensors)clsr   r   r]   r   saveable	trackabler   r   r   from_saveables  s   zMultiDeviceSaver.from_saveablesc                 C   sD   t jg tjdd}| |}| |j}tj|j	|j	|j	tjj
dS )z7Serializes to a SaverDef referencing the current graph.saver_filename)rZ   r5   r$   )filename_tensor_namesave_tensor_namerestore_op_nameversion)r   placeholderr   rd   _traced_save_traced_restoreopr   SaverDefr$   V2)r   rF   save_tensor
restore_opr   r   r   to_proto  s   
zMultiDeviceSaver.to_protor   rY   F)input_signaturerX   c              	   C   s~   |  |}td+ t|g t|W  d    W  d    S 1 s(w   Y  W d    d S 1 s8w   Y  d S Nr   )r4   r   r)   control_dependenciesr   identity)r   r+   save_opr   r   r   r     s   
"zMultiDeviceSaver._traced_savec              	   C   s   |  |}td, t|  t|W  d    W  d    S 1 s)w   Y  W d    d S 1 s9w   Y  d S r   )r>   r   r)   r   valuesr   r   )r   r+   restore_opsr   r   r   r      s   
"z MultiDeviceSaver._traced_restorec                    s   pt  td* tt dt	dt	d}t
 |g fddjD W d   n1 s8w   Y   fdd	t rctjd
krctjddfdd}|  dS  S )r   CPUz^s3://.*z.partz
_temp/partc                    s   i | ]}|t  |qS r   )rM   )rs   rL   rR   r   r   rt   X  s    
z)MultiDeviceSaver.save.<locals>.<dictcomp>Nc               	      s  g } j  D ]+\}\}}|| }|d ur2t|}tdd |D s-td| d| | qtj}g }t	j
|dd}d }	ttj D ]I\}
\}}|}	tt| t|
|}W d    n1 smw   Y  | | t| ||| W d    n1 sw   Y  qLt|5 jpt|	}t| tj|  ddW  d    W  d    S 1 sw   Y  W d    d S 1 sw   Y  d S )	Nc                 s   s&    | ]}t |o|jtjkV  qd S r?   )r
   
is_tf_typer5   r   rd   )rs   xr   r   r   	<genexpr>e  s
    
z9MultiDeviceSaver.save.<locals>.save_fn.<locals>.<genexpr>zNRegistered saver must return a (maybe empty) list of string type tensors. Got .rH   )r$   T)delete_old_dirs)r|   r   r   flattenallrz   extendr'   r{   r   rK   	enumeratesortedr   r)   r   r(   rE   r#   r4   r   r&   r   merge_v2_checkpoints)saved_prefixesrL   rU   _maybe_saved_prefixesflattened_saved_prefixesrH   sharded_savesnum_shards_tensorlast_devicerG   r)   savershard_prefixmerge_device)r+   r,   registered_pathsr   tmp_checkpoint_prefixr   r   rU   ]  sZ   



"z&MultiDeviceSaver.save.<locals>.save_fn   F)jit_compilec                      s
      d S r?   r   r   )rU   r   r   tf_function_save  s   
z/MultiDeviceSaver.save.<locals>.tf_function_save)r   r   r   r)   r   wherer   regex_full_matchr   rK   rJ   r|   r   executing_eagerlyr'   r{   r   ra   )r   r+   r,   sharded_suffixr   r   )r+   r,   r   rU   r   r   r   r4   )  s(   


3

zMultiDeviceSaver.savec                    s|   pt   fddtdd j D }t r9tjdks'|r9tj	dddfdd	}| }|S  }|S )
a  Restore the saveable objects from a checkpoint with `file_prefix`.

    Args:
      file_prefix: A string or scalar string Tensor containing the prefix for
        files to read from.
      options: Optional `CheckpointOptions` object.

    Returns:
      When not run eagerly or when saving on a single device, returns a
      dictionary mapping from SaveableObject names to restore operations;
      otherwise, returns an empty dict.
    c               
      sN  i } dd j  D }i }tj D ]\}}t|n | }| D ][\}}| D ]R\}}	j||f }
|rK|	| |
i |i |< n|	| |
i |< ||
  d8  < ||
 dkri }| |
  D ]\}}	|	|t	
|< qi|
|}t|tr|| q1q)W d    n1 sw   Y  qj D ]
\}\}}
|
  q|S )Nc                 S   rr   r   )r'   )rs   rT   keysr   r   r   rt     s    z@MultiDeviceSaver.restore.<locals>.restore_fn.<locals>.<dictcomp>r   r   )rv   r   r   r{   r   r)   r>   ru   r8   r   extract_local_namer    ry   updater|   )restore_fn_inputsrestore_fn_input_countr   r)   r   r<   r0   slice_and_tensorr%   r"   rj   r;   ckpt_keyretr   )r+   r,   r   r   r   rj     sZ   

&
z,MultiDeviceSaver.restore.<locals>.restore_fnc                 S   s   g | ]}t |qS r   )r   is_custom_device)rs   dr   r   r   
<listcomp>  s    
z,MultiDeviceSaver.restore.<locals>.<listcomp>r   F)r   rX   c                      s
      i S r?   r   r   )rj   r   r   tf_function_restore  s   z5MultiDeviceSaver.restore.<locals>.tf_function_restore)
r   r   anyr{   r   r   r   r'   r   ra   )r   r+   r,   has_custom_device_saverr   r   r   )r+   r,   rj   r   r   r>     s   3zMultiDeviceSaver.restore)NNr?   )r@   rA   rB   rC   r   classmethodr   r   r   ra   r	   rc   r   rd   r   r   r4   r>   r   r   r   r   rp      s,    	
@	


prp   N)%rC   tensorflow.core.protobufr   tensorflow.python.checkpointr   tensorflow.python.eagerr   r   tensorflow.python.frameworkr   r   r   r	   r
   tensorflow.python.opsr   r   r   r   tensorflow.python.saved_modelr   tensorflow.python.trackabler   !tensorflow.python.training.savingr   r   tensorflow.python.utilr   r   objectr   rE   rM   rg   rl   rw   rp   r   r   r   r   <module>   s6   X