+
    "Ý³j?Æ  ã                   ó  € R t ^ RIt^ RIt^ RIt^ RIt^ RIHt ^ RIHtH	t	 ^ RI
HtHtHtHt ^ RIt^ RIHu Ht ^ RIHt ^ RIHtHt ^ RIHtHtHt ^ RIHtHt ^ R	I H!t!  ^ R
I"H#t# ^ RI&H't' . RZOt(R t)R t*R R lt+R t,R t-R R lt.R R lt/R t0R t1R R lt2R R lt3R R  lt4R! R" lt5R# R$ lt6]Pn                  3R% R& llt8R' R( lt9R) R* lt:R+ R, lt;R[R- R. llt<]Pz                  P|                  P~                  P€                  ]Pz                  P|                  P~                  P‚                  ]Pz                  P|                  P„                  P€                  .tC]Pz                  P|                  Pˆ                  P€                  ]Pz                  P|                  Pˆ                  P‚                  ]Pz                  P|                  PŠ                  P€                  .tFR/ R0 ltGR1 tHR2 tIR3 R4 ltJR5 R6 ltKR7 R8 ltLR9 R: ltMR; R< ltNR= R> ltOR? R@ ltPR\RA RB lltQR\RC RD lltRRE RF ltSRG RH ltTRI RJ ltUR\RK RL lltVRM RN ltWRO tXR]RP RQ lltYR^RR RS lltZRT RU lt[RV RW lt\RX RY lt]R#   ]$ d    ^ RI"H%t% R R lt# ELi ; i)_z?
Utils shared by different modes of quantization (eager/graph)
N)ÚOrderedDict)ÚgetfullargspecÚ	signature)ÚAnyÚCallableÚOptionalÚUnion)Úquantized_decomposed_lib)Ú_assign_attrÚ	_AttrKind)ÚGraphÚGraphModuleÚNode)Úfuse_conv_bn_weightsÚfuse_linear_bn_weights)Úis_parametrized)Útreespec_leaf©ÚLeafSpecc                ó   € V ^8„  d   QhRR/# )é   Úreturnr   © )Úformats   "Ú`/home/luca/screen-checking/.venv/lib/python3.14/site-packages/torchao/quantization/pt2e/utils.pyÚ__annotate__r   (   s   € ÷ ñ ˜:ñ ó    c                  ó   € \        4       # ©Nr   r   r   r   r   r   (   s
   € Ü‹zÐr   )Ú_assert_and_get_unique_devicec                 ó^   € V \         P                  8H  ;'       g    V \         P                  8H  # r   )ÚtorchÚper_tensor_affineÚper_tensor_symmetric©Úqschemes   &r   Úis_per_tensorr&   E   s&   € Ø”e×-Ñ-Ñ-×VÐV°¼E×<VÑ<VÑ1VÐVr   c                 óf   € V \         P                  \         P                  \         P                  39   # r   )r!   Úper_channel_affineÚ per_channel_affine_float_qparamsÚper_channel_symmetricr$   s   &r   Úis_per_channelr+   I   s/   € ØÜ× Ñ Ü×.Ñ.Ü×#Ñ#ðñ ð r   c                ó<   € V ^8„  d   QhR\         R\        R\         /# )r   ÚobjÚfqnr   )r   Ústr)r   s   "r   r   r   Q   s!   € ÷ :ñ :œ#ð :¤Cð :¬Cñ :r   c                óX   € \         P                  ! \        VP                  R4      V 4      # )zG
Given an obj and a fqn such as "foo.bar.baz", returns gm.foo.bar.baz.
Ú.)Ú	functoolsÚreduceÚgetattrÚsplit)r-   r.   s   &&r   Úgetattr_from_fqnr6   Q   s!   € ô ×ÒœG S§Y¡Y¨s£^°SÓ9Ð9r   c                 ó   € \         P                  \         P                  \         P                  \         P                  \         P
                  \         P                  \         P                  \         P                  \         P                  \         P                  \         P                  \         P                  \         P                  \         P                  \         P                  \         P                  \         P                  \         P                  \         P                  \         P                  \         P                  \         P                  \         P                  \         P                  /pW9   g   Q R \        V 4      ,           4       hW,          # )zUnsupported dtype: )r!   Úquint8Úuint8Úqint8Úint8Úqint32Úint32Úquint4x2Úquint2x4Úuint16Úint16Úfloat8_e5m2Úfloat8_e4m3fnr/   )ÚqdtypeÚDTYPE_MAPPINGs   & r   Úto_underlying_dtyperF   X   sÓ   € ä�‰”e—k‘kÜ�‰”U—Z‘ZÜ�‰”e—k‘kÜ�‰œŸ™Ü�‰œŸ™Ü�‰”U—[‘[Ü�
‰
”E—J‘JÜ�‰”e—l‘lÜ�‰”U—[‘[Ü�‰”U—[‘[Ü×Ñœ5×,Ñ,Ü×ÑœU×0Ñ0ð€Mð Ô"ÐGÐ$9¼CÀ»KÕ$GÓGÐ"ØÕ Ð r   c                 ó:  € ^ RI Hp \        V RR4      pV P                  pRVRV/pV'       d   \	        W4      '       d   RRRV/# \        V4      '       d   \        P                  pMT\        V4      '       d6   V\        P                  8X  d   \        P                  pV P                  VR&   M\        RV 24      hW$R&   V P                  4       w  rVWTR&   WdR&   \        V R	4      '       d   V P                  VR	&   \        V R
4      '       d   V P                   VR
&   V# )é    )ÚPlaceholderObserverr%   NÚdtypeÚaxiszUnrecognized qscheme: ÚscaleÚ
zero_pointÚ	quant_minÚ	quant_max)Ú"torchao.quantization.pt2e.observerrI   r4   rJ   Ú
isinstancer&   r!   r"   r+   r*   r(   Úch_axisÚRuntimeErrorÚcalculate_qparamsÚhasattrrN   rO   )Úobserver_or_fake_quantrI   r%   rJ   ÚqparamsrL   rM   s   &      r   Úget_qparam_dictrX   k   s  € ÝFäÐ,¨i¸Ó>€GØ"×(Ñ(€EØ˜' 7¨EÐ2€Gç”jÐ!7×MÒMØ˜4 ¨%Ð0Ð0ä�W×ÒÜ×)Ñ)‰Ü	˜×	 Ò	 ð ”e×1Ñ1Ô1Ü×.Ñ.ˆGØ0×8Ñ8ˆ�ŠäÐ3°G°9Ð=Ó>Ð>ð !ˆIÑà.×@Ñ@ÓBÑ€EØˆGÑØ&ˆLÑäÐ% {×3Ò3Ø5×?Ñ?ˆ�ÑÜÐ% {×3Ò3Ø5×?Ñ?ˆ�Ñà€Nr   c                ód   € V ^8„  d   QhR\         P                  R\         P                  R\        /# )r   Úmin_valÚmax_valr   )r!   ÚTensorÚbool)r   s   "r   r   r   �   s)   € ÷ ñ ¤§¡ð ¼¿¹ð Ìñ r   c                óÐ  € V P                  4       ^ 8X  g   VP                  4       ^ 8X  d   \        P                  ! R4       R# V P                  4       ^ 8X  g   VP                  4       ^ 8X  dO   V \	        R4      8X  d)   V\	        R4      8X  d   \        P                  ! R4       R# W8:  g   Q RV  RV 24       h R# \
        P                  ! W8*  4      '       g   Q RV  RV 24       hR# )z€Checks if the given minimum and maximum values are valid, meaning that
they exist and the min value is less than the max value.
FÚinfz-infzmin z should be less than max TzMmust run observer before calling calculate_qparams. Returning default values.)ÚnumelÚwarningsÚwarnÚdimÚfloatr!   Úall)rZ   r[   s   &&r   Úcheck_min_max_validrf   �   sØ   € ð ‡}�}ƒ˜!Ô˜wŸ}™}›°!Ô3Ü�Šð*ô	
ñ à‡{�{ƒ}˜Ô˜WŸ[™[›]¨aÔ/Ø”e˜E“lÔ" w´%¸³-Ô'?Ü�MŠMð.ôñ
 àÔ!ÐU T¨'¨Ð2KÈGÈ9Ð#UÓUÑ!ñ ô	 �yŠy˜Ñ+×,Ò,ð 	
Ø�7�)Ð4°W°IÐ>ó	
Ð,ñ r   c                ó–   € V ^8„  d   QhR\         R\         R\        R\        P                  R\        R\        \         \         3,          /# )r   rN   rO   Úhas_customized_qrangerJ   Úreduce_ranger   )Úintr]   r!   rJ   Útuple)r   s   "r   r   r   ¬   sP   € ÷ ; ñ ; Üð; äð; ô  ð; ô �;‰;ð	; ô
 ð; ô Œ3”ˆ8…_ñ; r   c                ó¢  € V'       dì   V\         P                  \         P                  39   d   ^ RreM^ ^ÿreYr‡Ve   Ve   TTreWe,
          ^,           p	V\         P                  \         P                  39   d    ^ T	u;8  d   R8:  g   Q R4       h Q R4       hMCV\         P                  \         P                  39   d   ^ T	u;8  d   R8:  g   Q R4       h Q R4       hV'       d   V ^,          V^,          rW3# V\         P                  \         P                  39   d   V'       d   R^?rW3# R^r W3# V\         P
                  \         P                  39   d   V'       d   ^ ^rW3# ^ ^ÿr W3# V\         P                  \         P                  39   d   RR	rW3# V\         P                  39   d   ^ R
rW3# V\         P                  39   d   RRrW3# ^ ^rW3# )zlCalculates actual qmin and qmax based on the quantization range,
observer datatype and if range is reduced.
é   zRquantization range should be positive and not exceed the maximum bit range (=256).zYquantization range should be positive and not exceed the maximum bit range (=4294967296).l        l   ÿÿ iÀÿÿÿi€ÿÿÿi   €iÿÿÿiÿÿ  i €ÿÿiÿ  )	r!   r<   r=   r:   r;   r8   r9   r@   rA   )
rN   rO   rh   rJ   ri   Úinitial_quant_minÚinitial_quant_maxÚcustom_quant_minÚcustom_quant_maxÚ
qrange_lens
   &&&&&     r   Úcalculate_qmin_qmaxrs   ¬   s   € ÷ ð ”U—\‘\¤5§;¡;Ð/Ô/Ø34°iÑ0à34°cÐ0ð .7Ð*ØÒ'Ð,<Ò,Hà Ø ð  1ð
 'Õ:¸QÕ>ˆ
