a
    h>q                     @  s  d dl 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
  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mZmZmZ d d	lmZ d d
l m!Z! d dl"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+ dddddZ,dddddZ-dddddddZ.dddddZ/dddddZ0ed d!G d"d# d#eZ1ed d!G d$d% d%e1Z2ed d!G d&d' d'Z3G d(d) d)Z4ed d!G d*d+ d+Z5d,d#d-d.d/d0Z6dS )1    )annotationsN)ABC)	dataclass)Any)	getValueTisValueTypeLazyArgumentLazyIrPropertiesLazyIrSchematensorListValueT)	translate)	BaseCTypeBindingdeviceTDispatcherSignaturekernel_signatureNativeSignatureOptionalCTypeVectorCType)method_with_native_function)ts_lowering_body)	ArgumentBackendIndexBackendMetadataBaseTyBaseTypeFunctionSchemaListTypeNativeFunctionNativeFunctionsGroupr   str)argreturnc                 C  s  t | jrt| jtrd| jr(d| j S | jjtu rBd| j dS | jrVd| j dS d| j dS t| jt	r| jr| j d| j dS | jrd| j S d| j d	| j d
S t
d| j dnt| jtr| jjttjkr| j rd| j dS d| j d| j dS nt| jtrVt| jjtrVd| jjj d| j d| j dS t| jt	rt| jjtrt| jjjtrd| jjjj d| j dS | j S dS )z
    Given a LazyArgument,
    generate a c++ string for materializing an rvalue of that arg for passing into
    a lazy Node constructor.
    Znode_lazy_Z_tensorlistzGetSymIntValue()z->GetIrValue()z& ? std::make_optional(GetSymIntValue(*z)) : ::std::nulloptz ? std::make_optional(lazy_z ->GetIrValue()) : ::std::nullopt=TODO not sure if there are other valid types to handle here (zGetSymIntArrayRefValue(zstd::vector<int64_t>(z
.begin(), z.end())std::vector<>(ztorch::lazy::ToOptionalVector<N)r   	lazy_type
isinstancer   is_wrapped_scalarnametyper   is_symint_or_listr   AssertionError	orig_typer   elemr   r   ZSymIntsymintr   )r!    r2   C/var/www/auris/lib/python3.9/site-packages/torchgen/dest/lazy_ir.pynode_ctor_arg_rvalue_string+   sN    

"
r4   r
   schemar"   c                 C  s   dd |   D }d|S )zg
    Produce a formatted string with the arguments as passed into the constructor of a node class.
    c                 S  s   g | ]}t |qS r2   )r4   .0r!   r2   r2   r3   
<listcomp>j   s   z$node_ctor_inputs.<locals>.<listcomp>, )filtered_argsjoin)r6   Znode_ctor_valuesr2   r2   r3   node_ctor_inputsf   s    r=   %DispatcherSignature | NativeSignature)r6   sigoverload_namer"   c                 C  sz   t | j}t| | }ddd |D }t|rPd| j d| d}nd| j d}dt|  d	| d
| dS )zK
    Generate code that falls back to eager conditioned on a predicate
    z,
                c                 S  s   g | ]
}|j qS r2   exprr8   ar2   r2   r3   r9   z       z%gen_fallback_code.<locals>.<listcomp>z	ATEN_OP2(r:   r$   zATEN_OP(z"
        if (force_eager_fallback(zQ)) {
            return at::native::call_fallback_fn_symint<&ltc_eager_fallback, z>::call(
                z
            );
        }
)	r   from_schemafuncr   	argumentsr<   len	aten_nameaten_symbol)r6   r?   r@   dispatcher_sigexprsZfallback_argsZaten_op_strr2   r2   r3   gen_fallback_codep   s    rN   c                 C  s@   dh}| j |v rd| j  dS | j ds6d| j  S | j S d S )NZsigmoid_backwardz#c10::Symbol::fromQualString("aten::z")zat::z
at::aten::)rJ   
startswith)r6   Zmissing_interned_stringsr2   r2   r3   rK      s    
rK   r   ztuple[str, list[Binding]])r?   r"   c                 C  s   g }g }|   D ]^}t|jtrd|jj rd|j d}|d| d|j d ||| q|| qd	|}||fS )NZ_metazauto z = to_meta();	
        )
