
    i"                       U d Z ddlmZ ddlZddlZddlZddlmZmZm	Z	m
Z
 ddlmZmZ e
rddlmZ ddlmZ  ej$                  e      Z G d d	      Zeeeeeef   e	ee      e	e   gdf   Zd
ed<    G d d      Z G d d      Zy)a[  Metrics collection and management system for Dynamo.

This module provides context managers for gathering and reporting metrics during
compilation and runtime.

It includes two main components:
- MetricsContext: A context manager for collecting metrics during compilation, supporting
  nested contexts and various metric types (counters, sets, key-value pairs)
- RuntimeMetricsContext: A specialized context for runtime metrics collection that doesn't
  require explicit context management

The metrics system enables comprehensive monitoring and analysis of both compilation and
execution performance.
    )annotationsN)AnyCallableOptionalTYPE_CHECKING)Self	TypeAlias)Iterator)CapturedTracebackc                  2    e Zd ZdZdddZd	dZd
dZddZy)TopNz_
    Helper to record a list of metrics, keeping only the top N "most expensive" elements.
    c                     || _         g | _        y N)at_mostheap)selfr   s     W/var/www/html/engine/venv/lib/python3.12/site-packages/torch/_dynamo/metrics_context.py__init__zTopN.__init__'   s    +-	    c                    t        | j                        | j                  k  rt        j                  nt        j
                  } || j                  ||f       y r   )lenr   r   heapqheappushheappushpop)r   keyvalfns       r   addzTopN.add+   s8    "499~<U^^%BSBS
499sCj!r   c                ,    t        | j                        S r   )r   r   r   s    r   __len__zTopN.__len__0   s    499~r   c                >    d t        | j                  d      D        S )Nc              3  *   K   | ]  \  }}||f  y wr    ).0r   r   s      r   	<genexpr>z TopN.__iter__.<locals>.<genexpr>4   s     KxsCc
Ks   T)reverse)sortedr   r    s    r   __iter__zTopN.__iter__3   s    K6$))T+JKKr   N)   )r   int)r   r   r   r+   returnNone)r,   r+   )r,   zIterator[tuple[Any, int]])__name__
__module____qualname____doc__r   r   r!   r)   r$   r   r   r   r   "   s    ."
Lr   r   r	   
OnExitTypec                      e Zd ZddZddZ	 	 	 	 	 	 	 	 ddZddZddZddZdddZ	ddZ
ddd	Zdd
ZddZddZy)MetricsContextc                J    || _         i | _        d| _        d| _        g | _        y)aQ  
        Use this class as a contextmanager to create a context under which to accumulate
        a set of metrics, e.g., metrics gathered during a compilation. On exit of the
        contextmanager, call the provided 'on_exit' function and pass a dictionary of
        all metrics set during the lifetime of the contextmanager.
        r   N)_on_exit_metrics_start_time_ns_level_editsr   on_exits     r   r   zMetricsContext.__init__>   s(      (*#$@Br   c                    | j                   dk(  r i | _        t        j                         | _        | xj                   dz  c_         | S )z/
        Initialize metrics recording.
        r      )r9   r7   timetime_nsr8   r    s    r   	__enter__zMetricsContext.__enter__K   s8     ;;!DM"&,,.Dqr   c                4   | xj                   dz  c_         | j                   dk\  sJ | j                   dk(  r?	 t        j                         }| j                  | j                  || j
                  ||       yy# t        $ r t        j                  d       Y yw xY w)z>
        At exit, call the provided on_exit function.
        r>   r   z0Unexpected exception logging compilation metricsN)	r9   r?   r@   r6   r8   r7   	Exceptionlog	exception)r   exc_type	exc_value
_tracebackend_time_nss        r   __exit__zMetricsContext.__exit__W   s     	q{{a;;!R"lln''dmmXy   RPQRs   =A6 6BBc                     | j                   dkD  S )z4
        True if we've entered the context.
        r   )r9   r    s    r   in_progresszMetricsContext.in_progressk   s     {{Qr   c                    | j                   dk(  rt        d| d      || j                  vrd| j                  |<   | j                  |xx   |z  cc<   y)7
        Increment a metric by a given amount.
        r   zCannot increment  outside of a MetricsContextNr9   RuntimeErrorr7   r   metricvalues      r   	incrementzMetricsContext.incrementq   sT     ;;!!26(:VWXX&$%DMM&!f&r   c                R    ddj                  fd| j                  D              z   S )Nz

c              3  r   K   | ].  \  }}|z  r$d dj                  |j                               z    0 yw)zPrevious Traceback:
 N)joinformat)r%   ekpreds      r   r&   z/MetricsContext._render_edits.<locals>.<genexpr>|   s8      $
