o
    ϯiY                     @   s  U d dl Z d dlZd dlmZ d dlmZmZmZmZm	Z	m
Z
mZmZmZ d dlZd dlZd dlmZ d dlmZmZ d dlmZ d dlmZmZ edd ejd	dd
 D Zeedf e d< edkrud dl!m"Z" d dl#m$Z$m%Z% nedkre&ej"dre&ej"drd dlm"Z" d dl'm$Z$m%Z% ddgZ(edd ejd	dd
 D Zeedf e d< G dd dedde
e) fde
e) fde
ee)ee ee f  fgZ*G dd dZ+G dd dZ,dej-de
e) d e
e) fd!d"Z.de
e) d e)fd#d$Z/de
e) d e)fd%d&Z0d'ee)ef d(e)d dfd)d*Z1de
e) d ee)e
e) f fd+d,Z2d-e
e) d e)fd.d/Z3	0d3dej-d(e)d e	ee)ej-f  fd1d2Z4dS )4    N)defaultdict)	AnycastDictIOIterableList
NamedTupleOptionalTuple)HTTPURLHandlerPathManagercolored)DataParallelDistributedDataParallelc                 c       | ]}t |V  qd S Nint.0x r   L/home/ubuntu/.local/lib/python3.10/site-packages/fvcore/common/checkpoint.py	<genexpr>       r   .   .TORCH_VERSION)      )quantization)FakeQuantizeBaseObserverBaser       r#   r$   CheckpointerPeriodicCheckpointerc                 c   r   r   r   r   r   r   r   r       r   c                   @   s   e Zd ZdS )_IncompatibleKeysN)__name__
__module____qualname__r   r   r   r   r)   #   s    
r)   IncompatibleKeysmissing_keysunexpected_keysincorrect_shapesc                   @   sL  e Zd ZdZ	d1dddejdededed	d
f
ddZ	deded	d
fddZ
deded	d
fddZ	
d2dedeee  d	eeef fddZd	efddZd	efddZd	ee fddZdddeded	eeef fd d!Zd"ed	d
fd#d$Zd%ed	eeef fd&d'Zd(ed	efd)d*Zd+ed	d
fd,d-Zd.eeef d	d
fd/d0Zd
S )3r'   z^
    A checkpointer that can save/load model as well as extra checkpointable
    objects.
     T)save_to_diskmodelsave_dirr2   checkpointablesreturnNc                K   sp   t |ttfr
|j}|| _i | _| D ]
\}}| || qt	t
| _|| _|| _t | _| jt  dS )a  
        Args:
            model (nn.Module): model.
            save_dir (str): a directory to save and find checkpoints.
            save_to_disk (bool): if True, save checkpoint to disk, otherwise
                disable saving for this checkpointer.
            checkpointables (object): any checkpointable objects, i.e., objects
                that have the ``state_dict()`` and ``load_state_dict()`` method. For
                example, it can be used like
                `Checkpointer(model, "dir", optimizer=optimizer)`.
        N)
isinstancer   r   moduler3   r5   itemsadd_checkpointablelogging	getLoggerr*   loggerr4   r2   r   path_managerregister_handlerr   )selfr3   r4   r2   r5   kvr   r   r   __init__6   s   zCheckpointer.__init__keycheckpointablec                 C   s:   || j v rtd| dt|dstd|| j |< dS )z
        Add checkpointable object for this checkpointer to track.

        Args:
            key (str): the key used to save the object
            checkpointable: any object with ``state_dict()`` and
                ``load_state_dict()`` method
        zKey z! already used in the Checkpointer
state_dictz>add_checkpointable needs an object with 'state_dict()' method.N)r5   KeyErrorhasattr	TypeError)r@   rD   rE   r   r   r   r:   W   s   
	
zCheckpointer.add_checkpointablenamekwargsc           	      K   s   | j r| jsdS i }| j |d< | j D ]
\}}| ||< q|| d|}tj	
| j |}tj	||ks?J || jd| | j|d}t|ttt | W d   n1 sew   Y  | | dS )z
        Dump model and checkpointables to a file.

        Args:
            name (str): name of the file.
            kwargs (dict): extra arbitrary data to save.
        Nr3   z{}.pthzSaving checkpoint to {}wb)r4   r2   r3   rF   r5   r9   updateformatospathjoinbasenamer=   infor>   opentorchsaver   r   bytestag_last_checkpoint)	r@   rJ   rK   datarD   objrR   	save_filefr   r   r   rV   h   s   

