U
    xÊ¹j(E  ã                   @   sÂ   d dl Z d dlZd dlZd dlZd dlmZ ddlmZ dd„ Zd'dd	„Z	d(dd„Z
d)dd„ZG dd„ dƒZG dd„ dƒZdd„ Zd*dd„Zd+dd„Zdd„ Zdd „ Zed,d#d$„ƒZd-d%d&„ZdS ).é    N)Úcontextmanageré   )Úruntimec                 C   sL   d  | ¡} dddd|  dg}t |¡}| tjj¡ d¡}dd„ |D ƒ}|S )	Nú,ú
nvidia-smiú-iÚ0ú--query-gpu=ú--format=csv,noheader,nounitsc                 S   s   g | ]}t |ƒ‘qS © ©Úint©Ú.0Úxr   r   úM/var/www/html/bwave/python/venv/lib/python3.8/site-packages/triton/testing.pyÚ
<listcomp>   s     znvsmi.<locals>.<listcomp>©ÚjoinÚ
subprocessÚcheck_outputÚdecodeÚsysÚstdoutÚencodingÚsplit©ÚattrsÚcmdÚoutÚretr   r   r   Únvsmi
   s    

r!   é   c              	      sÊ  dd l ‰ˆj ¡ ˆj ¡ kr$tdƒ‚| ƒ  |d k	rT|D ]}| ¡  | d¡ d |_q6ˆj ¡ ‰ ˆj 	ˆ ¡� | ƒ  W 5 Q R X ˆj 
¡  ‡ fdd„} ˆjjdd�}ˆjjdd�}| ¡  | ƒ  | ¡  ˆj 
¡  | |¡}tdt|| ƒƒ}‡fdd	„t|ƒD ƒ}‡fd
d	„t|ƒD ƒ}g }d}	t|	ƒD ]Ž}
ˆj 
¡  t|ƒD ]@}|d k	�r\|D ]}d |_�qN||  ¡  | ƒ  ||  ¡  �q<ˆj 
¡  ˆ dd	„ t||ƒD ƒ¡}| ˆ |¡¡ �q&ˆ ˆ |¡¡ ¡ S )Nr   zQCannot capture graph in default stream. Please use side stream in benchmark code.Tc                      s   ˆ   ¡ S ©N)Zreplayr   )Úgr   r   Ú<lambda>,   ó    z$do_bench_cudagraph.<locals>.<lambda>©Zenable_timingr   c                    s   g | ]}ˆ j jd d�‘qS ©Tr'   ©ÚcudaÚEvent©r   Úi©Útorchr   r   r   8   s     z&do_bench_cudagraph.<locals>.<listcomp>c                    s   g | ]}ˆ j jd d�‘qS r(   r)   r,   r.   r   r   r   9   s     é2   c                 S   s   g | ]\}}|  |¡‘qS r   ©Úelapsed_time©r   ÚsÚer   r   r   r   K   s     )r/   r*   Zcurrent_streamZdefault_streamÚRuntimeErrorZdetach_Zrequires_grad_ÚgradZ	CUDAGraphÚgraphÚsynchronizer+   Úrecordr2   Úmaxr   ÚrangeÚtensorÚzipÚappendÚminÚmeanÚitem)ÚfnÚrepÚgrad_to_noner   Ústart_eventÚ	end_eventÚestimate_msÚn_repeatr    Z	n_retriesÚ_r-   Útimesr   )r$   r/   r   Údo_bench_cudagraph   sN    








