U
    <cW                     @   s(  d dl Z d dlZd dlZd dlZd dlmZmZ d dlmZm	Z	m
Z
mZmZmZmZmZmZmZmZ d dl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 d dl m!Z!m"Z"m#Z# d d	l$m%Z% d d
l&m'Z'm(Z(m)Z)m*Z* ddl+m,Z,m-Z-m.Z.m/Z/ eddddddgZ0e1eee!e"f  eee# ee ee# f dddZ2e1ee1 ddddZ3e1dddZ4G dd dZ5ddddZ6e5j7e5j8e5j9e5j:e5j;e5j<d d e5j=d d!d"d#d$d%d&d d'd(d)d*d+fe1e1e1e>ee1 e1ee1 e1e1e1ee e>e>e1e>e1e1e1e1e1e1e>e1e1e1e1e1dd,d-d.Z?e@d/kr$e6  dS )0    N)Counter
namedtuple)AnyCallableDictIterableIteratorListOptionalSequenceTupleTypeUnion)	setValueT)BaseCppType)	GenLazyIRGenTSLazyIR)get_grouped_native_functionsparse_native_yaml)NativeFunctionNativeFunctionsGroupOperatorName)SelectiveBuilder)	concatMapFileManagerNamespaceHelper
YamlLoader   )error_on_missing_kernelsgen_dispatcher_registrations"gen_dispatchkey_nativefunc_headersparse_backend_yamlParsedExternalYamlbackend_keyautograd_keycpp_namespacebackend_indicesfull_codegen)backend_yaml_pathgrouped_native_functionsreturnc           
   	   C   s   dd t dd |D }t| d}tj|td}W 5 Q R X t|tsJt|dg }|dg }|d	g }t|t	s|tt|t	stt|t	std
d |D }dd |D }	|||	fS )Nc                 S   s   i | ]}|j j|qS  )funcname).0fr+   r+   </tmp/pip-unpacked-wheel-gikjz4vx/torchgen/gen_lazy_tensor.py
<dictcomp>n   s    z/parse_native_functions_keys.<locals>.<dictcomp>c                 S   s   t | tr| gS t|  S )N)
isinstancer   list	functions)r/   r+   r+   r0   <lambda>q       z-parse_native_functions_keys.<locals>.<lambda>r)Loaderr'   
non_nativeir_genc                 S   s   g | ]}t |qS r+   r   parser.   r-   r+   r+   r0   
<listcomp>   s     z/parse_native_functions_keys.<locals>.<listcomp>c                 S   s   g | ]}t |qS r+   r;   r=   r+   r+   r0   r>      s     )
r   openyamlloadr   r2   dictAssertionErrorpopr3   )
r(   r)   Znative_functions_mapr/   Zyaml_valuesr'   r9   r:   Zfull_codegen_opnamesZir_gen_opnamesr+   r+   r0   parse_native_functions_keysi   s$    rE   )shape_inference_hdrexpected_shape_infr_declsr*   c              	      s   z0t | d}| }t|d W 5 Q R X W n" tk
rR   td|  Y nX d}tt||} fdd|D }|rt	d|  dt
j| d S )	Nr7   
z<Unable to read from the specified shape_inference_hdr file: zcompute_shape_(\w+)c                    s   g | ]}| kr|qS r+   r+   )r.   declZshape_infr_decl_linesr+   r0   r>      s     z3validate_shape_inference_header.<locals>.<listcomp>zGMissing shape inference function.

Please add declare this function in zH:

and implement it in the the corresponding shape_inference.cpp file.

)r?   readsetsplitIOErrorrC   r   refindall	Exceptionoslinesepjoin)rF   rG   r/   Zshape_infr_declsZshape_infr_regexZactual_shape_infr_name_countsZmissing_declsr+   rJ   r0   validate_shape_inference_header   s.    



rU   )r*   c                   C   s   dS )Na!  at::Tensor to_meta(const at::Tensor& tensor) {
  // undefined tensors can't be converted to the meta device, since they don't have sizes/strides
  if (!tensor.defined()) return tensor;
  auto out = at::native::empty_strided_meta_symint(tensor.sym_sizes(), tensor.sym_strides(), /*dtype=*/c10::make_optional(tensor.scalar_type()), /*layout=*/c10::make_optional(tensor.layout()), /*device=*/c10::make_optional(c10::Device(c10::kMeta)), /*pin_memory=*/c10::nullopt);
  // needs to handle wrapped numbers, so dtype promotion works properly.
  if (tensor.unsafeGetTensorImpl()->is_wrapped_number()) {
    out.unsafeGetTensorImpl()->set_wrapped_number(true);
  }
  return out;
}
c10::optional<at::Tensor> to_meta(const c10::optional<at::Tensor>& tensor) {
  if (tensor.has_value()) {
    return to_meta(*tensor);
  }
  return c10::nullopt;
}