rH   r)   argumentr   r,   Zis_tensor_liker+   append	with_namer<   )r?   contextZunwrapped_tensor_argsr!   Zunwrapped_nameZunwrap_tensor_args_strr2   r2   r3   convert_to_meta_tensors   s    
rV   T)frozenc                   @  s   e Zd ZU ded< ded< ded< ded< edd	d
ddZdddddZddddddZddddddZdddddZ	dd	dddZ
dS )	GenLazyIRr   backend_indexr    backend_name	node_basebooluse_lazy_shapez%NativeFunctionsGroup | NativeFunction	list[str]fr"   c                 C  sV   t |tr|jjn|j}| jt |tr.|jn|}t||d uoF| d}| |S )Nr1   )	r)   r   Z
functionalrG   rY   
get_kernelr
   supports_symintgen)selfr`   rG   metadatar6   r2   r2   r3   __call__   s    zGenLazyIR.__call__r
   r5   c                 C  s   dS N r2   )re   r6   r2   r2   r3   lowering_function   s    zGenLazyIR.lowering_functionr6   node_ctor_argsr"   c                 C  s   dS rh   r2   re   r6   rl   r2   r2   r3   create_function   s    zGenLazyIR.create_functionc                 C  s   d| dS )Nbool CanBeReused(z!) const {
    return false;
    }r2   rm   r2   r2   r3   can_be_reused_function   s    z GenLazyIR.can_be_reused_functionc           
      C  st  |j ddd}g }|D ]V}t|jttfr:||j  qt|jtrZ||j d qtd|j dqd	|}|j ddd}|j
jrd}n|j
jrd	d
 |D }|dd |D  d|j dd	| d}nT|j
jr*dd
 tt|D }|dd |D  d|j dd	| d}nd}d	dd |D }	| j d|j d| d| dt|j d|	 dS )NTFvaluesZscalars.value_or(kNullValue)zUnsupported type (z) - add support if necessaryr:   zstd::move(shapes),c                 S  s   g | ]
}|j qS r2   r+   rC   r2   r2   r3   r9      rE   z1GenLazyIR.node_base_ctor_call.<locals>.<listcomp>c                 s  s   | ]}|j V  qd S Nrt   rC   r2   r2   r3   	<genexpr>   rE   z0GenLazyIR.node_base_ctor_call.<locals>.<genexpr>Zcompute_shape_(z),c                 S  s   g | ]}d | dqS )zoperand(r$   r2   r8   ir2   r2   r3   r9      rE   c                 s  s   | ]}|j V  qd S ru   rt   rC   r2   r2   r3   rv      rE   z[&](){ return compute_shape_z)[0]; },ri   c                 s  s   | ]}|j  V  qd S ru   rt   rC   r2   r2   r3   rv      rE   z(
              z&::ClassOpKind(),
              OpList{z},
              z!
              /* num_outputs */ z#,
              torch::lazy::MHash()))r;   r)   r(   r   r   rS   r+   r   r.   r<   
propertiesShapePrecomputeZShapeComputeextend
ShapeCacherangerI   r[   	node_namereturns)
re   r6   
value_argsZbase_ctor_value_args_listr!   Zbase_ctor_value_argsscalar_argsZshape_ctor_argZ
shape_argsZscalar_hashesr2   r2   r3   node_base_ctor_call   sF    

zGenLazyIR.node_base_ctor_callc                 C  s  |j pt|}| }|jddd}dd |D }d|}| jrT|jjrT|d d|}dd	d |D }t|rd| }d
dd |D }	dd |jdddD }
d
dd |
D }ddd |
D }g }|D ]r}t	|j
tr6|j d}|jr
d}|d|j d|j d| d|j d	 q|d|j d|j d qd|}d|j d| j d| d|j d| d| | | d| d | j d!| d"| || d#| || d#| | d#|	 d
| d$gS )%NFTrq   c                 S  s$   g | ]}d |j   d|j qS )zconst z& r(   Zcpp_typer+   rx   r2   r2   r3   r9      rE   z!GenLazyIR.gen.<locals>.<listcomp>r:   z(std::vector<torch::lazy::Shape>&& shapesz
,
        c                 S  sJ   g | ]B}|j  d kr2|j d|j d|j dn|j d|j dqS )!::std::optional<c10::string_view>rw   z1.has_value() ? ::std::make_optional(std::string(*z)) : ::std::nullopt)r$   r   rC   r2   r2   r3   r9      s   z
  c                 S  s\   g | ]T}|j  d kr$d|j dn2|j  dkr@d|j dn|j   d|j dqS )zc10::string_viewzstd::string ;r   z::std::optional<std::string>  r   rC   r2   r2   r3   r9     s   c                 S  s   g | ]}t |jtr|jqS r2   )r)   r(   r   r+   r7   r2   r2   r3   r9     s   c                 S  s   g | ]}d | dqS )z	bool has_z: 1;r2   r8   valuer2   r2   r3   r9     rE   z
    c                 S  s   g | ]}d | d| dqS )Zhas_z = !!r   r2   r   r2   r2   r3   r9     rE   z.value()z"torch.Generator()"zif (z.has_value()) {
      ss << ", z=" << z;
    } else {
      ss << ", z=null";
    }z	ss << ", r   zclass z
 : public zX {
 public:
  static torch::lazy::OpKind ClassOpKind() {
    return torch::lazy::OpKind(z
);
  }

  rw   z
)
      : z	
  {
    zT
  }

  std::string ToString() const override {
    std::stringstream ss;
    ss << z::ToString();
    z
    return ss.str();
  }

  z

  z

};

)opkindrK   r;   r<   r]   r{   r|   rS   rI   r)   r(   r   r+   Zis_generatorr   r[   r   rn   rp   rj   )re   r6   r   all_argsr   Z	ctor_argsZreuse_ctor_argsrl   Zscalar_initializersZscalar_declsZoptional_valuesZhas_optional_declsZhas_optional_defsZmembers_to_stringr!   r   Zmembers_to_string_strr2   r2   r3   rd      s    


	





zGenLazyIR.genN)__name__
__module____qualname____annotations__r   rg   rj   rn   rp   r   rd   r2   r2   r2   r3   rX      s   
*rX   c                   @  s@   e Zd ZdddddZddddddZddddd	d
ZdS )GenTSLazyIRr
   r    r5   c                 C  s:   d}|j jr| dS |j jr2| dt| dS dS d S )Nz
  torch::lazy::TSOpVector Lower(
      std::shared_ptr<torch::jit::GraphFunction> function,
      torch::lazy::TSLoweringContext* loctx) const overrider   z {
    z
  }
            ri   )r{   LowerDeclOnlyZLowerr   )re   r6   	signaturer2   r2   r3   rj   V  s    
zGenTSLazyIR.lowering_functionrk   c                 C  s<   d| d}|j jr| dS |j js*dS | d|j dS )Nzstatic NodePtr Create(r$   r   ri   z {
    return ReuseOrMakeNode<z>(data);
  })r{   ZCreateFnDeclOnlyZCreateFnr   )re   r6   rl   r   r2   r2   r3   rn   f  s    
zGenTSLazyIR.create_functionc                 C  s  d| d}|j jr| dS |j js*dS g }t|j|jD ]8}t|jt	rd|
d|j d q>|
d|j  q>t|j|jD ]h}t|jt	r|
d|j d	|j d
|j d|j d|j d|j d q|
d|j d|j  qd|}| d| dS )Nro   z) constr   ri   znullable_operand(i++) == rs   zoperand(i++) == z	((!this->z&&!z) || (this->z&&z && *(this->z) == *rz   zthis->z == z &&
        z! {
    size_t i = 0;
    return (z);
  })r{   ZCanBeReusedDeclOnlyCanBeReused	itertoolschainZpositional_valuesZkeyword_valuesr)   r(   r   rS   r+   Zpositional_scalarsZkeyword_scalarsr<   )re   r6   rl   r   Zvalue_comparisonr!   Zvalue_comparison_strr2   r2   r3   rp   p  s,    
4
z"GenTSLazyIR.can_be_reused_functionN)r   r   r   rj   rn   rp   r2   r2   r2   r3   r   T  s   
r   c                   @  s.  e Zd ZU ded< ded< ded< ded< ded< ded	< ded
< ded< ded< ded< ded< ded< ded< ded< ded< ddddddZddddddddZddddddZdddddd Zddddd!d"Zddddd#d$Z	d0d&dd'd(d)Z
ddddd*d+Zedd,d-d.d/Zd%S )1GenLazyNativeFuncDefinitionr    class_method_namer   rY   tensor_classr\   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_tensor_ptrget_device_fnr   r
   )rG   r6   r"   c                 C  sv  |j ddd}g }|D ]R}|jrrt|jtrT|d|j d|j d|j d n|d|j d|j d	 q|jr|qqt|jtr|jj	t
u r|d
|j d| j d| j d|j d	 n2|| j d|j d| j d| j d|j d	
 qt|jtrX|jjtt ks$J |jj|| j d|j d| j d| j d|j d
 qtd|j dqd|S )NTFrq   z
auto node_z = z ?
                std::make_optional(torch::lazy::LazyGraphExecutor::Get()->
                    GetIrValueForScalarFromCodegen(*z3, *common_device)):
                ::std::nullopt;zf = torch::lazy::LazyGraphExecutor::Get()->
                            GetIrValueForScalarFromCodegen(z, *common_device);z
auto lazy_z_tensorlist = ::rw   rP   z lazy_z.value_or(at::Tensor()));r%   r$   rQ   )r;   r*   r)   r(   r   rS   r+   r-   r   r,   r   r   r   r   r   r0   r   r   r.   r<   )re   rG   r6   r   lazy_tensor_declsr!   r2   r2   r3   r     s`    

 z-GenLazyNativeFuncDefinition.lazy_tensor_declsr   r>   )rG   r6   rf   r?   r"   c                 C  s   | j rt|||jjjdS dS )N)r@   ri   )r   rN   rG   r+   r@   )re   rG   r6   rf   r?   r2   r2   r3   force_eager_fallback  s
    z0GenLazyNativeFuncDefinition.force_eager_fallbackc                 C  s   | j  dS )Nr   )r   )re   rG   r6   r2   r2   r3   metrics  s    z#GenLazyNativeFuncDefinition.metricsc                   s   |j ddd}|j ddd}dd |D }ttt  fdd|D }t|dksht|dkshJ d| j d	d
