o
    Zh                     @   s   U d Z ddlZddlZddlmZ ddlmZmZmZ ddl	m
Z
 G dd dZeeeeeef eee  ee gdf Ze
ed< G d	d
 d
ZG dd dZdS )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.
    N)Iterator)AnyCallableOptional)	TypeAliasc                   @   s^   e Zd ZdZddefddZdededd	fd
dZdefddZde	e
eef  fddZd	S )TopNz_
    Helper to record a list of metrics, keeping only the top N "most expensive" elements.
       at_mostc                 C   s   || _ g | _d S N)r	   heap)selfr	    r   L/var/www/auris/lib/python3.10/site-packages/torch/_dynamo/metrics_context.py__init__   s   
zTopN.__init__keyvalreturnNc                 C   s0   t | j| jk rtjntj}|| j||f d S r
   )lenr   r	   heapqheappushheappushpop)r   r   r   fnr   r   r   add    s   zTopN.addc                 C   s
   t | jS r
   )r   r   r   r   r   r   __len__%   s   
zTopN.__len__c                 C   s   dd t | jddD S )Nc                 s   s    | ]	\}}||fV  qd S r
   r   ).0r   r   r   r   r   	<genexpr>)   s    z TopN.__iter__.<locals>.<genexpr>T)reverse)sortedr   r   r   r   r   __iter__(   s   zTopN.__iter__)r   )__name__
__module____qualname____doc__intr   r   r   r   r   tupler   r   r   r   r   r      s    r   
OnExitTypec                	   @   s  e Zd ZdefddZd$ddZdeee  dee d	e	dd
fddZ
defddZdededd
fddZd%dede	dedd
fddZdedede	dd
fddZd%deee	f dedd
fddZdeee	f dd
fddZdede	dd
fdd Zdede	d!edd
fd"d#Zd
S )&MetricsContexton_exitc                 C   s   || _ i | _d| _d| _dS )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r   r(   r   r   r   r   3   s   
zMetricsContext.__init__r   c                 C   s,   | j dkri | _t | _|  j d7  _ | S )z/
        Initialize metrics recording.
        r      )r,   r*   timetime_nsr+   r   r   r   r   	__enter__?   s
   

zMetricsContext.__enter__exc_type	exc_value
_tracebackNc                 C   sL   |  j d8  _ | j dksJ | j dkr$t }| | j|| j|| dS dS )z>
        At exit, call the provided on_exit function.
        r.   r   N)r,   r/   r0   r)   r+   r*   )r   r2   r3   r4   end_time_nsr   r   r   __exit__K   s   	
zMetricsContext.__exit__c                 C   s
   | j dkS )z4
        True if we've entered the context.
        r   )r,   r   r   r   r   in_progress\   s   
zMetricsContext.in_progressmetricvaluec                 C   sD   | j dkrtd| d|| jvrd| j|< | j|  |7  < dS )7
        Increment a metric by a given amount.
        r   zCannot increment  outside of a MetricsContextNr,   RuntimeErrorr*   r   r8   r9   r   r   r   	incrementb   s
   


zMetricsContext.incrementF	overwritec                 C   sF   | j dkrtd| d|| jv r|std| d|| j|< dS )z
        Set a metric to a given value. Raises if the metric has been assigned previously
        in the current context.
        r   Cannot set r;   zMetric 'z-' has already been set in the current contextNr<   )r   r8   r9   r@   r   r   r   setl   s   

zMetricsContext.setr   c                 C   s@   | j dkrtd| d|| jvri | j|< || j| |< dS )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   rA   r;   Nr<   )r   r8   r   r9   r   r   r   set_key_valuey   s
   


zMetricsContext.set_key_valuevaluesc                 C   sL   | j dkr	td| j | @ }|r|std| d| j| dS )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
Metric(s) z- have already been set in the current contextN)r,   r=   r*   keysupdate)r   rD   r@   existingr   r   r   rG      s   

zMetricsContext.updatec                 C   s.   | j dkr	td| j dkr| | dS dS )zA
        Update, but only when at the outermost context.
        r   rE   r.   N)r,   r=   rG   )r   rD   r   r   r   update_outer   s
   

zMetricsContext.update_outerc                 C   sD   | j dkrtd| d|| jvrt | j|< | j| | dS )z8
        Records a metric as a set() of values.
        r   zCannot add r;   N)r,   r=   r*   rB   r   r>   r   r   r   
add_to_set   s
   

zMetricsContext.add_to_setr   c                 C   s:   | j dkrdS || jvrt | j|< | j| || dS )z;
        Records a metric as a TopN set of values.
        r   N)r,   r*   r   r   )r   r8   r   r   r   r   r   	add_top_n   s
   

zMetricsContext.add_top_n)r   r'   )F)r    r!   r"   r&   r   r1   r   typeBaseExceptionr   r6   boolr7   strr$   r?   rB   rC   dictrG   rI   rJ   rK   r   r   r   r   r'   2   s(    



 	
r'   c                	   @   sJ   e Zd ZdefddZdededeeee	f  ddfd	d
Z
dddZdS )RuntimeMetricsContextr(   c                 C   s   || _ i | _d| _dS )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)r)   r*   r+   r-   r   r   r   r      s   
zRuntimeMetricsContext.__init__r8   r9   extrar   Nc                 C   sp   | j st | _|| j vrd| j |< | j |  |7  < |r4| D ]\}}|| j vr3|dur3|| j |< q!dS dS )r:   r   N)r*   r/   r0   r+   items)r   r8   r9   rR   kvr   r   r   r?      s   



zRuntimeMetricsContext.incrementc                 C   s2   | j rt }| | j|| j dd i | _ dS dS )zW
        Call the on_exit function with the metrics gathered so far and reset.
        N)r*   r/   r0   r)   r+   )r   r5   r   r   r   finish   s
   
zRuntimeMetricsContext.finish)r   N)r    r!   r"   r&   r   rO   r$   r   rP   r   r?   rV   r   r   r   r   rQ      s    

rQ   )r#   r   r/   collections.abcr   typingr   r   r   Ztyping_extensionsr   r   r$   rP   rO   rL   rM   r&   __annotations__r'   rQ   r   r   r   r   <module>   s      