
    sg(                     >   U d dl Z d dlmZmZmZmZ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j4                  ej6                  feej4                  ej6                  ej8                  feej:                  ej<                  feej:                  ej<                  ej8                  feej>                  ej@                  feej>                  ej@                  ej8                  feej4                  ej8                  f eejB                        ej:                  ej8                  f eejD                        ej>                  ej8                  f eejF                        ejH                  ej6                  feejH                  ej8                  f eejJ                        ej<                  ej8                  f eejL                        ej@                  ej8                  f eejN                        ejP                  ej6                  feejR                  ej<                  feejT                  ej@                  feZ+eee	ejX                  ef   f   e-d
<   ddZ.d Z/d Z0d Z1dedeee	ejX                  ef   f   fdZ2y)    N)AnyCallableDictListOptionalTupleType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        ^/var/www/html/venv/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'   r7   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'   r7   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/   rI   )rL   rM   s   ` r.   _sequential_wrapper2rN      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   rO   r$   )op_listadditional_fuser_method_mappingall_mappingsrM   s       r.   r   r      sU     '.*,'$(*IL  ##GT2L#Q'Fwiq%QQ#r/   c                       fd}|S )Nc                      | ||      S rH   rI   )r)   xyfs      r.   reversedz_reverse2.<locals>.reversed   s    Ar/   rI   rZ   r[   s   ` r.   	_reverse2r]      s     Or/   c                       fd}|S )Nc                 $    |\  }} | |||      S rH   rI   )r)   rX   wrY   zrZ   s        r.   r[   z_reverse3.<locals>.reversed   s    1Aq!!r/   rI   r\   s   ` r.   	_reverse3rb      s    " Or/   c                     t        | t        t        f      r@g }| D ]  }|j                  t	        |              t        t        j                  |       }|S | t        g}|S )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append_get_valid_patterns	itertoolsproductr   )
op_pattern	sub_combssub_patternresults       r.   rh   rh      sg    . *udm,	% 	?K0=>	?i''34 M l+Mr/   rk   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
    NrQ   rR   )rh   r$   )rk   ro   op_patternsrM   s       r.   r   r     sa     &j1KL! 
+//
DA# #T'FzlRS%TT#r/   rH   )3ri   typingr   r   r   r   r   r   r	   r
   torch.ao.nn.intrinsicaor   	intrinsicr   torch.nntorch.ao.quantization.utilsr   r   r   __all__r   r   r   r   rN   r   BatchNorm1dReLUr   BatchNorm2dr   BatchNorm3dr4   r5   r6   Linear
LinearReLUBNReLU2dBNReLU3dConvTranspose1dConvTranspose2dConvTranspose3drO   
Sequential__annotations__r   r]   rb   rh   r   rI   r/   r.   <module>r      s    J J J # #  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 ( BwbmmX.E(FFGr/   