||  d}d| dS )NTFrq   c                 S  s   g | ]}|j s|j qS r2   r*   r+   rC   r2   r2   r3   r9     rE   z:GenLazyNativeFuncDefinition.get_device.<locals>.<listcomp>c                   s   g | ]}|j  kr|jqS r2   )r(   r+   rC   Zoptional_devicer2   r3   r9     s   r   z*Expected at least one Value or Device typerw   r:   r$   zauto common_device = z8;
        TORCH_INTERNAL_ASSERT(common_device);
        )r;   r   r   r   rI   r   r<   )re   rG   r6   r   r   value_types_namesZoptional_devicesZget_device_strr2   r   r3   
get_device  s    
z&GenLazyNativeFuncDefinition.get_devicec              
     s  | j |}|d usJ | }t|j}d|jv }|jpB|jd u}|sN|r(d}|dkrddddd d	 fd
dt	|D }	d|	 d }t
|j}
t|
\}}dd t||
 ddD }|r|jsJ d}nd}|j}|j r| r|d7 }d| d| d| dd| d| 
}n"t|j|| d}d|j d}|d| d7 }dt|j }|d dd!d" |D  d#| d$7 }|S )%N	view_copyzl
std::vector<torch::lazy::Shape> shapes{torch::lazy::Shape(out_meta.scalar_type(), out_meta.sizes().vec())};   intr    )ry   r"   c                 S  s   d|  d|  dS )Nztorch::lazy::Shape(std::get<z$>(out_meta).scalar_type(), std::get<z>(out_meta).sizes().vec())r2   )ry   r2   r2   r3   
this_shape  s    z?GenLazyNativeFuncDefinition.shape_inference.<locals>.this_shape,c                   s   g | ]} |qS r2   r2   rx   r   r2   r3   r9     rE   z?GenLazyNativeFuncDefinition.shape_inference.<locals>.<listcomp>z'std::vector<torch::lazy::Shape> shapes{z};c                 S  s   g | ]
}|j qS r2   rA   )r8   er2   r2   r3   r9     s   F)methodZ&compositeexplicitautogradnonfunctionalmetaZ_symintz        z
        auto out_meta = at::r   rw   r:   z);
        ra   z
            auto shapes = r   z4
            TORCH_INTERNAL_ASSERT(shapes.size() == rP   zaten::zq
            if(torch::lazy::symbolicShapeEnabled()){
                std::vector<torch::jit::IValue> inputs = { c                 s  s   | ]}t |jV  qd S ru   )r    r+   rC   r2   r2   r3   rv   2  rE   z>GenLazyNativeFuncDefinition.shape_inference.<locals>.<genexpr>z. };
                const char* schema_str = "z^";
                applySymbolicShapesOnLT(schema_str, inputs, shapes);
            }
        )rY   rb   r;   rI   r   tags
