
    Vh<                     V   U d dl Z d dlmZmZ d dlmZmZmZ d dlZd dl	m
Z
 d dlmZ d dlmZmZ d dlmZ d dlmZ d d	lmZmZmZ d d
lmZmZmZmZ d dlmZmZ d dl m!Z! d dl"m#Z# g Z$e%e&   e'd<   dede&dede(dedefdZ)de!defdZ*dejV                  jX                  de-e&ejV                  jX                  f   de#dede-e&e.e&e/f   f   de-e&ef   fdZ0dede1e&   de&ddfd Z2d!ed"efd#Z3d$ed%e%e   fd&Z4ded'eee&f   dedefd(Z5d) Z6d* Z7d+ Z8dede-eee&f   ef   fd,Z9ded-efd.Z:y)/    N)defaultdictOrderedDict)AnyCallableUnion)_FusedModule)QConfig)BackendConfigDTypeConfig)get_module_to_qat_module)_is_activation_post_process)_add_module_to_qconfig_obs_ctrqconfig_equals
QConfigAny)_MODULE_NAME_DICT_KEY_MODULE_NAME_REGEX_DICT_KEY_OBJECT_TYPE_DICT_KEYQConfigMapping)_parent_nameget_qconfig_dtypes)GraphModule)Graph__all__qconfig_mappingcur_module_pathcur_object_typecur_object_type_idxfallback_qconfigreturnc                 |    | j                   j                         D ]  \  \  }}}}||k(  s||k(  s||k(  s|c S  |S N)&module_name_object_type_order_qconfigsitems)	r   r   r   r   r   module_nameobject_typeindexqconfigs	            ^/home/dcms/DCMS/lib/python3.12/site-packages/torch/ao/quantization/fx/qconfig_mapping_utils.py7_maybe_adjust_qconfig_for_module_name_object_type_orderr)      s\     "HHNNP	
 	 	O+/--N
     modelc           	         |j                   }t        |      dk(  r|S t        | j                               }| j                  j
                  D ]  }|j                  dk(  s|j                  |v s"|t        |j                           }t        |t              sKt        |j                  j                               }|j                  t        |d         d      }|dd D ]Q  }t!        |j                  t        |      d      |      r)t#        ddt        |       dz   dt        |       z          |||t        |      <    y)	z
    Update the QConfigMapping to account for fused modules such as LinearReLU.
    This assumes the QConfigMapping's attributes have already been converted to OrderedDicts.
    r   call_moduleN   z+During fusion, we need to specify the same z!qconfigs for all module types in  zoffending type: )object_type_qconfigslendictnamed_modulesgraphnodesoptargetstr
isinstancer   list_modulesvaluesgettyper   LookupError)	r+   r   object_type_dictmodulesnodemaybe_fused_moduleopsfused_qconfigr6   s	            r(   _update_qconfig_for_fusionrF   4   sL   
 ';;
!5&&()G!! K77m#w(>!(T[[)9!:0,?)2299;<C,00c!ftDM !"g %$((b48- &E=dCU>V=WWXYZ,T"XJ78 	 (=J &8!9:7Kr*   rootrA   input_graphnode_name_to_scopec                 L   |j                   }i }t        d       }|j                  D ]y  }d }	|j                  dk(  rZt	        |j
                        \  }
}t        |t        ||
         |