Ø”U—[‘[¤%§*¡*Ð-Ô-Ø�zÖ( SÔ(ð ØdóÑ(ð ØdóÑ(ð ”u—|‘|¤U§[¡[Ð1Ô1Ø�zÖ* UÔ*ð ØkóÑ*ð ØkóÐ*÷ Ø#,°¥>°9Àµ>�yð* ÐÐð% ”U—[‘[¤%§*¡*Ð-Ô-ßØ'*¨B˜9ð  ÐÐð (,¨S™9ð ÐÐð ”u—|‘|¤U§[¡[Ð1Ô1ßØ'(¨#˜9ð ÐÐð ()¨#™9ð ÐÐð ”u—|‘|¤U§[¡[Ð1Ô1Ø#/°�yð ÐÐð ”u—|‘|�nÔ$Ø#$ i�yð
 ÐÐð	 ”u—{‘{�mÔ#Ø#+¨Y�yð ÐÐð $% b�yØÐÐr   c                ó€   € V P                  R^4      p\        V4      ^8X  d   RV^ ,          3# V^ ,          V^,          3# )z$
Turn 'foo.bar' into ['foo', 'bar']
r1   Ú )ÚrsplitÚlen)ÚtargetÚrs   & r   Ú_parent_namerz   ê   s>   € ð 	�‰�c˜1Ó€AÜ
ˆ1ƒv�„{Ø�1�Q•4ˆxˆà��t�Q�q•TˆzÐr   c                ó¾   € \        V P                  4      ^ 8X  d   R# \        V 4      '       d0   \        V P                  4      ^8H  ;'       d    RV P                  9   # R# )zŠ
Checks if module._modules is empty or
if module is a parametrization, checks that module._modules only has
the 'parametrizations' module
TÚparametrizationsF)rw   Ú_modulesr   )Úmodules   &r   Ú)has_no_children_ignoring_parametrizationsr   õ   sL   € ô ˆ6�?‰?Ó˜qÔ ÙÜ	˜×	 Ò	 Ü�6—?‘?Ó# qÑ(×RÐRÐ-?À6Ç?Á?Ñ-RÐRár   c                ó¢   € V ^8„  d   QhR\         P                  P                  R\         P                  P                  R\        \        ,          /# )r   ÚrootÚ	submoduler   )r!   ÚnnÚModuler   r/   )r   s   "r   r   r     s8   € ÷ ñ Ü
�(‰(�/‰/ðÜ&+§h¡h§o¡oðäŒc…]ñr   c                óJ   € V P                  4        F  w  r#WJ g   K  Vu # 	  R# )a.  Get the path (fully qualified name) of a submodule

Example::

>> class M(torch.nn.Module):
       def __init__(self) -> None:
           self.linear = torch.nn.Linear(5, 5)
       def forward(self, x):
           return self.linear(x)

>> m = M()
>> l = m.linear
>> _get_path_of_module(m, l)
"linear"
N)Únamed_modules)r�   r‚   ÚnÚps   &&  r   Ú_get_path_of_moduler‰     s(   € ð$ ×"Ñ"Ö$‰ˆØ�>ØŠHñ %ñ r   c                ó€   € V ^8„  d   QhR\         R\        \        \        3,          R\        \        \        3,          /# )r   ÚfÚlocr   ©r   Údictr/   r   )r   s   "r   r   r     s6   € ÷ Jñ JœXð J¬D´´c°­Nð J¼tÄCÌÀH½~ñ Jr   c                óŽ   € VP                  4        UUu/ uF#  w  r#V\        V 4      P                  9   g   K!  W#bK%  	  upp# u uppi )z�Get local keyword arguments

Example::

>> def f(self, a, b=9):
       pass
>> loc = {"a": 6, "c": 7}
>> _get_signature_locals(f, loc)
{"a": 6}
)Úitemsr   Ú
parameters)r‹   rŒ   ÚkÚvs   &&  r   Ú_get_signature_localsr”     s9   € ð !ŸY™Yœ[ÔI™[‘T�Q¨A´¸1³×1HÑ1HÑ,HŒDˆAŠD™[ÒIÐIùÓIs
   ”A·Ac                ó(   € V ^8„  d   QhR\         RR/# )r   r‹   r   úOrderedDict[str, Any]©r   )r   s   "r   r   r   )  s   € ÷ ñ œ8ð Ð(?ñ r   c                óH  € / p\        V 4      P                  P                  4        Fo  w  r#VP                  VP                  Jd   VP                  W&   K/  VP
                  VP                  J d   RW&   KO  VP
                  VP                  J g   Kk  / W&   Kq  	  \        V4      # )z�Get all default keyword arguments from function signature

Example::

>> def f(self, a, b=9):
       pass
>> _get_default_kwargs(f)
{"b": 9}
r   )	r   r‘   r�   ÚdefaultÚemptyÚkindÚVAR_POSITIONALÚVAR_KEYWORDr   )r‹   ÚkwargsÚnameÚparams   &   r   Ú_get_default_kwargsr¡   )  s‚   € ð €FÜ  “|×.Ñ.×4Ñ4Ö6‰ˆØ�=‰= §¡Ó+Ø Ÿ=™=ˆF‹LØ�Z‰Z˜5×/Ñ/Ó/ØˆF‹LØ�Z‰Z˜5×,Ñ,Õ,ØˆF‹Lñ 7ô �vÓÐr   c                óV   € V ^8„  d   QhR\         R\        \        \        3,          RR/# )r   ÚfuncrŒ   r   r–   r�   )r   s   "r   r   r   >  s*   € ÷ ñ œHð ¬4´´S°­>ð Ð>Uñ r   c                óœ   € \        V 4      p\        W4      pVP                  4       pVP                  4        F  w  rVWT9   g   K  WdV&   K  	  V# )a  Given a function and local function arguments, normalize the keyword
arguments by filling in default arguments from function signature

Example::

>> def f(self, key1=3, key2=3):
       pass
>> loc = {"key2": 6}
>> _normalize_kwargs(f, loc)
{"key1": 3, "key2": 6}
)r¡   r”   Úcopyr�   )r£   rŒ   Údefault_kwargsÚlocal_kwargsÚnormalized_kwargsÚattrÚvals   &&     r   Ú_normalize_kwargsr«   >  sR   € ô )¨Ó.€NÜ(¨Ó3€LØ&×+Ñ+Ó-ÐØ!×'Ñ'Ö)‰	ˆØÖ$à&)˜dÓ#ñ *ð Ðr   c                ó4   € V ^8„  d   QhR\         R\         RR/# )r   rN   rO   r   N©rj   )r   s   "r   r   r   T  s!   € ÷ ñ ¤#ð ´#ð ¸$ñ r   c                ó\   € V ^ u;8:  d   V8:  g   Q R4       h Q R4       hW8  g   Q R4       hR# )a=  Validates that the user-specified quantization range is properly initialized
and within the given bound supported by the observer dtype.

To accommodate lower-bit quantization with respect to the existing torch.qint8 and
torch.quint8 datatypes, the user can choose to use dynamic quantization range by passing
in a tuple of initial qmin and qmax values. One use case is these customized qmin and qmax
values are used to calculate static estimates of the scale and zero point for aggressive lower-bit
fake quantization. These estimates are compared against parameters learned through backpropagation.
The related literatures for scale and zero point via backpropagation are as follows:

Learned Step Size Quantization: https://openreview.net/pdf?id=rkgO66VKDS
Trained Quantization Thresholds: https://arxiv.org/pdf/1903.08066.pdf
z1Used-specified quantization range must include 0.zKqmin must be strictly less than qmax for user-specified quantization range.Nr   )rN   rO   s   &&r   Úvalidate_qmin_qmaxr¯   T  sI   € ð  ˜Ö&˜YÔ&ð Ø;óÑ&ð Ø;óÐ&ð Ô ð ØUóÒ r   c                ó2  € V ^8„  d   QhR\         P                  R\         P                  R\        R\        R\         P                  R\         P                  R\        R\         P
                  R	\        \         P                  \         P                  3,          /	# )
r   rZ   r[   rN   rO   rJ   Úepsrh   r%   r   )r!   r\   rj   rJ   r]   r%   rk   )r   s   "r   r   r   p  s“   € ÷ K>ñ K>Ü�\‰\ðK>ä�\‰\ðK>ô ðK>ô ð	K>ô
 �;‰;ðK>ô 
�‰ðK>ô  ðK>ô �]‰]ðK>ô Œ5�<‰<œŸ™Ð%Õ&ñK>r   c                ó�  € \        W4      '       g[   \        P                  ! R.V P                  P                  R7      \        P                  ! ^ .V P                  P                  R7      3# \        P
                  ! V \        P                  ! V 4      4      p\        P                  ! V\        P                  ! V4      4      p	VP                  p
