U
    dMH                     @   s  U d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlmZ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 erddlmZ edd	G d
d deZi Ze	ee
ej f ed< dd Ze ee j< G dd dZe j e j!e j"ej#e j$j%ej&e j'e e(de)dd
Z*e+eD ]Z,e-ee,e*e,< q2dedddZ.e j/j0ejdddZ1edd	eed e	e2df dddZ3edd	d1ee4dd d!Z5edd	d"d# Z6edd	eed$d%d&Z7edd	d2eee ee	e2ef  eee  ee	e2ef  e4ee d'd(d)Z8edd	d3e j9j:e2ee ee	e2ef  e4ee d*d+d,Z;ejeed-f e	e2ef e4ee d.d/d0Z<dS )4    N)	AnyCallableDictListOptionalTuple
NamedTuplecastTYPE_CHECKING)boolean_dispatched   )compatibility)OpOverloadPacket
OpOverload)ArgumentF)Zis_backward_compatiblec                   @   s2   e Zd ZU dZeedf ed< eeef ed< dS )ArgsKwargsPairz<
    Simple named tuple for wrapping args/kwargs pairs.
    .argskwargsN)	__name__
__module____qualname____doc__r   r   __annotations__r   str r   r   =/tmp/pip-unpacked-wheel-ua33x9lu/torch/fx/operator_schemas.pyr      s   
r   _manual_overridesc                  C   s>   g } dd }|  t| tddd}|  t| | S )Nc                 S   s   d S Nr   )selfr   r   r   nonzero   s    z!_nonzero_schemas.<locals>.nonzero)as_tuplec                S   s   d S r   r   )r   r    r   r   r   r   !   s    )appendinspect	signaturebool)
signaturesr   r   r   r   _nonzero_schemas   s    r&   c                   @   s   e Zd Zdd ZdS )_FakeGlobalNamespacec                 C   s   |dkrt S tdd S )Ntorchz!Expected a torch namespace lookup)r(   RuntimeError)r   namer   r   r   __getattr__*   s    z _FakeGlobalNamespace.__getattr__N)r   r   r   r+   r   r   r   r   r'   )   s   r'   t)
TensorZDeviceZLayoutnumberFutureZAnyEnumTypeZQSchemeZ	__torch__ZNoneTyper,   ztorch._C.JitType)ts_typereturnc                 C   s   t | jtS )z
    Convert a TorchScript type to a Python type (including subtypes) via
    eval'ing the annotation_str. _type_eval_globals sets up expressions
    like "List" and "Future" to map to actual types (typing.List and jit.Future)
    )evalZannotation_str_type_eval_globals)r0   r   r   r    _torchscript_type_to_python_type7   s    r4   )	ts_schemar1   c           	   	   C   s   g }| j D ]f}t|j}| r&|jntjj}|jdkr>|jnd}|j	rPtjj
ntjj}|tj||||d q
dd | jD }t|dkrd }nt|dkr|d }nt|}tj||dS )	Nr   input)r*   kinddefault
annotationc                 S   s   g | ]}t |jqS r   )r4   type).0retr   r   r   
<listcomp>L   s     z4_torchscript_schema_to_signature.<locals>.<listcomp>r   r   )return_annotation)	argumentsr4   r:   Zhas_default_valuedefault_valuer"   	Parameteremptyr*   Z
kwarg_onlyKEYWORD_ONLYPOSITIONAL_OR_KEYWORDr!   Zreturnslentuple	Signature)	r5   
parametersargarg_typer8   r*   r7   Zreturn_typesreturn_typer   r   r    _torchscript_schema_to_signature?   s    