|      }	t        |	|j                  |j
                  d             }n|j                  dk(  rt        ||j
                  |      }||j                     \  }}t        ||||      }	||   |j
                     }||   |j
                  xx   dz  cc<   t        |||j
                  ||	      }	t        |	|j                  |j
                  d             }nI|j                  dk(  r_||j                     \  }}t        ||j
                  ||      }	t        ||||	      }	t        |	|j                  |j
                  d             }n|j                  dk(  rt        ||j
                           rt        |t        ||j
                           |j
                  |      }	||j                     \  }}t	        |      \  }}||   |   }||   |xx   dz  cc<   t        |||||	      }	t        |	|j                  |j
                  d             }|||j
                     _        nd }|||j                  <   | |S )Nc                       t        t              S r!   )r   int r*   r(   <lambda>z0_generate_node_name_to_qconfig.<locals>.<lambda>n   s    C  r*   get_attrcall_functionr.   call_methodr-   )global_qconfigr   r5   r6   r   r7   -_maybe_adjust_qconfig_for_module_type_or_namer>   r   r=   _get_object_type_qconfignamer)   r   r'   )rG   rA   rH   r   rI   rR   node_name_to_qconfig#submodule_to_object_type_to_cur_idxrB   r'   r$   _qconfig_with_device_checkfunction_qconfigmodule_pathmodule_typer   parent_names                     r(   _generate_node_name_to_qconfigr^   ]   s    %33N KV K' !! SD77j )$++6NKCgk&:!;[.G )GT[[$7)% WW'  8n  (:$))'D$KCk;KG #Fk"R# 0<T[[IQNIMdkk;NPWG )GT[[$7)% WW%'9$))'D$K Dk>G
 Dk7G
 )GT[[$7)% WW%*74;;+?@Cgdkk&:!;T[[.G (:$))'D$K *+6NK"Ek"R# 0<[IQNIMk;NPWG )GT[[$7)% ,EGDKK ((,%*CTYY'gSDh  r*   config_dictallowed_keys	dict_namec                     | j                         D ],  }||vst        d|z   dz   t        |      z   dz   |z   dz          y)zChecks if the given config_dict has the correct keys

    Args:
      `config_dict`: dictionary whose keys we want to check
    z	Expected z to have the following keys: z. But found 'z
' instead.N)keys
ValueErrorr8   )r_   r`   ra   ks       r(   _check_is_valid_config_dictrf      sq      
L 12 l#$ "	"
   
r*   prepare_qconfig_mappingconvert_qconfig_mappingc                    t        | j                  |j                        sJ d       | j                  | j                  | j                  g}|j                  |j                  |j                  g}t
        t        t        g}t        t        |            D ]u  }||   j                         D ]]  }|||   v sJ d||    d| d       ||   |   $t        ||   |   ||   |         r=J d||    d| d||   |    d||   |            w y)	a  Compare the qconfig_mapping passed in convert to the one from prepare and check the values

    Args:
      `prepare_qconfig_mapping`: configuration for prepare quantization step
      `convert_qconfig_mapping`: configuration for convert quantization step
    zWExpected global qconfigs to be the same in the prepare and convert quantization configszMissing key r/   zI in convert QConfigMapping                 when it was present in prepareNzLExpected convert QConfigMapping to have the same qconfig as prepare for key z;                 prepare: z; convert: )r   rR   r0   module_name_qconfigsmodule_name_regex_qconfigsr   r   r   ranger1   rc   )rg   rh   prepare_dictsconvert_dicts
dict_namesirU   s          r(   )_compare_prepare_convert_qconfig_mappingsrq      s    ..0G0V0V a`a  	 4444::(M 	 4444::(M 	#J
 3}%& 	V!!$))+ 	VDa((0jm_AdV 4/ 00( !#D)1^a &a(8(>6 V]^hij^k]llmnrms t'*401]1=Md=S<TVV 	V	Vr*   r'   dtype_configsc                 `   |D ](  }|j                   }|d}|j                  xs t        j                  }|j                  xs t        j                  }|j
                  xs t        j                  }|j                  xs t        j                  }t        |       \  }}	}