\        P                  ! VP                  4       \        P                  V
R7      p\        P                  ! VP                  4       \        P                  V
R7      pVP                  V
4      pV\        P                  8X  g   V\        P                  8X  dË   \        P                  ! V) V	4      p	V	\!        W2,
          4      ^,          ,          p\        P                  ! Wµ4      pV\        P"                  \        P$                  39   dX   V'       d0   VP'                  VP                  4       W#,           ^,          4      pEMVP'                  VP                  4       ^€4      pMýV\        P(                  8X  d^   W,
          \!        W2,
          4      ,          p\        P*                  ! Wµ8„  V\        P,                  ! V4      4      pRV ,          V,          pM‹W˜,
          \!        W2,
          4      ,          p\        P                  ! Wµ4      pV\        P.                  ! W‹,          4      P                  \        P0                  4      ,
          p\        P2                  ! WÂV4      p\5        VP6                  4      ^ 8X  d.   \        P                  ! \!        V4      .VP8                  V
R7      p\5        VP6                  4      ^ 8X  dp   \        P                  ! \1        V4      .VP8                  V
R7      pV\        P(                  8X  d.   \        P                  ! \!        V4      .VP8                  V
R7      pVP                  \        P                  4      VP                  \        P                  4      3# )aD  Calculates the quantization parameters, given min and max
value tensors. Works for both per tensor and per channel cases

Args:
    min_val: Minimum values per channel
    max_val: Maximum values per channel

Returns:
    scales: Scales tensor of shape (#channels,)
    zero_points: Zero points tensor of shape (#channels,)
g      ð?©Údevice)rJ   r´   éÿÿÿÿ)rf   r!   Útensorr´   ÚtypeÚminÚ
zeros_likeÚmaxÚonesÚsizeÚdoubleÚzerosÚint64Útor#   r*   rd   r9   r8   Únew_fullr)   ÚwhereÚ	ones_likeÚroundrj   Úclamprw   ÚshaperJ   )rZ   r[   rN   rO   rJ   r±   rh   r%   Úmin_val_negÚmax_val_posr´   rL   rM   s   &&&&&&&&     r   Údetermine_qparamsrÉ   p  sî  € ô* ˜w×0Ò0Ü�|Š|˜S˜E¨'¯.©.×*=Ñ*=Ô>ÄÇÂØˆC˜Ÿ™×+Ñ+ôA
ð 
ð 	
ô —)’)˜G¤U×%5Ò%5°gÓ%>Ó?€KÜ—)’)˜G¤U×%5Ò%5°gÓ%>Ó?€Kà×Ñ€FÜ�JŠJ�{×'Ñ'Ó)´·±ÀfÔM€EÜ—’˜[×-Ñ-Ó/´u·{±{È6ÔR€JØ
�&‰&�‹.€Cà”%×,Ñ,Ô,°¼5×;VÑ;VÔ0VÜ—i’i  ¨kÓ:ˆØœu YÕ%:Ó;¸aÕ?Õ@ˆÜ—	’	˜%Ó%ˆØ”U—[‘[¤%§,¡,Ð/Ô/ß$à'×0Ñ0Ø—O‘OÓ%¨	Õ(=À!Õ'Có’
ð (×0Ñ0°·±Ó1BÀCÓH�
øØ	”E×:Ñ:Ô	:ØÕ"¤e¨IÕ,AÓ&BÕBˆÜ—’˜E™K¨´·²ÀÓ0FÓGˆð
 ˜'•\ EÕ)‰
àÕ*¬e°IÕ4IÓ.JÕJˆÜ—	’	˜%Ó%ˆØ¤§¢¨[Õ-@Ó!A×!DÑ!DÄUÇYÁYÓ!OÕOˆ
Ü—[’[ ¸	ÓBˆ
ô ˆ5�;‰;Ó˜1Ôä—’œe E›l˜^°5·;±;ÀvÔNˆÜ
ˆ:×ÑÓ Ô!ä—\’\Ü�‹_Ð Z×%5Ñ%5¸fô
ˆ
ð ”e×<Ñ<Ô<ÜŸšÜ�zÓ"Ð#¨:×+;Ñ+;ÀFôˆJð �8‰8”E—L‘LÓ! :§=¡=´·±Ó#=Ð=Ð=r   c                ó0   € V ^8„  d   QhR\         R\        /# )r   r‹   r   )r   rj   )r   s   "r   r   r   ¾  s   € ÷ 
'ñ 
'œð 
'¤cñ 
'r   c                ó>   € \        \        V 4      P                  4      # )zGet number of positional args for a function

Example::

>> def f(self, key1=3, key2=3):
       pass
>> _get_num_pos_args(f)
3
)rw   r   Úargs)r‹   s   &r   Ú_get_num_pos_argsrÍ   ¾  s   € ô Œ~˜aÓ ×%Ñ%Ó&Ð&r   c          
      óº   € V ^8„  d   QhR\         P                  P                  R\        \        R3,          R\
        \        \        \        R3,          3,          /# )r   ÚmodelÚexample_inputs.r   )r!   rƒ   r„   rk   r   rŽ   r/   )r   s   "r   r   r   Ë  sF   € ÷ 6!ñ 6!Ü�8‰8�?‰?ð6!Ü,1´#°s°(­Oð6!ä	Œ#Œu”S˜#�X�Ð
Õñ6!r   c                ó>  aaa€ V o/ oVVV3R lp\         P                  P                  P                  oV\         P                  P                  n         V ! V!   S\         P                  P                  n        S#   S\         P                  P                  n        i ; i)aÑ  Given a model and its example inputs, return a dictionary from
fully qualified name of submodules to example_inputs for that submodule,
e.g. {"linear1": (tensor1,), "linear2": (tensor2,), "sub": (tensor3,),
      "sub.linear1": (tensor4,), ...}

Used to make quantizing submodules easier now that FX Graph Mode Quantization requires
example inputs.

Also works for keyword arguments with default values, we would flatten keyword
arguments as positional arguments and fill in the missing keyword args with default
values, e.g. if we have a forward function:
def forward(self, x, key1=3, key2=3):
    ...

and we call it with self.submodule(x, key2=6)
we'll get example_inputs: (x, 3, 6)

user can also override `key1` with positional arguments as well:
for self.submodule(x, 5, key2=6)
we'll get: (x, 5, 6)

variable positional arguments and variable positional keyword arguments in forward
function are not supported currently, so please make sure no submodules is using
them.
c                 ó®  <€ \        V4      P                  4       p\        V P                  V4      p\	        V P                  4      ^,
          pV\        V4      ,
          pV'       d&   V'       d   VP                  RR7       V^,          pK-  VP                  VP                  4       4       \        V4      p\        SV 4      pVe   VS	V&   S
! V .VO5/ VB # )é   F)Úlast)Úlistr¥   r«   ÚforwardrÍ   rw   ÚpopitemÚextendÚvaluesrk   r‰   )ÚselfrÌ   rž   Úsubmodule_example_inputsr¨   Únum_argsÚ
num_to_popÚsubmodule_example_inputs_tupler.   Úfqn_to_example_inputsÚorig_module_callr�   s   &*,      €€€r   Ú_patched_module_callÚ7get_fqn_to_example_inputs.<locals>._patched_module_callê  s½   ø€ Ü#'¨£:§?¡?Ó#4Ð Ü-¨d¯l©l¸FÓCÐä$ T§\¡\Ó2°QÕ6ˆØ¤Ð$<Ó =Õ=ˆ
ß×.Ø×%Ñ%¨5Ð%Ô1Ø˜!�OŠJØ ×'Ñ'Ð(9×(@Ñ(@Ó(BÔCÜ).Ð/GÓ)HÐ&Ü! $¨Ó-ˆØŠ?Ø)GÐ! #Ñ&Ù Ð6 tÒ6¨vÑ6Ð6r   )r!   rƒ   r„   Ú__call__)rÏ   rÐ   rá   rß   rà   r�   s   && @@@r   Úget_fqn_to_example_inputsrä   Ë  st   ú€ ð8 €DØÐ÷7ô  —x‘x—‘×/Ñ/ÐØ3„E‡H�H‡O�OÔð4Ùˆ~Òð $4Œ�‰�‰Ô Ø Ð øð $4Œ�‰�‰Õ ús   ÁA; Á;!Bc                ó0   € V ^8„  d   QhR\         R\        /# )r   Úprefixr   )r/   r   )r   s   "r   r   r   	  s   € ÷ ñ ¬#ð ´(ñ r   c                 ó>   a € S P                  R R4      o R V 3R llpV# )r1   Ú_c                óL   € V ^8„  d   QhR\         P                  P                  /# )r   r~   )r!   rƒ   r„   )r   s   "r   r   Ú3get_new_attr_name_with_prefix.<locals>.__annotate__  s   € ÷ 	ñ 	¤%§(¡(§/¡/ñ 	r   c                 óv   <€ R  V3R llp^ pV! V4      p\        W4      '       d   V^,          pV! V4      pK$  V# )c                ó$   € V ^8„  d   QhR\         /# )r   Úir­   )r   s   "r   r   ÚNget_new_attr_name_with_prefix.<locals>.get_new_attr_name.<locals>.__annotate__  s   € ÷ 	#ñ 	#œSñ 	#r   c                 ó(   <€ S\        V 4      ,           # r   )r/   )rí   ræ   s   &€r   Úget_attr_nameÚOget_new_attr_name_with_prefix.<locals>.get_new_attr_name.<locals>.get_attr_name  s   ø€ ØœC ›F•?Ð"r   )rU   )r~   rð   rí   Ú	attr_nameræ   s   &   €r   Úget_new_attr_nameÚ8get_new_attr_name_with_prefix.<locals>.get_new_attr_name  sB   ø€ ÷	#ð 	#ð ˆÙ! !Ó$ˆ	Ü�f×(Ò(Ø��FˆAÙ% aÓ(ŠIØÐr   )Úreplace)ræ   ró   s   f r   Úget_new_attr_name_with_prefixrö   	  s%   ø€ Ø�^‰^˜C Ó%€F÷	ð 	ð Ðr   c                ó²   € V ^8„  d   QhR\         P                  P                  R\        R\        R\
        R\        \         P                  ,          R\        /# )r   r~   Úgraphræ   Úvaluer´   r   )	r!   rƒ   r„   r   r/   r   r   r´   r   )r   s   "r   r   r     sU   € ÷ ñ Ü�H‰H�O‰Oðäðô ðô ð	ô
 ”U—\‘\Õ"ðô 
ñr   c                ó:  € \        V4      pV! V 4      pVf   \        V 4      p\        V\        P                  4      '       d   VP                  4       P                  4       M\        P                  ! W4R7      pV P                  Wg4       VP                  RV4      pV# )z�
Given a value of any type, creates a getattr node corresponding to the value and
registers the value as a buffer to the module.
r³   Úget_attr)
rö   r   rQ   r!   r\   ÚdetachÚcloner¶   Úregister_bufferÚcreate_node)	r~   rø   ræ   rù   r´   ró   rò   Ú	new_valueÚ	attr_nodes	   &&&&&    r   Úcreate_getattr_from_valuer    sˆ   € ô 6°fÓ=ÐÙ! &Ó)€IØ‚~Ü.¨vÓ6ˆô �eœUŸ\™\×*Ò*ð 	�‰‹×ÑÔä�\Š\˜%Ô/ð ð
 ×Ñ˜9Ô0à×!Ñ! *¨iÓ8€IØÐr   c                óŒ   € V ^8„  d   QhR\         P                  P                  R\         P                  P                  R\        /# )r   ÚsourceÚdestr   )r!   Úfxr   r]   )r   s   "r   r   r   B  s1   € ÷ ñ œ%Ÿ(™(Ÿ-™-ð ¬u¯x©x¯}©}ð Äñ r   c                ó¦  € \         \        ,           pVP                  \        P                  P
                  P                  P                  4       VP                  V9   dp   \        VP                  ^ ,          \        P                  P                  4      '       g    \        RVP                  ^ ,           24      hVP                  ^ ,          pK€  W8H  # )zÅ
Assuming dest is one of the ops inserted by quant workflow, this function
finds if source and dest are connected. Assumption is that only quant workflow
inserted ops exist between source and dest
z=expected arg[0] of quant workflow ops to be a node but found )Ú_QUANTIZE_OPSÚ_DEQUANTIZE_OPSÚappendr!   ÚopsÚquantized_decomposedÚchoose_qparamsr¶   rx   rQ   rÌ   r  r   Ú
ValueError)r  r  Úquant_workflow_opss   && r   Ú_is_connectedr  B  s˜   € ô '¬Õ8ÐØ×ÑœeŸi™i×<Ñ<×KÑK×RÑRÔSØ
�+‰+Ð+Ô
+Ü˜$Ÿ)™) A�,¬¯©¯©×6Ò6ÜØOÐPT×PYÑPYÐZ[ÕP\È~Ð^óð ð �y‰y˜�|ŠØ‰>Ðr   c           	      óv  € V f   R # V P                   R8X  d   \        R4      hV P                   R8w  d   \        RV P                    24      hV P                  P                  R4      pTp\	        V4       FA  w  rE\        W54      '       g!   \        RRP                  VR V 4       24      h\        W54      pKC  	  V# )NÚplaceholderznExpected get_attr node, got placeholder. If working with an ExportedProgram, make sure you are using .module()rû   zExpected get_attr node, got r1   z#Node referenced nonexistent target )	Úopr  rx   r5   Ú	enumeraterU   rS   Újoinr4   )ÚnodeÚmÚtarget_atomsÚattr_itrrí   Úatoms   &&    r   Ú_get_tensor_constant_from_noder  S  s¾   € Ø‚|ÙØ‡w�w�-ÔÜðTó
ð 	
ð ‡w�w�*ÔÜÐ7¸¿¹°yÐAÓBÐBØ—;‘;×$Ñ$ SÓ)€LØ€HÜ˜\Ö*‰ˆÜ�x×&Ò&ÜØ5°c·h±h¸|ÈBÈQÐ?OÓ6PÐ5QÐRóð ô ˜8Ó*Šñ +ð €Or   c                 óF  € . p\        V4       F�  w  rEVP                  V9   d$   VP                  WP                  ,          4       K9  VP                  '       g*   V\	        V 4      8  d   VP                  W,          4       Kt  VP                  VP
                  4       K‘  	  V# r   )r  rŸ   r
  Ú
kwarg_onlyrw   Údefault_value)Ú	orig_argsÚorig_kwargsÚargs_schemaÚall_argsrí   Úschemas   &&&   r   Ú_get_all_argumentsr$  h  su   € Ø€HÜ˜{Ö+‰	ˆØ�;‰;˜+Ô%Ø�O‰O˜K¯©Õ4Ö5Ø×"×"Ð" q¬3¨y«>Ô'9Ø�O‰O˜I�LÖ)à�O‰O˜F×0Ñ0Ö1ñ ,ð €Or   c                ó$   € V ^8„  d   QhR\         /# ©r   r  ©r   )r   s   "r   r   r   t  s   € ÷ (ñ (´ñ (r   c                óŒ  € \         P                  P                  P                  P                  \         P                  P                  P
                  P                  \         P                  P                  P                  P                  \         P                  P                  P                  P                  .pV P                  V9   # )zM
Return True if the given node refers to an aten batch norm op QAT supports.
)	r!   r  ÚatenÚ
batch_normr™   Ú_native_batch_norm_legitÚcudnn_batch_normÚmiopen_batch_normrx   )r  Úsupported_opss   & r   Ú%_is_supported_batch_norm_for_trainingr/  t  sz   € ô
 	�	‰	�‰×!Ñ!×)Ñ)Ü�	‰	�‰×/Ñ/×7Ñ7ô 	�	‰	�‰×'Ñ'×/Ñ/Ü�	‰	�‰×(Ñ(×0Ñ0ð€Mð �;‰;˜-Ñ'Ð'r   c                ó$   € V ^8„  d   QhR\         /# ©r   r‡   r'  )r   s   "r   r   r   „  s   € ÷ ñ ”Tñ r   c                ól  € V P                   R8H  ;'       Ed    V P                  \        P                  P                  P
                  P                  \        P                  P                  P
                  P                  \        P                  P                  P                  P                  \        P                  P                  P                  P                  \        P                  P                  P                  P                  \        P                  P                  P                  P                  39   # )z4
Return whether the node refers to an aten conv op.
Úcall_function)
r  rx   r!   r  r)  Úconv1dr™   ÚpaddingÚconv2dÚconv3d©r‡   s   &r   Ú_is_conv_noder9  „  s¹   € ð �4‰4�?Ñ"÷ ñ  q§x¡xÜ�	‰	�‰×Ñ×%Ñ%Ü�	‰	�‰×Ñ×%Ñ%Ü�	‰	�‰×Ñ×%Ñ%Ü�	‰	�‰×Ñ×%Ñ%Ü�	‰	�‰×Ñ×%Ñ%Ü�	‰	�‰×Ñ×%Ñ%ð4ñ (ð r   c                ó$   € V ^8„  d   QhR\         /# r1  r'  )r   s   "r   r   r   ’  s   € ÷ ñ œtñ r   c                ó0  € V P                   R8H  ;'       Ed     V P                  \        P                  P                  P
                  \        P                  P                  P
                  P                  \        P                  P                  P                  \        P                  P                  P                  P                  \        P                  P                  P                  \        P                  P                  P                  P                  39   # )z>
