U
    yh\                      @   s@  d dl Z d dlmZ d dlm  mZ e jjZd dl	m
Z
 d dlmZ d dlmZ d dlmZ d dlmZ ddlmZ d d	lmZmZ d d
lmZmZmZmZmZmZmZ ee ee f eeeef  dddZ!eee ee ef f Z"eee"e"f ee"e"e"e"f f Z#eee#e$f  dddZ%ee#e
ee e&dddZ'dS )    N)GraphModule)Node)get_native_backend_config)!_get_pattern_to_quantize_handlers)getattr_from_fqn   )NSNodeTargetType)ObserverBaseFakeQuantizeBase)DictTupleSetCallableAnyUnionList) base_name_to_sets_of_related_opsreturnc                 C   st   t  }|  D ]`}t|}tdt|D ]D}t|t|D ]0}||| || f ||| || f q:q(q|S )Nr   )setvalueslistrangelenadd)r   Ztype_a_related_to_bsZs_listZidx_0Zidx_1 r   N/var/www/html/venv/lib/python3.8/site-packages/torch/ao/ns/fx/pattern_utils.pyget_type_a_related_to_b   s    r   )r   c            	   	   C   s  g } t t }d}| D ]}t|trpt|dkrpt|d trpt|d dkrp|d |d d |d d f}t|tr| ||f ttfD ]0}t|tr|f|}n||f}| ||f qqd}dt	j
ftjtjdf|ftjtjf|ftjtjf|ftjtjf|ftjtjtjf|ftjtjtjf|ftjtjtjf|fg}|D ]H}| | | tf|d |d f | tf|d |d f qH| S )a  
    Set of potential fusions, in reverse order.  The order is reversed
    to match how fusion patterns are defined in quantization code.

    Fusion format:
    ((fusion_op_0, fusion_op_1), base_op_idx)

    Where base_op_idx is the idx of the op we should use to match other related
    ops. Note: base_op_idx is specified in non-reverse order, i.e. a base_op_idx
    of 0 represents the first op in regular (non-reverse) order, 1 represents the
    second op, etc.
    r      r   toZ
dequantize)r   r   keys
isinstancetupler   appendr	   r
   torchZfloat16FZreluZlinearnnZBatchNorm1dZConv1dZBatchNorm2dZConv2dZBatchNorm3dZConv3dZReLU)	resultsZall_quant_patternsZdefault_base_op_idxZquant_patternclsZnew_patternZfp16_em_base_op_idxZpatterns_to_addpr   r   r   get_reversed_fusions2   s>    



 r*   )end_nodereversed_fusiongm
seen_nodesr   c                 C   s&  | }t t|D ]}||kr$ dS || }|jdkrt|t oLt|t }|r|j|krb dS t|jdkrt|jd tr|jd }q dS n dS q|jdkr2t|t}|r*t|jtst	t
||j}	t|ts dS t|	|s dS t|jdkr"t|jd tr"|jd }n dS n dS q|jdkrt|toTt|dk}
t|t}|sl|
r|r|j|kr dS nVt|tst	|j|d kr dS t|jdk r dS |jd |d kr dS t|jdkr
t|jd tr
|jd }n dS n dS q dS qdS )	zZ
    Returns true if a pattern ending with `end_node` matches
    the fusion pattern.
    FZcall_functionr   Zcall_moduleZcall_methodr   r   T)r   r   opr!   strtypetargetargsr   AssertionErrorr   r"   )r+   r,   r-   r.   Zcur_nodeZ
fusion_idxZcur_fusion_elZfusion_el_is_funZfusion_el_is_modZ
target_modZ!fusion_el_is_meth_with_second_argZfusion_el_is_meth_without_argsr   r   r    end_node_matches_reversed_fusion   sd    






"
"r5   )(r$   Ztorch.nnr&   Ztorch.nn.functionalZ
functionalr%   ZopsZ	quantizedZtoqZtorch.fxr   Ztorch.fx.graphr   Z$torch.ao.quantization.backend_configr   Z)torch.ao.quantization.fx.quantize_handlerr   Ztorch.ao.quantization.utilsr   Zns_typesr   Ztorch.ao.quantizationr	   r
   typingr   r   r   r   r   r   r   r0   r   ZNSFusionElTypeZNSFusionTypeintr*   boolr5   r   r   r   r   <module>   s@   $

N