zCheckpointer.saverP   c                 C   s   |s
| j d i S | j d| tj|s,| j|}tj|s,J d|| |}| 	|}|dur?| 
| |du rF| jn|D ]}||v re| j d|| | j| }||| qH|S )a  
        Load from the given checkpoint.

        Args:
            path (str): path or url to the checkpoint. If empty, will not load
                anything.
            checkpointables (list): List of checkpointable names to load. If not
                specified (None), will load all the possible checkpointables.
        Returns:
            dict:
                extra data loaded from the checkpoint that has not been
                processed. For example, those saved with
                :meth:`.save(**extra_data)`.
        z4No checkpoint found. Initializing model from scratchz"[Checkpointer] Loading from {} ...zCheckpoint {} not found!NzLoading {} from {} ...)r=   rS   rN   rO   rP   isfiler>   get_local_path
_load_file_load_model_log_incompatible_keysr5   load_state_dictpop)r@   rP   r5   
checkpointincompatiblerD   rZ   r   r   r   load   s$   



zCheckpointer.loadc                 C   s   t j| jd}| j|S )za
        Returns:
            bool: whether a checkpoint exists in the target directory.
        last_checkpoint)rO   rP   rQ   r4   r>   exists)r@   r[   r   r   r   has_checkpoint   s   zCheckpointer.has_checkpointc                 C   st   t j| jd}z| j|d}|  }W d   n1 s!w   Y  W n
 ty1   Y dS w t j| j|S )z[
        Returns:
            str: The latest checkpoint file in target directory.
        rg   rNr1   )	rO   rP   rQ   r4   r>   rT   readstripIOError)r@   r[   r\   
last_savedr   r   r   get_checkpoint_file   s   z Checkpointer.get_checkpoint_filec                    s     fdd j  jD }|S )z}
        Returns:
            list: All available checkpoint files (.pth files) in target
                directory.
        c                    s>   g | ]} j tj j|r|d rtj j|qS )z.pth)r>   r]   rO   rP   rQ   r4   endswith)r   filer@   r   r   
<listcomp>   s    z9Checkpointer.get_all_checkpoint_files.<locals>.<listcomp>)r>   lsr4   )r@   all_model_checkpointsr   rr   r   get_all_checkpoint_files   s   
z%Checkpointer.get_all_checkpoint_files)resumerw   c                C   s,   |r|   r|  }| |S | j|g dS )aG  
        If `resume` is True, this method attempts to resume from the last
        checkpoint, if exists. Otherwise, load checkpoint from the given path.
        This is useful when restarting an interrupted training job.

        Args:
            path (str): path to the checkpoint.
            resume (bool): if True, resume from the last checkpoint if it exists
                and load the model together with all the checkpointables. Otherwise
                only load the model without loading any checkpointables.

        Returns:
            same as :meth:`load`.
        )r5   )ri   ro   rf   )r@   rP   rw   r   r   r   resume_or_load   s   
zCheckpointer.resume_or_loadlast_filename_basenamec                 C   sN   t j| jd}| j|d}|| W d   dS 1 s w   Y  dS )z
        Tag the last checkpoint.

        Args:
            last_filename_basename (str): the basename of the last filename.
        rg   wN)rO   rP   rQ   r4   r>   rT   write)r@   ry   r[   r\   r   r   r   rX      s   "z Checkpointer.tag_last_checkpointr\   c                 C   s   t j|t ddS )a  
        Load a checkpoint file. Can be overwritten by subclasses to support
        different formats.

        Args:
            f (str): a locally mounted file path.
        Returns:
            dict: with keys "model" and optionally others that are saved by
                the checkpointer dict["model"] must be a dict which maps strings
                to torch.Tensor or numpy arrays.
        cpu)map_location)rU   rf   device)r@   r\   r   r   r   r_      s   zCheckpointer._load_filerd   c                 C   s   | d}| | t|d | j }g }t| D ]b}||v r~|| }tdkr2t|t	j
jr2qt|j}t|| j}||kr~tdkoOttdoOttd}	|	rqdtj	jdtdtj	jfdd	}
ttf}|
| j|}t||rqq||||f | | q| jj|d
d}t|j|j|dS )a  
        Load weights from a checkpoint.

        Args:
            checkpoint (Any): checkpoint contains the weights.

        Returns:
            ``NamedTuple`` with ``missing_keys``, ``unexpected_keys``,
                and ``incorrect_shapes`` fields:
                * **missing_keys** is a list of str containing the missing keys
                * **unexpected_keys** is a list of str containing the unexpected keys
                * **incorrect_shapes** is a list of (key, shape in checkpoint, shape in model)

            This is just like the return value of
            :func:`torch.nn.Module.load_state_dict`, but with extra support
            for ``incorrect_shapes``.
        r3   zmodule.r%   r$   r#   rD   r6   c                 S   s.   | dd d }| }|D ]}t||}q|S )Nr   )splitgetattr)r3   rD   	key_parts