Return whether the node refers to an aten conv_transpose op.
r3  )
r  rx   r!   r  r)  Úconv_transpose1dr™   Úconv_transpose2dÚinputÚconv_transpose3dr8  s   &r   Ú_is_conv_transpose_noder@  ’  s§   € ð �4‰4�?Ñ"÷ ñ  q§x¡xÜ�	‰	�‰×'Ñ'Ü�	‰	�‰×'Ñ'×/Ñ/Ü�	‰	�‰×'Ñ'Ü�	‰	�‰×'Ñ'×-Ñ-Ü�	‰	�‰×'Ñ'Ü�	‰	�‰×'Ñ'×-Ñ-ð4ñ (ð r   c                ó$   € V ^8„  d   QhR\         /# r1  r'  )r   s   "r   r   r      s   € ÷ :ñ :¤tñ :r   c                ó>   € \        V 4      ;'       g    \        V 4      # )zF
Return whether the node refers to an aten conv or conv transpose op.
)r9  r@  r8  s   &r   Ú_is_conv_or_conv_transpose_noderC     s   € ô ˜Ó×9Ð9Ô6°qÓ9Ð9r   c                ó$   € V ^8„  d   QhR\         /# r1  r'  )r   s   "r   r   r   §  s   € ÷ ñ ”tñ r   c                ó¨   € V P                   R8H  ;'       d=    V P                  \        P                  P                  P
                  P                  39   # )z6
