a
    hW                     @  s  d dl mZ d dlZd dlZd dlZd dlmZmZmZ d dl	m
Z
 d dlmZ d dlZd dlm  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mZ d d
lmZmZmZm Z m!Z!m"Z" d dl#m$Z$ d dl%m&Z&m'Z'm(Z(m)Z)m*Z* d dl+m,Z, erd dl-m.Z. edg dZ/dddddddZ0d3dddddddddddZ1ddd d!Z2d4d#ddddddddd$	d%d&Z3d5d#ddddddd)d*d*dd*dd+d,d-Z4d6ddd*d.dd/d0d1Z5e6d2kre2  dS )7    )annotationsN)Counterdefaultdict
namedtuple)Path)TYPE_CHECKING)DispatcherSignature)CodeTemplate)native_function_manager)get_grouped_native_functionsparse_native_yaml)BackendIndexBackendMetadataDispatchKeyNativeFunctionNativeFunctionsGroupOperatorName)SelectiveBuilder)	concatMapcontextFileManagerNamespaceHelperTarget)
YamlLoader)SequenceParsedExternalYaml)backend_keyautograd_key
class_namecpp_namespacebackend_indicesstrz/Sequence[NativeFunction | NativeFunctionsGroup]zdict[DispatchKey, BackendIndex])backend_yaml_pathgrouped_native_functionsr    returnc                   sL  dd t dd |D t| }tj|td}W d    n1 sD0    Y  t|ts\J g d}|dd d usJ d|d	d }|d
d d usJ d|dd}t|tsJ d| |dd}t|tsJ d| |dg }	|	d u r
g }	t|	t	s0J d|	 dt
|	 d|dg }
|
d u rJg }
t|
t	spJ d|	 dt
|	 dt|
}|dg }t|t	sJ d| |dg }|	| |di  |di  t| dksJ |  dd|  dd| d d!d"d#d#d$d%fd&d'}d t|	dkrtfd(d tW d    n1 sh0    Y  ||	|||d)}vsJ |< d  t|dkrtfd*d  td+  W d    n1 s0    Y  ||| ||d)} vsJ | < |D ]}t|tr~d u r:g nd,d-  |fD } d u rbg nd.d-   |fD }n`d u rg n d/d- fd0d-| D D } d u rg n d1d-  fd2d-| D D }d3d- |D }d4d- |D }t|dkst|dksJ d5|d j d6|d j d7qt |S )8Nc                 S  s   i | ]}|j j|qS  )funcname.0fr%   r%   H/var/www/auris/lib/python3.9/site-packages/torchgen/gen_backend_stubs.py
<dictcomp>0   s   z&parse_backend_yaml.<locals>.<dictcomp>c                 S  s   t | tr| gS t|  S N)
isinstancer   list	functionsr*   r%   r%   r+   <lambda>3       z$parse_backend_yaml.<locals>.<lambda>)Loader)
backendr   r   extra_headers	supportedautogradfull_codegen
non_nativeir_gensymintr5   z&You must provide a value for "backend"r   r   z,You must provide a value for "cpp_namespace"use_out_as_primaryFzHYou must provide either True or False for use_out_as_primary. Provided: device_guardzBYou must provide either True or False for device_guard. Provided: r7   z,expected "supported" to be a list, but got: z
 (of type )r<   z)expected "symint" to be a list, but got: r8   z+expected "autograd" to be a list, but got: r9   r:   r;   r   z contains unexpected keys: z, z). Only the following keys are supported: z	list[str]zset[str]r   boolr   )backend_ops
symint_opsdispatch_keyr=   use_device_guardr$   c          
        sv   i }| D ]Z}t |}|v s,J d| t| j}||v rL|d7 }t|d d}	|	||< qt||d||dS )Nz Found an invalid operator name: Z_symintF)kernelZ
structuredr   T)rC   r=   Zexternalr>   index)r   parse
dispatcherr'   r&   r   r   )
rA   rB   rC   r=   rD   metadataopop_nameZkernel_namem)r   native_functions_mapr%   r+   create_backend_index   s(    


z0parse_backend_yaml.<locals>.create_backend_indexc                     s   d  dS )NzFThe provided value for "backend" must be a valid DispatchKey, but got .r%   r%   r5   r%   r+   r2      r3   )r=   rD   c                     s   d  dS )NzThe "autograd" key was specified, which indicates that you would like to override the behavior of autograd for some operators on your backend. However "Autogradz" is not a valid DispatchKey.r%   r%   rP   r%   r+   r2      s   ZAutogradc                 S  s   g | ]}|d ur|qS r-   r%   r)   rL   r%   r%   r+   
<listcomp>   s   z&parse_backend_yaml.<locals>.<listcomp>c                 S  s   g | ]}|d ur|qS r-   r%   rQ   r%   r%   r+   rR      s   c                 S  s   g | ]}|d ur|qS r-   r%   rQ   r%   r%   r+   rR      s   c                   s   g | ]}   |qS r%   
get_kernelr(   )r    r   r%   r+   rR      s   c                 S  s   g | ]}|d ur|qS r-   r%   rQ   r%   r%   r+   rR      s   c                   s   g | ]}   |qS r%   rS   r(   )r   r    r%   r+   rR      s   c                 S  s   g | ]}|d ur|qS r-   r%   r(   r%   r%   r+   rR      r3   c                 S  s   g | ]}|d ur|qS r-   r%   r(   r%   r%   r+   rR      r3   zCurrently, all variants of an op must either be registered to a backend key, or to a backend's autograd key. They cannot be mix and matched. If this is something you need, feel free to create an issue! z" is listed under "supported", but z is listed under "autograd".)r   openyamlloadr   r.   dictpopr@   r/   typesetextendlenkeysjoinr   r   rG   r   rT   r0   rE   r   )r"   r#   r    r*   Zyaml_valuesZ
valid_keysr   r=   rD   r7   r<   Z
symint_setZsupported_autogradr9   rN   Zbackend_idxZautograd_idxgZforward_kernelsZbackward_kernelsr%   )r   r5   r    r   r   rM   r+   parse_backend_yaml+   s    
,