structuredstructured_delegater<   r   r   rF   rG   rV   r   rH   Z5has_composite_explicit_autograd_non_functional_kernelrJ   Z
has_symintrc   ComputeShapeSignaturekernel
shape_callr    )re   rG   r6   rf   r   returns_lengthis_view_copy_opis_structuredZmeta_outZ
shapes_strrL   Zmeta_conversion_strZmeta_call_ctxZmeta_call_argsZdispatch_nsrJ   Z	shape_str	shape_sigZfunc_schema_strr2   r   r3   shape_inference  sj    






z+GenLazyNativeFuncDefinition.shape_inferencec                 C  s8   t |}d|j d| d| || d|j d| dS )Nz3torch::lazy::NodePtr node = torch::lazy::ReuseNode<r'   z$);
        if (!node) {
            z*
            node = torch::lazy::MakeNode<zE, std::move(shapes));
            CacheNode(node);
        }
        )r=   r   r   )re   rG   r6   Znode_ctor_input_strr2   r2   r3   build_ir_node9  s    
z)GenLazyNativeFuncDefinition.build_ir_nodeNz
str | None)first_tensor_namer"   c                 C  s8   | j r&|d usJ d| d| j S | j d| j S )Nz+Requires first tensor to create lazy tensor.r   )r   r   r   )re   r   r2   r2   r3   create_lazy_tensorC  s    
z.GenLazyNativeFuncDefinition.create_lazy_tensorc                 C  s   t |j}|jddd}dd |D }t |dkr:|d nd }d| j d| | d	}|d
krt |dkstJ dd| j d| d| | dt  d| j d| d}|jjj	s|j
 r|d