Return whether the node refers to an aten linear op.
r3  )r  rx   r!   r  r)  Úlinearr™   r8  s   &r   Ú_is_linear_noderG  §  sF   € ð �4‰4�?Ñ"÷ ð  q§x¡xÜ�	‰	�‰×Ñ×%Ñ%ð4ñ (ð r   c                ó$   € V ^8„  d   QhR\         /# )r   Úconv_fnr—   )r   s   "r   r   r   °  s   € ÷ Sñ S¤8ñ Sr   c                 óf   € V \         P                  \         P                  \         P                  39   # r   )ÚFr<  r=  r?  )rI  s   &r   Ú_is_conv_transpose_fnrL  °  s&   € Ø”q×)Ñ)¬1×+=Ñ+=¼q×?QÑ?QÐRÑRÐRr   c                ó$   € V ^8„  d   QhR\         /# r1  r'  )r   s   "r   r   r   ´  s   € ÷ ñ ”4ñ r   c                 óž   € \        V 4      ;'       g<    V P                  \        P                  P                  P
                  P                  8H  # r   )r/  rx   r!   r  r)  Ú$_native_batch_norm_legit_no_trainingr™   r8  s   &r   Ú_is_bn_noderP  ´  s;   € ä-¨aÓ0÷ 	Sð 	SØ�8‰8”u—y‘y—~‘~×JÑJ×RÑRÑRðr   c                óz   € V ^8„  d   QhR\         R\         R\        \         ,          R\         R\        R\        RR/# )	r   Ú	conv_nodeÚconv_weight_nodeÚconv_bias_nodeÚbn_noder  Ú	fake_fuser   N©r   r   r   r]   )r   s   "r   r   r   »  s[   € ÷ q$ñ q$Üðq$äðq$ô œT•Nðq$ô ð	q$ô
 ðq$ô ðq$ð 
ñq$r   c                 ó.	  € \        W4      p\        W$4      p\        V 4      pVP                  P                  P                  p	\        VP                  VP                  V	4      p
\        V
^,          V4      p\        V
^,          V4      p\        V
^,          V4      p\        V
^,          V4      pVP                  \        P                  P                  P                  P                  8X  d   ^pM*\        V4      '       d   ^pM\        RVP                  4      hW¯,          p\        WgWÞVW¼VR7      w  pp\!        V P                  4      p\#        V4      ^8X  d   VP%                  R4       V'       d˜   \        P&                  P)                  WfP*                  4      pVe+   \        P&                  P)                  WwP*                  4      pMS\        P&                  P)                  \        P,                  ! V4      VP*                  R7      pM\        WgWÞVW¼VR7      w  ppVP                  p\/        V\0        4      '       g   Q h\3        VVV\4        P6                  4       Ve3   VP                  p\3        VV\1        V4      \4        P6                  4       M½VR,           p\3        VVV\4        P6                  4       VP8                  P;                  V 4      ;_uu_ 4        VP8                  P=                  V4      pRRR4       RV P>                  9   d<   V P>                  R,          P@                  PC                  VRR7      XP>                  R&   XV^&   \E        V4      V n        VP                  \        P                  P                  PF                  P                  8X  d   VPI                  V 4       MnVPJ                   F^  pVPL                  R	8w  g8   VP                  \N        PP                  8w  g   VP                  ^,          ^ 8w  d   KM  VPI                  V 4       K`  	  VP8                  PS                  4        VPT                  '       g:   \#        VPJ                  4      ^ 8X  d   VP8                  PW                  V4       R# R# R#   + '       g   i     EL–; i)
rÓ   úBN node target is unexpected )Ú	transposeN©Úrequires_gradÚ_biasrª   T)Ústatic_shapesr3  ),r  r@  rx   Ú_schemaÚ	argumentsr$  rÌ   rž   r!   r  r)  rO  r™   r/  r  r   rÕ   rw   r
  rƒ   Ú	Parameterr\  r¹   rQ   r/   r
   r   Ú	PARAMETERrø   Úinserting_beforerû   ÚmetaÚ	fake_modeÚfrom_tensorrk   r*  Úreplace_all_uses_withÚusersr  ÚoperatorÚgetitemÚeliminate_dead_codeÚ_erasedÚ
erase_node)rR  rS  rT  rU  r  rV  Úconv_wÚconv_brZ  Úbn_args_schemaÚbn_argsÚbn_wÚbn_bÚbn_rmÚbn_rvÚeps_arg_indexÚbn_epsÚfused_weightÚ
fused_biasÚ	conv_argsÚweight_attr_nameÚbias_attr_nameÚget_bias_nodeÚusers   &&&&&&                  r   Úfold_bn_weights_into_conv_noder  »  sƒ  € ô ,Ð,<Ó@€FÜ+¨NÓ>€FÜ'¨	Ó2€Ið —^‘^×+Ñ+×5Ñ5€NÜ  §¡¨w¯~©~¸~ÓN€GÜ)¨'°!­*°aÓ8€DÜ)¨'°!­*°aÓ8€DÜ*¨7°1­:°qÓ9€EÜ*¨7°1­:°qÓ9€EØ‡~�~œŸ™Ÿ™×LÑL×TÑTÔTØ‰Ü	.¨w×	7Ò	7Ø‰äÐ8¸'¿.¹.ÓIÐIØÕ#€Fä3Ø˜ f¨dÀIô Ñ€L�*ô
 �Y—^‘^Ó$€Iä
