U
    •Ê¹j÷3  ã                   @   s  d dl Z d dlZd dlmZ d dlmZ d dlmZmZ d dl	m
Z
 d dlmZ d dlmZ dd	„ d
fedœdd„Ze jedd	„ dd�Ze jedd	„ d
d�ZeG dd„ dƒƒZeG dd„ dƒƒZG dd„ dƒZG dd„ dƒZd#dd„Zdd	„ d dfdd„Zdd „ Zd!d"„ ZdS )$é    N)Údeque)Ú	dataclass)ÚDictÚList)Ú_KinetoEvent©Úprofile)Ú
DeviceTypec                 C   s   | j S ©N)Úchildren©Úx© r   úT/var/www/html/bwave/python/venv/lib/python3.8/site-packages/torch/profiler/_utils.pyÚ<lambda>   ó    r   F)Úreversec                 c   sP   |rt ndd„ }t|| ƒƒ}|rL||ƒ}|V  |||ƒƒD ]}| |¡ q:qd S )Nc                 S   s   | S r
   r   r   r   r   r   r      r   z_traverse.<locals>.<lambda>)Úreversedr   Úappend)ÚtreeÚnext_fnZchildren_fnr   ÚorderÚ	remainingÚ
curr_eventÚchild_eventr   r   r   Ú	_traverse   s    r   c                 C   s   |   ¡ S r
   )Úpopr   r   r   r   r      r   T)r   r   c                 C   s   |   ¡ S r
   )Úpopleftr   r   r   r   r      r   c                   @   sJ   e Zd ZU dZeed< dZeed< dZeed< dZeed< e	dd„ ƒZ
dS )	ÚEventMetricsr   Úduration_time_nsÚself_time_nsÚidle_time_nsÚqueue_depthc                 C   s   | j dkrdS | j| j  S )Nr   g        )r   r!   ©Úselfr   r   r   Úfraction_idle_time$   s    
zEventMetrics.fraction_idle_timeN)Ú__name__Ú
__module__Ú__qualname__r   ÚintÚ__annotations__r    r!   r"   Úpropertyr%   r   r   r   r   r      s   
r   c                   @   s*   e Zd ZU eed< eed< dZeed< dS )ÚIntervalÚstartÚendr   r"   N)r&   r'   r(   r)   r*   r"   r   r   r   r   r,   +   s   
r,   c                   @   s>   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zee d	œd
d„Z	dS )ÚEventKeyc                 C   s
   || _ d S r
   ©Úevent)r$   r1   r   r   r   Ú__init__3   s    zEventKey.__init__c                 C   s   t | jjƒS r
   )Úhashr1   Úidr#   r   r   r   Ú__hash__6   s    zEventKey.__hash__c                 C   s   | j j|j jkS r
   )r1   r4   )r$   Úotherr   r   r   Ú__eq__9   s    zEventKey.__eq__c                 C   s
   | j j› S r
   )r1   Únamer#   r   r   r   Ú__repr__<   s    zEventKey.__repr__)Ú	intervalsc           	      C   sê   d}t |dd„ d�}|rTt| jj|d jƒ}t| jj|d jƒ}||k rT||| 7 }d\}}|t|ƒk ræ|| }|| }|d7 }|j|jkr°|j|jkr¤|d7 }q\n|j|_|}t| jj|jƒ}t| jj|jƒ}||k r\||| 7 }q\|S )Nr   c                 S   s   | j S r
   ©r-   r   r   r   r   r   A   r   z,EventKey.intervals_overlap.<locals>.<lambda>©Úkey)r   é   r>   )	ÚsortedÚmaxr1   Ústart_time_nsr-   ÚminÚend_time_nsr.   Úlen)	r$   r:   Zoverlap_timeZoverlap_startZoverlap_endÚiÚjZprev_intervalZcurr_intervalr   r   r   Úintervals_overlap?   s.    zEventKey.intervals_overlapN)
r&   r'   r(   r2   r5   r7   r9   r   r,   rG   r   r   r   r   r/   2   s
   r/   c                   @   sL   e Zd Zedœdd„Zdd„ Zdd„ Zdd	„ Zd
d„ Zde	e
dœdd„ZdS )ÚBasicEvaluation)Úprofc                 C   sd   || _ i | _|  ¡  tdd„ | j ¡ D ƒdd„ d�| _dd„ | jD ƒ| _g | _|  ¡ | _	|  
¡  d S )Nc                 s   s   | ]
}|V  qd S r
   r   ©Ú.0Úer   r   r   Ú	<genexpr>f   s     z+BasicEvaluation.__init__.<locals>.<genexpr>c                 S   s   | j jS r
   )r1   rA   r   r   r   r   r   f   r   z*BasicEvaluation.__init__.<locals>.<lambda>r<   c                 S   s   g | ]
}|j ‘qS r   r0   rJ   r   r   r   Ú
<listcomp>h   s     z,BasicEvaluation.__init__.<locals>.<listcomp>)r   ÚmetricsÚcompute_self_timer?   ÚkeysZ
event_keysÚeventsÚcuda_eventsÚcompute_queue_depthÚqueue_depth_listÚcompute_idle_time)r$   rI   r   r   r   r2   a   s     ÿ
zBasicEvaluation.__init__c                 C   s¤   | j jdk	st‚t| j j ¡ ƒ}|r | ¡ }|j}|jD ]}||j8 }| |¡ q8t	|ƒ| j
ksxtd|j› d|j› �ƒ‚t|d�| j
t	|ƒ< |j| j
t	|ƒ _q dS )zM
        Computes event's self time(total time - time in child ops).
        NzDuplicate id: z, )r    )r   Úkineto_resultsÚAssertionErrorr   Zexperimental_event_treer   r   r   r   r/   rO   r4   r8   r   )r$   Ústackr   Ú	self_timer   r   r   r   rP   m   s"    