cur_modulekey_partr   r   r   _get_module_for_key/  s
   z5Checkpointer._load_model.<locals>._get_module_for_keyF)strict)r.   r/   r0   )rc   _convert_ndarray_to_tensor_strip_prefix_if_presentr3   rF   listkeysr   r7   nn	parameterUninitializedParametertupleshaperH   r"   rU   Modulestrr$   r#   appendrb   r)   r.   r/   )r@   rd   checkpoint_state_dictmodel_state_dictr0   rA   model_paramshape_modelshape_checkpointhas_observer_base_classesr   cls_to_skiptarget_modulere   r   r   r   r`      sV   








zCheckpointer._load_modelre   c                 C   sp   |j D ]\}}}| jd||| q|jr(t| j|j}|r(| jt| |jr6| jt	|j dS dS )zZ
        Log information about the incompatible keys returned by ``_load_model``.
        zSkip loading parameter '{}' to the model due to incompatible shapes: {} in the checkpoint but {} in the model! You might want to double check if this is expected.N)
r0   r=   warningrN   r.   _filter_reused_missing_keysr3   get_missing_parameters_messager/   !get_unexpected_parameters_message)r@   re   rA   r   r   r.   r   r   r   ra   M  s$   z#Checkpointer._log_incompatible_keysrF   c                 C   sd   t | D ])}|| }t|tjs"t|tjs"td|t	|t|tjs/t
|||< qdS )z
        In-place convert all numpy arrays in the state_dict to torch tensor.
        Args:
            state_dict (dict): a state-dict to be loaded to the model.
                Will be modified.
        z,Unsupported type found in checkpoint! {}: {}N)r   r   r7   npndarrayrU   Tensor
