U
    yÊ¹jÉ  ã                	   @   sî  d dl mZ d dlmZ d dlmZmZ d dlmZ dd„ Z	G dd„ de
ƒZeG d	d
„ d
ƒƒZG dd„ dƒZdd„ Zeee edœdd„Zeee edœdd„ZdZedk�rêd dlmZ eed�Zejdddd� ejddedd� ejd ed!d"d#� e ¡ Zeƒ Zg ZejD ],ZeeƒZe ¡ Ze  ej!¡ e "e¡ �qd$d%„ ej# $¡ D ƒZ%ej& 'd&¡ (d'¡�Z)e) *d(d) +e%¡ ¡ W 5 Q R X d*d%„ ej# $¡ D ƒZ,ej& 'd+¡ (d'¡�:Z)d!Z&e&d(7 Z&e&d,7 Z&e&d)7 Z&e&d) +e,¡7 Z&e) *e&¡ W 5 Q R X d-S ).é    )Údefaultdict)ÚPath)ÚSequenceÚUnion)Ú	dataclassc                 C   s   | d k	S ©N© )Úxr   r   úP/var/www/html/bwave/python/venv/lib/python3.8/site-packages/triton/tools/link.pyÚ_exists   s    r   c                   @   s   e Zd ZdS )ÚLinkerErrorN)Ú__name__Ú
__module__Ú__qualname__r   r   r   r
   r      s   r   c                   @   sR   e Zd ZU ee ed< ee ed< eeedf  ed< eed< eed< eed< dS )ÚKernelLinkerMetaÚ	arg_namesÚ
arg_ctypesNÚsizesÚsig_hashÚsuffixÚ	num_specs)r   r   r   r   ÚstrÚ__annotations__r   Úintr   r   r   r
   r      s   
r   c                   @   sb   e Zd Zddœdd„Zedœdd„Zedœd	d
„Zedœdd„Zedœdd„Zee	dœdd„Z
dS )ÚHeaderParserN)Úreturnc                 C   sF   dd l }| d¡| _| d¡| _| d¡| _| d¡| _ttƒ| _d S )Nr   z"//[\s]*tt-linker:[\s]*([\w]+):(.+)z^([\w]+)_([\w]+)_([\w]+)$z([0-9]+)([c,d])z[\s]*(\w+)\s(\w+)[,]?)	ÚreÚcompileÚlinker_directivesÚkernel_nameÚkernel_suffixÚc_sigr   ÚlistÚkernels)Úselfr   r   r   r
   Ú__init__   s    zHeaderParser.__init__)Úheaderc                 C   sŽ   |  ¡ D ]€}| d¡r| j |¡}t|ƒr| d¡| d¡ }}|  |¡\}}}|  |¡\}	}
|  |¡\}}|  	|t
|
|	||||d�¡ qd S )Nz//é   é   )r   r   r   r   r   r   )Ú
splitlinesÚ
startswithr   Úmatchr   ÚgroupÚ_match_nameÚ_match_c_sigÚ_match_suffixÚ_add_kernelr   )r$   r&   ÚlnÚmÚker_namer!   Únamer   r   Zc_typesr   r   r   r   r   r
   Úextract_linker_meta*   s&    
úþz HeaderParser.extract_linker_meta)r3   c                 C   sR   | j  |¡}t|ƒr@| d¡| d¡| d¡  }}}|||fS t|› d�ƒ‚d S )Nr'   r(   é   z is not a valid kernel name)r   r+   r   r,   r   )r$   r3   r2   r4   r   r   r   r   r
   r-   @   s
    "
zHeaderParser._match_name)r!   c                 C   sZ   | j  |¡}t|ƒrHg g  }}|D ]\}}| |¡ | |¡ q"||fS t|› d�ƒ‚d S )Nz" is not a valid argument signature)r!   ÚfindallÚlenÚappendr   )r$   r!   r2   ZtysÚargsÚtyZarg_namer   r   r
   r.   G   s    

zHeaderParser._match_c_sig)r   c                 C   sx   | j  |¡}t|ƒs"t|› d�ƒ‚g }t|ƒ}dddœ}|D ]2\}}t|ƒt|ƒk r`| d ¡ qD| || ¡ q<||fS )Nz is not a valid kernel suffixr'   é   )ÚcÚd)r    r7   r8   r   r   r9   )r$   r   r2   r   r   Zs2iZargnumZarg_size_annr   r   r
   r/   R   s    
