
    Vh(                     .   U d dl Z d dlmZmZmZmZ d dlmc mc m	Z
 d dlmZ d dlmZmZmZ g dZd Zd Zd Zd Zd	 Zi ej,                  ej.                  feej,                  ej.                  ej0                  feej2                  ej4                  feej2                  ej4                  ej0                  feej6                  ej8                  feej6                  ej8                  ej0                  feej,                  ej0                  f ee
j:                        ej2                  ej0                  f ee
j<                        ej6                  ej0                  f ee
j>                        ej@                  ej.                  feej@                  ej0                  f ee
jB                        ej4                  ej0                  f ee
jD                        ej8                  ej0                  f ee
jF                        ejH                  ej.                  feejJ                  ej4                  feejL                  ej8                  feZ'e(e)eejT                  ef   f   e+d
<   ddZ,d Z-d Z.d Z/dede(eeejT                  ef   f   fdZ0y)    N)AnyCallableOptionalUnion)get_combined_dictMatchAllNodePattern)fuse_conv_bnfuse_conv_bn_relufuse_linear_bnfuse_convtranspose_bnget_fuser_methodget_fuser_method_newc                 6   |j                   |j                   k(  sJ d       t        j                  t        j                  t        j
                  t        j                  t        j                  t        j                  i}| r||j                  |j                  k(  sJ d       |j                  sJ d       |j                  sJ d       |j                  t        |      d      }|	 |||      S t        d||f       t        j                   j#                  ||      S )a  Return the fused the conv and bn modules.
    Given the conv and bn modules, fuses them and returns the fused module

    Args:
        is_qat: a flag for whether we are using quantization aware training fusion
        or post training quantization fusion
        conv: Module instance of type conv2d/conv3d
        bn: Spatial BN instance that needs to be fused with the conv

    Examples::

        >>> m1 = nn.Conv2d(10, 20, 3)
        >>> b1 = nn.BatchNorm2d(20)
        >>> # xdoctest: +SKIP
        >>> m2 = fuse_conv_bn(m1, b1)
    :Conv and BN both must be in the same mode (train or eval).z?Output channel of Conv2d must match num_features of BatchNorm2dz7Only support fusing BatchNorm2d with affine set to TruezGOnly support fusing BatchNorm2d with tracking_running_stats set to TrueNCannot fuse train modules: )trainingnnConv1dnniConvBn1dConv2dConvBn2dConv3dConvBn3dnum_featuresout_channelsaffinetrack_running_statsgettypeNotImplementedErrorutilsfuse_conv_bn_eval)is_qatconvbnfused_module_class_mapfused_module_classs        [/home/dcms/DCMS/lib/python3.12/site-packages/torch/ao/quantization/fuser_method_mappings.pyr
   r
      s   $ 	$DCD$ 			3<<
		3<<
		3<< OOt000	ML	M0yySSSy""	UT	U"377ddK)%dB//%(CT2J<&PQQxx))$33    c                    |j                   |j                   cxk(  r|j                   k(  sJ d        J d       d}| rt        j                  t        j                  t        j
                  t        j                  t        j                  t        j                  i}|j                  |j                  k(  sJ d       |j                  sJ d       |j                  sJ d       |j                  t        |      d      }|
 ||||      S t        d|||f       t        j                  t        j                   t        j
                  t        j"                  t        j                  t        j$                  i}|j                  t        |      d      }|3t        j&                  j(                  j+                  ||      } |||      S t        d|||f       )aJ  Return the fused conv and bv modules.

    Given the conv and bn modules, fuses them and returns the fused module

    Args:
        is_qat: a flag for whether we are using quantization aware training fusion
        or post training quantization fusion
        conv: Module instance of type conv2d/conv3d
        bn: Spatial BN instance that needs to be fused with the conv

    Examples::

        >>> m1 = nn.Conv2d(10, 20, 3)
        >>> b1 = nn.BatchNorm2d(20)
        >>> r1 = nn.ReLU(inplace=False)
        >>> # xdoctest: +SKIP
        >>> m2 = fuse_conv_bn_relu(m1, b1, r1)
    r   Nz;Output channel of Conv must match num_features of BatchNormz5Only support fusing BatchNorm with affine set to TruezEOnly support fusing BatchNorm with tracking_running_stats set to Truer   zCannot fuse eval modules: )r   r   r   r   ConvBnReLU1dr   ConvBnReLU2dr   ConvBnReLU3dr   r   r   r   r    r!   r"   