|t        j                  k(  r%|	t        j                  k(  r|st        j                  nt        j                  }|r&|
xr! ||k(  xr |t        j                  k(  xr ||	k(  }n||k(  xr ||k(  xr ||	k(  xr ||k(  }|s) y y)NFT)	
is_dynamicinput_dtypetorchfloatweight_dtype
bias_dtypeoutput_dtyper   float16)r'   rr   dtype_configrt   ru   rx   ry   rz   qconfig_activation_dtypeqconfig_weight_dtypeqconfig_input_act_is_dynamicqconfig_bias_dtypeis_matchs                r(   &_is_qconfig_supported_by_dtype_configsr     sL    & &!,,
J"..=%++#00?EKK!,,;
#00?EKK
 w'		
$ (
 )EMM9(EMM9"	 MM  	 , 9#;;9 EKK/9 !$88	  77 5 $<<5 $885 "44	  M&N r*   r%   c                 :    | j                   j                  ||      S r!   )r0   r=   )r   r%   r   s      r(   rT   rT   1  s    
 //33KAQRRr*   c                 ~    | j                   j                         D ]  \  }}t        j                  ||      s|c S  |S r!   )rk   r#   rematch)r   r$   r   regex_patternr'   s        r(   _get_module_name_regex_qconfigr   9  s@    "1"L"L"R"R"T w88M;/N r*   c                     |dk(  r|S || j                   v r| j                   |   S t        |      \  }}t        | ||      S )N )rj   r   _get_module_name_qconfig)r   r$   r   parentrX   s        r(   r   r   A  sM    bo:::33K@@ -	'AQRRr*   c                 T    t        | ||      }t        | ||      }t        | ||      }|S r!   )rT   r   r   )r   r\   r$   rR   module_type_qconfigmodule_name_regex_qconfigmodule_name_qconfigs          r(   rS   rS   L  sH     3n !?&9! 3&? r*   c                     d| j                   i}| j                  j                         D ]
  \  }}|||<    | j                  j                         D ]
  \  }}|||<    |S )a  flatten the global, object_type and module_name qconfig
    to the same qconfig_dict so that it can be used by
    propagate_qconfig_ function.
    "module_name_regex" is ignored for now since it's not supported
    in propagate_qconfig_, but it can be fixed later.

    For example:
    Input: {
      "": qconfig,
      "object_type": [
        (torch.add, qconfig)
      ],
      "module_name": [
        ("conv", qconfig)
      ]
    }

    Output: {
      "": qconfig,
      torch.add: qconfig,
      "conv": qconfig
    }
    r   )rR   r0   r#   rj   )r   	flattenedobjr'   s       r(   _get_flattened_qconfig_dictr   ^  st    6 	O**9I (<<BBD !W 	#!'<<BBD !W 	#!r*   backend_configc                     t        |      }| j                  }|j                         }|j                         D ]  \  }}||v s||||   <    y)z
    Update the qconfig_mapping to account for module swaps during QAT.
    During QAT we perform a module swap on the nn.Module types to the corresponding nn.qat.modules types.
    N)r   r0   copyr#   )r   r   module_to_qat_module_classr@   new_object_type_dictre   vs          r(   _update_qconfig_for_qatr     sb     ":.!I&;;+002$**, @1**>?7:;@r*   );r   collectionsr   r   typingr   r   r   rv   torch.ao.nn.intrinsicr   torch.ao.quantizationr	   $torch.ao.quantization.backend_configr
   r   *torch.ao.quantization.backend_config.utilsr   torch.ao.quantization.observerr   torch.ao.quantization.qconfigr   r   r   %torch.ao.quantization.qconfig_mappingr   r   r   r   torch.ao.quantization.utilsr   r   torch.fxr   torch.fx.graphr   r   r:   r8   __annotations__rL   r)   rF   nnModuler2   tupler>   r^   setrf   rq   r   rT   r   r   rS   r   r   rM   r*   r(   <module>r      s   	 0 ' '  . ) K O F 
  I     c #  	
 ! *&Kk &KN &KRg 
((//g #uxx&'g  g  $	g 
 S%T	"223g  
#z/g T$'H9<	,$V+$VFT$VN**%)+%6*ZS#Sx}%S !S 	SS$!#!	%#


*+!H@#@5B@r*   