U
    9%eYr                     @   s  d dl 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 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. ee/dddZ0ee/dddZ1eeeef e/e/dddZ2ee/dddZ3ee
e/ee f dddZ4eddG dd deZ5eddG dd de5Z6eddG dd  d Z7G d!d" d"Z8eddG d#d$ d$Z9eee/ef  e5ee/ d%d&d'Z:dS )(    N)ABC)	dataclass)AnyDictListOptionalTupleUnion)	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)argreturnc                 C   s  t | jrt| jtrd| jr(d| j S | jjtk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& ? c10::make_optional(GetSymIntValue(*z)) : c10::nulloptz ? c10::make_optional(lazy_z->GetIrValue()) : c10::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$    r5   T/var/www/html/Darija-Ai-API/env/lib/python3.8/site-packages/torchgen/dest/lazy_ir.pynode_ctor_arg_rvalue_string)   sL    
 "
r7   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 r5   )r7   .0r$   r5   r5   r6   
<listcomp>h   s    z$node_ctor_inputs.<locals>.<listcomp>, )filtered_argsjoin)r9   Znode_ctor_valuesr5   r5   r6   node_ctor_inputsd   s    r@   )r9   sigoverload_namer%   c              	   C   s   t | j}t| | }ddd |D }t|rPd| j d| d}nd| j d}d}| jrd	| jj	 d
| jj	 d}dt
|  d| d| d| d	S )zK
    Generate code that falls back to eager conditioned on a predicate
    z,
                c                 S   s   g | ]
}|j qS r5   exprr;   ar5   r5   r6   r<   x   s     z%gen_fallback_code.<locals>.<listcomp>z	ATEN_OP2(r=   r'   zATEN_OP( z || (z.has_value() && z->defined())z"
        if (force_eager_fallback(zP) {
            return at::native::call_fallback_fn_symint<&ltc_eager_fallback, z>::call(
                z
            );
        }
)r   from_schemafuncr   	argumentsr?   len	aten_nameZgenerator_argr.   aten_symbol)r9   rA   rB   dispatcher_sigexprsZfallback_argsZaten_op_strZor_has_generatorr5   r5   r6   gen_fallback_coden   s$    rP   c                 C   s@   dh}| j |k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::)rL   
startswith)r9   Zmissing_interned_stringsr5   r5   r6   rM      s    
rM   )rA   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 )N_metazauto z = to_meta();	
        )
rJ   r,   argumentr   r/   Zis_tensor_liker.   append	with_namer?   )rA   contextZunwrapped_tensor_argsr$   Zunwrapped_nameZunwrap_tensor_args_strr5   r5   r6   convert_to_meta_tensors   s    
rY   T)frozenc                   @   s   e Zd ZU eed< eed< eed< eed< eee	e
f ee dddZeedd	d
ZeeedddZeeedddZeedddZeee dddZdS )	GenLazyIRbackend_indexbackend_name	node_baseuse_lazy_shapefr%   c                 C   sV   t |tr|jjn|j}| jt |tr.|jn|}t||d k	oF| d}| |S )Nr4   )	r,   r#   Z
functionalrI   r\   
get_kernelr   supports_symintgen)selfra   rI   metadatar9   r5   r5   r6   __call__   s     zGenLazyIR.__call__r8   c                 C   s   dS NrG   r5   )rf   r9   r5   r5   r6   lowering_function   s    zGenLazyIR.lowering_functionr9   node_ctor_argsr%   c                 C   s   dS ri   r5   rf   r9   rl   r5   r5   r6   create_function   s    zGenLazyIR.create_functionc                 C   s   d| dS )Nbool CanBeReused(z!) const {
    return false;
    }r5   rm   r5   r5   r6   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 r5   r.   rE   r5   r5   r6   r<      s     z1GenLazyIR.node_base_ctor_call.<locals>.<listcomp>c                 s   s   | ]}|j V  qd S Nrt   rE   r5   r5   r6   	<genexpr>   s     z0GenLazyIR.node_base_ctor_call.<locals>.<genexpr>Zcompute_shape_(z),c                 S   s   g | ]}d | dqS )zoperand(r'   r5   r;   ir5   r5   r6   r<      s     c                 s   s   | ]}|j V  qd S ru   rt   rE   r5   r5   r6   rv      s     z[&](){ return compute_shape_z)[0]; },rG   c                 s   s   | ]}|j  V  qd S ru   rt   rE   r5   r5   r6   rv      s     z(
              z&::ClassOpKind(),
              OpList{z},
              z!
              /* num_outputs */ z#,
              torch::lazy::MHash()))r>   r,   r+   r   r   rV   r.   r   r1   r?   
