U
    ,d-                     @   s   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mZ d dl	m
Z
 d dlmZ d dlmZ G dd dZed	d
ddddddddg	Zdd ZG dd dZedddgZG dd deZdS )    N)
namedtuple)Sequence)contextmanager)cached_property)configc                   @   s.   e Zd ZdZdgZdd Zdd Zdd Zd	S )
RecordLLVMPassTimingsz9A helper context manager to track LLVM pass timings.
    _datac                 C   s   t d | S )z)Enables the pass timing in LLVM.
        T)llvmset_time_passesself r   @/tmp/pip-unpacked-wheel-eu7e0c37/numba/misc/llvm_pass_timings.py	__enter__   s    
zRecordLLVMPassTimings.__enter__c                 C   s   t  | _t d dS )z2Reset timings and save report internally.
        FN)r	   Zreport_and_reset_timingsr   r
   )r   exc_valexc_typeexc_tbr   r   r   __exit__   s    

zRecordLLVMPassTimings.__exit__c                 C   s
   t | jS )ztRetrieve timing data for processing.

        Returns
        -------
        timings: ProcessedPassTimings
        )ProcessedPassTimingsr   r   r   r   r   get!   s    zRecordLLVMPassTimings.getN)__name__
__module____qualname____doc__	__slots__r   r   r   r   r   r   r   r      s
   r   PassTimingRecordZ	user_timeZuser_percentZsystem_timeZsystem_percentZuser_system_timeZuser_system_percent	wall_timewall_percent	pass_namec                    s\   | d j dkstfddfdddD  tdd	 | } fd
d}tt||S )zAdjust timing records because of truncated information.

    Details: The percent information can be used to improve the timing
    information.

    Returns
    -------
    res: List[PassTimingRecord]
    Totalc                    s4   |  d|  d t  fdd}|S )N_time_percentc                    s$   }||    d }|| < | S )z'Compute percent x total_time = adjustedg{Gz?r   )dtotaladjusted)percent_attr	time_attrtime_getter	total_recr   r   adjustM   s    z6_adjust_timings.<locals>.make_adjuster.<locals>.adjust)operator
attrgetter)attrr*   )r)   )r&   r'   r(   r   make_adjusterH   s
    


z&_adjust_timings.<locals>.make_adjusterc                    s   g | ]} |qS r   r   ).0x)r.   r   r   
<listcomp>W   s    z#_adjust_timings.<locals>.<listcomp>)usersystemuser_systemwallc                 S   s   |   S N)_asdictr0   r   r   r   <lambda>\       z!_adjust_timings.<locals>.<lambda>c                    s    D ]}|| } qt f | S r6   )r   )r#   fn)adj_fnsr   r   chained^   s    
z _adjust_timings.<locals>.chained)r   AssertionErrormaplist)recordsZdictsr=   r   )r<   r.   r)   r   _adjust_timings;   s    

rB   c                   @   s^   e Zd 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
edd Zdd ZdS )r   zA class for processing raw timing report from LLVM.

    The processing is done lazily so we don't waste time processing unused
    timing information.
    c                 C   s
   || _ d S r6   	_raw_data)r   raw_datar   r   r   __init__o   s    zProcessedPassTimings.__init__c                 C   s
   t | jS r6   )boolrD   r   r   r   r   __bool__r   s    zProcessedPassTimings.__bool__c                 C   s   | j S )zWReturns the raw string data.

        Returns
        -------
        res: str
        rC   r   r   r   r   get_raw_datau   s    z!ProcessedPassTimings.get_raw_datac                 C   s   |   d jS )zhCompute the total time spend in all passes.

        Returns
        -------
        res: float
        r   )list_recordsr   r   r   r   r   get_total_time~   s    z#ProcessedPassTimings.get_total_timec                 C   s   | j S )z{Get the processed data for the timing report.

        Returns
        -------
        res: List[PassTimingRecord]
        )