ConvReLU1d
ConvReLU2d
ConvReLU3dr#   fusionr$   )r%   r&   r'   relufused_modulemap_to_fused_module_trainmap_to_fused_module_eval
fused_convs           r*   r   r   @   s   ( 	55DCD5DCD526LIIs''IIs''IIs''%
! OOt000	IH	I0yyQQQy""	SR	S"044T$ZF#b$//%(CT2tDTCU&VWW IIs~~IIs~~IIs~~$
 
 033DJE#::4DJ
D11%(BD"dCSBT&UVVr+   c                 R   |j                   |j                   k(  sJ d       | r\|j                  |j                  k(  sJ d       |j                  sJ d       |j                  sJ d       t        j                  ||      S t        j                  j                  j                  ||      S )a  Return the fused linear and bn modules.
    Given the linear and bn modules, fuses them and returns the fused module

    Args:
        is_qat: a flag for whether we are using quantization aware training fusion
        or post training quantization fusion
        linear: Module instance of type Linear
        bn: BatchNorm1d instance that needs to be fused with the linear layer

    Examples::

        >>> m1 = nn.Linear(20, 10)
        >>> b1 = nn.BatchNorm1d(10)
        >>> # xdoctest: +SKIP
        >>> m2 = fuse_linear_bn(m1, b1)
    z<Linear and BN both must be in the same mode (train or eval).z@Output features of Linear must match num_features of BatchNorm1dz7Only support fusing BatchNorm1d with affine set to TruezGOnly support fusing BatchNorm1d with tracking_running_stats set to True)r   r   out_featuresr   r   r   
LinearBn1dr   r#   r3   fuse_linear_bn_eval)r%   linearr'   s      r*   r   r   w   s    $ 	2;;&FEF& OOv222	NM	N2yySSSy""	UT	U"~~fb))xx2262>>r+   c                     |j                   |j                   k(  sJ d       | rt        d      t        j                  j                  j                  ||d      S )a  Return the fused ConvTranspose and bn modules.
    Given ConvTranspose and bn modules, fuses them and returns the fused module

    Args:
        convt: Module instance of type ConvTransposeNd
        bn: BatchNormNd instance that needs to be fused with the linear layer.
            batch norm N should match the ConvTranspose N

    Examples::

        >>> m1 = nn.ConvTranspose2d(10, 20, 3)
        >>> b1 = nn.BatchNorm2d(20)
        >>> # xdoctest: +SKIP
        >>> m2 = fuse_convtranspose_bn(m1, b1)
    zCConvTranspose and BN both must be in the same mode (train or eval).z8Fusing ConvTranspose+BatchNorm not yet supported in QAT.T)	transpose)r   	Exceptionr   r#   r3   r$   )r%   convtr'   s      r*   r   r      s]    " 	"++%MLM% F
 	
 xx00d0KKr+   c                       fd}|S )a!  Return a sequential wrapped that for is_qat and two modules.
    Given a sequential class for two modules, return a function that takes
    is_qat, and then two modules as argument, that ignores the is_qat flag
    and always returns the sequential that combines the two input modules
    c                      ||      S N )r%   m1m2
