o
    vZh>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+ d3ddZ,d4ddZ-d5ddZ.d4ddZ/d6d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,Z5d7d1d2Z6dS )8    )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NativeFunctionsGroupargr   returnstrc                 C  s  t | jrbt| jtr2| jrd| j S | jjtu r!d| j dS | jr+d| j dS d| j dS t| jt	rY| jrE| j d| j dS | jrNd| j S d| j d	| j d
S t
d| j dt| jtr| jjttjkr| jr{d| j dS d| j d| j dS t| jtrt| jjtrd| 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 )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<)r   	lazy_type
isinstancer   is_wrapped_scalarnametyper   is_symint_or_listr   AssertionError	orig_typer   elemr   r   ZSymIntsymintr   )r     r2   D/var/www/auris/lib/python3.10/site-packages/torchgen/dest/lazy_ir.pynode_ctor_arg_rvalue_string+   sN   

"
r4   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)r5   Znode_ctor_valuesr2   r2   r3   node_ctor_inputsf   s   
r<   sig%DispatcherSignature | NativeSignatureoverload_namec                 C  sz   t | j}t| | }ddd |D }t|r(d| 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     g | ]}|j qS r2   exprr7   ar2   r2   r3   r8   z       z%gen_fallback_code.<locals>.<listcomp>z	ATEN_OP2(r9   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)r5   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sd| j  S | j S )NZsigmoid_backwardz#c10::Symbol::fromQualString("aten::z")zat::z
at::aten::)rJ   
startswith)r5   Zmissing_interned_stringsr2   r2   r3   rK      s   
rK   r   tuple[str, list[Binding]]c                 C  s   g }g }|   D ]/}t|jtr2|jj r2|j d}|d| d|j d ||| q|| qd	|}||fS )N_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   
rX   T)frozenc                   @  sn   e Zd ZU ded< ded< ded< ded< edddZdddZdddZdddZdddZ	dddZ
dS ) 	GenLazyIRr   backend_indexr"   backend_name	node_basebooluse_lazy_shapef%NativeFunctionsGroup | NativeFunctionr!   	list[str]c                 C  sV   t |tr	|jjn|j}| jt |tr|jn|}t||d uo#| d}| |S )Nr1   )	r)   r   Z
functionalrG   r[   
get_kernelr
   supports_symintgen)selfr`   rG   metadatar5   r2   r2   r3   __call__   s   
zGenLazyIR.__call__r5   r
   c                 C     dS N r2   )rg   r5   r2   r2   r3   lowering_function      zGenLazyIR.lowering_functionnode_ctor_argsc                 C  rj   rk   r2   rg   r5   ro   r2   r2   r3   create_function   rn   zGenLazyIR.create_functionc                 C  s   d| dS )Nbool CanBeReused(z!) const {
    return false;
    }r2   rp   r2   r2   r3   can_be_reused_function      z GenLazyIR.can_be_reused_functionc           
      C  sp  |j ddd}g }|D ]*}t|jttfr||j  qt|jtr-||j d qtd|j dd	|}|j ddd}|j
jrId}nL|j
jrld	d
 |D }|dd |D  d|j dd	| d}n)|j
jrd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 necessaryr9   zstd::move(shapes),c                 S  r@   r2   r+   rC   r2   r2   r3   r8      rE   z1GenLazyIR.node_base_ctor_call.<locals>.<listcomp>c                 s      | ]}|j V  qd S Nrx   rC   r2   r2   r3   	<genexpr>       z0GenLazyIR.node_base_ctor_call.<locals>.<genexpr>Zcompute_shape_(z),c                 S     g | ]}d | dqS )zoperand(r$   r2   r7   ir2   r2   r3   r8          c                 s  ry   rz   rx   rC   r2   r2   r3   r{      r|   z[&](){ return compute_shape_z)[0]; },rl   c                 s  s    | ]}|j  V  qd S rz   rx   rC   r2   r2   r3   r{      s    z(
              z&::ClassOpKind(),
              OpList{z},
              z!
              /* num_outputs */ z#,
              torch::lazy::MHash()))r:   r)   r(   r   r   rU   r+   r   r.   r;   
propertiesShapePrecomputeZShapeComputeextend
ShapeCacherangerI   r]   	node_namereturns)
rg   r5   
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r*|jjr*|d d|}dd	d |D }t|rBd| }d
dd |D }	dd |jdddD }
d
dd |
D }ddd |
D }g }|D ]7}t	|j
tr|j d}|jrd}|d|j d|j d| d|j d	 qp|d|j d|j d qpd|}d|j d| j d| d|j d| d| | | d| d | j d!| d"| || d#| || d#| | d#|	 d
| d$gS )%NFTru   c                 S  s$   g | ]}d |j   d|j qS )zconst z& r(   Zcpp_typer+   r   r2   r2   r3   r8      s   $ z!GenLazyIR.gen.<locals>.<listcomp>r9   z(std::vector<torch::lazy::Shape>&& shapesz
,
        c                 S  sJ   g | ]!}|j  d kr|j d|j d|j dn	|j d|j dqS )!::std::optional<c10::string_view>r}   z1.has_value() ? ::std::make_optional(std::string(*z)) : ::std::nullopt)r$   r   rC   r2   r2   r3   r8      s    z
  c                 S  s\   g | ]*}|j  d krd|j dn|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   r8     s    c                 S  s   g | ]}t |jtr|jqS r2   )r)   r(   r   r+   r6   r2   r2   r3   r8     s    
c                 S  r~   )z	bool has_z: 1;r2   r7   valuer2   r2   r3   r8     r   z
    c                 S  s   g | ]}d | d| dqS )Zhas_z = !!r   r2   r   r2   r2   r3   r8     s    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
);
  }

  r}   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   rU   rI   r)   r(   r   r+   Zis_generatorr   r]   r   rq   rs   rm   )rg   r5   r   all_argsr   Z	ctor_argsZreuse_ctor_argsro   Zscalar_initializersZscalar_declsZoptional_valuesZhas_optional_declsZhas_optional_defsZmembers_to_stringr    r   Zmembers_to_string_strr2   r2   r3   rf      s   


	






zGenLazyIR.genN)r`   ra   r!   rb   r5   r
   r!   r"   r5   r
   ro   r"   r!   r"   )r5   r
   r!   rb   )__name__