*
0

ra   zSequence[NativeFunction]r   zDispatchKey | Nonezlist[OperatorName] | NoneNone)native_functionsr    r   r   r   kernel_defn_file_pathr9   r$   c                   s  z4t |}| }W d    n1 s(0    Y  W n4 tyh }	 ztd| |	W Y d }	~	n
d }	~	0 0 d u rvg || jg|d u rg n
|| jg }
tttdd |
fdd| D }tt}|D ]}||j	j
  | qd| d}tdd t||D }d	}| D ]t\}}t|}|| }||krd
dddd d fdd|D }|d| d| d| d| d| d7 }q|d	ksJ |d S )Nz2Unable to read from the specified impl_path file: c                 S  s   dd |   D S )Nc                 S  s   g | ]\}}||j fqS r%   )rE   )r)   rK   rI   r%   r%   r+   rR     s   z>error_on_missing_kernels.<locals>.<lambda>.<locals>.<listcomp>)items)rF   r%   r%   r+   r2     s   z*error_on_missing_kernels.<locals>.<lambda>c                   s,   g | ]$}|j j  v r|j jvr|qS r%   )r&   r'   r^   r(   )expected_backend_op_namesr9   r%   r+   rR     s   z,error_on_missing_kernels.<locals>.<listcomp>z(.*)z::\s*([\w\d]*)\(c                 S  s   g | ]\}}| d s|qS ):)endswith)r)   xyr%   r%   r+   rR   6  s   
 r   r!   )r*   r$   c                 S  s<   t |   t| j W  d    S 1 s.0    Y  d S r-   )r
   r   Zfrom_schemar&   declr1   r%   r%   r+   create_declC  s    
z-error_on_missing_kernels.<locals>.create_decl
c                   s   g | ]} |qS r%   r%   r(   )rm   r%   r+   rR   G  r3   z$ is missing a kernel definition for z. We found z( kernel(s) with that name,
but expected zH kernel(s). The expected function schemas for the missing operator are:
z

)rU   readOSErrorAssertionErrorrF   rX   r/   r   r   r&   r'   appendr   refindallre   r]   r_   )rc   r    r   r   r   rd   r9   r*   Zbackend_defnseindicesZexpected_backend_native_funcsZ#expected_backend_kernel_name_countsZnative_fZkernel_defn_regexZ!actual_backend_kernel_name_countsZmissing_kernels_err_msgZexpected_namefuncsZexpected_overload_countZactual_overload_countZexpected_schemas_strr%   )rm   rf   r9   r+   error_on_missing_kernels   sv    	
*




rx   )r$   c                  C  sz   t jdd} | jddddd | jdd	d
dd | jddtddd | jddtd dd |  }t|j|j|j	|j
 d S )NzGenerate backend stub files)descriptionz-sz--source-yamlz--source_yamlzApath to source yaml file containing operator external definitions)helpz-oz--output-dirz--output_dirzoutput directoryz	--dry-runz	--dry_runF)rZ   defaultrz   z--impl-pathz--impl_pathz9path to the source C++ file containing kernel definitions)argparseArgumentParseradd_argumentr@   r!   
parse_argsrunsource_yaml
output_dirdry_run	impl_path)parseroptionsr%   r%   r+   mainQ  s(    
r   rk   r   )	fmr   r   r    r#   backend_dispatch_keyautograd_dispatch_keybackend_namer$   c                   s|   d usJ dt ttfdd|t ttfdd| t||  dd fdd d S )NzAAutogenerated file by gen_backend_stubs.py. Do not edit directly!c                   s   t |   S r-   destZ#compute_native_function_declarationr1   )r   r    r%   r+   r2   ~  s   z4gen_dispatchkey_nativefunc_headers.<locals>.<lambda>c                   s    d u rg S t |   S r-   r   r1   )r   r    r%   r+   r2     s
    NativeFunctions.hzDispatchKeyNativeFunctions.hc                     s   j j  dS )N)generated_commentZnamespace_prologuer   Znamespace_epilogueZdispatch_declarationsZBackendNamer   )prologueepiloguer%   )autograd_declarationsbackend_declarationsr   r   r   r   	ns_helperr%   r+   r2     s    )sortedr[   r   r   write_with_template)r   r   r   r    r#   r   r   r   r%   )	r   r   r   r   r    r   r   r   r   r+   "gen_dispatchkey_nativefunc_headersi  s2    

