U
    <c                     @   s   U d dl Z d dlZd dlZd dlmZ ddgZg Zee ed< ej	dej
dZej	dej
dZeeed	d
dZedddZdddZdd Zdd Zedkre Zeed krd nd dS )    N)List#check_code_for_cuda_kernel_launchescheck_cuda_kernel_launchesexclude_filesz^.*<<<[^>]+>>>\s*\()flagsz/\s*;(?![^;}]*C10_CUDA_KERNEL_LAUNCH_CHECK\(\);))sstartposreturnc                 C   sd   d}t | |d D ]B\}}|dkr.|d7 }q|dkr|d8 }|dkr|| d   S qtddS )zGiven a string "prefix (unknown number of characters) suffix"
    and the position of the first `(` returns the index of the character
    1 past the `)`, accounting for paren nesting
    r   N(   )zClosing parens not found!)	enumerate
IndexError)r   r   Zopeningic r   Q/tmp/pip-unpacked-wheel-gikjz4vx/torch/testing/_internal/check_kernel_launches.pyfind_matching_paren.   s    
r   )r	   c                 C   s   t D ]}| |r dS qdS )NTF)r   endswith)filenameZexclude_suffixr   r   r   should_exclude_file?   s    
r   c                 C   s   |dkrd}t | d} dd | D } d| } d}t| D ]X}t| | d }t| |r@|d7 }| |	 |d  }t
d| d	| tjd
 q@|S )aE  Checks code for CUDA kernel launches without cuda error checks.

    Args:
        filename - Filename of file containing the code. Used only for display
                   purposes, so you can put anything here.
        code     - The code to check

    Returns:
        The number of unsafe kernel launches in the code
    Nz##Python Function Call##
c                 S   s   g | ]\}}| d | qS )z: r   ).0linenoZlinecoder   r   r   
<listcomp>W   s     z7check_code_for_cuda_kernel_launches.<locals>.<listcomp>r   r   z)Missing C10_CUDA_KERNEL_LAUNCH_CHECK in 'z'. Context:
file)r   splitjoinkernel_launch_startfinditerr   end	has_checkmatchstartprintsysstderr)coder   Znum_launches_without_checksmZ	end_parencontextr   r   r   r   F   s    
c              	   C   sP   |  ds|  dsdS t| r$dS t| d}| }t|| }W 5 Q R X |S )zChecks a file for CUDA kernel launches without cuda error checks

    Args:
        filename - File to check

    Returns:
        The number of unsafe kernel launches in the file
    z.cuz.cuhr   r)r   r   openreadr   )r   focontentsZunsafeCountr   r   r   
check_filee   s    	r0   c            
      C   s"  t jt jt} t j| } t j| } d}g }t | D ]v\}}}|t j| dksl|t j| dkrzg |dd< q>|D ]4}t j||}t|}|dkr~||7 }|| q~q>|dkrd| dt	| d}	t
|	tjd t
d	tjd |D ]}t
d
| tjd qt
|	tjd |S )zChecks all pytorch code for CUDA kernel launches without cuda error checks

    Returns:
        The number of unsafe kernel launches in the codebase
    r   buildztorch/includeNzFound z instances in z0 files where kernel launches didn't have checks.r   zFiles without checks:	)ospathdirnamerealpath__file__walkr   r0   appendlenr%   r&   r'   )
Z	torch_dirZkernels_without_checksZfiles_without_checksrootdirnames	filenamesxr   Zfile_resultZ	count_strr   r   r   r   x   s.    $
__main__r   )N)r3   rer&   typingr   __all__r   str__annotations__compile	MULTILINEr   r"   intr   boolr   r   r0   r   __name__Zunsafe_launchesexitr   r   r   r   <module>   s0    
  
)