ˆ9ƒ~˜ÔØ×Ñ˜ÔçÜ—x‘x×)Ñ)¨&×2FÑ2FÓGˆØÒÜŸ™×+Ñ+¨F×4HÑ4HÓI‰JäŸ™×+Ñ+Ü× Ò  Ó'°v×7KÑ7Kð ,ó ‰Jô $8Ø˜E¨&°$È	ô$
Ñ ˆ�jð
 (×.Ñ.ÐÜÐ&¬×,Ò,Ð,Ð,Ü�˜qÐ"2´I×4GÑ4GÔHØÒ!Ø'×.Ñ.ˆÜ�Z ¤C¨Ó$7¼×9LÑ9LÕMà)¨GÕ3ˆÜ�Z  N´I×4GÑ4GÔHØ�W‰W×%Ñ% i×0Õ0ØŸG™G×,Ñ,¨^Ó<ˆM÷ 1à�I—N‘NÔ"Ø(1¯©°uÕ(=×(GÑ(G×(SÑ(SØØ"ð )Tó )ˆM×Ñ˜uÑ%ð
 %ˆ	�!‰Ü˜9Ó%€I„Nð
 ‡~�~œŸ™Ÿ™×2Ñ2×:Ñ:Ô:ð 	×%Ñ% iÕ0ð —M”MˆDà—‘˜?Ô*Ø—;‘;¤(×"2Ñ"2Ô2Ø—9‘9˜Q•< 1Ô$áØ×&Ñ& yÖ1ñ "ð ‡G�G×ÑÔ!Ø�?�?ˆ?œs 7§=¡=Ó1°QÔ6Ø	�‰×Ñ˜7Ö#ñ  7‰?÷e 1×0Ð0ús   ËRÒR	c                óz   € V ^8„  d   QhR\         R\         R\        \         ,          R\         R\        R\        RR/# )	r   Úlinear_nodeÚlinear_weight_nodeÚlinear_bias_noderU  r  rV  r   NrW  )r   s   "r   r   r   /  s[   € ÷ g$ñ g$Üðg$äðg$ô œt•nðg$ô ð	g$ô
 ðg$ô ðg$ð 
ñg$r   c           	      óV  € \        W4      p\        W$4      pVP                  P                  P                  p\	        VP
                  VP                  V4      p	\        V	^,          V4      p
\        V	^,          V4      p\        V	^,          V4      p\        V	^,          V4      pVP                  \        P                  P                  P                  P                  8X  d   ^pM*\        V4      '       d   ^pM\        RVP                  4      hWž,          p\        V P
                  4      p\        V4      ^8X  d   VP!                  R4       V'       d˜   \        P"                  P%                  WfP&                  4      pVe+   \        P"                  P%                  WwP&                  4      pMQ\        P"                  P%                  \        P(                  ! V4      VP&                  R7      pM\+        WgWÍWúV4      w  ppVP                  p\-        V\.        4      '       g   Q h\1        VVV\2        P4                  4       Ve3   VP                  p\1        VV\/        V4      \2        P4                  4       MqVR,           p\1        VVV\2        P4                  4       VP6                  P9                  V 4      ;_uu_ 4        VP6                  P;                  V4      pRRR4       XV^&   \=        V4      V n        VP                  \        P                  P                  P>                  P                  8X  d   VPA                  V 4       MnVPB                   F^  pVPD                  R8w  g8   VP                  \F        PH                  8w  g   VP
                  ^,          ^ 8w  d   KM  VPA                  V 4       K`  	  VP6                  PK                  4        VPL                  '       g:   \        VPB                  4      ^ 8X  d   VP6                  PO                  V4       R# R# R#   + '       g   i     ELJ; i)rÓ   rY  Nr[  r]  r3  )(r  rx   r_  r`  r$  rÌ   rž   r!   r  r)  rO  r™   r/  r  rÕ   rw   r
  rƒ   ra  r\  r¹   r   rQ   r/   r
   r   rb  rø   rc  rû   rk   r*  rg  rh  r  ri  rj  rk  rl  rm  )r�  r‚  rƒ  rU  r  rV  Úlinear_wÚlinear_brp  rq  rr  rs  rt  ru  rv  rw  Úlinear_argsrx  ry  r{  r|  r}  r~  s   &&&&&&                 r   Ú fold_bn_weights_into_linear_noderˆ  /  s   € ô .Ð.@ÓD€HÜ-Ð.>ÓB€Hð —^‘^×+Ñ+×5Ñ5€NÜ  §¡¨w¯~©~¸~ÓN€GÜ)¨'°!­*°aÓ8€DÜ)¨'°!­*°aÓ8€DÜ*¨7°1­:°qÓ9€EÜ*¨7°1­:°qÓ9€EØ‡~�~œŸ™Ÿ™×LÑL×TÑTÔTØ‰Ü	.¨w×	7Ò	7Ø‰äÐ8¸'¿.¹.ÓIÐIØÕ#€Fô �{×'Ñ'Ó(€Kä
ˆ;Ó˜1ÔØ×Ñ˜4Ô çÜ—x‘x×)Ñ)¨(×4JÑ4JÓKˆØÒÜŸ™×+Ñ+¨H×6LÑ6LÓM‰JäŸ™×+Ñ+Ü× Ò  Ó'°x×7MÑ7Mð ,ó ‰Jô $:Ø ¨f¸Dó$
Ñ ˆ�jð
 *×0Ñ0ÐÜÐ&¬×,Ò,Ð,Ð,Ü�˜qÐ"2´I×4GÑ4GÔHØÒ#Ø)×0Ñ0ˆÜ�Z ¤C¨Ó$7¼×9LÑ9LÕMà)¨GÕ3ˆÜ�Z  N´I×4GÑ4GÔHØ�W‰W×%Ñ% k×2Õ2ØŸG™G×,Ñ,¨^Ó<ˆM÷ 3ð 'ˆ�A‰Ü˜[Ó)€KÔð
 ‡~�~œŸ™Ÿ™×2Ñ2×:Ñ:Ô:ð 	×%Ñ% kÕ2ð —M”MˆDà—‘˜?Ô*Ø—;‘;¤(×"2Ñ"2Ô2Ø—9‘9˜Q•< 1Ô$áØ×&Ñ& {Ö3ñ "ð ‡G�G×ÑÔ!Ø�?�?ˆ?œs 7§=¡=Ó1°QÔ6Ø	�‰×Ñ˜7Ö#ñ  7‰?÷[ 3×2Ð2ús   Ê:PÐP(	c                ó(   € V ^8„  d   QhR\         RR/# ©r   r  r   N©r   )r   s   "r   r   r   š  s   € ÷ ñ ”kð  dñ r   c           
      ó’  € \         ;QJ d0    R  V P                  P                   4       F  '       g   K   RM%	  RM!! R  V P                  P                   4       4      pV'       g   R# \        4       pV P                  P                   EF  pVP                  R8w  gl   VP
                  \        P                  P                  P                  P                  \        P                  P                  P                  P                  39  d   K‚  TpVP                  ^ ,          p\        V4      '       g   Kª  TpVP                  ^,          p\        VP                  4      ^8”  d   VP                  ^,          MRp\        VVVVV Wb9   4       VP!                  V4       EK  	  V P                  P#                  4        V P%                  4        R# )c              3   ó8   "  € T F  p\        V4      x € K  	  R # 5ir   ©rP  ©Ú.0r‡   s   & r   Ú	<genexpr>Ú!_fuse_conv_bn_.<locals>.<genexpr>›  ó   é € Ð7© A”˜Q—�«ùó   ‚TFNr3  )Úanyrø   ÚnodesÚsetr  rx   r!   r  r)  rO  r™   r*  rÌ   rC  rw   r  Úaddrk  Ú	recompile)r  Úhas_bnÚfused_convs_weight_nodesr‡   rU  rR  rS  rT  s   &       r   Ú_fuse_conv_bn_rœ  š  s@  € ß‹SÑ7¨¯©¯ªÓ7�S�SŠSÑ7¨¯©¯ªÓ7Ó7€FßÙô  #›uÐØ�W‰W�]�]ˆØ�4‰4�?Ô" a§h¡hÜ�I‰I�N‰N×?Ñ?×GÑGÜ�I‰I�N‰N×%Ñ%×-Ñ-ð7
ô '
ñ ØˆØ�L‰L˜�OˆÜ.¨q×1Ò1ÙØˆ	Ø$Ÿ>™>¨!Õ,ÐÜ.1°)·.±.Ó.AÀAÔ.E˜Ÿ™¨Ö*È4ˆÜ&ØØØØØØÑ9ô	
ð 	!×$Ñ$Ð%5×6ñ+ ð, ‡G�G×ÑÔ!Ø‡K�K†Mr   c                ó(   € V ^8„  d   QhR\         RR/# rŠ  r‹  )r   s   "r   r   r   »  s   € ÷ 9ñ 9œð 9¨ñ 9r   c           
     óð  € \         ;QJ d0    R V P                  P                   4       F  '       g   K   RM%	  RM!! R V P                  P                   4       4      pV'       g   R# \        4       pV P                  P                   EFÀ  pVP                  R8w  gl   VP
                  \        P                  P                  P                  P                  \        P                  P                  P                  P                  39  d   K‚  TpVP                  ^ ,          p\        V4      '       g   Kª  TpVP                  ^ ,          p\        V\        4      '       d‡   VP                   P#                  R4      pVeh   \        V\        P$                  4      '       dH   VP&                  ^8”  d7   \(        P*                  ! RVP,                   RVP&                   R	2^R
7       EK[  VP                  ^,          p\/        VP                  4      ^8”  d   VP                  ^,          MRp	\1        VVV	VV W‚9   4       VP3                  V4       EKÃ  	  V P                  P5                  4        V P7                  4        R# )zKFuse linear bn weights, inplace modification of the graph_module and graph.c              3   ó8   "  € T F  p\        V4      x € K  	  R # 5ir   rŽ  r�  s   & r   r‘  Ú#_fuse_linear_bn_.<locals>.<genexpr>½  r“  r”  TFNr3  rª   zNot fusing linear+bn for node 'z': the linear input is z:-D so Linear and BatchNorm operate on different dimensions)Ú
stacklevel)r•  rø   r–  r—  r  rx   r!   r  r)  rO  r™   r*  rÌ   rG  rQ   r   rd  Úgetr\   Úndimra   rb   rŸ   rw   rˆ  r˜  rk  r™  )
r  rš  Úfused_linear_weight_nodesr‡   rU  r�  Úlinear_input_nodeÚlinear_input_valr‚  rƒ  s
   &         r   Ú_fuse_linear_bn_r§  »  sè  € ç‹SÑ7¨¯©¯ªÓ7�S�SŠSÑ7¨¯©¯ªÓ7Ó7€FßÙä #£ÐØ�W‰W�]�]ˆØ�4‰4�?Ô" a§h¡hÜ�I‰I�N‰N×?Ñ?×GÑGÜ�I‰I�N‰N×%Ñ%×-Ñ-ð7
ô '
ñ ØˆØ�L‰L˜�OˆÜ˜q×!Ò!ÙØˆð (×,Ñ,¨QÕ/ÐÜÐ'¬×.Ò.Ø0×5Ñ5×9Ñ9¸%Ó@Ðà Ò,ÜÐ/´·±×>Ò>Ø$×)Ñ)¨AÔ-ä—’ðØ#×(Ñ(Ð)ð *Ø*×/Ñ/Ð0ð 1!ð"ð
  !õò à(×-Ñ-¨aÕ0ÐÜ25°k×6FÑ6FÓ2GÈ!Ô2K˜;×+Ñ+¨AÖ.ÐQUÐÜ(ØØØØØØÑ<ô	
ð 	"×%Ñ%Ð&8×9ña ðb ‡G�G×ÑÔ!Ø‡K�K†Mr   c                ót   € V ^8„  d   QhR\         R\        \        \        \        \        3,          3,          /# )r   rÏ   r   )r   rŽ   r/   rk   r·   )r   s   "r   r   r   ÷  s-   € ÷ 
ñ 
¤;ð 
´4¼¼UÄ3ÌÀ9Õ=MÐ8MÕ3Nñ 
r   c                 óR  € / pV P                   P                   FŠ  pVP                  P                  R R4      pR\	        R4      3pV'       dI   \        VP                  4       4      R,          pV^ ,          P                  R4      R,          V^,          3pWAVP                  &   KŒ  	  V# )Únn_module_stackNru   r1   rµ   )	rø   r–  rd  r¢  r·   rÕ   rÙ   r5   rŸ   )rÏ   Únode_name_to_scoper‡   rª  Úcurrent_scopeÚbts   &     r   Ú_get_node_name_to_scoper®  ÷  sŽ   € à68ÐØ�[‰[×ÔˆØŸ&™&Ÿ*™*Ð%6¸Ó=ˆØœT $›ZÐ(ˆßÜ�o×,Ñ,Ó.Ó/°Õ3ˆBØ �UŸ[™[¨Ó-¨bÕ1°2°aµ5Ð9ˆMØ%2˜1Ÿ6™6Ó"ñ ð Ðr   c                ób   € V ^8„  d   QhR\         R\        \        R3,          R\        R\        /# )r   ÚpatternrÐ   .Úis_cudar   )r   rk   r   r]   r   )r   s   "r   r   r     s8   € ÷ /ñ /Üð/äœ#˜s˜(•Oð/ô ð/ô
 ñ/r   c           	     ód  € V'       dL   \        V Uu. uF5  p\        V\        P                  4      '       d   VP	                  4       MTNK7  	  up4      p\        P
                  P                  V VVRR7      P                  4       pVP                  P                  4        VP                  4        VP                  P                   FŒ  pVP                  R8X  g   K  VP                  \        P                  P                  P                  P                   8X  g   KU  \#        VP$                  4      ^ 8X  g   Kq  VP                  P'                  V4       KŽ  	  \        P(                  P+                  R4      '       dˆ   \-        VP                  P                  4       Fd  pVP                  R8X  g   K  VP.                  R8X  g   K)  VP                  P'                  V4       \1        VR4      '       g   KX  \3        VR4       Kf  	  VP                  P                  4        VP                  4        V# u upi )z>
Convert the pattern to an FX graph with decomposed aten ops.
T)Ústrictr3  z2.9Úcall_moduleÚ
_guards_fn)rk   rQ   r!   r\   ÚcudaÚexportr~   rø   rk  r™  r–  r  rx   r  r)  Úcopy_r™   rw   rh  rm  Ú__version__Ú
startswithrÕ   rŸ   rU   Údelattr)r°  rÐ   r±  rž   ÚxÚaten_patternr  s   &&&,   r   Ú"_get_aten_graph_module_for_patternr¾    sž  € ÷ ÜÙESÓTÁ^Àœ A¤u§|¡|×4Ò4ˆQ�V‰VŒX¸!Ò;Á^ÑTó
ˆô —<‘<×&Ñ&ØØØØð	 'ó ÷
 �fƒhð ð ×Ñ×*Ñ*Ô,Ø×ÑÔð ×"Ñ"×(Ô(ˆà�G‰G�Ö&Ø—‘œuŸy™yŸ~™~×3Ñ3×;Ñ;Ö;Ü�D—J‘J“ 1Ö$à×Ñ×)Ñ)¨$Ö/ñ )ô ×Ñ×#Ñ# E×*Ò*ô ˜×+Ñ+×1Ñ1Ö2ˆDØ�w‰w˜-Ö'¨D¯I©I¸Ö,EØ×"Ñ"×-Ñ-¨dÔ3ä˜<¨×6Ô6Ü˜L¨,Ö7ñ 3ð ×Ñ×*Ñ*Ô,Ø×ÑÔàÐùòI Us   ’;H-c                ó(   € V ^8„  d   QhR\         RR/# )r   Úmatch_patternr   Nr‹  )r   s   "r   r   r   6  s   € ÷ &ñ &´kð &Àdñ &r   c                ó^  € \         P                  P                  P                  P                  \         P                  P                  P                  \         P                  P                  P
                  P                  \         P                  P                  P
                  \         P                  P                  P                  P                  \         P                  P                  P                  \         P                  P                  P
                  P                  \         P                  P                  P
                  \         P                  P                  P                  P                  \         P                  P                  P                  \         P                  P                  P
                  P                  \         P                  P                  P
                  \         P                  P                  P                  P                  \         P                  P                  P                  \         P                  P                  P                  P                  \         P                  P                  P                  \         P                  P                  P                  P                  \         P                  P                  P                  /	pV P                  P                   F@  pVP                  R8w  d   K  VP                   V9   g   K)  WP                   ,          Vn        KB  	  R# )z¡Remove .tensor overload for quantize/dequantize ops so that we can
use the match_pattern that we get from torchdynamo export to match the output of convert_pt2e
r3  N)r!   r  r  Úquantize_per_tensorr™   Údequantize_per_tensorr¶   Útensor2Úquantize_per_channelÚdequantize_per_channelr)  rÅ   r\   rø   r–  r  rx   )rÀ  Ú_MAPr‡   s   &  r   Ú"remove_tensor_overload_for_qdq_opsrÈ  6  sÊ  € ô
 	�	‰	×&Ñ&×:Ñ:×BÑBÄEÇIÁI×DbÑDb×DvÑDvÜ�	‰	×&Ñ&×<Ñ<×DÑDÄeÇiÁi×FdÑFd×FzÑFzÜ�	‰	×&Ñ&×:Ñ:×AÑAÄ5Ç9Á9×CaÑCa×CuÑCuÜ�	‰	×&Ñ&×<Ñ<×CÑCÄUÇYÁY×EcÑEc×EyÑEyÜ�	‰	×&Ñ&×:Ñ:×BÑBÄEÇIÁI×DbÑDb×DvÑDvÜ�	‰	×&Ñ&×<Ñ<×DÑDÄeÇiÁi×FdÑFd×FzÑFzÜ�	‰	×&Ñ&×;Ñ;×CÑCÄUÇYÁY×EcÑEc×ExÑExÜ�	‰	×&Ñ&×=Ñ=×EÑEÄuÇyÁy×GeÑGe×G|ÑG|Ü�	‰	�‰×Ñ×#Ñ#¤U§Y¡Y§^¡^×%9Ñ%9ð