std::vector<at::Tensor> to_meta(at::ITensorListRef t_list) {
  std::vector<at::Tensor> outs;
  outs.reserve(t_list.size());
  for (const auto& tensor : t_list) {
    outs.push_back(to_meta(tensor));
  }
  return outs;
}
r+   r+   r+   r+   r0   get_ltc_helper_fns   s    rV   c                   @   sj   e Zd ZU dZeed< dZee ed< dZeed< dZ	eed< d	Z
eed
< eZee ed< dZeed< dS )default_argsNode	node_baseNnode_base_hdr&torch/csrc/lazy/core/shape_inference.hrF   ztorch::lazy::LazyTensortensor_classztorch/csrc/lazy/core/tensor.htensor_class_hdrlazy_ir_generatorZTorchScriptbackend_name)__name__
__module____qualname__rY   str__annotations__rZ   r
   rF   r\   r]   r   r^   r   r_   r+   r+   r+   r0   rW      s   
rW   c                  C   sP  t jdd} | jdddd | jddd	d | jd
tdd	d | jdtd dd | jdddd | jdttjdd | jdttjdd | jdttjdd | jdttj	dd | jdttj
dd | jdttjdd |  }ttjjj }t|d d  d! }tj}|jrt}t||j|j|j|j|j|j|j	|j
|j||j d S )"Nz"Generate Lazy Tensor backend files)descriptionz-sz--source_yamlzApath to source yaml file containing operator external definitions)helpz-oz--output_dirzoutput directoryz	--dry_runF)typedefaultrf   z--impl_pathz9path to the source C++ file containing kernel definitionsz--gen_ts_lowerings
store_truezIGenerate TorchScript lowerings in addition to Lazy IR and NativeFunctions)actionrf   z--node_basez7Name of backend specific custom Lazy IR Node base classz--node_base_hdrz;Path to header file defining custom Lazy IR Node base classz--shape_inference_hdrzBPath to header file defining custom Lazy shape inference functionsz--tensor_classz1Name of backend specific custom Lazy Tensor classz--tensor_class_hdrz5Path to header file defining custom Lazy Tensor classz--backend_namezName of the backend to generateZatensrcZATen)argparseArgumentParseradd_argumentboolrc   rW   rY   rZ   rF   r\   r]   r_   
parse_argspathlibPath__file__parentabsoluter^   Zgen_ts_loweringsr   run_gen_lazy_tensorsource_yaml
output_dirdry_run	impl_path)parseroptionsZ
torch_root	aten_pathr^   r+   r+   r0   main   s    r~   Fztorch::lazyZGetTensorListZ$GetLtcTensorOrCreateForWrappedNumberZTryGetLtcTensorzTORCH_LAZY_FN_COUNTER("lazy::")zLazyTensor::Createz$torch::lazy::CreateAtenFromLtcTensorz$torch::lazy::TupleAtenFromLtcTensorsztorch::lazy::ValueZLazyTensorPtrztorch::lazy::GetBackendDevice)r}   rw   rx   ry   rz   rY   rZ   r\   r]   rF   r^   build_in_treeper_operator_headersr_   gen_forced_fallback_codebackend_namespaceget_tensorlistget_tensor_or_wrap_numbertry_get_tensormetrics_countercreate_tensorcreate_from_first_tensorcreate_aten_from_ltc_tensortuple_aten_from_ltc_tensorslazy_value_classlazy_tensor_ptrget_device_fnr*   c           ,         s  | d}|d }d|d d }tt|| tj| dttdfdd}|}tj| d} tj| d}!t| |!}"|"j	|"j
 }# t|#tttf td	d
d}$t|$dt| }%|%j|%j}&|%j}'|%j
 t|\fttgtt f ttttf  tt tt dddt }(d k	sBt   })|d k	rlt|# |&|)| d k	rt t!"  }*t#|* |)d k	stt$||)|' |&| |&d krΈgn|&gD ]&}+t%||) |+|(|||dd qt&|'|' dd 	
fdd |
  |||'ddfdd |'ddfdd d S )Nz::Z	templates)install_dirr*   c                    s   t |  dS )N)r   template_dirry   )r   )r   )ry   r   r+   r0   make_file_managerG  s
      z.run_gen_lazy_tensor.<locals>.make_file_managerznative/native_functions.yamlznative/tags.yaml)r/   r*   c                 S   s$   t | tr| jjn| j}t|jjS )z
        We sort the native function because of the note in concat_map_codegen.
        TODO(alanwaketan): Remove this sorting hack once all ops are grouped properly.
        )r2   r   Z
