
    ȅi*                     *   % S SK r S SKJr  S SKJr  S SKJs  Js  Jr	  S SK
Jr  S SKJrJrJr  / SQrS rS rS rS	 rS
 r0 \R*                  \R,                  4\_\R*                  \R,                  \R.                  4\_\R0                  \R2                  4\_\R0                  \R2                  \R.                  4\_\R4                  \R6                  4\_\R4                  \R6                  \R.                  4\_\R*                  \R.                  4\" \	R8                  5      _\R0                  \R.                  4\" \	R:                  5      _\R4                  \R.                  4\" \	R<                  5      _\R>                  \R,                  4\_\R>                  \R.                  4\" \	R@                  5      _\R2                  \R.                  4\" \	RB                  5      _\R6                  \R.                  4\" \	RD                  5      _\RF                  \R,                  4\_\RH                  \R2                  4\_\RJ                  \R6                  4\_r&\'\(\RR                  \-  4   \*S'   SS jr+S r,S r-S r.S\S\'\\RR                  \-  4   4S jr/g)    N)Callable)Any)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                 r   UR                   UR                   :w  a  [        S5      e[        R                  [        R
                  [        R                  [        R                  [        R                  [        R                  0nU (       a  UR                  UR                  :w  a  [        S5      eUR                  (       d  [        S5      eUR                  (       d  [        S5      eUR                  [        U5      5      nUb  U" X5      $ [!        SX4 35      e[        R"                  R%                  X5      $ )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 BatchNorm2d.7Only support fusing BatchNorm2d with affine set to TrueGOnly support fusing BatchNorm2d with tracking_running_stats set to TrueCannot fuse train modules: )trainingAssertionError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        e/home/james-whalen/.local/lib/python3.13/site-packages/torch/ao/quantization/fuser_method_mappings.pyr   r      s   " }}#H
 	

 			3<<
		3<<
		3<< ??d/// R  yy I  %% Y  477T
C)%d//%(CTJ<&PQQxx))$33    c                    UR                   UR                   s=:X  a  UR                   :X  d  O  [        S5      eSnU (       a  [        R                  [        R
                  [        R                  [        R                  [        R                  [        R                  0nUR                  UR                  :w  a  [        S5      eUR                  (       d  [        S5      eUR                  (       d  [        S5      eUR                  [        U5      5      nUb	  U" XU5      $ [!        SXU4 35      e[        R                  [        R"                  [        R                  [        R$                  [        R                  [        R&                  0nUR                  [        U5      5      nUb1  [        R(                  R*                  R-                  X5      nU" Xs5      $ [!        SXU4 35      e)a  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 Conv2d must match num_features of BatchNorm2dr   r   r   zCannot fuse eval modules: )r   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	   G   s   & MMR[[9DMM9H
 	
 04LIIs''IIs''IIs''%
!
 ??d/// Q  yy I  %% Y  144T$Z@#$//%(CTtDTCU&VWW IIs~~IIs~~IIs~~$
 
 033DJ?#::4DJ
11%(BDdCSBT&UVVr,   c                    UR                   UR                   :w  a  [        S5      eU (       as  UR                  UR                  :w  a  [        S5      eUR                  (       d  [        S5      eUR
                  (       d  [        S5      e[        R                  " X5      $ [        R                  R                  R                  X5      $ )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   r   out_featuresr   r    r   
LinearBn1dr   r$   r4   fuse_linear_bn_eval)r&   linearr(   s      r+   r
   r
      s    " "++%J
 	
 ??f111 R  yy I  %% Y  ~~f))xx226>>r,   c                     UR                   UR                   :w  a  [        S5      eU (       a  [        S5      e[        R                  R
                  R                  XSS9$ )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   r   	Exceptionr   r$   r4   r%   )r&   convtr(   s      r+   r   r      sY      ~~$Q
 	
 F
 	
 xx00d0KKr,   c                    ^  U 4S jnU$ )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                    > T" X5      $ N )r&   m1m2
sequentials      r+   fuser_method*_sequential_wrapper2.<locals>.fuser_method   s    "!!r,   rF   )rI   rJ   s   ` r+   _sequential_wrapper2rL      s    " r,    _DEFAULT_OP_LIST_TO_FUSER_METHODc                 x    Uc  0 n[        [        U5      nUR                  U S5      nUc  [        SU  S35      eU$ )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   rM   r!   r   )op_listadditional_fuser_method_mappingall_mappingsrJ   s       r+   r   r      sU     '.*,'$(*IL  ##GT2L>wiqIJJr,   c                    ^  U 4S jnU$ )Nc                    > T" XU5      $ rE   rF   )r&   xyfs      r+   reversed_reverse2.<locals>.reversed   s    Ar,   rF   rX   rY   s   ` r+   	_reverse2r\      s     Or,   c                    ^  U 4S jnU$ )Nc                    > Uu  p4T" XX15      $ rE   rF   )r&   rV   wrW   zrX   s        r+   rY   _reverse3.<locals>.reversed  s    A!!r,   rF   r[   s   ` r+   	_reverse3rb     s    " Or,   c                     [        U [        [        45      (       a9  U  Vs/ s H  n[        U5      PM     nn[        [        R
                  " U6 5      nU$ U [        /nU$ s  snf )a  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+   rg   rg   
  sb    . *udm,,IST+(5	Ti''34 M l+M	 Us   Arj   fuser_method_mappingc                     [        U 5      nSnU H  n UR                  U 5      nUc  M    O   Uc  [        SU  S35      eU$ )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
NrO   rP   )rg   r!   r   )rj   rn   op_patternsrJ   s       r+   r   r   )  sY     &j1KL!
+//
;# " >zl!LMMr,   rE   )0rh   collections.abcr   typingr   torch.ao.nn.intrinsicaor   	intrinsicr   torch.nntorch.ao.quantization.utilsr   r   r   __all__r   r	   r
   r   rL   r   BatchNorm1dReLUr   BatchNorm2dr   BatchNorm3dr1   r2   r3   Linear
LinearReLUBNReLU2dBNReLU3dConvTranspose1dConvTranspose2dConvTranspose3drM   dictre   
Sequential__annotations__r   r\   rb   rg   r   rF   r,   r+   <module>r      s    $  # #  P P/4d:Wz%?PL:
KYYKYY(*;K YYK YY(*;	K
 YYK YY(*;K YY.s~~>K YY.s~~>K YY.s~~>K YYK YY.s~~>K ^^RWW3CLLAK ^^RWW3CLLAK (*?K (*?K  (*?!K  $ubmmh.F'F"G (">w(@@Ar,   