rL   )r   .r   )targetr   r   c                 C   s   t | dd\}}|r|rg }t||D ]R\}}z|j|| |||f W q& tk
rv } zW Y q&W 5 d }~X Y q&X q&dd }	t|dkrn"t|dkr|d \}
}|	| n d S )NT)return_schemasc                 S   s   | j rtd|  dd S )Nz!Tried to trace mutable operation z|. FX only supports functional code, so operations that mutate operands in-place (e.g. via `out` arguments) are not supported)Z
is_mutabler)   )schemar   r   r   throw_if_mutableg   s    z5check_for_mutable_operation.<locals>.throw_if_mutabler   r   )get_signature_for_torch_opzipbindr!   	TypeErrorrE   )rM   r   r   r%   schemasmatched_schemascandidate_signaturerO   erP   _Zschema_to_checkr   r   r   check_for_mutable_operationV   s"    rZ   )oprN   c                    s   t  tr jg}nnt  tr6 fdd  D }nLt }|rT|rP|dfS dS tjj	
 }|dkrv|rrdS dS tj|}dd |D }|r||fS |S )a  
    Given an operator on the `torch` namespace, return a list of `inspect.Signature`
    objects corresponding to the overloads of that op.. May return `None` if a signature
    could not be retrieved.

    Args:
        op (Callable): An operator on the `torch` namespace to look up a signature for

    Returns:
        Optional[List[inspect.Signature]]: A list of signatures for the overloads of this
            operator, or None if the operator signatures could not be retrieved. If
            return_schemas=True, returns a tuple containing the optional Python signatures
            and the optional TorchScript Function signature
    c                    s   g | ]}t  |jqS r   )getattr_schema)r;   overloadr[   r   r   r=      s     z.get_signature_for_torch_op.<locals>.<listcomp>N)NNc                 S   s   g | ]}t |qS r   )rL   r;   rO   r   r   r   r=      s     )
isinstancer   r]   r   Z	overloadsr   getr(   jitZ	_builtinsZ_find_builtin_CZ_jit_get_schemas_for_operator)r[   rN   rU   overrideZaten_fnr%   r   r_   r   rQ   z   s    



rQ   c              
   C   s   zt | tst | trt | tr*dd }ndd }t| dkrH|tW S | d }| D ]0}t||rfqTqTt||rv|}qT|t  W S qT||W S W n4 tk
r } ztj	d|   W 5 d }~X Y nX | S )Nc                 S   s   t |  S r   )r   xr   r   r   ret_type   s    z"create_type_hint.<locals>.ret_typec                 S   s   t | df S )N.)r   rf   r   r   r   rh      s    r   z@We were not able to successfully create type hint from the type )
ra   listrF   rE   r   
issubclass	Exceptionr(   warningswarn)rg   rh   Z	base_typer,   rX   r   r   r   create_type_hint   s&    




rn   )signature_typeargument_typec                    s.  t | d| }|  krdS |tjkrF|  krF| j}t fdd|D S | tt kr^ tkr^dS t | dd tthkr| jd t	st
d|  d dS t  dd tthkrt jd S fd	d
}| S | tkr tjkrdS | tjkr tthkrdS t	 r*t	| r*t | S dS )N
__origin__Tc                 3   s   | ]}t | V  qd S r   )type_matchesr;   c)rp   r   r   	<genexpr>   s     ztype_matches.<locals>.<genexpr>r   z.Does not support nested parametric types, got z. Please file a bug.Fc                    sB   t | dd tthkrdS | j}| jdkr,dS t fdd|D S )Nrq   F)r   Tc                 3   s    | ]}|t kpt| V  qd S r   )Ellipsisrj   rs   sig_el_typer   r   ru      s     z=type_matches.<locals>.is_homogeneous_tuple.<locals>.<genexpr>)r\   rF   r   __args__all)r,   Z	containedrw   r   r   is_homogeneous_tuple   s    
z*type_matches.<locals>.is_homogeneous_tuple)r\   typingUnionry   anyr   intri   r"   isclassrl   rm   rj   r(   ZdtypenumbersNumberfloat)ro   rp   Zsig_origin_typeZsig_containedr{   r   )rp   rx   r   rr      s4    


	
rr   )rM   r   r   	arg_typeskwarg_typesnormalize_to_only_use_kwargsr1   c                 C   s\  |dkri }d}t | tjst | tst | ts| }| tkrt | trJtt|  }|d |d  }	}
t	|	j
t	|
j
krdS |	}t|stt	t|}t||||}nt| stt| }g }|rX|D ]L}z|j|| || W q tk
r } zW Y qW 5 d}~X Y qX qt|dkr4n$t|dkrXt|d |||}n |dk	sl|dk	r*|rv|nttt d}|r|ni }|D ]}d}zB|j||}|j D ]&\}}|j
| }|ot|j|}qW n( tk
r } zd}W 5 d}~X Y nX |rt||||} qXqn.d	d
d |D }tdt|  d| |S )a  
    Returns normalized arguments to PyTorch functions. This means that
    `args/kwargs` will be matched up to the functional's
    signature and return exclusively kwargs in positional order if
    `normalize_to_only_use_kwargs` is True.
    Also populates default values. Does not support positional-only
    parameters or varargs parameters (*args, **kwargs). Does not support modules.

    May require `arg_types` and `kwarg_types` in order to disambiguate overloads.

    Args:
        target (Callable): Function that we are normalizing
        args (Tuple[Any]): Tuple of args to the function
        kwargs (Optional[Dict[str, Any]]): Dict of kwargs to the function
        arg_types (Optional[Tuple[Any]]): Tuple of arg types for the args
        kwarg_types (Optional[Dict[str, Any]]): Dict of arg types for the kwargs
        normalize_to_only_use_kwargs (bool): Whether to normalize to only use kwargs.

    Returns:

        Returns normalized_args_and_kwargs, or `None` if not successful.
    Nif_trueif_falser   r   r   TF
