o
    Xεi,                     @   s~  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 d dlmZm	Z	m
Z
mZmZmZ d dlmZ d dlZd dlZd dlmZ d dlmZ dd Zd	efd
dZ		d)dedeee	eje
eeejf eeejf f f dedefddZd*ddZdedefddZdd Z		d+ddZ		 	d,ddZ dedeeef fdd Z!ded!e"ddfd"d#Z#d-d$ed%ed&edee fd'd(Z$dS ).    N)Path)AnyCallableDictListTupleUnion)urlparse)Coqpit)loggerc                 C   sr   t jdkr!dd l}||jd}||d\}}t|jdd}nt jdkr-td }nt	 
d	}|
| S )
Nwin32r   z@Software\Microsoft\Windows\CurrentVersion\Explorer\Shell FolderszLocal AppDataF)strictdarwinz~/Library/Application Support/z.local/share)sysplatformwinregOpenKeyHKEY_CURRENT_USERQueryValueExr   resolve
expanduserhomejoinpath)appnamer   keydir__ans r   >/home/ubuntu/.local/lib/python3.10/site-packages/trainer/io.pyget_user_data_dir   s   


r    configc                 C   sd   t j|d}i |  |}tj|ddd}tj||dd W d   dS 1 s+w   Y  dS )a5  Copy config.json and other model files to training folder and add
    new fields.

    Args:
        config (Coqpit): Coqpit config defining the training run.
        out_path (str): output path to copy the file.
        new_fields (dict): new fileds to be added or edited
            in the config file.
    zconfig.jsonwutf8)encoding   )indentN)ospathjointo_dictfsspecopenjsondump)r!   out_path
new_fieldscopy_config_path
new_configfr   r   r   copy_model_files!   s
   
"r4   Tr(   map_locationcachereturnc                 K   s   t j| pt j| }|r>|s>tjd|  dttdidd}tj	|fd|i|W  d   S 1 s7w   Y  dS t| d}tj	|fd|i|W  d   S 1 sZw   Y  dS )a  Like torch.load but can load from other locations (e.g. s3:// , gs://).
    Args:
        path: Any path or url supported by fsspec.
        map_location: torch.device or str.
        cache: If True, cache a remote file locally for subsequent calls. It is cached under `get_user_data_dir()/trainer_cache`. Defaults to True.
        **kwargs: Keyword arguments forwarded to torch.load.
    Returns:
        Object stored in path.
    zfilecache::cache_storage	tts_cacherb)	filecachemoder5   N)
r'   r(   isdirisfiler+   r,   strr    torchload)r(   r5   r6   kwargsis_localr3   r   r   r   load_fsspec3   s   $$rD   Fc                 C   s@   t |tdd}| |d  |r|   |r|   | |fS )Ncpu)r5   model)rD   r@   deviceload_state_dictcudaeval)rF   checkpoint_pathuse_cudarJ   stater   r   r   load_checkpointO   s   rN   rM   c                 K   sF   t |d}tj| |fi | W d   dS 1 sw   Y  dS )zLike torch.save but can save to other locations (e.g. s3:// , gs://).

    Args:
        state: State object to save
        path: Any path or url supported by fsspec.
        **kwargs: Keyword arguments forwarded to torch.save.
    wbN)r+   r,   r@   save)rM   r(   rB   r3   r   r   r   save_fsspecY   s   "rQ   c              	   K   s   t |dr|j }	n| }	t|trdd |D }
nt|tr+dd | D }
n
|d ur3| nd }
t|trBdd |D }n
|d urJ| nd }t| trU|  } | |	|
|||t	j
 dd}|| |rs||| d S t|| d S )	Nmodulec                 S      g | ]}|  qS r   
state_dict).0optimr   r   r   
<listcomp>k       zsave_model.<locals>.<listcomp>c                 S   s   i | ]	\}}||  qS r   rT   )rV   kvr   r   r   
<dictcomp>m   s    zsave_model.<locals>.<dictcomp>c                 S   rS   r   rT   )rV   sr   r   r   rX   r   rY   z	%B %d, %Y)r!   rF   	optimizerscalerstepepochdate)hasattrrR   rU   
isinstancelistdictitemsr
   r*   datetimerb   todaystrftimeupdaterQ   )r!   rF   r^   r_   current_stepra   output_path	save_funcrB   model_stateoptimizer_statescaler_staterM   r   r   r   
