o
    zif6                     @   s8  d dl Z d dlZd dlZd dl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 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 Z$G dd dZ%dd Z&dde'fddZ(G dd dZ)dS )     N)defaultdictwraps)box)Console)Group)Live)Markdown)Padding)Panel)	BarColumn)Progress)SpinnerColumn)TimeElapsedColumn)TimeRemainingColumn)Rule)Table)SummaryWriterc                   C   s   g S N r   r   r   L/home/ubuntu/.local/lib/python3.10/site-packages/audiotools/ml/decorators.pydefault_list   s   r   c                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )MeanzFKeeps track of the running mean, along with the latest
    value.
    c                 C   s   |    d S r   )resetselfr   r   r   __init__$   s   zMean.__init__c                 C   s   | j t| jd }|S N   )totalmaxcount)r   meanr   r   r   __call__'   s   zMean.__call__c                 C   s   d| _ d| _d S )Nr   )r!   r   r   r   r   r   r   +   s   
z
Mean.resetc                 C   s.   t |r|  jd7  _|  j|7  _d S d S r   )mathisfiniter!   r   )r   valr   r   r   update/   s   
zMean.updateN)__name__
__module____qualname____doc__r   r#   r   r'   r   r   r   r   r      s    r   c                        fdd}|S )a;  Runs a function only when the condition is met. The condition is
    a function that is run.

    Parameters
    ----------
    condition : Callable
        Function to run to check whether or not to run the decorated
        function.

    Example
    -------
    Checkpoint only runs every 100 iterations, and only if the
    local rank is 0.

    >>> i = 0
    >>> rank = 0
    >>>
    >>> @when(lambda: i % 100 == 0 and rank == 0)
    >>> def checkpoint():
    >>>     print("Saving to /runs/exp1")
    >>>
    >>> for i in range(1000):
    >>>     checkpoint()

    c                    s   t   fdd}|S )Nc                     s     r
| i |S d S r   r   )argskwargs)	conditionfnr   r   	decoratedQ   s   z*when.<locals>.decorator.<locals>.decoratedr   r0   r1   r/   r0   r   	decoratorP   s   zwhen.<locals>.decoratorr   )r/   r5   r   r3   r   when5   s   r6   timeprefixc                    r,   )am  Adds execution time to the output dictionary of the decorated
    function. The function decorated by this must output a dictionary.
    The key added will follow the form "[prefix]/[name_of_function]"

    Parameters
    ----------
    prefix : str, optional
        The key added will follow the form "[prefix]/[name_of_function]",
        by default "time".
    c                    s   t   fdd}|S )Nc                     sH   t  } | i |}t|tsJ t  }|| | d j < |S )N/)r7   perf_counter