c                 s   s   | ]}t |V  qd S r   )r   r`   r   r   r   ru   C  s     z%normalize_function.<locals>.<genexpr>z Tried to normalize arguments to zy but the schema match was ambiguous! Please provide argument types to the normalize_arguments() call. Available schemas:
)ra   typesBuiltinFunctionTyper   r   r   r   AssertionErrorr"   r#   rH   callableunwrap&_args_kwargs_to_normalized_args_kwargsrQ   rS   r!   rT   rE   r	   r   r   r?   itemsrr   r9   joinr)   r(   typename)rM   r   r   r   r   r   new_args_and_kwargsZtarget_for_analysisZ
dispatchedr   r   sigZtorch_op_schemasrV   rW   rX   Zsig_matchesZbound_typesZarg_namerJ   paramZschema_printoutsr   r   r   normalize_function   sn    
r   )rootrM   r   r   r   r1   c           	      C   s   z|  |}W n$ tk
r2   td| dY nX t|jdr|jj}ttj|d|jkrt	
t	|j}|dkrzi }t||||}|S dS )a(  
    Returns normalized arguments to PyTorch modules. This means that
    `args/kwargs` will be matched up to the functional's
    signature and return exclusively kwargs in positional order if
    `normalize_to_only_use_kwargs` is True.
    Also populates default values. Does not support positional-only
    parameters or varargs parameters (*args, **kwargs).

    Args:
        root (nn.Module): root module upon which we query modules
        target (Callable): Function that we are normalizing
        args (Tuple[Any]): Tuple of args to the function
        kwargs (Optional[Dict[str, Any]]): Dict of kwargs to the function
        normalize_to_only_use_kwargs (bool): Whether to normalize to only use kwargs.

    Returns:

        Returns normalized_args_and_kwargs, or `None` if not successful.
    z$Tried to normalize node with target z# but root did not have that target!r   N)Zget_submoduleAttributeErrorr)   hasattr	__class__r   r\   r(   nnr"   r#   r   Zforwardr   )	r   rM   r   r   r   Zsubmod	classnamer   r   r   r   r   normalize_moduleJ  s    r   .)r   r   r   r   r1   c           	         s   t jjt jjh t fdd| j D r0dS | j||}|  i }g }t	| jD ]8\}}|s|t
|k r||j|  qV|j| ||< qVtt||S )a  
    Given a call target, args, and kwargs, return the arguments normalized into
    an ArgsKwargsPair, or None if the type signature is not supported by
    this normalization.

    Args:

        target (inspect.Signature): Signature object for the target
        args (Tuple): Arguments that appear at the callsite for `target`
        kwargs (Dict): Keyword arguments that appear at the callsite for `target`
        normalize_to_only_use_kwargs (bool): Whether to normalize to only use kwargs.

    Returns:

        Optional[ArgsKwargsPair]: Normalized args and kwargs for `target`, or `None` if
            this target is not supported.
    c                 3   s   | ]}|j  kV  qd S r   )r7   )r;   pZsupported_parameter_typesr   r   ru     s     z9_args_kwargs_to_normalized_args_kwargs.<locals>.<genexpr>N)r"   rA   rD   rC   r~   rH   valuesrS   apply_defaults	enumeraterE   r!   r?   r   rF   )	r   r   r   r   Z
bound_argsZ
new_kwargsnew_argsir   r   r   r   r   q  s     r   )F)NNNF)NF)=r(   r"   r   r   r|   enumrl   r   r   r   r   r   r   r   r	   r
   Ztorch._jit_internalr   Z_compatibilityr   Z
torch._opsr   r   noder   r   r   rG   r   r&   r   r'   r-   ZdeviceZlayoutr   rc   r/   EnumZqschemer:   TypeVarr3   dirkr\   r4   rd   ZFunctionSchemarL   r   rZ   r$   rQ   rn   rr   r   r   Moduler   r   r   r   r   r   <module>   s    ,    #!
/        
 a      &
 