sequentials      r*   fuser_methodz*_sequential_wrapper2.<locals>.fuser_method   s    "b!!r+   rE   )rH   rI   s   ` r*   _sequential_wrapper2rJ      s    " r+    _DEFAULT_OP_LIST_TO_FUSER_METHODc                 l    |i }t        t        |      }|j                  | d      }|J d|  d       |S )zGet fuser method for the given list of module types.

    Get fuser method for the given list of module types,
    return None if fuser method does not exist
    Ndid not find fuser method for:  )r   rK   r    )op_listadditional_fuser_method_mappingall_mappingsrI   s       r*   r   r      sU     '.*,'$(*IL  ##GT2L#Q'Fwiq%QQ#r+   c                       fd}|S )Nc                      | ||      S rD   rE   )r%   xyfs      r*   reversedz_reverse2.<locals>.reversed   s    Ar+   rE   rV   rW   s   ` r*   	_reverse2rY      s     Or+   c                       fd}|S )Nc                 $    |\  }} | |||      S rD   rE   )r%   rT   wrU   zrV   s        r*   rW   z_reverse3.<locals>.reversed   s    1Aq!!r+   rE   rX   s   ` r*   	_reverse3r^      s    " Or+   c                     t        | t        t        f      r5| D cg c]  }t        |       }}t        t	        j
                  |       }|S | t        g}|S c c}w )aQ  Return a list of valid patterns generated from the op_pattern.

    Returns a list of valid patterns generated from the op_pattern,
    since MatchAllNode can match all types of nodes,
    e.g. pattern (torch.nn.Conv2d, torch.add) should also be able to match keys like
    (MatchAllNode, torch.add) and (torch.nn.Conv2d, MatchAllNode)

    Example Input:
    (torch.add, (torch.nn.ReLU, torch.nn.Conv2d))

    Example Output:
    [(torch.add, (torch.nn.ReLU, torch.nn.Conv2d)),
     (torch.add, (torch.nn.ReLU, MatchAllNode)),
     (torch.add, (MatchAllNode, torch.nn.Conv2d)),
     (torch.add, (MatchAllNode, MatchAllNode)),
     (MatchAllNode, (torch.nn.ReLU, torch.nn.Conv2d)),
     (MatchAllNode, (torch.nn.ReLU, MatchAllNode)),
     (MatchAllNode, (MatchAllNode, torch.nn.Conv2d)),
     (MatchAllNode, (MatchAllNode, MatchAllNode)),
    ]
    )
isinstancetuplelist_get_valid_patterns	itertoolsproductr   )
op_patternsub_pattern	sub_combsresults       r*   rc   rc      s^    . *udm,IST+(5T	Ti''34 M l+M	 Us   Arf   fuser_method_mappingc                 t    t        |       }d}|D ]  } |j                  | d      }| n |J d|  d       |S )zGet fuser method.

    This will be made default after we deprecate the get_fuser_method
    Would like to implement this first and have a separate PR for deprecation
    NrM   rN   )rc   r    )rf   rj   op_patternsrI   s       r*   r   r     sa     &j1KL! 
+//
DA# #T'FzlRS%TT#r+   rD   )1rd   typingr   r   r   r   torch.ao.nn.intrinsicaor   	intrinsicr   torch.nntorch.ao.quantization.utilsr   r   r	   __all__r
   r   r   r   rJ   r   BatchNorm1dReLUr   BatchNorm2dr   BatchNorm3dr0   r1   r2   Linear
LinearReLUBNReLU2dBNReLU3dConvTranspose1dConvTranspose2dConvTranspose3drK   dictra   
Sequential__annotations__r   rY   r^   rc   r   rE   r+   r*   <module>r      s    1 1 # #  P P)4X4Wn?DL8
QYYQYY(*;Q YYQ YY(*;	Q
 YYQ YY(*;Q YY.s~~>Q YY.s~~>Q YY.s~~>Q YYQ YY.s~~>Q ^^RWW3CLLAQ ^^RWW3CLLAQ (*?Q (*?Q  (*?!Q  $ueBMM84K.L'L"M ( >wbmmX.E(FFGr+   