ksJ d| dd| d| d}|d7 }|S )NTFrq   c                 S  s   g | ]}|j s|j qS r2   r   rC   r2   r2   r3   r9   P  rE   zBGenLazyNativeFuncDefinition.return_aten_tensor.<locals>.<listcomp>r   zauto result = z(
                z#(std::move(node), *common_device));r   z3Code below assumes there is at least one tensor argr&   z,> lazy_tensors;
        for (int i = 0; i < z,; i++) {
            lazy_tensors.push_back(rw   z=(node, i), *common_device));
        }
        auto result = <z>(lazy_tensors);zqWe assumed there was no such case where an op is an in-place variant and has tuple outputs, but got tuple of len r   r#   z2->SetInPlaceIrValue(node);
        auto& result = r   z
        return result;)rI   r   r;   r   r   r   r   r   r+   ZinplacerG   Z	is_out_fn)re   rG   r6   r   r   r   r   Z
bridge_strr2   r2   r3   return_aten_tensorM  s>    



z.GenLazyNativeFuncDefinition.return_aten_tensorr^   )rG   r"   c                 C  s   t || j}| j|}|d us$J t|j| d}d|j| j d|j d d| 	|||| d| 
|| d| || d| || d| || d| || dgS )Nra   z    r   rt   z {
        rQ   z
    }

    )r   rY   rb   r
   rG   rc   declr   r   r   r   r   r   r   r   )re   rG   r?   rf   r6   r2   r2   r3   rg   k  s(    




z$GenLazyNativeFuncDefinition.__call__)N)r   r   r   r   r   r   r   r   r   r   r   r   r   rg   r2   r2   r2   r3   r     s2   
-K