__module____qualname____annotations__r   ri   rm   rq   rs   r   rf   r2   r2   r2   r3   rZ      s   
 



*rZ   c                   @  s*   e Zd ZdddZddd	Zdd
dZdS )GenTSLazyIRr5   r
   r!   r"   c                 C  s6   d}|j jr| dS |j jr| dt| dS dS )Nz
  torch::lazy::TSOpVector Lower(
      std::shared_ptr<torch::jit::GraphFunction> function,
      torch::lazy::TSLoweringContext* loctx) const overrider   z {
    z
  }
            rl   )r   LowerDeclOnlyZLowerr   )rg   r5   	signaturer2   r2   r3   rm   V  s   
zGenTSLazyIR.lowering_functionro   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   rl   z {
    return ReuseOrMakeNode<z>(data);
  })r   ZCreateFnDeclOnlyZCreateFnr   )rg   r5   ro   r   r2   r2   r3   rq   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 ]}t|jt	r2|
d|j d q|
d|j  qt|j|jD ]4}t|jt	rk|
d|j d	|j d
|j d|j d|j d|j d qD|
d|j d|j  qDd|}| d| dS )Nrr   z) constr   rl   znullable_operand(i++) == rw   zoperand(i++) == z	((!this->z&&!z) || (this->z&&z && *(this->z) == *r   zthis->z == z &&
        z! {
    size_t i = 0;
    return (z);
  })r   ZCanBeReusedDeclOnlyCanBeReused	itertoolschainZpositional_valuesZkeyword_valuesr)   r(   r   rU   r+   Zpositional_scalarsZkeyword_scalarsr;   )rg   r5   ro   r   Zvalue_comparisonr    Zvalue_comparison_strr2   r2   r3   rs   p  s,   