functionalr,   rc   r-   )r/   r,   r+   r+   r0   sort_native_functionW  s    z1run_gen_lazy_tensor.<locals>.sort_native_function)key)r,   xsops_listr*   c                 s   sT   |D ]J}t |trt| n|g}|D ]$}|jj|kr(| |D ]
}|V  q@q(qdS )z
        We code-gen for the functional variant, which is all we need for IR classes/lowerings/shape inferences, but we
        only code-gen additional entries for the inplace variant for the native functions.
        N)r2   r   r3   r4   r,   r-   )r,   r   r   xfsr/   r7   r+   r+   r0   concat_map_codegens  s    
z/run_gen_lazy_tensor.<locals>.concat_map_codegenF)r   r   r_   Zeager_registrationzNativeFunctions.cppzDispatchKeyNativeFunctions.cppc                      s   dd ddddddd	d
ddd d d dgrBdgng  D t  djjtt d  
	dS )Nc                 S   s   g | ]}d | dqS z
#include <>r+   r.   pathr+   r+   r0   r>     s   9run_gen_lazy_tensor.<locals>.<lambda>.<locals>.<listcomp>zATen/Functions.hzATen/native/TensorConversions.hzATen/NativeFunctions.hz6ATen/CompositeExplicitAutogradNonFunctionalFunctions.hzATen/MetaFunctions.hzATen/Operators.hzATen/native/CPUFallback.h!torch/csrc/lazy/core/ir_builder.hz*torch/csrc/lazy/core/lazy_graph_executor.hztorch/csrc/lazy/core/metrics.htorch/csrc/lazy/core/shape.h/zNativeFunctions.hz	/LazyIr.hz.torch/csrc/lazy/ts_backend/ts_eager_fallback.h ZNativeFunctions)ZincludesZ
helper_fnsZnative_functions_includenamespace_prologuenamespace_epilogueZnative_function_definitions)rV   prologueepiloguer3   destZGenLazyNativeFuncDefinitionr+   )r&   r#   r   r   r   r   r   r   r   r   r   r)   r   r   	ns_helperrx   rF   r\   r]   r   r   r+   r0   r5     sb    z%run_gen_lazy_tensor.<locals>.<lambda>zLazyIr.hc                      sD   dd dD d k	r"d dgng t   jjdS )Nc                 S   s   g | ]}d | dqS r   r+   r   r+   r+   r0   r>     s   r   )zATen/core/Formatting.hzc10/core/ScalarType.hzc10/util/Optional.hztorch/csrc/lazy/core/hash.htorch/csrc/lazy/core/ir.hr   Zvectorz
#include "")Zlazy_ir_sysincZlazy_ir_incZir_declarationsr   r   )r3   r   r   r+   )r   r'   r)   r:   lazy_ir_objrZ   r   r+   r0   r5     s       zLazyNonNativeIr.hc                      s:   dd ddddgrgng  D t  jjdS )Nc                 S   s   g | ]}|rd | dqS r   r+   r   r+   r+   r0   r>   3  s   r   r   r   z+torch/csrc/lazy/core/internal_ops/ltc_ops.hr[   )Zlazy_non_native_ir_incZnon_native_ir_nodesr   r   )r   Z!generate_non_native_lazy_ir_nodesr   r   r+   )r   rZ   r9   r   r+   r0   r5   2  s      )(rM   rT   r   r   rR   r   rc   r   r   native_functionsr&   r   r   r   r   sortedr!   r#   r$   r%   rE   r   r   r   r	   r   r   r   Zget_nop_selectorrC   Znative_function_class_namer   r3   r   ZGenLazyShapeInferenceDefinitionrU   r    r   r   Zwrite_with_template),r}   rw   rx   ry   rz   rY   rZ   r\   r]   rF   r^   r   r   r_   r   r   r   r   r   r   r   r   r   r   r   r   r   Z	lv_tokensZlv_classZlv_nsr   ZfmZnative_yaml_pathZtags_yaml_pathZparsed_yamlr   r   Zparsed_backend_yamlr$   r%   selector
class_namerG   Zdispatch_keyr+   )r&   r#   r   r   r   r   r   ry   r'   r   r   r   r   r)   r:   r   r   r   rZ   r9   r   rx   rF   r   r\   r]   r   r   r0   rv     s    "

    


 	

2:  rv   __main__)Arl   rR   rq   rO   collectionsr   r   typingr   r   r   r   r   r	   r
   r   r   r   r   r@   Ztorchgen.destr   Ztorchgen.api.lazyr   Ztorchgen.api.typesr   Ztorchgen.dest.lazy_irr   r   Ztorchgen.genr   r   Ztorchgen.modelr   r   r   Z!torchgen.selective_build.selectorr   Ztorchgen.utilsr   r   r   r   Zgen_backend_stubsr   r   r    r!   r"   rc   rE   rU   rV   rW   r~   rY   rZ   r\   r]   rF   r^   r_   ro   rv   r`   r+   r+   r+   r0   <module>   s   4C  
W  *