€Dð × Ñ ×&Ô&ˆØ�4‰4�?Ô"ÙØ�8‰8�tÖØŸH™H•~ˆAŽHó	 'r   c                 ó¬   € \        V \        \        34      '       d   R # \        V \        \        34      '       d   \        \        \        V 4      4      # R# )TF)rQ   rj   rd   rk   rÕ   re   ÚmapÚ_is_literal)Úargs   &r   rË  rË  L  s<   € Ü�#œœU�|×$Ò$ÙÜ�#œœt�}×%Ò%Ü”3”{ CÓ(Ó)Ð)Ùr   c                ó�   € V ^8„  d   QhR\         P                  P                  R\        R\        \
        \        ,          ,          /# )r   ÚgmÚ	merge_dupÚexclude_literals)r!   r  r   r]   r   rÕ   r   )r   s   "r   r   r   T  s>   € ÷ Wñ WÜ�‰×ÑðWäðWô œt¤C�yÕ)ñWr   c           
     óp  € Rp^ p/ pVf   . pV P                   pVP                  ^ ,          pV P                  P                   EF<  pVP                  R8X  d   TpV^,          pK"  V P                  P                  V4      ;_uu_ 4        . p	VP                   FÊ  p
\        V
4      '       d¦   W¢9  d    V'       d    W¥9   d   V	P                  WZ,          4       KA  V P                  P                  R\        V4      ,           4      pV	P                  V4       VP                  P                  \        4       4       V^,          pV'       d   WµV
&   K·  K¹  V	P                  V
4       KÌ  	  \        V	4      p	RRR4       X	Vn        EK?  	  VP                  4        VP                  4        V #   + '       g   i     L>; i)aC  Replace the literals in the graph with placeholder nodes that's created on the fly while we
traverse the graph, so that the literal arguments in the graph can be matched and replaced

To use this, the pattern and replacement graph should have the exact same number of literal args
and they should be used in the exact same order in the pattern and replacement graph.

If the literal arguments are not used in the same order in pattern and replacement graph, please
use `_replace_literals_with_existing_placeholders` instead

Args:
    `gm`: input GraphModule that we'll transform
    `merge_dup`: boolean flag to indicate that if the same literal appears multiple times in
     the graph, whether they should correspond to the same placeholder or not
    `exclude_literals`: a list of literals that will not be replaced with placeholders

Example:

# 1. Original Graph
def pattern(self, x):
    return x + 3

def replacement(self, x):
    return x - 3

example_inputs = (torch.randn(1, 3, 3, 3),)
pattern_gm = _get_aten_graph_module_for_pattern(pattern, example_inputs)
replacement_gm = _get_aten_graph_module_for_pattern(pattern, example_inptus)

# 2. Before calling replace literals we'll see the following graph:
def pattern(self, x):
    return x + 3

def replacement(self, x):
    return x - 3

pattern_gm = _replace_literals_with_new_placeholders(pattern_gm)
replacement_gm = _replace_literals_with_new_placeholders(replacement_gm)

# 3. After replacing literals with new placeholder nodes

def pattern(self, x, new_ph):
    return x + new_ph

def pattern(self, x, new_ph):
    return x - new_ph

Nr  rÌ  )Ú_in_specÚchildren_specsrø   r–  r  Úinserting_afterrÌ   rË  r
  r  r/   r   rk   Ú__post_init__)rÎ  rÏ  rÐ  Úlast_phÚcntÚliteral_to_phÚin_specÚ	args_specr  Únew_argsrÌ  Úph_nodes   &&&         r   Ú'_replace_literals_with_new_placeholdersrÝ  T  s^  € ðh €GØ
€CØFH€MØÒØÐà�k‰k€GØ×&Ñ& qÕ)€IØ—‘—•ˆØ�7‰7�mÔ#ØˆGØ�1�HˆCÙØ�X‰X×%Ñ% g×.Õ.ØˆHØ—y”y�Ü˜s×#Ò#¨Ô(Cß  SÔ%9Ø Ÿ™¨Õ(:Ö;à"$§(¡(×"6Ñ"6°u¼sÀ3»xÕ7GÓ"H˜Ø Ÿ™¨Ô0Ø!×0Ñ0×7Ñ7¼»ÔHØ˜q�˜ß$Ø18¨#Ó.ñ %ð —O‘O CÖ(ñ !ô ˜X“ˆH÷ /ð" ˆ�	ñ- ð2 ×ÑÔØ×ÑÔØ€I÷- /×.ús   Â0F%Â8B7F%Æ%F5c                ó  € V ^8„  d   QhR\         P                  P                  R\        \        \
        ,          ,          R\        \        \        \        \        \        \         P                  3,          \        3,          ,          /# )r   rÎ  rÐ  Úliteral_to_ph_idx)r!   r  r   r   rÕ   r   rŽ   r   rd   rj   r]   rJ   )r   s   "r   r   r   ®  s_   € ÷ Tñ TÜ�‰×ÑðTäœt¤C�yÕ)ðTô  ¤¤U¬5´#´t¼U¿[¹[Ð+HÕ%IÌ3Ð%NÕ OÕPñTr   c                ó&  € Vf   . pVf   / pV P                   P                   Uu. uF  q3P                  R8X  g   K  VNK  	  ppV P                   P                   F®  pVP                  R8w  d   K  . pVP                   Fu  p\	        V\
        4      '       d   \        V4      p\        V4      '       d0   Wa9  d*   Wb9   d$   W&,          pWG,          pVP                  V4       Kd  VP                  V4       Kw  	  \        V4      pWSn        K°  	  V # u upi )aX	  Replace the literals in the graph with **existing** placeholder nodes, so that the literal arguments