rL   é   éd   TrA   c                    sê  |dkst ‚dd l‰ | ƒ  ˆ j ¡  |r@ˆ jtdƒˆ jdd�}nˆ jtdƒˆ jdd�}ˆ jjdd�}ˆ jjdd�}	| ¡  t	d	ƒD ]}
| 
¡  | ƒ  q‚|	 ¡  ˆ j ¡  | |	¡d	 }td
t|| ƒƒ}td
t|| ƒƒ}‡ fdd„t	|ƒD ƒ}‡ fdd„t	|ƒD ƒ}	t	|ƒD ]}
| ƒ  �qt	|ƒD ]H}|d k	�rD|D ]}d |_�q6| 
¡  ||  ¡  | ƒ  |	|  ¡  �q$ˆ j ¡  ˆ jdd„ t||	ƒD ƒˆ jd�}|d k	�rØˆ  |ˆ j|ˆ jd�¡ ¡ }t|ƒd
k�rÔ|d }|S tˆ |ƒ|ƒ ¡ S )N)r@   r;   rA   Zmedianr   g    €„ŽAr*   )ÚdtypeÚdeviceg    €„®ATr'   é   r   c                    s   g | ]}ˆ j jd d�‘qS r(   r)   r,   r.   r   r   r   �   s     zdo_bench.<locals>.<listcomp>c                    s   g | ]}ˆ j jd d�‘qS r(   r)   r,   r.   r   r   r   ‚   s     c                 S   s   g | ]\}}|  |¡‘qS r   r1   r3   r   r   r   r   –   s     )rO   )ÚAssertionErrorr/   r*   r9   Úemptyr   Úint8r+   r:   r<   Zzero_r2   r;   r7   r=   r>   ÚfloatZquantileÚtolistÚlenÚgetattrrB   )rC   ZwarmuprD   rE   Z	quantilesZ
fast_flushZreturn_modeÚcacherF   rG   rJ   rH   Zn_warmuprI   r-   r   rK   r    r   r.   r   Údo_benchP   sL    





 
rZ   Ú c                 C   sN  dd l }dd l}t| |jƒs&| | ¡} t||jƒs<| |¡}|d krHd}t|ƒrZ|| jƒn|}|d krjd}t|ƒr||| jƒn|}t| |jƒr°| j|jkr |  ¡ } |  	¡  
¡   ¡ } t||jƒrà|j|jkrÐ| ¡ }| 	¡  
¡   ¡ }| jdksö|jdk�r|jj| |||dd� d S |j| |||d��sJt|› d| › d	|› d
|› d|› d�
ƒ‚d S )Nr   g{®Gáz„?g        r   T)ÚatolÚrtolZ	equal_nan)r\   r]   ú z is not close to z (atol=z, rtol=ú))Únumpyr/   Ú
isinstanceZTensorr=   ÚcallablerO   Úbfloat16rU   ÚcpuÚdetachÚsizeZtestingZassert_allcloseZallcloserR   )r   Úyr\   r]   Úerr_msgÚnpr/   r   r   r   Úassert_closeŸ   s2    

rj   c                   @   s   e Zd ZdZddd„ZdS )Ú	Benchmarkzk
    This class is used by the :code:`perf_report` function to generate line plots with a concise API.
    r[   FNc                 C   sL   || _ || _|
| _|| _|| _|| _|| _|| _|| _|	| _	|| _
|| _dS )a  
        Constructor

        :param x_names: Name of the arguments that should appear on the x axis of the plot. If the list contains more than one element, all the arguments are assumed to have the same value.
        :type x_names: List[str]
        :param x_vals: List of values to use for the arguments in :code:`x_names`.
        :type x_vals: List[Any]
        :param line_arg: Argument name for which different values correspond to different lines in the plot.
        :type line_arg: str
        :param line_vals: List of values to use for the arguments in :code:`line_arg`.
        :type line_vals: List[str]
        :param line_names: Label names for the different lines.
        :type line_names: List[str]
        :param plot_name: Name of the plot.
        :type plot_name: str
        :param args: List of arguments to remain fixed throughout the benchmark.
        :type args: List[str]
        :param xlabel: Label for the x axis of the plot.
        :type xlabel: str, optional
        :param ylabel: Label for the y axis of the plot.
        :type ylabel: str, optional
        :param x_log: Whether the x axis should be log scale.
        :type x_log: bool, optional
        :param y_log: Whether the y axis should be log scale.
        :type y_log: bool, optional
        N)Úx_namesÚx_valsÚx_logÚline_argÚ	line_valsÚ
line_namesÚy_logÚstylesÚxlabelÚylabelÚ	plot_nameÚargs)Úselfrl   rm   ro   rp   rq   rv   rw   rt   ru   rn   rr   Úcolorrs   r   r   r   Ú__init__É   s    *zBenchmark.__init__)r[   r[   FFNN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rz   r   r   r   r   rk   Ä   s         òrk   c                   @   s&   e Zd Zdd„ Zdd„ Zd
dd„Zd	S )ÚMarkc                 C   s   || _ || _d S r#   )rC   Ú
benchmarks)rx   rC   r€   r   r   r   rz     s    zMark.__init__c              
      sæ  dd l }dd lm} dd l}|j}dd„ |jD ƒ}	dd„ |jD ƒ}
|j|jd g| |	 |
 d�}|jD ]¼‰ ‡ fdd„|jD ƒ}g g g   }}}|jD ]p}| j	f ||j