r   FTr   r@   )r   r   r   r    r#   r   rC   selectorbuild_in_treeper_operator_headersr   eager_registrationr$   c                   s   | d| dg}|r,d dd |D nd dd |D d usLJ |  tttj tj
dd dd	}dtd
ddd|rtd}|j	|dntd}|j	|
|d
d dd 	
fdd d S )N/r   rn   c                 s  s   | ]}d | dV  qdS )z
#include <>Nr%   r)   hr%   r%   r+   	<genexpr>  r3   z/gen_dispatcher_registrations.<locals>.<genexpr>c                 s  s   | ]}d | dV  qdS )z
#include ""Nr%   r   r%   r%   r+   r     r3   FTrocmr<   Zclass_method_nameZskip_dispatcher_op_registrationat)Znamespace_strrk   zOTORCH_LIBRARY_IMPL(aten, $dispatch_key, m) {
    $dispatch_registrations_body
})rC   dispatch_registrations_bodyzTORCH_API void Register${backend_name}${dispatch_key}NativeFunctions();
TORCH_API void Register${backend_name}${dispatch_key}NativeFunctions() {
    static auto m = MAKE_TORCH_LIBRARY_IMPL(aten, $dispatch_key);
    $dispatch_registrations_body
})r   rC   r   ZRegisterz.cppzRegisterDispatchKey.cppc                     sX   d	sdnd  tj 	ddt d 
fdddS )	Nrk   z#include <ATen/Functions.h>F)r   r   zRegisterDispatchDefinitions.inic                     s>   j j dtttj tjdd dddS )Nrk   FTr   )Zns_prologueZns_epilogue"static_init_dispatch_registrationsdeferred_dispatch_registrationsdispatch_namespaceZdispatch_namespaced_definitionsZdispatch_anonymous_definitions)	r   r   lowerr/   r   r   RegisterDispatchKeyr   ZANONYMOUS_DEFINITIONr%   )backend_indexr   r   rC   r#   r   r   r   r%   r+   r2     s*    	z@gen_dispatcher_registrations.<locals>.<lambda>.<locals>.<lambda>)Zextra_cuda_headersZexternal_backend_headersZops_headersr   r   Zdispatch_headersZdispatch_helpersZdispatch_definitions)r   r   Zgen_registration_headersZgen_registration_helpersZsubstitute_with_templatesplitr%   r   r   r   rC   Zexternal_backend_headers_strr   r#   newliner   r   r   r   r%   r+   r2     s$    z.gen_dispatcher_registrations.<locals>.<lambda>)r_   r/   r   r   r   r   ZREGISTRATIONr   r	   
substituter   )r   r   r   r    r#   r   rC   r   r   r   r   r   headersr   Zstatic_templateZdeferred_templater%   r   r+   gen_dispatcher_registrations  s\    	

 r   z
str | None)r   r   r   r   r$   c              
     s>  t t jj}tj|dddd fdd}||}tj|d}tj|d}t||}	|	j|	j	 }
}t
|
}t| ||}|j}|j}|j}|j}|j	}t }|d u rd S |d u r||  }|d usJ |d urt|
||||| t||||||| |d u r|gn||gD ]}t|||||||| qd S )	Nzaten/src/ATen/templatesr!   r   )install_dirr$   c                   s   t |  dS )N)r   template_dirr   )r   )r   r   r   r%   r+   make_file_manager  s    zrun.<locals>.make_file_managerz*aten/src/ATen/native/native_functions.yamlzaten/src/ATen/native/tags.yaml)r   __file__absoluteparentospathr_   r   rc   r    r   ra   r   r   r   r   r   Zget_nop_selectorZnative_function_class_namerx   r   r   )r   r   r   r   Zpytorch_rootr   r   Znative_yaml_pathZtags_yaml_pathZparsed_yamlrc   r    r#   Zparsed_backend_yamlr   r   r   r   r   rC   r%   r   r+   r     sr    
	r   __main__)N)rk   )FFrk   T)N)7
__future__r   r|   r   rs   collectionsr   r   r   pathlibr   typingr   rV   Ztorchgen.api.dispatcherapirH   Ztorchgen.destr   Ztorchgen.api.typesr   Ztorchgen.code_templater	   Ztorchgen.contextr
   Ztorchgen.genr   r   Ztorchgen.modelr   r   r   r   r   r   Z!torchgen.selective_build.selectorr   Ztorchgen.utilsr   r   r   r   r   Ztorchgen.yaml_utilsr   collections.abcr   r   ra   rx   r   r   r   r   __name__r%   r%   r%   r+   <module>   sN     Y U   C    (s R