ÿþþÿz!BasicEvaluation.compute_self_timec                    sà  | j jdk	st‚| j j ¡ }dd„ ‰dd„ ‰t‡fdd„|D ƒdd	„ d
�}t‡fdd„|D ƒdd	„ d
�}t|| dd	„ d
�| _i }d}|D ]2‰ t|‡ fdd	„|d�}||ˆ < |dk	r¸|n|}qŠd}d}|| | j }	dd„ }
g }|	j|
d
� |	D ]ê}t|dƒ�rB| 	¡ d }| 	¡ | 
¡  d }||k�rZ|| dk	�rZ|| }nt|dƒ�rZ|j}|j}|t|ƒk �rŠ||  	¡ d |k�rŠ|d7 }�qZ|| d }t|dƒ}t|dƒ�rÀ| t|||ƒ¡ qðt|dƒrð|| jt|ƒ _qð|S )zâ
        Computes queue_depth at each event. This will calculate the queue depth data for
        All the events in the tree.
        This will return a list of Interval of queue depth data of cuda launch and kernels.
        Nc                 S   s
   | j dkS )NZcudaLaunchKernel)r8   ©rL   r   r   r   Úis_cuda_launch_kernelŒ   s    zBBasicEvaluation.compute_queue_depth.<locals>.is_cuda_launch_kernelc                 S   s   |   ¡ tjkod| j ¡ kS )NZmem)Zdevice_typer	   ÚCUDAr8   Úlowerr[   r   r   r   Úis_cuda_kernel�   s    z;BasicEvaluation.compute_queue_depth.<locals>.is_cuda_kernelc                 3   s   | ]}ˆ |ƒr|V  qd S r
   r   rJ   )r\   r   r   rM   •   s      z6BasicEvaluation.compute_queue_depth.<locals>.<genexpr>c                 S   s   |   ¡ S r
   ©Ústart_usr   r   r   r   r   –   r   z5BasicEvaluation.compute_queue_depth.<locals>.<lambda>r<   c                 3   s   | ]}ˆ |ƒr|V  qd S r
   r   rJ   )r_   r   r   rM   ™   s      c                 S   s   |   ¡ S r
   r`   r   r   r   r   r   š   r   c                 S   s   |   ¡ S r
   r`   r   r   r   r   r   ž   r   r   c                    s   |   ¡ ˆ   ¡ kS r
   )Zlinked_correlation_idr   )Úcuda_launch_eventr   r   r   ¦   s   ÿr;   éÿÿÿÿc                 S   s2   t | dƒr|  ¡ d S t | dƒr&| jS tdƒ‚d S )Nra   éè  rA   zUnknown Event Type)Úhasattrra   rA   Ú	Exceptionr0   r   r   r   Únew_old_event_comparator²   s
    

zEBasicEvaluation.compute_queue_depth.<locals>.new_old_event_comparatorra   rd   rA   r>   )r   rW   rX   rR   r?   rS   Úindex_of_first_matchÚsortre   ra   Zduration_usrA   rC   rD   r@   r   r,   rO   r/   r"   )r$   Zcuda_event_listZcuda_launch_eventsZcuda_kernel_eventsZkernel_mappingZlast_mapped_kernelÚindexZcurrent_kernel_indexZspawned_kernel_indexZ
all_eventsrg   rU   r1   Ú
start_timeZend_timeZcurrent_queue_depthr   )rb   r_   r\   r   rT   ƒ   sr    þþ ÿ
ü

ÿÿþ