propertiesShapePrecomputeZShapeComputeextend
ShapeCacherangerK   r^   	node_namereturns)
rf   r9   
value_argsZbase_ctor_value_args_listr$   Zbase_ctor_value_argsscalar_argsZshape_ctor_argZ
shape_argsZscalar_hashesr5   r5   r6   node_base_ctor_call   sF    

zGenLazyIR.node_base_ctor_callc                 C   s  |j pt|}| }|jddd}|jddd}dd |D }d|}| jrb|jjrb|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 ]\}t	|j
tr.|d|j d|j d|j 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 )#NTFrq   c                 S   s$   g | ]}d |j   d|j qS )zconst z& r+   Zcpp_typer.   rx   r5   r5   r6   r<      s     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 )c10::optional<c10::string_view>rw   z/.has_value() ? c10::make_optional(std::string(*z)) : c10::nullopt)r'   r   rE   r5   r5   r6   r<     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c10::optional<std::string>  r   rE   r5   r5   r6   r<     s   c                 S   s   g | ]}t |jtr|jqS r5   )r,   r+   r   r.   r:   r5   r5   r6   r<     s   c                 S   s   g | ]}d | dqS )z	bool has_z: 1;r5   r;   valuer5   r5   r6   r<     s     z
    c                 S   s   g | ]}d | d| dqS )Zhas_z = !!r   r5   r   r5   r5   r6   r<      s     zif (z.has_value()) {
      ss << ", z=" << z&.value();
    } 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

};

)opkindrM   r>   r?   r_   r{   r|   rV   rK   r,   r+   r   r.   r   r^   r   rn   rp   rj   )rf   r9   r   all_argsr   r   Z	ctor_argsZreuse_ctor_argsrl   Zscalar_initializersZscalar_declsZoptional_valuesZhas_optional_declsZhas_optional_defsZmembers_to_stringr$   Zmembers_to_string_strr5   r5   r6   re      s    


	

$



zGenLazyIR.genN)__name__
__module____qualname__r   __annotations__strboolr   r	   r#   r"   r   rh   r   rj   rn   rp   r   re   r5   r5   r5   r6   r[      s   
*r[   c                   @   s@   e Zd ZeedddZeeedddZeeedddZd	S )
GenTSLazyIRr8   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
  }
            rG   )r{   LowerDeclOnlyZLowerr   )rf   r9   	signaturer5   r5   r6   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   rG   z {
    return ReuseOrMakeNode<z>(data);
  })r{   ZCreateFnDeclOnlyZCreateFnr   )rf   r9   rl   r   r5   r5   r6   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   rG   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   rV   r.   Zpositional_scalarsZkeyword_scalarsr?   )rf   r9   rl   r   Zvalue_comparisonr$   Zvalue_comparison_strr5   r5   r6   rp   p  s,    
4
z"GenTSLazyIR.can_be_reused_functionN)r   r   r   r   r   rj   rn   rp   r5   r5   r5   r6   r   T  s   
r   c                   @   s>  e Zd ZU eed< eed< eed< eed< eed< eed< eed< eed< eed	< eed
< eed< eed< eed< eed< eed< eeedddZ	eee
eeef edddZeeedddZeeedddZeeedddZeeedddZd'ee edd d!Zeeedd"d#Zeeee d$d%d&ZdS )(GenLazyNativeFuncDefinitionclass_method_namer\   tensor_class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_fn)rI   r9   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
k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$t|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 ?
                c10::make_optional(torch::lazy::LazyGraphExecutor::Get()->
                    GetIrValueForScalarFromCodegen(*z1, *common_device)):
                c10::nullopt;zf = torch::lazy::LazyGraphExecutor::Get()->
                            GetIrValueForScalarFromCodegen(z, *common_device);z