save_modele   s2   





	rr   c	                 K   s`   d| d}
t j||
}td| t| ||||||fd|i|	 |d ur.t|| d S d S )Ncheckpoint_.pthz
 > CHECKPOINT : %srn   )r'   r(   r)   r   inforr   keep_n_checkpoints)r!   rF   r^   r_   rl   ra   output_foldersave_n_checkpointsrn   rB   	file_namerK   r   r   r   save_checkpoint   s&   	rz   c                 K   s:  t | tr'| d d uo|d d u}|r| d |d k p%| o%| d |d k }n| |k }t |
ttfr<t|
}
|o;||
k}|rd| d}tj||}td| t	|||||||f| |d| t
|j}|	rn||
k r|tj|d}|D ]}tj||kr|| qzd}tj||}||| | }|S )	N	eval_loss
train_lossbest_model_rt   z > BEST MODEL : %s)
model_lossrn   zbest_model*.pthzbest_model.pth)rd   rf   intfloatr'   r(   r)   r   ru   rr   r+   
get_mapperfsglobbasenamermcopy)current_loss	best_lossr!   rF   r^   r_   rl   ra   r/   keep_all_best
keep_afterrn   rB   use_eval_lossis_save_modelbest_model_namerK   r   model_names
model_nameshortcut_nameshortcut_pathr   r   r   save_best_model   sN   


r   c                    sz  t | j}|tj| d}t| jr'| 	d r'fdd|D }i }i }dD ]Y d}d}|D ]#}t
  d|}|durXt| d }	|du sT|	|krX|	}|}q5 fd	d|D }
|du rzt|
dkrzt|
tjjd
}t|d }|dur|| < || < q-|std|  dd|vr|d |d< nd|vr|d |d< n|d |d kr|d |d< |d |d fS )an  Get latest checkpoint or/and best model in path.

    It is based on globbing for `*.pth` and the RegEx
    `(checkpoint|best_model)_([0-9]+)`.

    Args:
        path: Path to files to be compared.

    Raises:
        ValueError: If no checkpoint or best_model files are found.

    Returns:
        Path to the last checkpoint
        Path to best checkpoint
    z*.pth://c                    s   g | ]} d  | qS )r   r   )rV   ry   )schemer   r   rX          z'get_last_checkpoint.<locals>.<listcomp>)
checkpoint
best_modelN	_([0-9]+)r   c                    s   g | ]} |v r|qS r   r   )rV   fnr   r   r   rX     r   r   r`   z!No models found in continue path !r   r   )r+   r   r   r   r'   r(   r)   r	   r   
startswithresearchr   groupslenmaxgetctimerD   
ValueError)r(   r   
file_nameslast_modelslast_model_numslast_model_num
last_modelry   match	model_numkey_file_namesr   )r   r   r   get_last_checkpoint   sF   
r   nc                 C   sH   t | j}t| d}t||kr |d|  D ]	}|| qdS dS )zKeep only the last n checkpoints in path.

    Args:
        path: Path to files to be compared.
        n: Number of checkpoints to keep.
    r   N)r+   r   r   sort_checkpointsr   r   )r(   r   r   r   ry   r   r   r   rv   #  s   
rv   rm   checkpoint_prefix	use_mtimec                 C   s   g }dd t | | dD }|D ]1}|r#|tj||f qtd| d|}|durD| durD|t	| d |f qt
|}dd |D }|S )	a)  Sort checkpoint paths based on the checkpoint step number.

    Args:
        output_path (str): Path to directory containing checkpoints.
        checkpoint_prefix (str): Prefix of the checkpoint files.
        use_mtime (bool): If True, use modification dates to determine checkpoint order.
    c                 S   s   g | ]}t |qS r   )r?   )rV   xr   r   r   rX   ;  rY   z$sort_checkpoints.<locals>.<listcomp>z_*z.*r   Nr   c                 S   s   g | ]}|d  qS )   r   )rV   r   r   r   r   rX   F  rY   )r   r   appendr'   r(   getmtimer   r   r   r   sorted)rm   r   r   ordering_and_checkpoint_pathglob_checkpointsr(   regex_matchcheckpoints_sortedr   r   r   r   1  s   r   )NT)FF)NN)Fr   N)F)%rh   r-   r'   r   r   pathlibr   typingr   r   r   r   r   r   urllib.parser	   r+   r@   coqpitr
   trainer.loggerr   r    r4   r?   rG   boolrD   rN   rQ   rr   rz   r   r   r   rv   r   r   r   r   r   <module>   sL     ,


,
)
:A$