14x $bggahhj&99$
s   47)rY   r:   )r   r]   s    `r   _render_editszMetricsContext._render_edits{   s,     $
$
 
 
 	
r   c                &   | j                   dk(  rt        d| d      || j                  v r$|s"t        | j                  |h      d| dz         | j                  j                  t        j                  d      |hf       || j                  |<   y)	z
        Set a metric to a given value. Raises if the metric has been assigned previously
        in the current context.
        r   Cannot set rO   z

RuntimeError: Metric 'z]' has already been set in the current context (see above for current and previous traceback).r>   skipN)r9   rQ   r7   r^   r:   appendr   extract)r   rS   rT   	overwrites       r   setzMetricsContext.set   s    
 ;;!VH4PQRRT]]"9""F8,.vh 7B BB 
 	-551=xHI %fr   c                    | j                   dk(  rt        d| d      || j                  vri | j                  |<   || j                  |   |<   y)a=  
        Treats a give metric as a dictionary and set the k and value within it.
        Note that the metric must be a dictionary or not present.

        We allow this to be called multiple times (i.e. for features, it's not uncommon
        for them to be used multiple times within a single compilation).
        r   r`   rO   NrP   )r   rS   r   rT   s       r   set_key_valuezMetricsContext.set_key_value   sR     ;;!VH4PQRR&$&DMM&!%*fc"r   c                   | j                   dk(  rt        d      | j                  j                         |j                         z  }|r:|s8t        | j	                  t        |j                                     d| dz         | j                  j                  t        j                  d      t        |j                               f       | j                  j                  |       y)z
        Set multiple metrics directly. This method does NOT increment. Raises if any
        metric has been assigned previously in the current context and overwrite is
        not set to True.
        r   1Cannot update metrics outside of a MetricsContextz

RuntimeError: Metric(s) z_ have already been set in the current context.  (see above for current and previous traceback).r>   ra   N)r9   rQ   r7   keysr^   rf   r:   rc   r   rd   update)r   valuesre   existings       r   rl   zMetricsContext.update   s     ;;!RSS==%%'&++-7I""3v{{}#560
 ;B BB 
 	-551=s6;;=?QRSV$r   c                z    | j                   dk(  rt        d      | j                   dk(  r| j                  |       yy)zA
        Update, but only when at the outermost context.
        r   rj   r>   N)r9   rQ   rl   )r   rm   s     r   update_outerzMetricsContext.update_outer   s9     ;;!RSS;;!KK r   c                    | j                   dk(  rt        d| d      || j                  vrt               | j                  |<   | j                  |   j	                  |       y)z8
        Records a metric as a set() of values.
        r   zCannot add rO   N)r9   rQ   r7   rf   r   rR   s      r   
add_to_setzMetricsContext.add_to_set   sX     ;;!VH4PQRR&$'EDMM&!f!!%(r   c                    | j                   dk(  ry|| j                  vrt               | j                  |<   | j                  |   j                  ||       y)z;
        Records a metric as a TopN set of values.
        r   N)r9   r7   r   r   )r   rS   r   r   s       r   	add_top_nzMetricsContext.add_top_n   sH     ;;!&$(FDMM&!f!!#s+r   Nr<   r2   )r,   r   )rF   zOptional[type[BaseException]]rG   zOptional[BaseException]rH   r   r,   r-   )r,   bool)rS   strrT   r+   r,   r-   )r]   zset[str]r,   rw   )F)rS   rw   rT   r   re   rv   r,   r-   )rS   rw   r   rw   rT   r   r,   r-   )rm   dict[str, Any]re   rv   r,   r-   )rm   rx   r,   r-   )rS   rw   rT   r   r,   r-   )rS   rw   r   r   r   r+   r,   r-   )r.   r/   r0   r   rA   rJ   rL   rU   r^   rf   rh   rl   rp   rr   rt   r$   r   r   r4   r4   =   sj    C
R/R +R 	R
 
R('
& +%$ ),r   r4   c                  6    e Zd ZddZ	 d	 	 	 	 	 	 	 ddZddZy)	RuntimeMetricsContextc                .    || _         i | _        d| _        y)z
        Similar to MetricsContext, but used to gather the runtime metrics that are
        decoupled from compilation, where there's not a natural place to insert a
        context manager.
        r   N)r6   r7   r8   r;   s     r   r   zRuntimeMetricsContext.__init__   s      (*#$r   Nc                .   | j                   st        j                         | _        || j                   vrd| j                   |<   | j                   |xx   |z  cc<   |r:|j	                         D ]&  \  }}|| j                   vs||| j                   |<   ( yy)rN   r   N)r7   r?   r@   r8   items)r   rS   rT   extrar\   vs         r   rU   zRuntimeMetricsContext.increment   s     }}"&,,.D&$%DMM&!f& )1DMM)am'(DMM!$) r   c                   | j                   rF	 t        j                         }| j                  | j                  || j                   dd       i | _         yy# t
        $ r t        j                  d       Y )w xY w# i | _         w xY w)zW
        Call the on_exit function with the metrics gathered so far and reset.
        Nz,Unexpected exception logging runtime metrics)r7   r?   r@   r6   r8   rC   rD   rE   )r   rI   s     r   finishzRuntimeMetricsContext.finish   st     ==#"lln''dmmT4 !#   NLMN !#s#   =A A52A8 4A55A8 8	Bru   r   )rS   rw   rT   r+   r~   zOptional[dict[str, Any]]r,   r-   )r,   r-   )r.   r/   r0   r   rU   r   r$   r   r   rz   rz      s8    % JN))"%).F)	)$#r   rz   )r1   
__future__r   r   loggingr?   typingr   r   r   r   typing_extensionsr   r	   collections.abcr
   torch.utils._tracebackr   	getLoggerr.   rD   r   r+   dictrw   typeBaseExceptionr2   __annotations__r4   rz   r$   r   r   <module>r      s    #    9 9 - ( 4 g!L L* !#tCH~x](;<h}>UV

I P, P,f*# *#r   