isinstancedictr(   )r-   r.   soutpute)r0   r8   r   r   r1   h   s   z+timer.<locals>.decorator.<locals>.decoratedr   r2   r8   r4   r   r5   g   s   ztimer.<locals>.decoratorr   )r8   r5   r   r@   r   timer[   s   rA   c                   @   s   e Zd ZdZ					d'dedededed	ef
d
dZdd Zdd Z	dedefddZ
dejjdejv fdedededejdef
ddZd(dededefdd Zd!d" Zd#d$ Zd%d& ZdS ))Trackera  
    A tracker class that helps to monitor the progress of training and logging the metrics.

    Attributes
    ----------
    metrics : dict
        A dictionary containing the metrics for each label.
    history : dict
        A dictionary containing the history of metrics for each label.
    writer : SummaryWriter
        A SummaryWriter object for logging the metrics.
    rank : int
        The rank of the current process.
    step : int
        The current step of the training.
    tasks : dict
        A dictionary containing the progress bars and tables for each label.
    pbar : Progress
        A progress bar object for displaying the progress.
    consoles : list
        A list of console objects for logging.
    live : Live
        A Live object for updating the display live.

    Methods
    -------
    print(msg: str)
        Prints the given message to all consoles.
    update(label: str, fn_name: str)
        Updates the progress bar and table for the given label.
    done(label: str, title: str)
        Resets the progress bar and table for the given label and prints the final result.
    track(label: str, length: int, completed: int = 0, op: dist.ReduceOp = dist.ReduceOp.AVG, ddp_active: bool = "LOCAL_RANK" in os.environ)
        A decorator for tracking the progress and metrics of a function.
    log(label: str, value_type: str = "value", history: bool = True)
        A decorator for logging the metrics of a function.
    is_best(label: str, key: str) -> bool
        Checks if the latest value of the given key in the label is the best so far.
    state_dict() -> dict
        Returns a dictionary containing the state of the tracker.
    load_state_dict(state_dict: dict) -> Tracker
        Loads the state of the tracker from the given state dictionary.
    Nr   d   writerlog_filerankconsole_widthstepc                 C   s   i | _ i | _|| _|| _|| _i | _tt ddt t	 dt
 | _t|dg| _t| jd dd| _|durE| jt|t|d	d
 dS dS )a3  
        Initializes the Tracker object.

        Parameters
        ----------
        writer : SummaryWriter, optional
            A SummaryWriter object for logging the metrics, by default None.
        log_file : str, optional
            The path to the log file, by default None.
        rank : int, optional
            The rank of the current process, by default 0.
        console_width : int, optional
            The width of the console, by default 100.
        step : int, optional
            The current step of the training, by default 0.
        z([progress.description]{task.description}z{task.completed}/{task.total}r9   )widthr   
   )consolerefresh_per_secondNa)rI   file)metricshistoryrD   rF   rH   tasksr   r   r   r   r   pbarr   consolesr   liveappendopen)r   rD   rE   rF   rG   rH   r   r   r   r      s(   	zTracker.__init__c                 C   s(   | j dkr| jD ]	}|| qdS dS )z
        Prints the given message to all consoles.

        Parameters
        ----------
        msg : str
            The message to be printed.
        r   N)rF   rS   log)r   msgcr   r   r   print   s
   
	
zTracker.printc           
      C   s0  | j dkr| j| j| d  t|dtjd}|jddd |jdd	d |jd
dd | j| d 	 }|D ] }| j| d | }| j| d
 |  }|
||d|d q8|| j| d< dd | j D }tg || jR  }	| jttddtd| dddtddtj|	dddd dS dS )a  
        Updates the progress bar and table for the given label.

        Parameters
        ----------
        label : str
            The label of the progress bar and table to be updated.
        fn_name : str
            The name of the function associated with the label.
        r   rR   T)titleexpandr   keycyan)stylevaluebright_bluer"   bright_greenz10.6ftablec                 S      g | ]}|d  qS rc   r   .0tr   r   r   
<listcomp>       z"Tracker.update.<locals>.<listcomp> )r   r   z[italic]z()white)r      z[b]Progressblue)paddingr[   border_styleN)rF   rR   advancerQ   r   r   MINIMAL
add_columnrO   keysadd_rowvaluesr   rT   r'   r
   r   r   fit)
r   labelfn_namerc   rt   kr`   r"   tablesgroupr   r   r   r'      s2   
zTracker.updaterx   r[   c                 C   s   | j D ]}| j | d  D ]}|  qq| jdkrG| j| j| d  dd | j D }ttd| g|| jR  }| | dS dS )a:  
        Resets the progress bar and table for the given label and prints the final result.

        Parameters
        ----------
        label : str
            The label of the progress bar and table to be reset.
        title : str
            The title to be displayed when printing the final result.
        r"   r   rR   c                 S   rd   re   r   rf   r   r   r   ri     rj   z Tracker.done.<locals>.<listcomp>z# N)	rO   rv   r   rF   rR   rQ   r   r	   rZ   )r   rx   r[   vr{   r|   r   r   r   done  s   


 zTracker.done
LOCAL_RANKlength	completedop
ddp_activec                    sX   j jd d||dt dj< t tdd dj<  fdd	}|S )
a  
        A decorator for tracking the progress and metrics of a function.

        Parameters
        ----------
        label : str
            The label to be associated with the progress and metrics.
        length : int
            The total number of iterations to be completed.
        completed : int, optional
            The number of iterations already completed, by default 0.
        op : dist.ReduceOp, optional
            The reduce operation to be used, by default dist.ReduceOp.AVG.
        ddp_active : bool, optional
            Whether the DistributedDataParallel is active, by default "LOCAL_RANK" in os.environ.
        z[white]Iteration ())r   r   )rR   rc   c                   S   s   t  S r   )r   r   r   r   r   <lambda>;  s    zTracker.track.<locals>.<lambda>)r`   r"   c                    s    t   fdd}|S )Nc                     s  | i |}t |tsj |S g }| D ];\}}t |ttfr,t|g}t	|s2q r>|j