auto lazy_z_tensorlist = ::rw   rS   z lazy_z.value_or(at::Tensor()));r(   r'   rT   )r>   r-   r,   r+   r   rV   r.   r0   r   r/   r   r   r   r   r   r3   r
   r1   r   r?   )rf   rI   r9   r   lazy_tensor_declsr$   r5   r5   r6   r     s<    
$* *z-GenLazyNativeFuncDefinition.lazy_tensor_decls)rI   r9   rg   rA   r%   c                 C   s   | j rt|||jjjdS dS )N)rB   rG   )r   rP   rI   r.   rB   )rf   rI   r9   rg   rA   r5   r5   r6   force_eager_fallback  s      z0GenLazyNativeFuncDefinition.force_eager_fallbackc                 C   s   | j  dS )Nr   )r   )rf   rI   r9   r5   r5   r6   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shtd| j d	d
||  d}d| dS )NTFrq   c                 S   s   g | ]}|j s|j qS r5   r-   r.   rE   r5   r5   r6   r<     s      z:GenLazyNativeFuncDefinition.get_device.<locals>.<listcomp>c                    s   g | ]}|j  kr|jqS r5   )r+   r.   rE   Zoptional_devicer5   r6   r<     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   rK   r1   r   r?   )rf   rI   r9   r   r   value_types_namesZoptional_devicesZget_device_strr5   r   r6   
get_device  s     


z&GenLazyNativeFuncDefinition.get_devicec              
      s  | j |}|d k	st| }t|j}d|jk}|jpB|jd k	}|sN|r(d}|dkrt	t
ddd d fdd	t|D }	d
|	 d }t|j}
t|
\}}dd	 t||
 ddD }|r|jst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())};   )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())r5   )ry   r5   r5   r6   
this_shape  s    z?GenLazyNativeFuncDefinition.shape_inference.<locals>.this_shape,c                    s   g | ]} |qS r5   r5   rx   r   r5   r6   r<     s     z?GenLazyNativeFuncDefinition.shape_inference.<locals>.<listcomp>z'std::vector<torch::lazy::Shape> shapes{z};c                 S   s   g | ]
}|j qS r5   rC   )r;   er5   r5   r6   r<     s   F)methodZ&compositeexplicitautogradnonfunctionalmetaZ_symintz        z
        auto out_meta = at::r   rw   r=   z);
        rb   z
            auto shapes = r   z4
            TORCH_INTERNAL_ASSERT(shapes.size() == rS   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.   rE   r5   r5   r6   rv   2  s     z>GenLazyNativeFuncDefinition.shape_inference.<locals>.<genexpr>z. };
                const char* schema_str = "z^";
                applySymbolicShapesOnLT(schema_str, inputs, shapes);
            }
        )r\   rc   r1   r>   rK   r   tags
structuredstructured_delegateintr   r?   r   r   rH   rI   rY   r   rJ   Z5has_composite_explicit_autograd_non_functional_kernelrL   Z
has_symintrd   ComputeShapeSignaturekernel
shape_call)rf   rI   r9   rg   r   returns_lengthis_view_copy_opis_structuredZmeta_outZ
shapes_strrN   Zmeta_conversion_strZmeta_call_ctxZmeta_call_argsZdispatch_nsrL   Z	shape_str	shape_sigZfunc_schema_strr5   r   r6   shape_inference  sr    


  
  

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   )rf   rI   r9   Znode_ctor_input_strr5   r5   r6   build_ir_node9  s    
z)GenLazyNativeFuncDefinition.build_ir_nodeN)first_tensor_namer%   c                 C   s8   | j r&|d k	std| d| j S | j d| j S )Nz+Requires first tensor to create lazy tensor.r   )r   r1   r   r   )rf   r   r5   r5   r6   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sttdd| j d| d| | dt  d| j d| d}|j	j	j
s|j r|d
kstd| dd| d| d}|d7 }|S )NTFrq   c                 S   s   g | ]}|j s|j qS r5   r   rE   r5   r5   r6   r<   P  s      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;)rK   r   r>   r   r   r1   r   r
   r   r.   ZinplacerI   Z	is_out_fn)rf   rI   r9   r   r   r   r   Z