|i|j—Ž}z|\}}	}
W n$ tk
ræ   |d d   }}	}
Y nX ||g7 }||	g7 }||
g7 }q–ˆ g| | | |jt|ƒ< qh|j�rˆ| ¡  | ¡ }|jd ‰ t|jƒD ] \}}||d  ||d	   }	}
|j�rŠ|j| d nd }|j�r¤|j| d
 nd }|j|ˆ  || |||d� |	d k	�rR|
d k	�rR|j|ˆ  |	|
d|d� �qR| ¡  |j�r
|jn
d |j¡}| |¡ | |j¡ | |j�r<dnd¡ | |j�rRdnd¡ |�rf|  ¡  |�rˆ| !|j" ||j› d�¡¡ ||jd g|j  }|�rºt#|jd ƒ t#|ƒ |�râ|j$|j" ||j› d�¡ddd� d S )Nr   c                 S   s   g | ]}|› d �‘qS )ú-minr   r   r   r   r   r     s     zMark._run.<locals>.<listcomp>c                 S   s   g | ]}|› d �‘qS )ú-maxr   r   r   r   r   r     s     )Úcolumnsc                    s   i | ]
}|ˆ “qS r   r   )r   Zx_name©r   r   r   Ú
<dictcomp>  s      zMark._run.<locals>.<dictcomp>r�   r‚   r   )Úlabelry   Zlsg333333Ã?)Úalphary   z = ÚlogZlinearz.pngú:z.csvz%.1fF)Zfloat_formatÚindex)%ÚosZmatplotlib.pyplotZpyplotZpandasrq   Z	DataFramerl   rm   rp   rC   ro   rw   Ú	TypeErrorÚlocrW   rv   ZfigureZsubplotÚ	enumeraters   ZplotZfill_betweenZlegendrt   r   Z
set_xlabelZ
set_ylabelru   Z
set_xscalern   Z
set_yscalerr   ÚshowZsavefigÚpathÚprintZto_csv)rx   ÚbenchÚ	save_pathÚ
show_plotsÚ
print_datar‹   ZpltÚpdZy_meanZy_minZy_maxZdfZx_argsZrow_meanZrow_minZrow_maxrg   r    Zaxr-   ÚcolZstyrt   r   r„   r   Ú_run  s^     





z	Mark._runFr[   c                 C   s„   t | jtƒ}|r| jgn| j}|r@ttj |d¡dƒ}| d¡ |D ],}|  ||||¡ |rD| d|j	› d�¡ qD|r€| d¡ d S )Nzresults.htmlÚwz<html><body>
z<image src="z.png"/>
z</body></html>
)
ra   r€   rk   Úopenr‹   r�   r   Úwriter˜   rv   )rx   r”   r•   r“   Zhas_single_benchr€   Úhtmlr’   r   r   r   Úrun:  s    
zMark.runN)FFr[   )r{   r|   r}   rz   r˜   r�   r   r   r   r   r     s   3r   c                    s   ‡ fdd„}|S )zê
    Mark a function for benchmarking. The benchmark can then be executed by using the :code:`.run` method on the return value.

    :param benchmarks: Benchmarking configurations.
    :type benchmarks: List of :class:`Benchmark`
    c                    s
   t | ˆ ƒS r#   )r   )rC   ©r€   r   r   r%   O  r&   zperf_report.<locals>.<lambda>r   )r€   Úwrapperr   rž   r   Úperf_reportH  s    r    c                 C   sf   ddl }ddlm} | s tjj} |s.|j ¡ }|j |¡d }|j |¡d }|| d d d	 }|S )
z return DRAM bandwidth in GB/s r   Nr   ©ÚdriverZmem_clock_rateZmem_bus_widthé   g    €„.Aé   )	r/   r   r¢   ÚbackendÚCUDAr*   Úcurrent_deviceÚutilsÚget_device_properties)r¥   rP   r/   r¢   Zmem_clock_khzZ	bus_widthZbw_gbpsr   r   r   Úget_dram_gbpsS  s    
rª   c           
      C   sÔ   dd l }ddlm} |s tjj}|s.|j ¡ }|j |¡d d }|sV|j |¡d }|j 	|¡}|d dk r‚| |j
ks|t‚d}n>| |jkr’d}n.| |j
|jfkr¨d	}n| |jkr¸d
}ntdƒ‚|| | d }	|	S )Nr   r   r¡   Úmultiprocessor_counté   Úsm_clock_rater¤   é   i   i   údtype not supportedç•Ö&è.>)r/   r   r¢   r¥   r¦   r*   r§   r¨   r©   Úget_device_capabilityÚfloat16rR   Úfloat32rc   rT   r6   )
rO   r¥   rP   Ú
clock_rater/   r¢   Únum_subcoresÚ
capabilityÚops_per_sub_coreÚtflopsr   r   r   Úget_max_tensorcore_tflopsb  s,    