ÿ
z#BasicEvaluation.compute_queue_depthc                 C   sÔ   d}d}g }| j rP| jrP|t| jd j| j d jƒt| j d j| jd jƒg7 }| j D ]@}|jdkrr|sr|j}d}|jdkrV|rV| t||jƒ¡ d}qVdd„ | j	 
¡ D ƒ}|D ]}t|ƒ |¡| j	t|ƒ _q°dS )z4
        Computes idle time of the profile.
        Fr   rc   Tc                 S   s   g | ]
}|j ‘qS r   r0   rJ   r   r   r   rN   ï   s     z5BasicEvaluation.compute_idle_time.<locals>.<listcomp>N)rU   rR   r,   rA   r-   r.   rC   r"   r   rO   rQ   r/   rG   r!   )r$   ZidleZ
idle_startZidle_intervalsZ
data_pointÚ
event_listr1   r   r   r   rV   Ù   s,    þ
ÿþz!BasicEvaluation.compute_idle_timec                    s¨  ddl }ttˆjƒƒ}dd„ |D ƒ}d‰ d}g ‰d}|t|ƒk rà|| ˆ krV|d7 }q4t|d t|ƒƒD ]l}t|‡ fdd„|d	�}t|||d
�}	|	dk	rh||	 |krhˆ t	||	 j
|| j
ƒ¡ |dk	rÌ|n|} qÖqh|d7 }q4‡fdd„ˆj ¡ D ƒ}
|
�r¤|j‡fdd„|
D ƒ|jd�}|j‡fdd„|
D ƒ|jd�}|| |¡ | |¡ }|| |¡ | |¡ }|d|  }dd„ tt||
ƒdd„ dd�D ƒ}
|
d|… }
|
S )a  
        Filter and Rank the events based on some heuristics:
        1) Events that are in the falling phase of the queue depth.
        2) Events that have a high idle_time, self_time difference.

        Parameters:
            length: The number of events to return.
        r   Nc                 S   s   g | ]
}|j ‘qS r   )r"   rJ   r   r   r   rN     s     z/BasicEvaluation.rank_events.<locals>.<listcomp>é   r>   c                    s   | ˆ kS r
   r   r   )Úbottom_threasholdr   r   r     r   z-BasicEvaluation.rank_events.<locals>.<lambda>r;   )r-   r.   c                    s   g | ]}|  ˆ ¡r|‘qS r   )rG   ©rK   r1   )Údecrease_intervalr   r   rN      s   
þc                    s   g | ]}ˆ j | j‘qS r   )rO   r    ro   r#   r   r   rN   '  s     )Zdtypec                    s   g | ]}ˆ j | j‘qS r   )rO   r%   ro   r#   r   r   rN   +  s     g333333ã?c                 S   s   g | ]\}}|‘qS r   r   )rK   Ú_r1   r   r   r   rN   3  s   ÿc                 S   s   | d S )Nr   r   r   r   r   r   r   7  r   T)r=   r   )ÚtorchÚlistr   rU   rD   Úrangerh   Úargmaxr   r,   r-   rO   rQ   ZtensorZfloat32ZmeanZstdr?   Úzip)r$   Úlengthrr   rU   Z	qd_valuesZtop_threasholdrE   rF   Znext_minimum_idxZpeak_idxrl   rZ   Z	idle_timeZnormalized_gainZnormalized_selfZheuristic_score_listr   )rn   rp   r$   r   Úrank_eventsõ   sh     
 ÿ ÿÿ

þþþýþzBasicEvaluation.rank_eventsr>   T)rw   Úprint_enablec                    sJ   ˆ   |¡}|s|S |rdnd}|d ‡ fdd„|D ƒ¡7 }|rFt|ƒ |S )NzOptimizable events:
zNo events to optimize
Ú
c                    s@   g | ]8}d › d|› dt |jƒ› dˆ j| jd d›dd › �	‘qS )zP--------------------------------------------------------------------------------z
Event:                z
Source code location: z
Percentage idle time: éd   z.2fz%
)Úsource_code_locationr1   rO   r%   ro   r#   r   r   rN   E  s   ûÿþz:BasicEvaluation.get_optimizable_events.<locals>.<listcomp>)rx   ÚjoinÚprint)r$   rw   ry   rl   Úoutputr   r#   r   Úget_optimizable_events>  s    

úÿ
z&BasicEvaluation.get_optimizable_eventsN)r>   T)r&   r'   r(   r   r2   rP   rT   rV   rx   r)   Úboolr€   r   r   r   r   rH   `   s   VIrH   c                 C   sD   |d ks|t | ƒkrt | ƒ}t||ƒD ]}|| | ƒr&|  S q&d S r
   )rD   rt   )ÚseqÚ	predicater-   r.   rE   r   r   r   rh   S  s    
rh   c                 C   s   | S r
   r   r   r   r   r   r   \  r   c                 C   s2   | ||… } t | ƒdkrd S |  t| |d�¡| S )Nr   r<   )rD   rj   r@   )r‚   r=   r-   r.   r   r   r   ru   \  s    ru   c                 C   s0   | d k	r,t  d| j¡}|d kr&| j} q | jS dS )Nz
\.py\(.*\)zNo source code location found)ÚreÚsearchr8   Úparent)r1   Úmatchr   r   r   r|   c  s    r|   c               	   C   s"   ddl m}  | ƒ � W 5 Q R X d S )Nr   r   )Útorch.autograd.profilerr   r   r   r   r   Ú_init_for_cuda_graphsq  s    r‰   )r   N)Ú	functoolsr„   Úcollectionsr   Údataclassesr   Útypingr   r   Ztorch.autogradr   rˆ   r   Ztorch.profilerr	   r�   r   ÚpartialZtraverse_dfsZtraverse_bfsr   r,   r/   rH   rh   ru   r|   r‰   r   r   r   r   Ú<module>   s2   
  ÿ. t
	