in the graph can be matched and replaced

To use this, all literal args in the graph should be unique and each of them should correspond
to exactly one placeholder node

# 1. Original Graph
def pattern(self, x_i8, scale, zero_point, quant_min, quant_max):
    return torch.dequantize_per_tensor(x_i8, scale, zero_point, quant_min, quant_max)

def replacement(x_i8, scale, zero_point, quant_min, quant_max):
    x_i8 = torch.clamp(x_i8, quant_min, quant_max)
    return ((x_i8.to(torch.float32) - zero_point) * scale).to(dtype=torch.float32)

example_inputs = (
    torch.randn(1, 3, 3, 3),
    1.0,
    0,
    -128,
    127,
)
pattern_gm = _get_aten_graph_module_for_pattern(pattern, example_inputs)
replacement_gm = _get_aten_graph_module_for_pattern(pattern, example_inptus)

# 2. Before calling replace literals we'll see the following graph:
def pattern(self, x_i8, scale, zero_point, quant_min, quant_max):
    # scale/zero_point/quant_min/quant_max are burnt in since they are scalar values
    return torch.dequantize_per_tensor(x_i8, 1.0, 0, -128, 127)

def replacement(x_i8, scale, zero_point, quant_min, quant_max):
    # scale/zero_point/quant_min/quant_max are burnt in since they are scalar values
    x_i8 = torch.clamp(x_i8, -128, 127)
    return ((x_i8.to(torch.float32) - 0) * 1.0).to(dtype=torch.float32)

# Note that literal args appear in different order in pattern and replacement graph, so
# we can't use _replace_literals_with_new_placeholders

literal_to_ph_idx = {1.0: 1, 0: 2, -128: 3, 127: 4}
pattern_gm = _replace_literals_with_existing_placeholders(pattern_gm, literal_to_ph_idx)
replacement_gm = _replace_literals_with_existing_placeholders(replacement_gm, literal_to_ph_idx)

# 3. After replacing literals with existing placeholder nodes

def pattern(self, x_i8, scale, zero_point, quant_min, quant_max):
    # scale/zero_point/quant_min/quant_max are burnt in since they are scalar values
    return torch.dequantize_per_tensor(x_i8, scale, zero_point, quant_min, quant_max)

def replacement(x_i8, scale, zero_point, quant_min, quant_max):
    # scale/zero_point/quant_min/quant_max are burnt in since they are scalar values
    x_i8 = torch.clamp(x_i8, quant_min, quant_max)
    return ((x_i8.to(torch.float32) - zero_point) * scale).to(dtype=torch.float32)
r  r3  )	rø   r–  r  rÌ   rQ   rÕ   rk   rË  r
  )	rÎ  rÐ  rß  r  ÚphsrÛ  rÌ  Úph_idxrÜ  s	   &&&      r   Ú,_replace_literals_with_existing_placeholdersrã  ®  sé   € ðr ÒØÐàÒ ØÐàŸH™HŸNšNÓ
G™N�D¯g©g¸Ñ.F�4ˆ4™N€CÐ
Gà—‘—”ˆØ�7‰7�oÔ%ÙØˆØ—9”9ˆCÜ˜#œt×$Ò$Ü˜C“j�ä˜C× Ò ØÔ/ØÔ,à*Õ/�Ø�+�Ø—‘ Ö(à—‘ Ö$ñ ô ˜“?ˆØŽ	ñ% ð& €Iùò+ Hs
   ¥D¼Dc                ó$   € V ^8„  d   QhR\         /# )r   rÏ   r‹  )r   s   "r   r   r     s   € ÷ ñ ¤ñ r   c                ó¤   a€ RoRR V3R lllpRR V3R lllp\         P                  ! W4      V n        \         P                  ! W 4      V n        V # )z©
Disallow calling `model.train()` or `model.eval()` on the given GraphModule.
This is useful for exported models, where these methods don't actually behave as expected.
ap  
        Calling train() or eval() is not supported for exported models.
        Please call `torchao.quantization.pt2e.move_exported_model_to_train(model)` (or eval) instead.

        If you cannot replace the calls to `model.train()` and `model.eval()`, you may override
        the behavior for these methods by calling `torchao.quantization.pt2e.allow_exported_model_train_eval(model)`,
        which does the above automatically for you. Note that this has limited effect on switching
        behavior between train and eval modes, and should be used only for special ops such as dropout
        and batchnorm.
        c                ó$   € V ^8„  d   QhR\         /# ©r   Úmode©r]   )r   s   "r   r   Ú*_disallow_eval_train.<locals>.__annotate__  s   € ÷ 1ñ 1œ4ñ 1r   c                 ó   <€ \        S4      hr   ©ÚNotImplementedError©rÚ   rè  Úerror_messages   &&€r   Ú_trainÚ$_disallow_eval_train.<locals>._train  ó   ø€ Ü! -Ó0Ð0r   c                ó$   € V ^8„  d   QhR\         /# rç  ré  )r   s   "r   r   rê    s   € ÷ 1ñ 1œ$ñ 1r   c                 ó   <€ \        S4      hr   rì  rî  s   &&€r   Ú_evalÚ#_disallow_eval_train.<locals>._eval  rò  r   )T)ÚtypesÚ
MethodTypeÚtrainÚeval)rÏ   rð  rõ  rï  s   &  @r   Ú_disallow_eval_trainrû    sI   ø€ ð
	€M÷1ò 1÷1ò 1ô ×"Ò" 6Ó1€E„KÜ×!Ò! %Ó/€E„JØ€Lr   c                ó$   € V ^8„  d   QhR\         /# r&  r'  )r   s   "r   r   r   "  s   € ÷ ñ œDñ r   c                 ó  € V P                   R 8H  ;'       dD    V P                  \        P                  P                  P
                  P                  8H  ;'       g®    V P                  \        P                  P                  P                  P                  8H  ;'       gk    V P                  \        P                  P                  P                  8H  ;'       g2    V P                  \        P                  P                  P
                  8H  # )r3  )r  rx   r!   r  r)  Úsym_sizer™   Ú	sym_numel)r  s   &r   Ú_is_sym_size_noder   "  s³   € à�‰�?Ñ"÷ 	;ð 	;Ø�K‰Kœ5Ÿ9™9Ÿ>™>×2Ñ2×:Ñ:Ñ:÷	2ð 	2à�;‰;œ%Ÿ)™)Ÿ.™.×2Ñ2×:Ñ:Ñ:÷	2ð 	2ð �;‰;œ%Ÿ)™)Ÿ.™.×2Ñ2Ñ2÷	2ð 	2ð �;‰;œ%Ÿ)™)Ÿ.™.×1Ñ1Ñ1ðr   c                ó–   € V ^8„  d   QhR\         P                  P                  R\        \         P                  P                  ,          /# )r   r  r   )r!   r  r   rÕ   )r   s   "r   r   r   ,  s/   € ÷ ñ ¤§¡§¡ð ´4¼¿¹¿¹Õ3Fñ r   c                 óF   € \        \        R  V P                  4      4      pV# )c                 ó   € \        V 4      R J # ©F)r   )r¼  s   &r   Ú<lambda>Ú(_filter_sym_size_users.<locals>.<lambda>-  s   € Ô):¸1Ó)=ÀÑ)Fr   )rÕ   Úfilterrh  )r  Ú
node_userss   & r   Ú_filter_sym_size_usersr	  ,  s   € Ü”fÑGÈ$Ï*É*ÓUÓV€JØÐr   )r&   r+   r6   rX   rf   rs   r   rä   rF   rÉ   r¯   rö   r  r¾  r9  r@  r   r	  r   r  )FN)NN)^Ú__doc__r2   ri  r÷  ra   Úcollectionsr   Úinspectr   r   Útypingr   r   r   r   r!   Útorch.nn.functionalrƒ   Ú
functionalrK  Ú$torch.ao.quantization.fx._decomposedr	   Útorch.export.unflattenr
   r   Útorch.fxr   r   r   Útorch.nn.utils.fusionr   r   Útorch.nn.utils.parametrizer   Útorch.utils._pytreer   ÚImportErrorr   Útorchao.utilsr   Ú__all__r&   r+   r6   rF   rX   rf   rs   rz   r   r‰   r”   r¡   r«   r¯   r"   rÉ   rÍ   rä   rö   r  r  r  rÂ  r™   r¶   rÅ  r  rÃ  rÆ  r	  r  r  r$  r/  r9  r@  rC  rG  rL  rP  r  rˆ  rœ  r§  r®  r¾  rÈ  rË  rÝ  rã  rû  r   r	  r   r   r   Ú<module>r     s  ðñó ó Û Û Ý #ß -ß 1Ó 1ã ß Ð õ Jß :ß -Ñ -ß NÝ 6ð
Ý1õ 8ò€ò.Wòõ:ò!ò&!õHõ:; ò|òõõ0Jõõ*õ,ðH #×4Ñ4÷K>õ\
'õ6!õ|÷"ð6 
‡I�I×"Ñ"×6Ñ6×>Ñ>Ø	‡I�I×"Ñ"×6Ñ6×=Ñ=Ø	‡I�I×"Ñ"×7Ñ7×?Ñ?ð€ð 
‡I�I×"Ñ"×8Ñ8×@Ñ@Ø	‡I�I×"Ñ"×8Ñ8×?Ñ?Ø	‡I�I×"Ñ"×9Ñ9×AÑAð€õò"ò*	õ(õ õõ:õõSõ÷q$÷hg$õVõB9õx
÷/õd&ò,÷W÷tTõrõ6÷øðO( ô Ý,÷ð ðús   Á!I' É'I>É=I>