ó
    EñiÝC  ã            	       ó¦  • S SK r S SKrS SKrS SKrS SKJr  S SKJrJr  S SK	r	S SK
r
S SKJs  Jr  S SKJr  S SKJr  SSKJr  SSKJrJrJr  SS	KJr  \R4                  " \5      r " S
 S\5      r " S S\5      r\ R>                  S\4S j5       r S\!S\4S jr"S\RF                  S\4S jr$S6S\
RJ                  S\&S\&4S jjr'S6S\
RJ                  S\&S\&4S jjr(S\RF                  S\&4S jr)S\RF                  S\&4S jr* " S S\5      r+ " S S\5      r, " S S\5      r-S /S!//r.S"/S"//S#/S#//S$/S%///r// S&Q/ S'Q/ S(Q/ S)Q/r0S\\1   4S* jr2S+\&S,\&S-\S\14S. jr3S\RF                  S\14S/ jr4S0\
Rj                  Rl                  S\&4S1 jr7S0\
Rj                  Rl                  S\&4S2 jr8  S7S0\
Rj                  Rl                  S3\\&   S4\9S\14S5 jjr:g)8é    N)ÚIntEnum)ÚAnyÚOptional)Ú	size_hint)Únormalize_functioné   )Úir)Úget_dtype_sizeÚsnode_args_kwargsÚsympy_product)ÚVc                   ó(   • \ rS rSrSrSrSrSrSrSr	g)	Ú	NCCL_COLLé   r   r   é   é   é   © N)
Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú
ALL_REDUCEÚ
ALL_GATHERÚREDUCE_SCATTERÚ
ALL_TO_ALLÚUNSUPPORTEDÚ__static_attributes__r   ó    ÚZ/home/mande/repo/quber/.venv/lib/python3.13/site-packages/torch/_inductor/comm_analysis.pyr   r      s   † Ø€JØ€JØ€NØ€JØƒKr   r   c                   ó$   • \ rS rSrSrSrSrSrSrg)ÚNVIDIA_GPU_TYPEé   r   r   r   r   r   N)	r   r   r   r   ÚVOLTAÚAMPEREÚHOPPERÚ	BLACKWELLr   r   r   r    r"   r"      s   † Ø€EØ€FØ€FØƒIr   r"   Úreturnc                  ó¤  ^ • [         R                  R                  R                  [         R                  R                  R                  5      =(       d    Sm ST ;   a  [
        R                  $ ST ;   a  [
        R                  $ ST ;   a  [
        R                  $ [        U 4S jS 5       5      (       a  [
        R                  $ [
        R                  $ )NÚ ÚV100ÚA100ÚH100c              3   ó,   >#   • U  H	  oT;   v •  M     g 7f©Nr   )Ú.0ÚgpuÚgpu_infos     €r    Ú	<genexpr>Úget_gpu_type.<locals>.<genexpr>/   s   øé € ÐAÒ(@ �HŽ_Ò(@ùó   ƒ)ÚB100ÚB200ÚB300)ÚtorchÚutilsÚcollect_envÚget_gpu_infoÚrunr"   r$   r%   r&   Úanyr'   )r2   s   @r    Úget_gpu_typer?   &   s›   ø€ ä�{‰{×&Ñ&×3Ñ3´E·K±K×4KÑ4K×4OÑ4OÓP×VÐTV€HØ�ÓÜ×$Ñ$Ð$Ø	�8Ó	Ü×%Ñ%Ð%Ø	�8Ó	Ü×%Ñ%Ð%Ü	ÔAÑ(@ÓA×	AÑ	AÜ×(Ñ(Ð(ô ×%Ñ%Ð%r   Úkernel_namec                 ó  ^ • T c   eST ;   a  [         R                  $ ST ;   a  [         R                  $ ST ;   a  [         R                  $ [	        U 4S jS 5       5      (       a  [         R
                  $ [         R                  $ )NÚ
all_reduceÚ
all_gatherÚreduce_scatterc              3   ó,   >#   • U  H	  oT;   v •  M     g 7fr/   r   )r0   Úcommr@   s     €r    r3   Ú7get_collective_type_from_kernel_name.<locals>.<genexpr>>   s   øé € ÐHÒ-G T�[Ö Ò-Gùr5   )Ú
all_to_allÚalltoall)r   r   r   r   r>   r   r   )r@   s   `r    Ú$get_collective_type_from_kernel_namerJ   6   su   ø€ ØÑ"Ð"Ð"Ø�{Ó"Ü×#Ñ#Ð#Ø	˜Ó	$Ü×#Ñ#Ð#Ø	˜[Ó	(Ü×'Ñ'Ð'Ü	ÔHÑ-GÓH×	HÑ	HÜ×#Ñ#Ð#ä×$Ñ$Ð$r   Únodec                 ó”   • [        U [        R                  5      (       d  [        SU  35      eU R                  nUc   e[        U5      $ )Nz!node is not a collective kernel: )Ú
isinstancer	   Ú_CollectiveKernelÚ
ValueErrorÚpython_kernel_namerJ   )rK   Únames     r    Úget_collective_typerR   D   sJ   € Ü�dœB×0Ñ0×1Ñ1ÜÐ<¸T¸FÐCÓDÐDà×"Ñ"€DØÑÐÐÜ/°Ó5Ð5r   ÚsizeÚfallbackc                 óº   • [        U 5      n[        U[        R                  5      (       a  [	        U5      $ [
        R                  R                  R                  X!S9$ )N©rT   )	r   rM   ÚsympyÚIntegerÚintr   ÚgraphÚsizevarsÚoptimization_hint)rS   rT   Únumels      r    Úget_ir_node_size_numelr^   M   sE   € Ü˜$Ó€EÜ�%œŸ™×'Ñ'Ü�5‹zÐÜ�7‰7×Ñ×-Ñ-¨eÐ-ÐGÐGr   c                 ód   • [         R                  " [        R                  U S5      n[	        X!S9nU$ )Nr   rV   )Ú	functoolsÚreduceÚoperatorÚmulr   )rS   rT   r]   Úresults       r    Úget_fx_node_size_numelre   T   s)   € Ü×ÒœXŸ\™\¨4°Ó3€EÜ�uÑ0€FØ€Mr   c                 ó¶   • SnU R                    HF  n[        UR                  R                  5      nX[	        UR                  R
                  5      -  -  nMH     U$ )Nr   )Úinputsr^   ÚlayoutrS   r
   Údtype)rK   Úsz_bytesÚinpr]   s       r    Úget_collective_input_size_bytesrl   Z   sJ   € Ø€HØ�{Œ{ˆÜ& s§z¡z§¡Ó7ˆØœN¨3¯:©:×+;Ñ+;Ó<Ñ<Ñ<Šñ ð €Or   c                 óÐ   • [        U [        R                  5      (       a:  [        U [        R                  5      (       d  SSKJn  U" U R                  S   5      $ [        SU  35      e)Nr   ©Ú_get_group_size_by_nameéÿÿÿÿzUnsupported collective type: )rM   r	   rN   Ú_WaitKernelÚ"torch.distributed.distributed_c10dro   Úconstant_argsÚ	TypeError)rK   ro   s     r    Úget_collective_group_sizeru   b   sQ   € Ü�$œ×,Ñ,×-Ñ-´jÀÄrÇ~Á~×6VÑ6VÝNá& t×'9Ñ'9¸"Ñ'=Ó>Ð>äÐ7¸°vÐ>Ó?Ð?r   c                   ó    • \ rS rSrSrSrSrSrg)ÚNCCL_HWép   r   r   r   r   N)r   r   r   r   ÚNVLINKÚPCIÚNETr   r   r   r    rw   rw   p   s   † Ø€FØ
€CØ
ƒCr   rw   c                   ó   • \ rS rSrSrSrSrg)Ú	NCCL_ALGOév   r   r   r   N)r   r   r   r   ÚTREEÚRINGr   r   r   r    r}   r}   v   s   † Ø€DØƒDr   r}   c                   ó   • \ rS rSrSrSrg)Ú
NCCL_PROTOé{   r   r   N)r   r   r   r   ÚLLr   r   r   r    r‚   r‚   {   s	   † ð 
ƒBr   r‚   g333333@gffffff@g333333ã?ç      ð?g      @gš™™™™™@)ç     €C@r†   gffffff4@)gÍÌÌÌÌìU@g     €6@g      3@)g      a@g     €F@g     €A@)g      q@g     €V@g     €Q@c                 óR  • U R                   nUc   e[        USS5      nUR                  S   nSSKJn  U" U5      n[
        R                  R                  U5      n[
        R                  " SU 35      n[        U5      n[        U 5      u  pšSU;   a  U	SS  U	S   -   n	[
        R                  R                  XWS	9 nU" U	0 U
D6n[
        R                  R                  R                  R                  U5        S S S 5        WR                   nUS:  a  g US
-  nU$ ! , (       d  f       N(= f)NrP   r*   rp   r   )Ú_resolve_process_groupzcuda:Úall_gather_into_tensor_outr   )ÚgroupÚdeviceç     @�@)rK   Úgetattrrs   rr   rˆ   r9   ÚdistributedÚget_rankr‹   Úevalr   Ú_time_estimatorÚopsÚ_c10d_functionalÚwait_tensorÚdefaultÚestimated_time)ÚsnodeÚkernelÚpy_kernel_nameÚpg_namerˆ   ÚpgÚrankr‹   ÚfnÚargsÚkwargsÚtime_estimatorÚwÚest_time_usÚest_time_mss                  r    Ú/estimate_nccl_collective_runtime_nccl_estimatorr¤   Ä   s"  € Ø�Z‰Z€FØÑÐÐÜ˜VÐ%9¸2Ó>€NØ×"Ñ" 2Ñ&€GÝIá	 Ó	(€BÜ×!Ñ!×*Ñ*¨2Ó.€Dô �\Š\˜E $ ˜.Ó)€Fä	ˆnÓ	€BÜ$ UÓ+�L€Dð $ ~Ó5Ø�A�Bˆx˜$˜q™'Ñ!ˆä	×	Ñ	×	*Ñ	*°Ð	*Ñ	CÀ~Ù�Ð˜ÑˆÜ�	‰	×"Ñ"×.Ñ.×6Ñ6°qÔ9÷ 
Dð !×/Ñ/€Kð �QƒØØ Ñ#€KØÐ÷ 
DÕ	Cús   Â:<DÄ
D&Útensor_storage_size_bytesÚ
group_sizeÚcollc                 óª  • U S-  S-  S-  nSn[         R                  " X-  5      nUnUS::  a  g[        R                  n[        R
                  n[        R                  R                  R                  n	[        R                  R                  R                  n
[        5       nUS::  a  US-
  OSnUS:X  a  UOSn[        U   U   nUS:X  a  U	OU
nSnUU-  n[        UUUS:”  d  U[        R                  :X  a  SOS-  5      nU[        R                  :X  a	  SUS-
  -  nOFU[        R                   :X  a	  SUS-
  -  nO)U[        R"                  [        R$                  4;   a  US-
  nSU-  W-  nUU-  nUS	-  n[&        R(                  nU[        R                  :X  a  US:”  a  SU-  nO;SnO8U[        R"                  [        R$                  [        R                   4;   a  US-
  n[*        U   U   n[,        U   U   U   n[,        [&        R.                     U   U   nS
nUS:”  a  Sn[1        UU5      nUUW-
  U-  UU-  -   -  nUS-  nUU-  nUU-   nUS-  nU$ )a  
Returns estimated NCCL collective runtime in milliseconds (ms).

The following heuristics are copied from https://github.com/NVIDIA/nccl/blob/master/src/graph/tuning.cc.
We aim to estimate the runtime as accurately as possible.

Assumptions:
- only ring algorithm (NCCL_ALGO_RING) is used
- only Low-Latency protocol (NCCL_PROTO_LL) is used, i.e. Simple or LL128 is not used
- 8 gpus per node  # TODO: Need to find a way to get accurate "gpus per node" and "# nodes" info.
- collective is one of: allreduce, reducescatter, allgather
i   é   r   r   r   g      Ð?gUUUUUUÕ?r…   g    eÍÍAg        rŒ   g    €„.A)ÚmathÚceilr}   r€   r‚   r„   r9   Ú	_inductorÚconfigÚintra_node_bwÚinter_node_bwr?   ÚllMaxBwsÚminr   r   r   r   r   rw   ry   ÚbaseLatÚhwLatr{   Úmax) r¥   r¦   r§   Útensor_storage_size_GBÚnum_gpus_per_nodeÚnNodesÚnRanksÚ	nccl_algoÚ
nccl_protoÚbwIntraÚbwInterÚcompCapIndexÚindex2Úindex1ÚllMaxBwÚbwÚ	nChannelsÚbusBwÚnstepsÚratioÚ	bandwidthÚbandwidth_GB_per_nsÚintraHwÚnInterStepsÚlatencyÚintraLatÚinterLatÚnetOverheadÚ
latency_nsÚtransport_nsÚnsÚmss                                    r    Ú%estimate_nccl_collective_runtime_implrÒ   å   s€  € ð  7¸Ñ=ÀÑDÀtÑKÐð ÐÜ�YŠY�zÑ5Ó6€FØ€Fà�ƒ{Øô —‘€IÜ—‘€Jô
 �o‰o×$Ñ$×2Ñ2€GÜ�o‰o×$Ñ$×2Ñ2€Gä“>€LØ! Q›;ˆV�aŠZ¨A€Fà# q›[‰\¨a€FÜ�vÑ˜vÑ&€Gð ˜a“K‰ W€BØ€IØ˜‰N€Eô ØØØ !› t¬y×/CÑ/CÓ'C‰9È)ñ	Uó€Eð Œy×#Ñ#Ó#Ø�f˜q‘jÑ!‰Ø	”×%Ñ%Ó	%Ø�f˜q‘jÑ!‰Ø	”)×*Ñ*¬I×,@Ñ,@ÐAÓ	AØ˜!‘ˆð �6‰\˜VÑ#€EØ˜‘€Ià# c™/Ðô �n‰n€GàŒy×#Ñ#Ó#Ø�A‹:Ø˜f™*‰Kà‰KØ	”)×*Ñ*¬I×,@Ñ,@Ä)×BVÑBVÐWÓ	WØ˜q‘jˆô �iÑ  Ñ,€GÜ�W‰~˜iÑ(¨Ñ4€HÜ”W—[‘[Ñ! )Ñ,¨ZÑ8€Hð €KØ�ƒzØˆÜ�8˜[Ó)€HØ�˜Ñ$¨Ñ0°;ÀÑ3IÑIÑI€Gà˜3‘€Jð *Ð,?Ñ?€LØ	˜
Ñ	"€BØ	ˆc‰€BØ€Ir   c                 ó\   • [        U 5      n[        U 5      n[        U 5      n[        XU5      $ )á  
Returns estimated NCCL collective runtime in nanoseconds (ms).

The following heuristics are copied from https://github.com/NVIDIA/nccl/blob/master/src/graph/tuning.cc.
We aim to estimate the runtime as accurately as possible.

Assumptions:
- only ring algorithm (NCCL_ALGO_RING) is used
- only Low-Latency protocol (NCCL_PROTO_LL) is used, i.e. Simple or LL128 is not used
- 8 gpus per node  # TODO: Need to find a way to get accurate "gpus per node" and "# nodes" info.
- collective is one of: allreduce, reducescatter, allgather
)rl   ru   rR   rÒ   )rK   r¥   r¦   r§   s       r    Ú estimate_nccl_collective_runtimerÕ   R  s6   € ô !@ÀÓ EÐÜ*¨4Ó0€JÜ˜tÓ$€DÜ0Ø!¨tóð r   Úfx_nodec                 óè  ^^• SmU R                   U R                  p![        U5      nUR                  SS5        S[        R
                  S[        4S jmS[        R                  R                  4UU4S jjn[        R                  " [        R                  R                  UX45        U R                  R                  SS5      nTb  [        U[        R
                  5      (       d  g	T" U5      nTU-   $ )
zSEstimate the size of a collective operation in bytes, including inputs and outputs.NÚoutÚtr(   c                 ó`   • [        U R                  5       5      [        U R                  5      -  $ r/   )re   rS   r
   ri   )rÙ   s    r    Útensor_bytesÚ1estimate_fx_collective_size.<locals>.tensor_bytesq  s!   € Ü% a§f¡f£hÓ/´.ÀÇÁÓ2IÑIÐIr   rk   c                 óž   >• U R                   R                  SS 5      n[        U[        R                  5      (       d  g Tc  SmTT" U5      -  mg )NÚvalr   )ÚmetaÚgetrM   r9   ÚTensor)rk   Úinp_valÚinput_bytesrÛ   s     €€r    Úadd_inp_bytesÚ2estimate_fx_collective_size.<locals>.add_inp_bytest  sG   ø€ Ø—(‘(—,‘,˜u dÓ+ˆÜ˜'¤5§<¡<×0Ñ0Øð ÑØˆKØ‘| GÓ,Ñ,‰r   rÞ   r   )rž   rŸ   ÚdictÚpopr9   rá   rY   ÚfxÚNodeÚpytreeÚtree_map_onlyrß   rà   rM   )rÖ   rž   rŸ   rä   Ú
output_valÚoutput_bytesrã   rÛ   s         @@r    Úestimate_fx_collective_sizerî   g  sÌ   ù€ à€Kà—<‘< §¡ˆ&Ü�&‹\€Fð ‡J�Jˆu�dÔðJœŸ™ð J¬ô Jð-œ5Ÿ8™8Ÿ=™=÷ -ð -ô ×ÒÜ�‰�‰ØØ	ˆôð —‘×!Ñ! %¨Ó.€JàÑ¤*¨Z¼¿¹×"FÑ"FØá 
Ó+€Là˜Ñ%Ð%r   c                 óL   • SSK Jn  [        U 5      nU" U 5      (       d  U$ US-  $ )zËEstimate the memory footprint of a collective operation in bytes.

This returns the total bytes that need to be live concurrently in memory.
For all_reduce, we divide by 2 since it can be done in-place.
r   )Úis_all_reduce_tensorr   )Ú#torch._inductor.fx_passes.bucketingrð   rî   )rÖ   Úis_all_reducerS   s      r    Ú'estimate_fx_collective_memory_footprintró   Ž  s,   € õô ' wÓ/€DÙ$ W×-Ñ-ˆ4Ð<°4¸1±9Ð<r   Úoverride_sizeÚuse_nccl_estimatorc                 ó˜  ^ ^^
^^• SSK Jn  T R                  [        R                  R
                  R                  R                  L a  SnTc  [        T 5      nOTn[        T R                  [        5      (       a   e[        T R                  T R                  T R                  SS9nUc   eUu  m
mTS   mU" T5      n[        T R                  [        R                  R                  5      (       d   e[!        T R                  R#                  5       5      nS[$        [&           4U
U UUU4S jjnU(       a  U" 5       n	U	b  U	$ [)        XFU5      $ )	rÔ   r   rn   FT)rž   rŸ   Únormalize_to_only_use_kwargsÚ
group_namer(   c                  ó¦  >^^• SSK Jn JnJn  U" T5      n[        R
                  R                  R                  U5      UR                  :X  a  g U " U5      nUR                  U5      nUR                  (       d  g [        R                  " TT45      u  pgS[        R                  4U4S jjmS[        R                  S[         4S jnS["        S["        4UU4S jjmU V	s/ s H  n	T" U	5      PM     nn	[        R$                  " Xg5      u  p«TR&                  n[)        U[        R*                  R,                  5      (       d   e[        R
                  R/                  US	9 nU" U
0 UD6n[        R0                  R2                  R4                  R7                  U5        S S S 5        WR8                  nUS:  a  g US
-  nU$ s  sn	f ! , (       d  f       N-= f)Nr   )Ú_get_pg_default_devicerˆ   ÚBackendr(   c                 ó<   >• [         R                  " Tc  U OT/UUS9$ )N)ri   r‹   )r9   Úempty)rS   ri   r‹   rô   s      €r    Ú_tensorÚVestimate_nccl_collective_runtime_from_fx_node.<locals>._nccl_estimate.<locals>._tensorÜ  s&   ø€ Ü—;’;Ø%Ñ-‘°M°?ØØñð r   Úsc                 óR   • [         R                  R                  R                  U SS9$ )Nr   rV   )r   rZ   r[   r\   )r   s    r    Útry_size_hintÚ\estimate_nccl_collective_runtime_from_fx_node.<locals>._nccl_estimate.<locals>.try_size_hintã  s"   € Ü—7‘7×#Ñ#×5Ñ5°aÀ!Ð5ÐDÐDr   Úec                 ó.  >• [        U [        R                  R                  5      (       a  T" U R                  S   5      $ [        U [        R
                  5      (       a6  T" [        U R                  5       5      /U R                  U R                  5      $ U $ )NrÞ   )
rM   r9   rè   ré   rß   rá   re   rS   ri   r‹   )r  rþ   Úto_real_tensors    €€r    r  Ú]estimate_nccl_collective_runtime_from_fx_node.<locals>._nccl_estimate.<locals>.to_real_tensoræ  sg   ø€ Ü˜!œUŸX™XŸ]™]×+Ñ+Ù% a§f¡f¨U¡mÓ4Ð4Ü˜!œUŸ\™\×*Ñ*ÙÔ 6°q·v±v³xÓ @ÐAÀ1Ç7Á7ÈAÏHÉHÓUÐUØˆHr   )rŠ   rŒ   )rr   rú   rˆ   rû   r9   rŽ   Údistributed_c10dÚget_backendÚFAKEÚ_get_backendÚsupports_time_estimaterê   Útree_flattenrá   rW   ÚExprrY   r   Útree_unflattenÚtargetrM   Ú_opsÚ
OpOverloadr‘   r’   r“   r”   r•   r–   )rú   rˆ   rû   r›   r‹   ÚbackendÚ	flat_argsÚflat_args_pytree_specr  ÚaÚ	real_argsÚreal_kwargsr�   r    r¡   r¢   r£   rþ   r  rž   rÖ   rø   rŸ   rô   s                    @@€€€€€r    Ú_nccl_estimateÚEestimate_nccl_collective_runtime_from_fx_node.<locals>._nccl_estimateÈ  s’  ú€ ÷	
ñ 	
ñ $ JÓ/ˆÜ×Ñ×-Ñ-×9Ñ9¸"Ó=ÀÇÁÓMàá'¨Ó+ˆØ—/‘/ &Ó)ˆØ×-×-Øä+1×+>Ò+>ÀÀf¸~Ó+NÑ(ˆ	ð	¬E¯L©L÷ 	ð	EœUŸZ™Zð 	E¬Cô 	Eð	œcð 	¤c÷ 	ð 	ñ 1:Ó:²	¨1‘^ AÖ&±	ˆ	Ð:Ü!'×!6Ò!6°yÓ!XÑˆ	à�^‰^ˆÜ˜"œeŸj™j×3Ñ3×4Ñ4Ð4Ð4Ü×Ñ×.Ñ.°RÐ.Ñ8¸NÙ�IÐ- Ñ-ˆAÜ�I‰I×&Ñ&×2Ñ2×:Ñ:¸1Ô=÷ 9ð %×3Ñ3ˆð ˜‹?ØØ! CÑ'ˆØÐùò ;÷
 9Õ8ús   ÃF=Å<GÇ
G)rr   ro   r  r9   r’   r“   Úall_to_all_singler•   rî   rM   Ústrr   rž   rŸ   r  r  rJ   rQ   r   ÚfloatrÒ   )rÖ   rô   rõ   ro   r¥   Úopt_args_kwargsr¦   r§   r  r£   rž   rø   rŸ   s   ``        @@@r    Ú-estimate_nccl_collective_runtime_from_fx_noder  œ  s'  ü€ õ" Kà‡~�~œŸ™×3Ñ3×EÑE×MÑMÒMð #ÐàÑÜ$?ÀÓ$HÑ!à$1Ð!ä˜'Ÿ.™.¬#×.Ñ.Ð.Ð.Ü(Ø�‰Ø�\‰\Ø�~‰~Ø%)ñ	€Oð Ñ&Ð&Ð&Ø"�L€Dˆ&à˜Ñ%€JÙ(¨Ó4€JÜ�g—n‘n¤e§j¡j×&;Ñ&;×<Ñ<Ð<Ð<Ü/°·±×0CÑ0CÓ0EÓF€Dð3œH¤U™O÷ 3ó 3öj Ù$Ó&ˆØÑ"ØÐä0Ø!¨tóð r   )i   )NT);r`   Úloggingrª   rb   Úenumr   Útypingr   r   rW   r9   Útorch.utils._pytreer:   Ú_pytreerê   Ú%torch.fx.experimental.symbolic_shapesr   Útorch.fx.operator_schemasr   r*   r	   r
   r   r   Úvirtualizedr   Ú	getLoggerr   Úlogr   r"   Ú	lru_cacher?   r  rJ   ÚIRNoderR   ÚSizerY   r^   re   rl   ru   rw   r}   r‚   r²   r³   r°   r  r¤   rÒ   rÕ   rè   ré   rî   ró   Úboolr  r   r   r    Ú<module>r.     s{  ðÛ Û Û Û Ý ß  ã ã ß $Ð $Ý ;Ý 8å ß CÑ CÝ ð ×Ò˜Ó!€ô�ô ô�gô ð ×Ñð&�oó &ó ð&ð%°cð %¸iô %ð6˜bŸi™ið 6¨Iô 6ñH §¡ð H°sð HÈSõ Hñ §¡ð °sð ÈSõ ð¨"¯)©)ð ¸ô ð@ B§I¡Ið @°#ô @ôˆgô ô�ô ô
�ô ð 	ðð
 	ðð	€ð  
ˆØ	ˆðð 
ˆØ	ˆðð 
ˆØ	ˆðð	€ò,òòòð)€ð8¸hÀu¹oô ðBeØ"ðeØ03ðeØ;Dðeà
ôeðZ¨2¯9©9ð ¸ô ð*$&¨¯©¯©ð $&¸3ô $&ðN=°U·X±X·]±]ð =Àsô =ð  $(Ø#ñhØ�X‰X�]‰]ðhà˜C‘=ðhð ðhð ö	hr   