ValueErrorrN   type
from_numpy)r@   rF   rA   rB   r   r   r   r   d  s   
z'Checkpointer._convert_ndarray_to_tensorr1   r   )r*   r+   r,   __doc__r   r   r   boolr   rC   r:   rV   r
   r   r   rf   ri   ro   rv   rx   rX   r_   r)   r`   ra   r   r   r   r   r   r'   0   sF    
!


*$Oc                   @   sn   e Zd ZdZ			ddededee dee ded	dfd
dZdede	d	dfddZ
dede	d	dfddZdS )r(   a-  
    Save checkpoints periodically. When `.step(iteration)` is called, it will
    execute `checkpointer.save` on the given checkpointer, if iteration is a
    multiple of period or if `max_iter` is reached.

    Attributes:
        checkpointer (Checkpointer): the underlying checkpointer object
    Nr3   checkpointerperiodmax_itermax_to_keepfile_prefixr6   c                 C   sH   || _ t|| _|| _|dur|dksJ || _g | _|j| _|| _dS )a  
        Args:
            checkpointer: the checkpointer object used to save checkpoints.
            period (int): the period to save checkpoint.
            max_iter (int): maximum number of iterations. When it is reached,
                a checkpoint named "{file_prefix}_final" will be saved.
            max_to_keep (int): maximum number of most current checkpoints to keep,
                previous checkpoints will be deleted
            file_prefix (str): the prefix of checkpoint's filename
        Nr   )r   r   r   r   r   recent_checkpointsr>   r   )r@   r   r   r   r   r   r   r   r   rC     s   

zPeriodicCheckpointer.__init__	iterationrK   c                 K   s   t |}d|i}|| |d | j dkrV| jjd| j|fi | | jdurV| j	| j
  t| j| jkrV| jd}| j|rV|| j dsV| j| | jdurr|| jd krt| jj| j dfi | dS dS dS )a
  
        Perform the appropriate action at the given iteration.

        Args:
            iteration (int): the current iteration, ranged in [0, max_iter-1].
            kwargs (Any): extra data to save, same as in
                :meth:`Checkpointer.save`.
        r   r    r   z	{}_{:07d}Nz
_final.pth_final)r   rM   r   r   rV   rN   r   r   r   r   ro   lenrc   r>   rh   rp   rmr   )r@   r   rK   additional_statefile_to_deleter   r   r   step  s0   	


 zPeriodicCheckpointer.steprJ   c                 K   s   | j j|fi | dS )a  
        Same argument as :meth:`Checkpointer.save`.
        Use this method to manually save checkpoints outside the schedule.

        Args:
            name (str): file name.
            kwargs (Any): extra data to save, same as in
                :meth:`Checkpointer.save`.
        N)r   rV   )r@   rJ   rK   r   r   r   rV     s   
zPeriodicCheckpointer.save)NNr3   )r*   r+   r,   r   r'   r   r
   r   rC   r   r   rV   r   r   r   r   r(   x  s(    
r3   r   r6   c           	         s   t | tt }t| D ]*\}}t|jddt|jdd D ]\}}|r*|d nd| }|| | q q| D ]!}t fdd|D r\t	 fdd|D s\ fdd|D  q;t S )	z\
    Filter "missing keys" to not include keys that have been loaded with another name.
    F)recurser   r1   c                 3   s    | ]}| v V  qd S r   r   r   nkeysetr   r   r     r   z._filter_reused_missing_keys.<locals>.<genexpr>c                    s   g | ]}| v r  |qS r   )remover   r   r   r   rs     s    z/_filter_reused_missing_keys.<locals>.<listcomp>)
setr   _named_modules_with_dupr   named_parametersnamed_buffersaddvaluesanyall)	r3   r   param_to_namesmodule_prefixr8   rJ   param	full_namenamesr   r   r   r     s   
,r   c                 C   s>   t | }tdd | D }d}|ddd |D 7 }|S )z
    Get a logging-friendly message to report parameter names (keys) that are in
    the model but not found in a checkpoint.
    Args:
        keys (list[str]): List of keys that were not found in the checkpoint.
    Returns:
        str: message.
    c                 s   s     | ]\}}|t | V  qd S r   )_group_to_strr   rA   rB   r   r   r   r     s    z1get_missing_parameters_message.<locals>.<genexpr>zBSome model parameters or buffers are not found in the checkpoint:

c                 S   s   g | ]}t |d qS )bluer   r   r   r   r   rs     s    z2get_missing_parameters_message.<locals>.<listcomp>)_group_checkpoint_keyssortedr9   rQ   )r   groupsmsg_per_groupmsgr   r   r   r     s
   	r   c                 C   s,   t | }d}|ddd | D 7 }|S )z
    Get a logging-friendly message to report parameter names (keys) that are in
    the checkpoint but not found in the model.
    Args:
        keys (list[str]): List of keys that were not found in the model.
    Returns:
        str: message.
    zHThe checkpoint state_dict contains keys that are not used by the model:
r   c                 s   s*    | ]\}}d t |t| d V  qdS )z  magentaN)r   r   r   r   r   r   r     s    
z4get_unexpected_parameters_message.<locals>.<genexpr>)r   rQ   r9   )r   r   r   r   r   r   r     s   	
r   rF   prefixc                    s   t |  }t fdd|D sdS |D ]}|t d }| || |< qz| j}W n
 ty6   Y dS w t| D ]}t|dkrFq=|t d }||||< q=dS )z
    Strip the prefix in metadata, if any.
    Args:
        state_dict (OrderedDict): a state-dict to be loaded to the model.
        prefix (str): prefix.
    c                 3   s&    | ]}t |d kp| V  qdS )r   N)r   
startswith)r   rD   r   r   r   r     s   $ z+_strip_prefix_if_present.<locals>.<genexpr>Nr   )r   r   r   r   rc   	_metadataAttributeErrorr   )rF   r   r   rD   newkeymetadatar   r   r   r     s"   
r   c                 C   sb   t t}| D ](}|d}|dkr"|d| ||d d g}}n|g }}|| | q|S )a.  
    Group keys based on common prefixes. A prefix is the string up to the final
    "." in each key.
    Args:
        keys (list[str]): list of parameter names, i.e. keys in the model
            checkpoint dict.
    Returns:
        dict[list]: keys with common prefixes are grouped into lists.
    r   r   Nr    )r   r   rfindextend)r   r   rD   posheadtailr   r   r   r      s   

"
r   groupc                 C   s>   t | dkrdS t | dkrd| d  S ddt|  d S )z
    Format a group of parameter name suffixes into a loggable string.
    Args:
        group (list[str]): list of parameter name suffixes.
    Returns:
        str: formated string.
    r   r1   r    r   z.{z, })r   rQ   r   )r   r   r   r   r   5  s
   r   r1   c                 c   sR    || fV  | j  D ]\}}|du rq||rdnd | }t||E dH  qdS )z{
    The same as `model.named_modules()`, except that it includes
    duplicated modules that have more than one name.
    Nr   r1   )_modulesr9   r   )r3   r   rJ   r8   submodule_prefixr   r   r   r   F  s   
r   r   )5r;   rO   collectionsr   typingr   r   r   r   r   r   r	   r
   r   numpyr   rU   torch.nnr   iopath.common.file_ior   r   	termcolorr   torch.nn.parallelr   r   r   __version__r   r   r   __annotations__torch.aor"   torch.ao.quantizationr#   r$   rH   torch.quantization__all__r   r)   r'   r(   r   r   r   r   r   r   r   r   r   r   r   r   <module>   sd   
,2

2


  J R"!