a
    hT                     @   s   U 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	 ddl
mZ ee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                   @   sZ   e Zd ZdZdedddZeedddd	Zed
ddZe	e
eef  d
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   K/var/www/auris/lib/python3.9/site-packages/torch/_dynamo/metrics_context.py__init__    s    zTopN.__init__N)keyvalreturnc                 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.addr   c                 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>-       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edddZd dddZeee  ee e	ddd	d
Z
edddZeeddddZd"ee	eddddZeee	ddddZd#eee	f eddddZeee	f ddddZee	ddddZee	edd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   7   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__C   s
    

zMetricsContext.__enter__N)exc_type	exc_value
_tracebackr   c                 C   sj   |  j d8  _ | j dksJ | j dkrfz"t }| | j|| j|| W n tyd   td Y n0 dS )z>
        At exit, call the provided on_exit function.
        r1   r   z0Unexpected exception logging compilation metricsN)	r/   r2   r3   r,   r.   r-   	Exceptionlog	exception)r   r5   r6   r7   end_time_nsr   r   r   __exit__O   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_progressc   s    zMetricsContext.in_progress)metricvaluer   c                 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   r>   r?   r   r   r   	incrementi   s
    


zMetricsContext.incrementF)r>   r?   	overwriter   c                 C   sF   | j dkrtd| d|| jv r8|s8t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 rA   zMetric 'z-' has already been set in the current contextNrB   )r   r>   r?   rF   r   r   r   sets   s    

zMetricsContext.set)r>   r   r?   r   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   rG   rA   NrB   )r   r>   r   r?   r   r   r   set_key_value   s
    


zMetricsContext.set_key_value)valuesrF   r   c                 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/   rC   r-   keysupdate)r   rJ   rF   existingr   r   r   rM      s    

zMetricsContext.update)rJ   r   c                 C   s*   | j dkrtd| j dkr&| | dS )zA
        Update, but only when at the outermost context.
        r   rK   r1   N)r/   rC   rM   )r   rJ   r   r   r   update_outer   s    

zMetricsContext.update_outerc                 C   sD   | j dkrtd| d|| jvr0t | j|< | j| | dS )z8
        Records a metric as a set() of values.
        r   zCannot add rA   N)r/   rC   r-   rH   r   rD   r   r   r   
add_to_set   s
    

zMetricsContext.add_to_set)r>   r   r   r   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   r>   r   r   r   r   r   	add_top_n   s
    

zMetricsContext.add_top_n)F)F)r"   r#   r$   r(   r   r4   r   typeBaseExceptionr   r<   boolr=   strr&   rE   rH   rI   dictrM   rO   rP   rQ   r   r   r   r   r)   6   s   

	
r)   c                   @   sJ   e Zd ZedddZdeeeeee	f  ddddZ
d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.   r0   r   r   r   r      s    zRuntimeMetricsContext.__init__N)r>   r?   extrar   c                 C   sl   | j st | _|| j vr$d| j |< | j |  |7  < |rh| D ]$\}}|| j vrB|durB|| j |< qBdS )r@   r   N)r-   r2   r3   r.   items)r   r>   r?   rX   kvr   r   r   rE      s    


zRuntimeMetricsContext.incrementr   c                 C   s^   | j rZzJz"t }| | j|| j dd W n tyF   td Y n0 W i | _ ni | _ 0 dS )zW
        Call the on_exit function with the metrics gathered so far and reset.
        Nz,Unexpected exception logging runtime metrics)r-   r2   r3   r,   r.   r8   r9   r:   )r   r;   r   r   r   finish   s    zRuntimeMetricsContext.finish)N)r"   r#   r$   r(   r   rU   r&   r   rV   r   rE   r\   r   r   r   r   rW      s    rW   )r%   r   loggingr2   collections.abcr   typingr   r   r   Ztyping_extensionsr   	getLoggerr"   r9   r   r&   rV   rU   rR   rS   r(   __annotations__r)   rW   r   r   r   r   <module>   s    
  