o
    ?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   n/home/www/facesmatcher.com/pyenv/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   Zsave_v2)r   file_prefixoptionstensor_namesZtensorsslice_specscheckpoint_keytensor_slicesr%   r"   Ztensor_valueZ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   Z
restore_v2pop
setdefault)r   r*   r+   r,   Ztensor_dtypesr-   r.   r/   r%   r"   Zrestore_devicerestored_tensorsrestored_tensor_dictZrestored_tensorr   r   r   restoreV   s6   

	
z_SingleDeviceSaver.restoreN)__name__
__module____qualname____doc__	__slots__r   r0   r6   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   r=   ~   s   r=   c                 C   s   t | td| gS )N-)r   string_joinr   constant)r>   
saver_namer   r   r   registered_saver_filename   s   rE   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*   fnrI   r   r   save_fn      z/_get_mapped_registered_save_fn.<locals>.save_fnNF	autographr   shaper1   rJ   c                        | gS r7   r   rJ   call_with_mapped_capturesconcreter   r   save_fn_with_replaced_captures   rN   zF_get_mapped_registered_save_fn.<locals>.save_fn_with_replaced_capturesr   functionZget_concrete_functionr	   
TensorSpecr   string)rL   rI   rU   rM   tf_fnrW   r   rU   rV   rL   rI   r   _get_mapped_registered_save_fn   s   r^   c                    rF   )rG   c                    rH   )N)rI   merged_prefixr   r_   rK   r   r   
restore_fn   rN   z5_get_mapped_registered_restore_fn.<locals>.restore_fnNFrO   r   rQ   r`   c                    rS   r7   r   r`   rT   r   r   !restore_fn_with_replaced_captures   rN   zL_get_mapped_registered_restore_fn.<locals>.restore_fn_with_replaced_capturesrX   )rL   rI   rU   ra   r\   rb   r   r]   r   !_get_mapped_registered_restore_fn   s   rc   c                  O   s   d S r7   r   )argskwargsr   r   r   <lambda>   s    rf   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_noopZ_restore_from_tensorsr    dict
ValueErrorr3   r#   r   r(   r)   _single_device_savers_registered_saversr^   r   Zget_save_functionrc   Zget_restore_function)r   serialized_tensorsregistered_saversrU   Ztensors_by_deviceobjZtensor_dictra   r.   Zmaybe_tensorr%   r"   Zhost_deviceZregistered_namerI   rM   r   r   r   r      sT   

zMultiDeviceSaver.__init__c                 C   s:   t  }|D ]}tj||gd}| ||< q| |||S )N)	saveables)r   ZObjectIdentityDictionaryr   ZSaveableCompatibilityConverterZ_serialize_to_tensors)clsrv   rt   rU   rs   ZsaveableZ	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.Zsaver_filename)rR   r1   r$   )Zfilename_tensor_nameZsave_tensor_nameZrestore_op_nameversion)r   placeholderr   r[   _traced_save_traced_restoreopr   ZSaverDefr$   ZV2)r   r>   Zsave_tensorZ
restore_opr   r   r   to_proto  s   
zMultiDeviceSaver.to_protor   rQ   F)Zinput_signaturerP   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   )r0   r   r)   control_dependenciesr   identity)r   r*   Z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   )r6   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   ZCPUz^s3://.*z.partz
_temp/partc                    s   i | ]}|t  |qS r   )rE   )rj   rD   rJ   r   r   rk   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 r7   )r
   Z
is_tf_typer1   r   r[   )rj   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 .r@   )r$   T)Zdelete_old_dirs)rr   r   r   flattenallrp   extendr'   rq   r   rC   	enumeratesortedr   r)   r   r(   r=   r#   r0   r   r&   r   Zmerge_v2_checkpoints)Zsaved_prefixesrD   rM   _Zmaybe_saved_prefixesZflattened_saved_prefixesr@   Zsharded_savesZnum_shards_tensorZlast_devicer?   r)   saverZshard_prefixZmerge_device)r*   r+   registered_pathsr   tmp_checkpoint_prefixr   r   rM   ]  sZ   



"z&MultiDeviceSaver.save.<locals>.save_fn   F)jit_compilec                      s
      d S r7   r   r   )rM   r   r   tf_function_save  s   
z/MultiDeviceSaver.save.<locals>.tf_function_save)r   r   r   r)   r   wherer   Zregex_full_matchr   rC   rB   rr   r   executing_eagerlyr'   rq   r   rY   )r   r*   r+   Zsharded_suffixr   r   )r*   r+   r   rM   r   r   r   r0   )  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   ri   r   )r'   )rj   rL   keysr   r   r   rk     s    z@MultiDeviceSaver.restore.<locals>.restore_fn.<locals>.<dictcomp>r   r   )rm   r   r   rq   r   r)   r6   rl   r3   r   Zextract_local_namer    ro   updaterr   )Zrestore_fn_inputsZrestore_fn_input_countr   r)   r   r5   r.   Zslice_and_tensorr%   r"   ra   r4   Zckpt_keyretr   )r*   r+   r   r   r   ra     sZ   

&
z,MultiDeviceSaver.restore.<locals>.restore_fnc                 S   s   g | ]}t |qS r   )r   Zis_custom_device)rj   dr   r   r   
<listcomp>  s    
z,MultiDeviceSaver.restore.<locals>.<listcomp>r   F)r   rP   c                      s
      i S r7   r   r   )ra   r   r   tf_function_restore  s   z5MultiDeviceSaver.restore.<locals>.tf_function_restore)
r   r   anyrq   r   r   r   r'   r   rY   )r   r*   r+   Zhas_custom_device_saverr   r   r   )r*   r+   ra   r   r   r6     s   3zMultiDeviceSaver.restore)NNr7   )r8   r9   r:   r;   r   classmethodrx   r~   r   rY   r	   rZ   r   r[   r{   r|   r0   r6   r   r   r   r   rg      s,    	
@	


prg   N)%r;   Ztensorflow.core.protobufr   Ztensorflow.python.checkpointr   Ztensorflow.python.eagerr   r   Ztensorflow.python.frameworkr   r   r   r	   r
   Ztensorflow.python.opsr   r   r   r   Ztensorflow.python.saved_modelr   Ztensorflow.python.trackabler   Z!tensorflow.python.training.savingr   r   Ztensorflow.python.utilr   r   objectr   r=   rE   r^   rc   rn   rg   r   r   r   r   <module>   s6   X