U
    Kc                     @   s  d dl mZmZmZmZmZmZmZ d dlZd dl	m
Z
 d dlm
  mZ ddlmZmZ ddlmZ ddd	d
ddddddddgZeeeee f dddZeeedf dddZeeedf ddd	Zeeeeeef f ddd
Zeeeej
j eej
j f dddZeeeee
jef f dddZeeeeej
j f dddZeeeef dddZ eeeef dddZ!edddZ"edd dZ#edd!dZ$dS )"    )DictAnyListCallableUnionTupleTypeN   )BackendConfigDTypeConfig   )Patternget_pattern_to_dtype_configsget_qat_module_classesget_fused_module_classes"get_pattern_to_input_type_to_index-get_root_module_to_quantized_reference_moduleget_fuser_method_mappingget_module_to_qat_module&get_fusion_pattern_to_root_node_getter)get_fusion_pattern_to_extra_inputs_getter!remove_boolean_dispatch_from_namepattern_to_human_readableentry_to_pretty_str)backend_configreturnc                 C   s&   i }| j  D ]\}}|j||< q|S N)configsitemsdtype_configs)r   Zpattern_to_dtype_configspatternconfig r"   N/tmp/pip-unpacked-wheel-gikjz4vx/torch/ao/quantization/backend_config/utils.pyr      s    .c                 C   s6   g }| j  D ]}|jd k	r||j qtt|S r   )r   values
qat_moduleappendtupleset)r   Zqat_module_classesr!   r"   r"   r#   r      s
    
c                 C   s6   g }| j  D ]}|jd k	r||j qtt|S r   )r   r$   Zfused_moduler&   r'   r(   )r   Zfused_module_classesr!   r"   r"   r#   r   %   s
    
c                 C   s&   i }| j  D ]\}}|j||< q|S r   )r   r   Z_input_type_to_index)r   Zpattern_to_input_type_to_indexr    r!   r"   r"   r#   r   ,   s    c                 C   s8   i }| j  D ]$}|jd k	r|jd k	r|j||j< q|S r   )r   r$   Zroot_moduleZreference_quantized_module)r   mappingr!   r"   r"   r#   r   2   s
    c                 C   s0   i }| j  D ]\}}|jd k	r|j||< q|S r   )r   r   Zfuser_method)r   Zfuser_method_mappingr    r!   r"   r"   r#   r   :   s
    
c                 C   s0   i }| j  D ]\}}|jd k	r|j||< q|S r   )r   r   r%   )r   Zmodule_to_qat_moduler    r!   r"   r"   r#   r   A   s
    
c                 C   s0   i }| j  D ]\}}|jdk	r|j||< q|S )a   Get a map from fusion pattern to a function that returns the root node
    from the fusion pattern, e.g. the most common one is:
    def get_root_node(node_pattern):
        while not isinstance(node_pattern[-1], Node):
            node_pattern = node_pattern[-1]
        return node_pattern[-1]
    This can work for all patterns whose root node is the "last node" in the pattern,
    e.g. (torch.add, MatchAllNode, (torch.ReLU, torch.Conv2d))
    N)r   r   Z_root_node_getter)r   Zroot_node_getter_mappingr    r!   r"   r"   r#   r   H   s
    

c                 C   s0   i }| j  D ]\}}|jdk	r|j||< q|S )a   Get a map from fusion pattern to a function that returns extra input nodes
    from the fusion pattern, in the order required by the root node. This is optional,
    if not specified, we will not copy over any extra inputs for the root node.
    Example:
    # Let's say we have the pattern (torch.add, MatchAllNode, (torch.nn.BatchNorm2d, torch.nn.Conv2d))
    # and root node is torch.nn.Conv2d, and the node in MatchAllNode would be an extra
    # argument to the fused module, we can unpack the pattern and return the node at
    # MatchAllNode here
    # we can implement extra_inputs_getter as follows:
    def extra_inputs_getter(pattern) -> List[Any]:
        add, extra_input, conv_pattern = pattern
        return [extra_input]
    N)r   r   Z_extra_inputs_getter)r   Zextra_inputs_getter_mappingr    r!   r"   r"   r#   r   X   s
    
)r   c                 C   s   | t jkrdS | t jkrdS | t jkr*dS | t jkr8dS | t jkrFdS | t jkrTdS | t jkrbdS | t jkrpdS d	t	| kst
|  d
d | S )z
    Some ops have a default string representation such as
    '<function boolean_dispatch.<locals>.fn at 0x7ff1106bf280>',
    this function replaces them with the hardcoded function names.
    z)torch.nn.functional.fractional_max_pool2dz)torch.nn.functional.fractional_max_pool3dztorch.nn.functional.max_pool1dztorch.nn.functional.max_pool2dztorch.nn.functional.max_pool3dz'torch.nn.functional.adaptive_max_pool1dz'torch.nn.functional.adaptive_max_pool2dz'torch.nn.functional.adaptive_max_pool3dZboolean_dispatchz2 does not have a human readable representation in zquantization documentation)FZfractional_max_pool2dZfractional_max_pool3dZ
max_pool1dZ
max_pool2dZ
max_pool3dZadaptive_max_pool1dZadaptive_max_pool2dZadaptive_max_pool3dstrAssertionErrorpr"   r"   r#   r   l   s,    







c                 C   s:   t | trtdd | D S t | tr*| S t| } | S d S )Nc                 s   s   | ]}t |V  qd S r   )r   ).0Zinner_pr"   r"   r#   	<genexpr>   s     z,pattern_to_human_readable.<locals>.<genexpr>)
isinstancer'   r+   r   r-   r"   r"   r#   r      s    

c                 C   s  d}d| kr(t | d }|d| d7 }d| kr|d7 }| d D ]<}|d7 }| D ]\}}|d| d	| d7 }qT|d
7 }q@|d7 }d| kr|d7 }| d  D ]\}}|d| d| d7 }q|d7 }dddg}| D ](}||krq|d| d	| |  d7 }q|d7 }|S )zo
    Given a backend_config_dict entry, returns a string with the human readable
    representation of it.
    z{
r    z  'pattern': z,
r   z  'dtype_configs': [
z    {
z      'z': z    },
z  ],
Z#num_tensor_args_to_observation_typez+  'num_tensor_args_to_observation_type': {
z    z: z  },
z  '})r   r   )entrysZpattern_strZdtype_configkvZcustom_handled_fields
field_namer"   r"   r#   r      s6    
)%typingr   r   r   r   r   r   r   ZtorchZtorch.nnnnZtorch.nn.functionalZ
functionalr*   r   r
   r   Zquantization_typesr   __all__r   typer   r   r+   intr   Moduler   Z
Sequentialr   r   r   r   r   r   r   r"   r"   r"   r#   <module>   s@   $  " 