zHeaderParser._match_suffix)r4   Úkerc              
   C   sv   || j krb| j | d }t|j|jƒD ]:\}}||kr&td|› dd |j¡› dd |j¡› �ƒ‚q&| j |  |¡ d S )Néÿÿÿÿz Mismatched signature for kernel z: 
	existing sig is: ú,z
	current is: )r#   Úzipr   r   Újoinr9   )r$   r4   r?   ÚlastÚcurZnew_r   r   r
   r0   `   s    
$ÿzHeaderParser._add_kernel)r   r   r   r%   r   r5   r-   r.   r/   r   r0   r   r   r   r
   r      s   r   c                 C   s   d  dd„ t| j| jƒD ƒ¡S )Nú, c                 S   s   g | ]\}}|› d |› �‘qS )ú r   )Ú.0r;   Úargr   r   r
   Ú
<listcomp>n   s     z!gen_signature.<locals>.<listcomp>)rC   rB   r   r   ©r2   r   r   r
   Úgen_signaturem   s    rL   )r4   Úmetasr   c              	   C   s&   d| › dt |d ƒ› d| › d| › d�	S )Nz

CUresult úE(CUstream stream, unsigned int gX, unsigned int gY, unsigned int gZ, r@   z);
void load_z();
void unload_z();
    )rL   )r4   rM   r   r   r
   Ú
make_declsq   s    ÿ
ÿÿÿrO   c                    sÈ  d| › d�}t |dd„ d�D ].}|d| › d|j› d|j› dt|ƒ› d	�	7 }q|d7 }|d| › dt|d
 ƒ› d�7 }|d7 }t |dd„ d�D ]l}dd„ ‰ d ‡ fdd„t|j|jƒD ƒ¡}|d|› d�7 }|d| › d|j› d|j› dd |j¡› d	�	7 }qŠ|d7 }dD ]¾}|d|› d| › d�7 }t |dd„ d�D ],}|d|› d| › d|j› d|j› d�	7 }�q.|d|› d| › d�7 }|d7 }t |dd„ d�D ],}|d|› d| › d|j› d|j› d�	7 }�qŠ|d7 }�q|S ) Nz// launcher for: Ú
c                 S   s   | j  S r   ©r   rK   r   r   r
   Ú<lambda>{   ó    z(make_kernel_dispatcher.<locals>.<lambda>)Úkeyz	CUresult Ú_rN   z);
r@   z){c                 S   s   | j  S r   rQ   rK   r   r   r
   rR   �   rS   c                 S   s8   |dkrd| › d|› d�S |dkr4d| › d|› d�S d S )Nr<   ú(z % z == 0)r'   z == ú)r   )ÚvalÚhintr   r   r
   rR   ‚   rS   z && c                    s"   g | ]\}}|d k	rˆ ||ƒ‘qS r   r   )rH   rX   rY   ©Zcond_fnr   r
   rJ   ƒ   s      z*make_kernel_dispatcher.<locals>.<listcomp>z  if (z)
z    return z(stream, gX, gY, gZ, rF   z}
)ÚloadZunloadz
// z for: c                 S   s   | j  S r   rQ   rK   r   r   r
   rR   Š   rS   zvoid z();
z() {c                 S   s   | j  S r   rQ   rK   r   r   r
   rR   Ž   rS   z  )Úsortedr   r   rL   rC   rB   r   r   )r4   rM   ÚsrcÚmetaZcondsÚmoder   rZ   r
   Úmake_kernel_dispatchery   s,    ,"0**r`   a0  
Triton ahead-of-time linker:

This program takes in header files generated by compile.py, and generates a
single entry-point responsible for dispatching the user's input to the right
kernel given the specializations that were compiled.

Example usage:
python link.py /path/to/headers/*.h -o kernel_name
Ú__main__)ÚArgumentParser)ÚdescriptionÚheadersú+z_Paths to header files to link. Must include linker directive annotations (autogenerated by ttc))ÚnargsÚhelpz--outz-ozOut filename)Útyperg   z--prefixÚ z(String to prefix kernel dispatcher names)rh   Údefaultrg   c                 C   s   g | ]\}}t ||ƒ‘qS r   )rO   ©rH   r4   r^   r   r   r
   rJ   ¶   s     rJ   z.hÚwz#include <cuda.h>
rP   c                 C   s   g | ]\}}t ||ƒ‘qS r   )r`   rk   r   r   r
   rJ   »   s     z.cz#include <stdint.h>
N)-Úcollectionsr   Úpathlibr   Útypingr   r   Údataclassesr   r   Ú	Exceptionr   r   r   rL   r   rO   r`   Údescr   Úargparserb   ÚparserÚadd_argumentÚ
parse_argsr:   Zincludesrd   r&   Zh_pathÚ	read_textZh_strr9   r4   r5   r#   ÚitemsZdeclsÚoutÚwith_suffixÚopenÚfpÚwriterC   Zdefsr   r   r   r
   Ú<module>   sR   
R

ý