r>tj|d | ||< t|dkrV|| | ||< q| D ]\}}||vrdq[|j d |< j d | | q[j |S )N)r   r   r`   r"   )r;   r<   r'   r(   itemsintfloattorchtensor	is_tensoris_cudadist
all_reducedetachnumelrU   itemrO   )r-   r.   r>   scalar_keysrz   r}   )r   r0   rx   r   r   r   r   r1   ?  s0   



z3Tracker.track.<locals>.decorator.<locals>.decoratedr   r2   r   rx   r   r   r4   r   r5   >  s   z Tracker.track.<locals>.decorator)rR   add_taskr   rQ   r   rO   )r   rx   r   r   r   r   r5   r   r   r   track  s   
"zTracker.trackr`   T
value_typerP   c                    s<   dv sJ |r j vrttj  <  fdd}|S )a  
        A decorator for logging the metrics of a function.

        Parameters
        ----------
        label : str
            The label to be associated with the logging.
        value_type : str, optional
            The type of value to be logged, by default "value".
        history : bool, optional
            Whether to save the history of the metrics, by default True.
        )r"   r`   c                    s   t   fdd}|S )Nc                     s    | i |}j dkrXj  }| D ]0\}}t|tr#| n|}jd ur8j| d |j jv rGj | 	| qjv rXj d 	j |S )Nr   r9   rH   )
rF   rO   r   r;   r   rD   
add_scalarrH   rP   rU   )r-   r.   r>   rO   rz   r}   )r0   rx   r   r   r   r   r1   u  s   



z1Tracker.log.<locals>.decorator.<locals>.decoratedr   r2   rx   r   r   r4   r   r5   t  s   zTracker.log.<locals>.decorator)rP   r   r   )r   rx   r   rP   r5   r   r   r   rW   b  s   
zTracker.logc                 C   s$   | j | | d t| j | | kS )a  
        Checks if the latest value of the given key in the label is the best so far.

        Parameters
        ----------
        label : str
            The label of the metrics to be checked.
        key : str
            The key of the metric to be checked.

        Returns
        -------
        bool
            True if the latest value is the best so far, otherwise False.
        )rP   min)r   rx   r]   r   r   r   is_best  s   $zTracker.is_bestc                 C   s   | j | jdS )z
        Returns a dictionary containing the state of the tracker.

        Returns
        -------
        dict
            A dictionary containing the history and step of the tracker.
        rP   rH   r   r   r   r   r   
state_dict  s   	zTracker.state_dictc                 C   s   |d | _ |d | _| S )aB  
        Loads the state of the tracker from the given state dictionary.

        Parameters
        ----------
        state_dict : dict
            A dictionary containing the history and step of the tracker.

        Returns
        -------
        Tracker
            The tracker object with the loaded state.
        rP   rH   r   )r   r   r   r   r   load_state_dict  s   

zTracker.load_state_dict)NNr   rC   r   )r`   T)r(   r)   r*   r+   r   strr   r   rZ   r'   r~   r   ReduceOpAVGosenvironboolr   rW   r   r   r   r   r   r   r   rB   v   sN    .
.(
G)rB   )r7   )*r$   r   r7   collectionsr   	functoolsr   r   torch.distributeddistributedr   richr   rich.consoler   r   	rich.liver   rich.markdownr	   rich.paddingr
   
rich.panelr   rich.progressr   r   r   r   r   	rich.ruler   
rich.tabler   torch.utils.tensorboardr   r   r   r6   r   rA   rB   r   r   r   r   <module>   s6    &