bridge_strr5   r5   r6   return_aten_tensorM  s<    





z.GenLazyNativeFuncDefinition.return_aten_tensor)rI   r%   c                 C   s   t || j}| j|}|d k	s$tt|j| d}d|j| j d|j	 d d| 
|||| d| || d| || d| || d| || d| || dgS )Nrb   z    r   rt   z {
        rT   z
    }

    )r   r\   rc   r1   r   rI   rd   declr   r   r   r   r   r   r   r   )rf   rI   rA   rg   r9   r5   r5   r6   rh   k  s(    




z$GenLazyNativeFuncDefinition.__call__)N)r   r   r   r   r   r   r   r"   r   r   r   r	   r   r   r   r   r   r   r   r   r   r   r   r   rh   r5   r5   r5   r6   r     s<   
/
K

r   c                   @   sb   e Zd ZdZeeedddZedddZeddd	Z	e
edd
dZe
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_namera   r4   c                C   s\   t |j|d| _ddd tj|j|dD | _ddd | jjddD | _|| _	d S )Nrb   r=   c                 S   s   g | ]}|  qS r5   )r   rE   r5   r5   r6   r<     s     z2ComputeShapeSignature.__init__.<locals>.<listcomp>c                 S   s   g | ]}|j  qS r5   rt   r:   r5   r5   r6   r<     s     T)	generator)
r   rI   Z_ComputeShapeSignature__schemar?   
dispatcherrJ   %_ComputeShapeSignature__dispatch_argsr>   !_ComputeShapeSignature__call_args#_ComputeShapeSignature__kernel_name)rf   r   ra   r4   r5   r5   r6   __init__  s    zComputeShapeSignature.__init__)r%   c                 C   s   | j  d| j dS Nrw   r'   )r   r   rf   r5   r5   r6   Z__decl_suffix  s    z#ComputeShapeSignature.__decl_suffixc                 C   s   | j  d| j dS r   )r   r   r   r5   r5   r6   Z__call_suffix  s    z#ComputeShapeSignature.__call_suffixc                 C   s   d|    S )Nz8TORCH_API std::vector<torch::lazy::Shape> compute_shape_)#_ComputeShapeSignature__decl_suffixr   r5   r5   r6   
shape_decl  s    z ComputeShapeSignature.shape_declc                 C   s   d|    S )Nztorch::lazy::compute_shape_)#_ComputeShapeSignature__call_suffixr   r5   r5   r6   r     s    z ComputeShapeSignature.shape_callN)r   r   r   __doc__r   r"   r   r   r   r   propertyr   r   r5   r5   r5   r6   r     s   
r   c                   @   s6   e Zd ZU eed< eed< eeee dddZ	dS )GenLazyShapeInferenceDefinitionr\   r   r`   c                 C   sx   t || j}| j|}|d k	s$td|jk}|jp<|jd k	}|sF|rJg S t|j||	 d}d
|j dggS d S )Nr   rb   
r   )r   r\   rc   r1   r   r   r   r   r   rd   r?   r   )rf   ra   rA   rg   r   r   r   r5   r5   r6   rh     s    
  z(GenLazyShapeInferenceDefinition.__call__N)
r   r   r   r   r   r   r   r"   r   rh   r5   r5   r5   r6   r     s   
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{   TrI   rb   r   r   )	r   getsetattrr   r    parser   rV   re   )r   r   Znodesopr{   pr9   r5   r5   r6   !generate_non_native_lazy_ir_nodes  s    r   );r   abcr   dataclassesr   typingr   r   r   r   r   r	   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#   r   r7   r@   rP   rM   rY   r[   r   r   r   r   r   r5   r5   r5   r6   <module>   sD     (
,;
 *8 r 