o
    ziy                      @   s   d 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
 ddlm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 eeZG dd deZG dd deZdS )z
Timer
^^^^^
    N)	timedelta)AnyDictOptionalUnion)override)CallbackRunningStage)LightningEnum)MisconfigurationException)rank_zero_infoc                   @   s   e Zd ZdZdZdS )IntervalstepepochN)__name__
__module____qualname__r   r    r   r   U/home/ubuntu/.local/lib/python3.10/site-packages/pytorch_lightning/callbacks/timer.pyr   %   s    r   c                	       s  e Zd ZdZdejdfdeeee	e
eef f  dededdf fdd	Zejfd
edee fddZejfd
edee fddZejfd
edefddZejfd
edee fddZed2ddZed2ddZed2ddZed2ddZed2dd Zed2d!d"Zeddd#ed$eddfd%d&Zeddd#ed$eddfd'd(Zeddd#ed$eddfd)d*Zede
eef fd+d,Z ed-e
eef ddfd.d/Z!d3d0d1Z"  Z#S )4Timera  The Timer callback tracks the time spent in the training, validation, and test loops and interrupts the Trainer
    if the given time limit for the training loop is reached.

    Args:
        duration: A string in the format DD:HH:MM:SS (days, hours, minutes seconds), or a :class:`datetime.timedelta`,
            or a dict containing key-value compatible with :class:`~datetime.timedelta`.
        interval: Determines if the interruption happens on epoch level or mid-epoch.
            Can be either ``"epoch"`` or ``"step"``.
        verbose: Set this to ``False`` to suppress logging messages.

    Raises:
        MisconfigurationException:
            If ``duration`` is not in the expected format.
        MisconfigurationException:
            If ``interval`` is not one of the supported choices.

    Example::

        from pytorch_lightning import Trainer
        from pytorch_lightning.callbacks import Timer

        # stop training after 12 hours
        timer = Timer(duration="00:12:00:00")

        # or provide a datetime.timedelta
        from datetime import timedelta
        timer = Timer(duration=timedelta(weeks=1))

        # or provide a dictionary
        timer = Timer(duration=dict(weeks=4, days=2))

        # force training to stop after given time limit
        trainer = Trainer(callbacks=[timer])

        # query training/validation/test time (in seconds)
        timer.time_elapsed("train")
        timer.start_time("validate")
        timer.end_time("test")

    NTdurationintervalverbosereturnc                    s   t    t|tr9td| }|std|dtt	|
dt	|
dt	|
dt	|
dd}nt|trEtdi |}|ttvrZtd	| d
dtt |d urb| nd | _|| _|| _dd tD | _dd tD | _d| _d S )Nz(\d+):(\d\d):(\d\d):(\d\d)z`Timer(duration=zH)` is not a valid duration. Expected a string in the format DD:HH:MM:SS.            )dayshoursminutessecondsz,Unsupported parameter value `Timer(interval=z)`. Possible choices are: z, c                 S      i | ]}|d qS Nr   .0stager   r   r   
<dictcomp>r       z"Timer.__init__.<locals>.<dictcomp>c                 S   r#   r$   r   r%   r   r   r   r(   s   r)   r   r   )super__init__
isinstancestrre	fullmatchstripr   r   intgroupdictsetr   jointotal_seconds	_duration	_interval_verboser
   _start_time	_end_time_offset)selfr   r   r   duration_match	__class__r   r   r+   T   s6   




zTimer.__init__r'   c                 C      t |}| j| S )z8Return the start time of a particular stage (in seconds))r
   r:   r=   r'   r   r   r   
start_timev      
zTimer.start_timec                 C   rA   )z6Return the end time of a particular stage (in seconds))r
   r;   rB   r   r   r   end_time{   rD   zTimer.end_timec                 C   sX   |  |}| |}|tjkr| jnd}|du r|S |du r&t | | S || | S )z;Return the time elapsed for a particular stage (in seconds)r   N)rC   rE   r
   TRAININGr<   time	monotonic)r=   r'   startendoffsetr   r   r   time_elapsed   s   

zTimer.time_elapsedc                 C   s   | j dur| j | | S dS )z=Return the time remaining for a particular stage (in seconds)N)r7   rL   rB   r   r   r   time_remaining   s   
zTimer.time_remainingtrainer
pl.Trainer	pl_modulepl.LightningModulec                 C      t  | jtj< d S r$   )rG   rH   r:   r
   rF   r=   rN   rP   r   r   r   on_train_start      zTimer.on_train_startc                 C   rR   r$   )rG   rH   r;   r
   rF   rS   r   r   r   on_train_end   rU   zTimer.on_train_endc                 C   rR   r$   )rG   rH   r:   r
   
VALIDATINGrS   r   r   r   on_validation_start   rU   zTimer.on_validation_startc                 C   rR   r$   )rG   rH   r;   r
   rW   rS   r   r   r   on_validation_end   rU   zTimer.on_validation_endc                 C   rR   r$   )rG   rH   r:   r
   TESTINGrS   r   r   r   on_test_start   rU   zTimer.on_test_startc                 C   rR   r$   )rG   rH   r;   r
   rZ   rS   r   r   r   on_test_end   rU   zTimer.on_test_endargskwargsc                 O   s   | j d u rd S | | d S r$   )r7   _check_time_remainingr=   rN   r]   r^   r   r   r   on_fit_start   s   
zTimer.on_fit_startc                 O   (   | j tjks| jd u rd S | | d S r$   )r8   r   r   r7   r_   r`   r   r   r   on_train_batch_end      zTimer.on_train_batch_endc                 O   rb   r$   )r8   r   r   r7   r_   r`   r   r   r   on_train_epoch_end   rd   zTimer.on_train_epoch_endc                    s   d fddt D iS )NrL   c                    s   i | ]	}|j  |qS r   )valuerL   r%   r=   r   r   r(      s    z$Timer.state_dict.<locals>.<dictcomp>r	   rg   r   rg   r   
state_dict   s   zTimer.state_dictrh   c                 C   s"   | di }| tjjd| _d S )NrL   r   )getr
   rF   rf   r<   )r=   rh   rL   r   r   r   load_state_dict   s   zTimer.load_state_dictc                 C   sp   | j d usJ |  | j k}|j|}|jp||_|r4| jr6tt| tj	d}t
d| d d S d S d S )N)r"   z$Time limit reached. Elapsed time is z. Signaling Trainer to stop.)r7   rL   strategy	broadcastshould_stopr9   r   r1   r
   rF   r   )r=   rN   rm   elapsedr   r   r   r_      s   
zTimer._check_time_remaining)rN   rO   rP   rQ   r   N)rN   rO   r   N)$r   r   r   __doc__r   r   r   r   r-   r   r   r1   boolr+   r
   rF   floatrC   rE   rL   rM   r   rT   rV   rX   rY   r[   r\   r   ra   rc   re   rh   rj   r_   __classcell__r   r   r?   r   r   *   sR    +"r   )ro   loggingr.   rG   datetimer   typingr   r   r   r   typing_extensionsr   pytorch_lightningpl$pytorch_lightning.callbacks.callbackr    pytorch_lightning.trainer.statesr
   pytorch_lightning.utilitiesr   &pytorch_lightning.utilities.exceptionsr   %pytorch_lightning.utilities.rank_zeror   	getLoggerr   logr   r   r   r   r   r   <module>   s    
