U
    Jck                     @   s\  d dl Z d dlZd dlZd dlZd dlmZ ddlmZ ddl	m
Z
mZ dddd	d
gZeZejejejejej  ejeejej f f  Zejeef ZeddG dd de jZeddG dd deZejejeejjf ejjgef Z edde edddZ!eddeeddd	Z"eddG dd
 d
Z#ejjej$dddZ%dS )    N)compatibility   )TensorMetadata)get_node_targetCALLABLE_NODE_OPSOperatorSupportBaseOperatorSupportcreate_op_supportchain
OpSupportsF)Zis_backward_compatiblec                   @   s:   e Zd ZdZejejee	j
jf e	jjedddZdS )r   z@Interface for determining if a fx.Node is supported by a backend
submodulesnodereturnc                 C   s
   t  d S N)NotImplementedErrorselfr   r    r   D/tmp/pip-unpacked-wheel-gikjz4vx/torch/fx/passes/operator_support.pyis_node_supported   s    z%OperatorSupportBase.is_node_supportedN)__name__
__module____qualname____doc__abcabstractmethodtMappingstrtorchnnModulefxNodeboolr   r   r   r   r   r      s    c                   @   sT   e Zd ZU dZeed< d
eje dddZej	e
ejjf ejjeddd	ZdS )r   a  
    `_support_dict` maps node.target typename to supported inputs dtypes.

    node.target typename is retrieved using helper function `get_node_target()`

    If supported inputs dtypes is None, it means any dtype is supported, else
    we should see a tuple like (([dtypes], ...), {"name":[dtypes], ...}).

    The first tuple ([dtypes], ...) indicates what dtypes are supported for
    inputs in node.args and the second dict {"name": [dtypes], ...} indicates
    what dtypes are supported for inputs in node.kwargs.

    For inputs in args, if we don't want to check it, we can put None there,
    e.g. (None, [torch.float]) indicates that we don't care about the type of
    the first input in args. And for inputs in kwargs, if not listed, will not
    be checked.
    _support_dictN)support_dictc                 C   s   |pi | _ d S r   )r&   )r   r'   r   r   r   __init__;   s    zOperatorSupport.__init__r   c                 C   s   |j tkrdS t||}|| jkr&dS | j| dkr8dS | j| \}}t|D ]V\}}t|j|krh q|dkrrqNt|j| tj	j
sqNt|j| }||krN dS qN| D ]F\}	}|	|jkrqt|j|	 tj	j
sqt|j|	 }
|
|kr dS qdS )aM  
        Args:
            `sumodules`: mapping from module name to the module. This can be
                         retrieved by calling model.named_modules().

            `node`: a Fx node that we want to determine whether it's supported.

        Returns:
            `is_supported`: whether the arg `node` is supported.
        TFN)opr   r   r&   	enumeratelenargs
isinstancer    r#   r$   _get_arg_dtypeitemskwargs)r   r   r   targetZargs_dtypesZkwargs_dtypesiZdtypes	arg_dtypekZkwarg_dtyper   r   r   r   A   s6    



z!OperatorSupport.is_node_supported)N)r   r   r   r   SupportDict__annotations__r   Optionalr(   r   r   r    r!   r"   r#   r$   r%   r   r   r   r   r   r   %   s   
  )r   r   c                    s   G  fdddt }| S )zWraps a `IsNodeSupported` function into an `OperatorSupportBase` instance

    `IsNodeSupported` has the same call signature as
    `OperatorSupportBase.is_node_supported`
    c                       s4   e Zd Zejeejjf ej	j
ed fddZdS )z4create_op_support.<locals>.FunctionalOperatorSupportr   c                    s
    ||S r   r   r   r   r   r   r      s    zFcreate_op_support.<locals>.FunctionalOperatorSupport.is_node_supportedN)r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r   r   r8   r   r   FunctionalOperatorSupport   s    r9   )r   )r   r9   r   r8   r   r	      s    )
op_supportr   c                     s   t d fdd}t|S )zCombines a sequence of `OperatorSupportBase` instances to form a single `OperatorSupportBase`
    instance by evaluating each input `OperatorSupportBase` instance, and returns False if
    any of it reports False.
    )r   c                    s   t  fddD S )Nc                 3   s   | ]}|  V  qd S r   r8   ).0xr   submodsr   r   	<genexpr>   s   z(chain.<locals>._chain.<locals>.<genexpr>)all)r>   r   r:   r=   r   _chain   s    zchain.<locals>._chain)r%   r	   )r:   rB   r   rA   r   r
      s    c                   @   s@   e Zd ZdZeejedddZee	j
e edddZdS )	r   zA set of atomic `OperatorSupportBase` instances that can be combined together
    to form more complex operator support logic.
    )dtyper   c                    s0   t jttjjf tjjtd fdd}t	|S )zCReport a node as non-supported, if any of its arguments is of dtyper   c                    s2   |j D ]&}|jdkrqt|}| kr dS qdS )NZget_attrFT)Zall_input_nodesr)   r.   )r   r   argr3   rC   r   r   _decline_if_input_dtype   s    

zBOpSupports.decline_if_input_dtype.<locals>._decline_if_input_dtype
r   r   r   r    r!   r"   r#   r$   r%   r	   )clsrC   rF   r   rE   r   decline_if_input_dtype   s
    z!OpSupports.decline_if_input_dtype)disallow_setr   c                    s0   t jttjjf tjjtd fdd}t	|S )za
        If a node has a name that is in the disallow set, reported it as non-supported.
        r   c                    s   |j  krdS dS d S )NFT)name)r   r   rJ   r   r   _decline_if_node_in_names   s    
zFOpSupports.decline_if_node_in_names.<locals>._decline_if_node_in_namesrG   )rH   rJ   rM   r   rL   r   decline_if_node_in_names   s
    z#OpSupports.decline_if_node_in_namesN)r   r   r   r   classmethodr    rC   r   rI   r   Setr   rN   r   r   r   r   r      s
   )rD   r   c                 C   s<   t | tjjst| jd}t |tr.|jn| jd }|S )Ntensor_metatype)	r-   r    r#   r$   AssertionErrormetagetr   rC   )rD   rQ   rC   r   r   r   r.      s    r.   )&r   typingr   r    Ztorch.fxZtorch.fx._compatibilityr   Z
shape_propr   Ztools_commonr   r   __all__r   ZTargetTypeNamer7   TupleSequencerC   DictZSupportedArgumentDTypesr   r5   ABCr   r   Callabler!   r"   r#   r$   r%   ZIsNodeSupportedr	   r
   r   Anyr.   r   r   r   r   <module>   s8   	]$&