r   c                   @  sd   e Zd ZdZdddddddZdd	d
dZdd	ddZedd	ddZedd	ddZ	dS )r   zm
    Here we use the base name as the suffix of the signature to avoid generating for in-place variants.
    r    r   r\   None)kernel_namer`   r1   r"   c                C  s\   t |j|d| _ddd tj|j|dD | _ddd | jjddD | _|| _	d S )Nra   r:   c                 S  s   g | ]}|  qS r2   )r   rC   r2   r2   r3   r9     rE   z2ComputeShapeSignature.__init__.<locals>.<listcomp>c                 S  s   g | ]}|j  qS r2   rt   r7   r2   r2   r3   r9     rE   T)	generator)
r
   rG   Z_ComputeShapeSignature__schemar<   
dispatcherrH   %_ComputeShapeSignature__dispatch_argsr;   !_ComputeShapeSignature__call_args#_ComputeShapeSignature__kernel_name)re   r   r`   r1   r2   r2   r3   __init__  s    zComputeShapeSignature.__init__)r"   c                 C  s   | j  d| j dS Nrw   r$   )r   r   re   r2   r2   r3   Z__decl_suffix  s    z#ComputeShapeSignature.__decl_suffixc                 C  s   | j  d| j dS r   )r   r   r   r2   r2   r3   Z__call_suffix  s    z#ComputeShapeSignature.__call_suffixc                 C  s   d|    S )Nz8TORCH_API std::vector<torch::lazy::Shape> compute_shape_)#_ComputeShapeSignature__decl_suffixr   r2   r2   r3   
shape_decl  s    z ComputeShapeSignature.shape_declc                 C  s   d|    S )Nztorch::lazy::compute_shape_)#_ComputeShapeSignature__call_suffixr   r2   r2   r3   r     s    z ComputeShapeSignature.shape_callN)
r   r   r   __doc__r   r   r   propertyr   r   r2   r2   r2   r3   r     s   
r   c                   @  s2   e Zd ZU ded< ded< eddddd	Zd
S )GenLazyShapeInferenceDefinitionr   rY   r    r   r   r^   r_   c                 C  sl   | j |}|d usJ d|jv }|jp0|jd u}|s:|r>g S t|j|| d}d|j	 dggS d S )Nr   ra   
r   )
rY   rb   r   r   r   r   r   rc   r<   r   )re   r`   rf   r   r   r   r2   r2   r3   rg     s    
z(GenLazyShapeInferenceDefinition.__call__N)r   r   r   r   r   rg   r2   r2   r2   r3   r     s   
r   zlist[dict[str, Any]]r^   )
non_nativegen_lazy_irr"   c                 C  st   g }| D ]f}t ddd}|dg D ]}t||d q$tt|d |dd}|d|_|||d	  q|S )
z,Generate the non-native lazy IR node classesr~   r   r   r{   TrG   ra   r   r   )	r	   getsetattrr
   r   parser   rS   rd   )r   r   nodesopr{   pr6   r2   r2   r3   !generate_non_native_lazy_ir_nodes  s    r   )7
__future__r   r   abcr   Zdataclassesr   typingr   Ztorchgen.api.dispatcherapir   Ztorchgen.api.lazyr   r   r   r	   r
   r   Ztorchgen.api.translater   Ztorchgen.api.typesr   r   r   r   r   r   r   r   Ztorchgen.contextr   Ztorchgen.dest.lazy_ts_loweringr   Ztorchgen.modelr   r   r   r   r   r   r   r   r   r4   r=   rN   rK   rV   rX   r   r   r   r   r   r2   r2   r2   r3   <module>   s8    (
,;
 ,8 r