o
    hT                     @   s   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
 d dlmZmZmZmZmZmZmZ dZdedefdd	Zed
dG dd dZdS )    )	dataclass)CallableListSequenceTuple)BindingCType
NamedCType)ArgumentBaseTyBaseTypeListTypeNativeFunctionOptionalTypeTypez
	freturnc                 C   s   | j j S )N)funcnameunambiguous_name)r    r   V/var/www/html/ai/venv/lib/python3.10/site-packages/torchgen/executorch/api/unboxing.pyr      s   r   T)frozenc                   @   s  e Zd ZU dZedef ed< dee de	e
e e
e f fddZdd	d
ededede	eee
e e
e f fddZdededede	e
e e
e f fddZdeded
edede	e
e e
e f f
ddZdeded
edede	e
e e
e f f
ddZdS )Unboxinga  
    Takes a sequence of Bindings and unbox EValues to these Bindings. Return generated code that performs correct unboxing.
    A sample generated code:
    // aten::mul.out(Tensor self, Tensor other, *, Tensor(a!) out) -> Tensor(a!)
    void mul_out(EValue** stack) {
        EValue& self = *stack[0];
        EValue& other = *stack[1];
        EValue& out = *stack[2];
        const torch::executor::Tensor & self_base = self.to<torch::executor::Tensor>();
        const torch::executor::Tensor & other_base = other.to<torch::executor::Tensor>();
        torch::executor::Tensor & out_base = out.to<torch::executor::Tensor>();

        EXECUTORCH_SCOPE_PROF("native_call_mul.out");
        torch::executor::mul_outf(self_base, other_base, out_base);


    }
    .argument_type_genargsr   c           
         s    fddt t D }g } D ]3}t|jts td| |j}| j|j|j|j	d\}}}}	|
|	 |
| ||| q||fS )Nc                    s$   g | ]}d  | j  d| dqS )zEValue& z
 = *stack[z];)r   ).0ir   r   r   
<listcomp>7   s   $ z.Unboxing.convert_arguments.<locals>.<listcomp>z7Unexpected argument type, expecting `Argument` but got mutable)rangelen
isinstanceargumentr
   	Exceptionargumenttype_evalue_converttyper   is_writeextendappend	with_name)
selfr   	code_listbinding_listargr%   unboxed_name_codedeclr   r   r   convert_arguments4   s   

zUnboxing.convert_argumentsFr    targ_namer!   c                C   s   | j |||dj}t|tr| d}| j|||d\}}n6t|tr4| d}| j||||d\}}n t|trJ| d}| j||||d\}}n
t	d| d| ||||fS )	a  
        Takes in the type, name and mutability corresponding to an argument, and generates a tuple of:
        (1) the C++ code necessary to unbox the argument
        (2) A Binding corresponding to the newly created unboxed variable, including variable name and its CType
        :param t: a `Type` of an argument
        :param arg_name: argument name
        :param mutable: boolean for whether this argument type is mutable
        :return: unboxed result
        )r!   binds_base)r7   out_namectype_opt_out)r7   r:   r6   r;   	_list_outzCannot handle type z. arg_name: )
r   r(   r$   r   _gen_code_base_typer   _gen_code_optional_typer   _gen_code_list_typer&   )r-   r6   r7   r!   r;   r:   r3   r4   r   r   r   r'   H   s$   





z$Unboxing.argumenttype_evalue_convertr:   r;   c              	   C   s.   |   d| d| d|j dd dgg fS )N  = z.to<T	strip_refz>();)cpp_type)r-   r7   r:   r;   r   r   r   r>   i   s   &zUnboxing._gen_code_base_typec           
   
   C   sX   | d}|  |j|\}}}}	d|jdd d| d| d|jdd d	d	|	fS )
N_opt_in
    TrC   rA   rB   z.toOptional<z>();
            
)r'   elemrE   split)
r-   r7   r:   r6   r;   in_nameres_name	base_typeres_coder4   r   r   r   r?   p   s$   


z Unboxing._gen_code_optional_typec                 C   sn  | d}| d}g }|  |j|\}}	}
}t|jtr>|jjtjkr>|d|jdd d| d| d	d	 ||fS t|jtrl|jjtj
ksR|jjtjkrl|d|jdd d| d| d
	d	 ||fS t|jtr|jjtjkr|d|jdd d| d| d	d	 ||fS t|jtr|jjtjkr|d|jdd d| d| d	d	 ||fS t|jtrt|jjtr|jjjtjkr|d| d| d| d| d| d| d| d| d| d	d	 ||fS |d }|d|	jdd d| d |d| d| dt|
 d| d| d|jdd d| d| d	d	 ||fS )N_list_in_elemrG   TrC   rA   rB   z!.toTensorList();
                rH   z.toIntList();
                z!.toDoubleList();
                z.toBoolList();
                z=
#ifdef USE_ATEN_LIB
at::ArrayRef<c10::optional<at::Tensor>> z>.toListOptionalTensor();
c10::List<c10::optional<at::Tensor>> z;
for (auto z: z) {
    z.push_back(zY);
}
#else
torch::executor::ArrayRef<torch::executor::optional<torch::executor::Tensor>> z0.toListOptionalTensor();
#endif
                _veczstd::vector<z> ;z
    for (EValue z) {
        z	
        z);
    }
    (z);
                )r'   rI   r$   r   r   r   Tensorr*   rE   rJ   intSymIntfloatboolr   r+   	connectorjoin)r-   r7   r:   r6   r;   rK   	elem_namer3   rL   	res_ctyperN   r4   vec_namer   r   r   r@      s   


J
@
8
/

!
zUnboxing._gen_code_list_typeN)__name__
__module____qualname____doc__r   r	   __annotations__r   r   r   r   strr5   r   rX   r   r'   r>   r   r?   r   r@   r   r   r   r   r      sj   
 

!

r   N)dataclassesr   typingr   r   r   r   torchgen.api.typesr   r   r	   torchgen.modelr
   r   r   r   r   r   r   rY   rc   r   r   r   r   r   r   <module>   s    $