_processedr   r   r   r   rJ      s    z!ProcessedPassTimings.list_recordsc                 C   s(   |   }td}t||dd |S )a  Returns the top(n) most time-consuming (by wall-time) passes.

        Parameters
        ----------
        n: int
            This limits the maximum number of items to show.
            This function will show the ``n`` most time-consuming passes.

        Returns
        -------
        res: List[PassTimingRecord]
            Returns the top(n) most time-consuming passes in descending order.
        r   Nr   )rJ   r+   r,   heapqnlargest)r   nrA   keyr   r   r   list_top   s    
zProcessedPassTimings.list_top   r   c                    sv   g  d|  fdd}|d|   dd |d | |D ](}|d|jdd	|jd
d|j  qBd S )a  Return a string summarizing the timing information.

        Parameters
        ----------
        topn: int; optional
            This limits the maximum number of items to show.
            This function will show the ``topn`` most time-consuming passes.
        indent: int; optional
            Set the indentation level. Defaults to 0 for no indentation.

        Returns
        -------
        res: str
         c                    s      |   d S r6   )append)argbufprefixr   r   ap   s    z(ProcessedPassTimings.summary.<locals>.apzTotal .4fszTop timings:z  zs (5z%) 
)rK   rQ   r   r   r   join)r   topnindentrY   pr   rV   r   summary   s    &zProcessedPassTimings.summaryc                 C   s   |   S )ztA cached property for lazily processing the data and returning it.

        See ``_process()`` for details.
        )_processr   r   r   r   rL      s    zProcessedPassTimings._processedc                 C   s   dd }t || j}t|S )zParses the raw string data from LLVM timing report and attempts
        to improve the data by recomputing the times
        (See `_adjust_timings()``).
        c                 3   s  |   }d}d| d}t|}dddddd	 |D ]6}t||}|r4td
|} fdd|D } qlq4|d dks|tg }	|dd D ]$}
|	|
 d |	|
 d qi }tjD ]}
|
|	kr|
dkrd||
< qd}d| d| dt	|d  }|d7 }|D ]x}t||}|dk	rt
| } dd t|	| D }|| | d }tf d|i|}|V  |jdkr qqd|}|rtd| dS )zwA generator that parses the raw_data line-by-line to extract
            timing information for each pass.
            z[a-zA-Z+ ]+z(?:\s*-+z-+)+r2   r3   r4   r5   r   )z	User TimezSystem TimezUser+Systemz	Wall TimeNamez[a-zA-Z][a-zA-Z+ ]+c                    s   g | ]} |   qS r   )strip)r/   kZ
header_mapr   r   r1      s     z@ProcessedPassTimings._process.<locals>.parse.<locals>.<listcomp>r   Nr!   r"           z\s*((?:[0-9]+\.)?[0-9]+)z\s+(?:z\s*\(z%\)|-+)   z\s*(.*)c                 S   s&   i | ]\}}||d k	rt |ndqS )Nrh   )float)r/   rf   vr   r   r   
<dictcomp>   s    z@ProcessedPassTimings._process.<locals>.parse.<locals>.<dictcomp>r    r]   z'unexpected text after parser finished:
)
splitlinesiterrematchfindallr>   rT   r   _fieldslenr@   groupszipupdater   r^   
ValueError)rE   linesZ	colheaderZmulticolheadersZ	line_iterlnmZraw_headersheadersattrsrf   missingrO   patdatar   rec	remainingr   rg   r   parse   sd    





z,ProcessedPassTimings._process.<locals>.parse)r@   rD   rB   )r   r   rA   r   r   r   rc      s    @zProcessedPassTimings._processN)rR   r   )r   r   r   r   rF   rH   rI   rK   rJ   rQ   rb   r   rL   rc   r   r   r   r   r   h   s   			

r   NamedTimingsnametimingsc                   @   sj   e Zd ZdZdd Zedd Zdd Zdd	 Zd
d Z	e
dd ZdddZdd Zdd Zdd ZdS )PassTimingsCollectionzA collection of pass timings.

    This class implements the ``Sequence`` protocol for accessing the
    individual timing records.
    c                 C   s   || _ g | _d S r6   )_name_records)r   r   r   r   r   rF     s    zPassTimingsCollection.__init__c              	   c   sB   t jr8t }dV  W 5 Q R X | }|r>| || ndV  dS )a  Record new timings and append to this collection.

        Note: this is mainly for internal use inside the compiler pipeline.

        See also ``RecordLLVMPassTimings``

        Parameters
        ----------
        name: str
            Name for the records.
        N)r   ZLLVM_PASS_TIMINGSr   r   _append)r   r   r   r   r   r   r   record  s    zPassTimingsCollection.recordc                 C   s   | j t|| dS )zAppend timing records

        Parameters
        ----------
        name: str
            Name for the records.
        timings: ProcessedPassTimings
            the timing records.
        N)r   rT   r   )r   r   r   r   r   r   r   6  s    
zPassTimingsCollection._appendc                 C   s"   | j rtdd | j D S dS dS )zComputes the sum of the total time across all contained timings.

        Returns
        -------
        res: float or None
            Returns the total number of seconds or None if no timings were
            recorded
        c                 s   s   | ]}|j  V  qd S r6   r   rK   )r/   rr   r   r   	<genexpr>L  s     z7PassTimingsCollection.get_total_time.<locals>.<genexpr>N)r   sumr   r   r   r   rK   B  s    	z$PassTimingsCollection.get_total_timec                 C   s   t | jdd ddS )zReturns the timings in descending order of total time duration.

        Returns
        -------
        res: List[ProcessedPassTimings]
        c                 S   s
   | j  S r6   r   r8   r   r   r   r9   X  r:   z:PassTimingsCollection.list_longest_first.<locals>.<lambda>T)rP   reverse)sortedr   r   r   r   r   list_longest_firstP  s    z(PassTimingsCollection.list_longest_firstc                 C   s   | j  S )z	
        r   r   r   r   r   is_empty[  s    zPassTimingsCollection.is_emptyrR   c                 C   s   | j r
dS g }|j}|d| j  |  }|d|d t| jD ]V\}}|d| d|j  |j | d }|d|d	d
 ||jj|dd qFd	|S dS )a  Return a string representing the summary of the timings.

        Parameters
        ----------
        topn: int; optional, default=5.
            This limits the maximum number of items to show.
            This function will show the ``topn`` most time-consuming passes.

        Returns
        -------
        res: str

        See also ``ProcessedPassTimings.summary()``
        zNo pass timings were recordedzPrinting pass timings for zTotal time: rZ   z== #rS   d   z
 Percent: z.1f%ri   )r_   r`   r]   N)
r   rT   r   rK   	enumerater   r   r   rb   r^   )r   r_   rW   rY   Zoverall_timeir   percentr   r   r   rb   a  s    zPassTimingsCollection.summaryc                 C   s
   | j | S )zGet the i-th timing record.

        Returns
        -------
        res: (name, timings)
            A named tuple with two fields:

            - name: str
            - timings: ProcessedPassTimings
        r   )r   r   r   r   r   __getitem__  s    z!PassTimingsCollection.__getitem__c                 C   s
   t | jS )z#Length of this collection.
        )rs   r   r   r   r   r   __len__  s    zPassTimingsCollection.__len__c                 C   s   |   S r6   )rb   r   r   r   r   __str__  s    zPassTimingsCollection.__str__N)rR   )r   r   r   r   rF   r   r   r   rK   r   propertyr   rb   r   r   r   r   r   r   r   r     s   


r   )ro   r+   rM   collectionsr   collections.abcr   
contextlibr   Znumba.core.utilsr   Z
numba.corer   Zllvmlite.bindingZbindingr	   r   r   rB   r   r   r   r   r   r   r   <module>   s6   - (