r¹   c                     s   ‡ fdd„}|S )Nc                    s   t  ˆ ¡‡‡ fdd„ƒ}|S )Nc            
         sÚ   dd l }| t ¡ ¡ ¡ }ˆ  ¡ | ¡ k}|rÌ|dkrÌtj ˆjd ¡}tj	d ddœ}d|ksht
dƒ‚|d jjj}|› d	ˆj› d
|› d�}tjddd|gd|d�}	|	jdks¸t
dƒ‚dt|	jƒksÖt
‚n
ˆ| |Ž d S )Nr   zcuda-memcheckÚ__file__ÚPATHÚ1)r»   ZPYTORCH_NO_CUDA_MEMORY_CACHINGÚrequestz@memcheck'ed test must have a (possibly unused) `request` fixturez::ú[ú]Zpytestz-vsT)Úcapture_outputÚenvz7cuda-memcheck returned an error: bounds checking failedzERROR SUMMARY: 0 errors)ÚpsutilÚProcessr‹   ÚgetppidÚnameÚitemsr�   ÚrealpathÚ__globals__ÚenvironrR   ÚnodeZcallspecÚidr{   r   r�   Ú
returncodeÚstrr   )
rw   ÚkwargsrÂ   Z	ppid_nameZrun_cuda_memcheckr�   rÁ   Ztest_idr   r   )Útarget_kwargsÚtest_fnr   r   rŸ   „  s    z1cuda_memcheck.<locals>.decorator.<locals>.wrapper)Ú	functoolsÚwraps)rÐ   rŸ   ©rÏ   )rÐ   r   Ú	decoratorƒ  s    z cuda_memcheck.<locals>.decoratorr   )rÏ   rÔ   r   rÓ   r   Úcuda_memcheck‚  s    rÕ   c                 C   sL   d  | ¡} dddd|  dg}t |¡}| tjj¡ d¡}dd„ |D ƒ}|S )	Nr   r   r   r   r	   r
   c                 S   s   g | ]}t |ƒ‘qS r   r   r   r   r   r   r   ¤  s     znvsmi_attr.<locals>.<listcomp>r   r   r   r   r   Ú
nvsmi_attr™  s    
û
rÖ   éF  é¿  c                 c   s  zÎt  dddddg¡ t  dddd| › d	| › �g¡ t  dddd
|› d	|› �g¡ tdgƒd }tdgƒd }t||  ƒdk sŽtd| › d�ƒ‚t|| ƒdk s®td|› d�ƒ‚d|  }d| d }||fV  W 5 t  dddddg¡ t  ddddg¡ t  ddddg¡ X d S )Nr   r   r   z-pmz-rgcz-rmcr¼   z--lock-gpu-clocks=r   z--lock-memory-clocks=zclocks.current.smr   zclocks.current.memoryé
   zGPU SMs must run at z MHzgÞ 3ßÁOÌ?i   gü©ñÒMbP?)r   r   rÖ   ÚabsrR   )Zref_sm_clockZref_mem_clockZcur_sm_clockZcur_mem_clockr¸   Zgbpsr   r   r   Úset_gpu_clock¨  s4    üÿüÿ  rÛ   c           
      C   sÔ   dd l }ddlm} |s tjj}|s.|j ¡ }|j |¡d d }|j |¡d }|j 	¡ }|d dk r’| |j
krxd}qÀ| |jkrˆd	}qÀtd
ƒ‚n.| |j
kr¢d}n| |j|jfkr¸d	}ntd
ƒ‚|| | d }	|	S )Nr   r   r¡   r«   r¬   r­   r¤   é    é@   r¯   r°   )r/   r   r¢   r¥   r¦   r*   r§   r¨   r©   r±   r³   r²   r6   rc   )
rO   r¥   rP   r/   r¢   rµ   r´   r¶   r·   r¸   r   r   r   Úget_max_simd_tflopsÉ  s,    





rÞ   )r"   N)rM   rN   NNTrA   )NNr[   )NN)NNN)r×   rØ   )NN)rÑ   r‹   r   r   Ú
contextlibr   Z_C.libtriton.tritonr   r!   rL   rZ   rj   rk   r   r    rª   r¹   rÕ   rÖ   rÛ   rÞ   r   r   r   r   Ú<module>   s.   	
=    ý
O
%>F

  