4
z"GenTSLazyIR.can_be_reused_functionNr   r   )r   r   r   rm   rq   rs   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< d2ddZd3ddZd2d d!Zd2d"d#Zd2d$d%Zd2d&d'Z	d4d5d+d,Z
d2d-d.Zed6d0d1Zd(S )7GenLazyNativeFuncDefinitionr"   class_method_namer   r[   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_fnrG   r   r5   r
   r!   c                 C  sl  |j ddd}g }|D ]}|jr8t|jtr)|d|j d|j d|j d q|d|j d|j d	 q|jr<qt|jtry|jj	t
u r_|d
|j d| j d| j d|j d	 q|| j d|j d| j d| j d|j d	
 qt|jtr|jjtt ksJ |jj|| j d|j d| j d| j d|j d
 qtd|j dd|S )NTFru   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 = ::r}   rR   z lazy_z.value_or(at::Tensor()));r%   r$   rS   )r:   r*   r)   r(   r   rU   r+   r-   r   r,   r   r   r   r   r   r0   r   r   r.   r;   )rg   rG   r5   r   lazy_tensor_declsr    r2   r2   r3   r     sh   


z-GenLazyNativeFuncDefinition.lazy_tensor_declsrh   r   r=   r>   c                 C  s   | j rt|||jjjdS dS )N)r?   rl   )r   rN   rG   r+   r?   )rg   rG   r5   rh   r=   r2   r2   r3   force_eager_fallback  s
   z0GenLazyNativeFuncDefinition.force_eager_fallbackc                 C  s   | j  dS )Nr   )r   )rg   rG   r5   r2   r2   r3   metrics  rt   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s4t|dks4J d| j d	d
||  d}d| dS )NTFru   c                 S     g | ]	}|j s|j qS r2   r*   r+   rC   r2   r2   r3   r8         z:GenLazyNativeFuncDefinition.get_device.<locals>.<listcomp>c                   s   g | ]
}|j  kr|jqS r2   )r(   r+   rC   Zoptional_devicer2   r3   r8     s    r   z*Expected at least one Value or Device typer}   r9   r$   zauto common_device = z8;
        TORCH_INTERNAL_ASSERT(common_device);
        )r:   r   r   r   rI   r   r;   )rg   rG   r5   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p!|jd u}|s&|rd}|dkrEd&dd	 d
 fddt	|D }	d|	 d }t
|j}
t|
\}}dd t||
 ddD }|ri|jsfJ 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())};   r   intr!   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   )r   r2   r2   r3   
this_shape  s   z?GenLazyNativeFuncDefinition.shape_inference.<locals>.this_shape,c                   s   g | ]} |qS r2   r2   r   r   r2   r3   r8         z?GenLazyNativeFuncDefinition.shape_inference.<locals>.<listcomp>z'std::vector<torch::lazy::Shape> shapes{z};c                 S  r@   r2   rA   )r7   er2   r2   r3   r8     s    F)methodZ&compositeexplicitautogradnonfunctionalmetaZ_symintz        z
        auto out_meta = at::r   r}   r9   z);
        rc   z
            auto shapes = r   z4
            TORCH_INTERNAL_ASSERT(shapes.size() == rR   zaten::zq
            if(torch::lazy::symbolicShapeEnabled()){
                std::vector<torch::jit::IValue> inputs = { c                 s  s    | ]}t |jV  qd S rz   )r"   r+   rC   r2   r2   r3   r{   2  s    z>GenLazyNativeFuncDefinition.shape_inference.<locals>.<genexpr>z. };
                const char* schema_str = "z^";
                applySymbolicShapesOnLT(schema_str, inputs, shapes);
            }
        )r   r   r!   r"   )r[   rd   r:   rI   r   tags
structuredstructured_delegater;   r   r   rF   rG   rX   r   rH   Z5has_composite_explicit_autograd_non_functional_kernelrJ   Z
has_symintre   ComputeShapeSignaturekernel
shape_callr"   )rg   rG   r5   rh   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   )rg   rG   r5   Znode_ctor_input_strr2   r2   r3   build_ir_node9  s   
z)GenLazyNativeFuncDefinition.build_ir_nodeNfirst_tensor_name
str | Nonec                 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   )rg   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rUt |dks:J dd| j d| d| | dt  d| j d| d}|jjj	s_|j
 rt|d
kskJ d| dd| d| d}|d7 }|S )NTFru   c                 S  r   r2   r   rC   r2   r2   r3   r8   P  r   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(r}   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)rg   rG   r5   r   r   r   r   Z
bridge_strr2   r2   r3   return_aten_tensorM  sB   



z.GenLazyNativeFuncDefinition.return_aten_tensorrb   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 )Nrc   z    r   rx   z {
        rS   z
    }

    )r   r[   rd   r
   rG   re   declr   r   r   r   r   r   r   r   )rg   rG   r=   rh   r5   r2   r2   r3   ri   k  s(   




z$GenLazyNativeFuncDefinition.__call__)rG   r   r5   r
   r!   r"   )
rG   r   r5   r
   rh   r   r=   r>   r!   r"   rz   )r   r   r!   r"   )rG   r   r!   rb   )r   r   r   r   r   r   r   r   r   r   r   r   r   ri   r2   r2   r2   r3   r     s4   
 

-



K


r   c                   @  sJ   e Zd ZdZdd
dZdddZdddZedddZe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.
    kernel_namer"   r`   r   r1   r^   r!   Nonec                C  s\   t |j|d| _ddd tj|j|dD | _ddd | jjddD | _|| _	d S )Nrc   r9   c                 S  s   g | ]}|  qS r2   )r   rC   r2   r2   r3   r8     r   z2ComputeShapeSignature.__init__.<locals>.<listcomp>c                 S  s   g | ]}|j  qS r2   rx   r6   r2   r2   r3   r8     r   T)	generator)
r
   rG   Z_ComputeShapeSignature__schemar;   
dispatcherrH   %_ComputeShapeSignature__dispatch_argsr:   !_ComputeShapeSignature__call_args#_ComputeShapeSignature__kernel_name)rg   r   r`   r1   r2   r2   r3   __init__  s   
zComputeShapeSignature.__init__c                 C     | j  d| j dS Nr}   r$   )r   r   rg   r2   r2   r3   Z__decl_suffix     z#ComputeShapeSignature.__decl_suffixc                 C  r   r   )r   r   r   r2   r2   r3   Z__call_suffix  r   z#ComputeShapeSignature.__call_suffixc                 C     d|    S )Nz8TORCH_API std::vector<torch::lazy::Shape> compute_shape_)#_ComputeShapeSignature__decl_suffixr   r2   r2   r3   
shape_decl     z ComputeShapeSignature.shape_declc                 C  r   )Nztorch::lazy::compute_shape_)#_ComputeShapeSignature__call_suffixr   r2   r2   r3   r     r   z ComputeShapeSignature.shape_callN)r   r"   r`   r   r1   r^   r!   r   )r!   r"   )
r   r   r   __doc__r   r   r   propertyr   r   r2   r2   r2   r3   r     s    



r   c                   @  s,   e Zd ZU ded< ded< edd	d
ZdS )GenLazyShapeInferenceDefinitionr   r[   r"   r   r`   r   r!   rb   c                 C  sh   | j |}|d usJ d|jv }|jp|jd u}|s|rg S t|j|| d}d|j	 dggS )Nr   rc   
r   )
r[   rd   r   r   r   r   r   re   r;   r   )rg   r`   rh   r   r   r   r2   r2   r3   ri     s   
z(GenLazyShapeInferenceDefinition.__call__N)r`   r   r!   rb   )r   r   r   r   r   ri   r2   r2   r2   r3   r     s
   
 r   
non_nativelist[dict[str, Any]]gen_lazy_irrb   c                 C  st   g }| D ]3}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   rc   r   r   )	r	   getsetattrr
   r   parser   rU   rf   )r   r   nodesopr   pr5   r2   r2   r3   !generate_non_native_lazy_ir_nodes  s   r   )r    r   r!   r"   r   )r5   r
   r=   r>   r?   r"   r!   r"   )r=   r   r!   rP   )r   r   r   rZ   r!   rb   )7
__future__r   r   abcr   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   rX   rZ   r   r   r   r   r   r2   r2   r2   r3   <module>   s:     (
,

;



 ,8 r