Ë
    Q/æjy6  ã                   ód  — d dl Z d dlZd dl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 d dlmZ e
rd dlmZ d„ d	fd
efd„Z e j&                  ed„ d¬«      Z e j&                  ed„ d	¬«      Ze G d„ d«      «       Ze G d„ d«      «       Z G d„ d«      Z G d„ d«      Zdd„Zd„ d dfd„Zd„ Zd„ Zy)é    N)Údeque)Ú	dataclass)ÚDictÚListÚTYPE_CHECKING©Úprofile)Ú
DeviceType)Ú_KinetoEventc                 ó   — | j                   S ©N)Úchildren©Úxs    úX/root/repos/pocs/video-evals/.venv/lib/python3.12/site-packages/torch/profiler/_utils.pyú<lambda>r      s
   € °1·:±:€ ó    FÚreversec              #   ó°   K  — |rt         nd„ }t         || «      «      }|r4 ||«      }|–—  | ||«      «      D ]  }|j                  |«       Œ |rŒ3y y ­w)Nc                 ó   — | S r   © r   s    r   r   z_traverse.<locals>.<lambda>   s   € ¨q€ r   )Úreversedr   Úappend)ÚtreeÚnext_fnÚchildren_fnr   ÚorderÚ	remainingÚ
curr_eventÚchild_events           r   Ú	_traverser!      s\   è ø€ Ù�H¡[€EÜ‘e˜D“kÓ"€IÙ
Ù˜YÓ'ˆ
ØÒÙ ¡¨ZÓ!8Ó9ò 	*ˆKØ×Ñ˜[Õ)ð	*ô ùs   ‚AAÁAc                 ó"   — | j                  «       S r   )Úpopr   s    r   r   r      s   € ¸a¿e¹e»g€ r   T)r   r   c                 ó"   — | j                  «       S r   )Úpopleftr   s    r   r   r      s   €  §¡£€ r   c                   óV   — e Zd ZU dZeed<   dZeed<   dZeed<   dZeed<   e	d„ «       Z
y)ÚEventMetricsr   Úduration_time_nsÚself_time_nsÚidle_time_nsÚqueue_depthc                 óT   — | j                   dk(  ry| j                  | j                   z  S )Nr   g        )r(   r*   ©Úselfs    r   Úfraction_idle_timezEventMetrics.fraction_idle_time(   s*   € à× Ñ  AÒ%ØØ× Ñ  4×#8Ñ#8Ñ8Ð8r   N)Ú__name__Ú
__module__Ú__qualname__r(   ÚintÚ__annotations__r)   r*   r+   Úpropertyr/   r   r   r   r'   r'   !   s=   … àÐ�cÓØ€L�#ÓØ€L�#ÓØ€K�Óàñ9ó ñ9r   r'   c                   ó0   — e Zd ZU eed<   eed<   dZeed<   y)ÚIntervalÚstartÚendr   r+   N)r0   r1   r2   r3   r4   r+   r   r   r   r7   r7   /   s   … àƒJØ	ƒHØ€K�Ôr   r7   c                   ó6   — e Zd Zd„ Zd„ Zd„ Zd„ Zdee   fd„Z	y)ÚEventKeyc                 ó   — || _         y r   ©Úevent)r.   r>   s     r   Ú__init__zEventKey.__init__7   s	   € Øˆ�
r   c                 ó@   — t        | j                  j                  «      S r   )Úhashr>   Úidr-   s    r   Ú__hash__zEventKey.__hash__:   s   € Ü�D—J‘J—M‘MÓ"Ð"r   c                 ó\   — | j                   j                  |j                   j                  k(  S r   )r>   rB   )r.   Úothers     r   Ú__eq__zEventKey.__eq__=   s   € Ø�z‰z�}‰} §¡§¡Ñ.Ð.r   c                 ó0   — | j                   j                  › S r   )r>   Únamer-   s    r   Ú__repr__zEventKey.__repr__@   s   € Ø—*‘*—/‘/Ð"Ð#r   Ú	intervalsc                 ó²  — d}t        |d„ ¬«      }|rgt        | j                  j                  |d   j                  «      }t        | j                  j                  |d   j                  «      }||k  r|||z
  z  }d\  }}|t        |«      k  rÊ||   }||   }|dz  }|j                  |j                  kD  r2|j                  |j                  kD  r|dz  }ŒU|j                  |_        |}t        | j                  j                  |j                  «      }t        | j                  j                  |j                  «      }||k  r|||z
  z  }|t        |«      k  rŒÊ|S )Nr   c                 ó   — | j                   S r   ©r8   r   s    r   r   z,EventKey.intervals_overlap.<locals>.<lambda>E   s
   € °A·G±G€ r   ©Úkey)r   é   rP   )	ÚsortedÚmaxr>   Ústart_time_nsr8   ÚminÚend_time_nsr9   Úlen)	r.   rJ   Úoverlap_timeÚoverlap_startÚoverlap_endÚiÚjÚprev_intervalÚcurr_intervals	            r   Úintervals_overlapzEventKey.intervals_overlapC   sJ  € ØˆÜ˜9Ñ*;Ô<ˆ	áÜ §
¡
× 8Ñ 8¸)ÀA¹,×:LÑ:LÓMˆMÜ˜dŸj™j×4Ñ4°iÀ±l×6FÑ6FÓGˆKà˜{Ò*Ø ¨mÑ ;Ñ;�à‰ˆˆ1Ø”#�i“.Ò Ø% a™LˆMØ% a™LˆMØ�‰FˆAØ× Ñ  =×#6Ñ#6Ò6à ×$Ñ$ }×'8Ñ'8Ò8Ø˜‘F�AØà*7×*;Ñ*;�MÔ'Ø�Aä §
¡
× 8Ñ 8¸-×:MÑ:MÓNˆMÜ˜dŸj™j×4Ñ4°m×6GÑ6GÓHˆKØ˜{Ò*Ø ¨mÑ ;Ñ;�ð! ”#�i“.Ó ð$ Ðr   N)
r0   r1   r2   r?   rC   rF   rI   r   r7   r^   r   r   r   r;   r;   6   s&   „ òò#ò/ò$ð¨4°©>ô r   r;   c                   óB   — e Zd Zdefd„Zd„ Zd„ Zd„ Zd„ Zdde	de
fd	„Zy
)ÚBasicEvaluationÚprofc                 óX  — || _         i | _        | j                  «        t        d„ | j                  j	                  «       D «       d„ ¬«      | _        | j
                  D �cg c]  }|j                  ‘Œ c}| _        g | _        | j                  «       | _
        | j                  «        y c c}w )Nc              3   ó    K  — | ]  }|–— Œ y ­wr   r   )Ú.0Úes     r   ú	<genexpr>z+BasicEvaluation.__init__.<locals>.<genexpr>j   s   è ø€ Ò,�1ŒQÑ,ùs   ‚c                 ó.   — | j                   j                  S r   )r>   rS   r   s    r   r   z*BasicEvaluation.__init__.<locals>.<lambda>j   s   € ¸A¿G¹G×<QÑ<Q€ r   rN   )r	   ÚmetricsÚcompute_self_timerQ   ÚkeysÚ
event_keysr>   ÚeventsÚcuda_eventsÚcompute_queue_depthÚqueue_depth_listÚcompute_idle_time)r.   ra   re   s      r   r?   zBasicEvaluation.__init__e   s†   € ØˆŒØ57ˆŒØ×ÑÔ Ü Ù,˜Ÿ™×)Ñ)Ó+Ô,Ñ2Qô
ˆŒð )-¯©Ö8 1�q—w“wÒ8ˆŒØ/1ˆÔØ $× 8Ñ 8Ó :ˆÔØ×ÑÕ ùò 9s   ÁB'c                 ó6  — | j                   j                  €J ‚t        | j                   j                  j                  «       «      }|rÒ|j	                  «       }|j
                  }|j                  D ]"  }||j
                  z  }|j                  |«       Œ$ t        |«      | j                  vs!J d|j                  › d|j                  › �«       ‚t        |¬«      | j                  t        |«      <   |j
                  | j                  t        |«         _        |rŒÑyy)zM
        Computes event's self time(total time - time in child ops).
        NzDuplicate id: z, )r)   )r	   Úkineto_resultsr   Úexperimental_event_treer#   r(   r   r   r;   rh   rB   rH   r'   )r.   Ústackr   Ú	self_timer    s        r   ri   z!BasicEvaluation.compute_self_timeq   sÿ   € ð �|‰|×*Ñ*Ð6Ð6Ð6Ü�d—l‘l×1Ñ1×IÑIÓKÓLˆñ ØŸ™›ˆJØ"×3Ñ3ˆIØ)×2Ñ2ò *�Ø˜[×9Ñ9Ñ9�	Ø—‘˜[Õ)ð*ô ˜Ó$¨D¯L©LÑ8ðCà 
§¡˜¨b°·±Ð0AÐBóCØ8ä1=È9Ô1UˆD�L‰Lœ *Ó-Ñ.ð ",×!<Ñ!<ð �L‰LÜ˜Ó$ñäô r   c                 óÚ  ‡‡‡— | j                   j                  €J ‚| j                   j                  j                  «       }d„ Šd„ Št        ˆfd„|D «       d„ ¬«      }t        ˆfd„|D «       d„ ¬«      }t        ||z   d„ ¬«      | _        i }d	}|D ]  Št        |ˆfd
„|¬«      }||‰<   |�|n|}Œ  d	}d}||z   | j                  z   }	d„ }
g }|	j                  |
¬«       |	D �]‡  }t        |d«      rE|j                  «       dz  }|j                  «       |j                  «       z   dz  }||v r
||   �||   }t        |d«      r@|j                  «       }|j                  «       |j                  «       z   }||v r/||   �*||   }n$t        |d«      r|j                  }|j                  }|t        |«      k  r@||   j                  «       k  r*|dz  }|t        |«      k  r||   j                  «       |k  rŒ*||z
  dz   }t        |d	«      }t        |d«      st        |d«      r|j!                  t#        |«      «       �Œ]t        |d«      s�Œk|| j$                  t'        |«         _        �ŒŠ |S )zâ
        Computes queue_depth at each event. This will calculate the queue depth data for
        All the events in the tree.
        This will return a list of Interval of queue depth data of cuda launch and kernels.
        c                 ó    — | j                   dk(  S )NÚcudaLaunchKernel)rH   ©re   s    r   Úis_cuda_launch_kernelzBBasicEvaluation.compute_queue_depth.<locals>.is_cuda_launch_kernel�   s   € à—6‘6Ð/Ñ/Ð/r   c                 ó€   — | j                  «       t        j                  k(  xr d| j                  j	                  «       vS )NÚmem)Údevice_typer
   ÚCUDArH   Úlowerry   s    r   Úis_cuda_kernelz;BasicEvaluation.compute_queue_depth.<locals>.is_cuda_kernel”   s+   € à—=‘=“?¤j§o¡oÑ5ÒU¸%ÀqÇvÁvÇ|Á|Ã~Ð:UÐUr   c              3   ó4   •K  — | ]  } ‰|«      sŒ|–— Œ y ­wr   r   )rd   re   rz   s     €r   rf   z6BasicEvaluation.compute_queue_depth.<locals>.<genexpr>™   s   øè ø€ ÒD�1Ñ+@ÀÕ+CŒQÑDùó   ƒ‘c                 ó"   — | j                  «       S r   ©Ústart_nsr   s    r   r   z5BasicEvaluation.compute_queue_depth.<locals>.<lambda>š   ó   € ˜!Ÿ*™*›,€ r   rN   c              3   ó4   •K  — | ]  } ‰|«      sŒ|–— Œ y ­wr   r   )rd   re   r€   s     €r   rf   z6BasicEvaluation.compute_queue_depth.<locals>.<genexpr>�   s   øè ø€ Ò=�1©>¸!Õ+<ŒQÑ=ùr‚   c                 ó"   — | j                  «       S r   r„   r   s    r   r   z5BasicEvaluation.compute_queue_depth.<locals>.<lambda>ž   r†   r   c                 ó"   — | j                  «       S r   r„   r   s    r   r   z5BasicEvaluation.compute_queue_depth.<locals>.<lambda>¢   s   € À1Ç:Á:Ã<€ r   r   c                 óF   •— | j                  «       ‰j                  «       k(  S r   )Úlinked_correlation_id)r   Úcuda_launch_events    €r   r   z5BasicEvaluation.compute_queue_depth.<locals>.<lambda>ª   s!   ø€ ˜!×1Ñ1Ó3Ø$×:Ñ:Ó<ñ=€ r   rM   éÿÿÿÿc                 ó¾   — t        | d«      r| j                  «       dz  S t        | d«      r| j                  «       S t        | d«      r| j                  S t	        d«      ‚)NÚstart_uséè  r…   rS   zUnknown Event Type)Úhasattrr�   r…   rS   Ú	Exceptionr=   s    r   Únew_old_event_comparatorzEBasicEvaluation.compute_queue_depth.<locals>.new_old_event_comparator¶   sW   € Ü�u˜jÔ)Ø—~‘~Ó'¨$Ñ.Ð.Ü�u˜jÔ)Ø—~‘~Ó'Ð'Ü�u˜oÔ.Ø×*Ñ*Ð*ÜÐ0Ó1Ð1r   r�   r�   r…   rS   rP   )r	   rr   rl   rQ   rm   Úindex_of_first_matchÚsortr‘   r�   Úduration_usr…   Úduration_nsrS   rU   rV   rR   r   r7   rh   r;   r+   )r.   Úcuda_event_listÚcuda_launch_eventsÚcuda_kernel_eventsÚkernel_mappingÚlast_mapped_kernelÚindexÚcurrent_kernel_indexÚspawned_kernel_indexÚ
all_eventsr“   ro   r>   Ú
start_timeÚend_timeÚcurrent_queue_depthrŒ   r€   rz   s                   @@@r   rn   z#BasicEvaluation.compute_queue_depth‡   sÇ  ú€ ð �|‰|×*Ñ*Ð6Ð6Ð6ØŸ,™,×5Ñ5×<Ñ<Ó>ˆò	0ò	Vô $ÛD˜ÔDÙ&ô
Ðô $Û=˜Ô=Ù&ô
Ðô
 "ØÐ!3Ñ3Ñ9Oô
ˆÔð 35ˆØÐØ!3ò 	TÐÜ(Ø"ó=à(ô	ˆEð 16ˆNÐ,Ñ-Ø*/Ð*;¡ÐASÑð	Tð  !ÐØ!Ðà'Ð*<Ñ<¸t¿{¹{ÑJˆ
ò	2ð ,.ÐØ�‰Ð4ˆÔ5Øó  	PˆEä�u˜jÔ)Ø"Ÿ^™^Ó-°Ñ4�
Ø!ŸN™NÓ,¨u×/@Ñ/@Ó/BÑBÀdÑJ�à˜NÑ*¨~¸eÑ/DÐ/PØ+9¸%Ñ+@Ð(Ü�u˜jÔ)Ø"Ÿ^™^Ó-�
Ø Ÿ>™>Ó+¨e×.?Ñ.?Ó.AÑA�à˜NÑ*¨~¸eÑ/DÐ/PØ+9¸%Ñ+@Ñ(Ü˜ Ô0Ø"×0Ñ0�
Ø ×,Ñ,�ð %¤sÐ+=Ó'>Ò>Ø'Ð(<Ñ=×FÑFÓHØòð %¨Ñ)Ð$ð	 %¤sÐ+=Ó'>Ò>Ø'Ð(<Ñ=×FÑFÓHØóð #7Ð9MÑ"MÐPQÑ"QÐÜ"%Ð&9¸1Ó"=Ðä�u˜jÔ)¬W°U¸JÔ-GØ ×'Ñ'Ü˜Z¨Ð3FÓGöô ˜ Ö0Ø<O�—‘œX e›_Ñ-Ö9ðA 	PðD  Ðr   c                 óæ  — d}d}g }| j                   rƒ| j                  rw|t        | j                  d   j                  | j                   d   j                  «      t        | j                   d   j
                  | j                  d   j                  «      gz  }| j                   D ][  }|j                  dk(  r|s|j
                  }d}|j                  dkD  sŒ2|sŒ5|j                  t        ||j                  «      «       d}Œ] | j                  j                  «       D �cg c]  }|j                  ‘Œ }}|D ]7  }t        |«      j                  |«      | j                  t        |«         _        Œ9 yc c}w )z4
        Computes idle time of the profile.
        Fr   r�   TN)ro   rl   r7   rS   r8   r9   rU   r+   r   rh   rj   r>   r;   r^   r*   )r.   ÚidleÚ
idle_startÚidle_intervalsÚ
data_pointre   Ú
event_listr>   s           r   rp   z!BasicEvaluation.compute_idle_timeå   sM  € ð
 ˆØˆ
Ø)+ˆØ× Ò  T§[¢[ØÜ˜Ÿ™ Q™×5Ñ5°t×7LÑ7LÈQÑ7O×7UÑ7UÓVÜ˜×.Ñ.¨rÑ2×6Ñ6¸¿¹ÀB¹×8SÑ8SÓTðñ ˆNð
 ×/Ñ/ò 	ˆJØ×%Ñ%¨Ò*±4Ø'Ÿ^™^�
Ø�Ø×%Ñ%¨Ó)ªdØ×%Ñ%¤h¨z¸:×;KÑ;KÓ&LÔMØ‘ð	ð (,§|¡|×'8Ñ'8Ó':Ö; !�a—g“gÐ;ˆ
Ð;Øò 	0ˆEÜ9AØó:çÑ Ó/ð �L‰Lœ %›Ñ)Õ6ñ	0ùò <s   ÄE.c                 óÔ  ‡— ddl }t        t        | j                  «      «      }|D �cg c]  }|j                  ‘Œ }}dŠd}g }d}|t        |«      k  r¦||   ‰kD  r|dz  }Œt        |dz   t        |«      «      D ]i  }	t        |ˆfd„|	¬«      }
t        ||	|
¬«      }|€Œ%||   |k\  sŒ.|j                  t        ||   j                  ||   j                  «      «       |
�|
n|} n |dz  }|t        |«      k  rŒ¦| j                  j                  «       D �cg c]  }|j                  |«      r|‘Œ }}|�r|j                  |D �cg c]  }| j                  |   j                   ‘Œ c}|j"                  ¬«      }|j                  |D �cg c]  }| j                  |   j$                  ‘Œ c}|j"                  ¬«      }||j'                  |«      z
  |j)                  |«      z  }||j'                  |«      z
  |j)                  |«      z  }|d	|z  z   }t+        t-        ||«      t/        j0                  d«      d
¬«      D ��cg c]  \  }}|‘Œ	 }}}|d| }|S c c}w c c}w c c}w c c}w c c}}w )a  
        Filter and Rank the events based on some heuristics:
        1) Events that are in the falling phase of the queue depth.
        2) Events that have a high idle_time, self_time difference.

        Parameters:
            length: The number of events to return.
        r   Né   rP   c                 ó   •— | ‰k  S r   r   )r   Úbottom_threasholds    €r   r   z-BasicEvaluation.rank_events.<locals>.<lambda>  s   ø€ ¨Ð.?Ñ)?€ r   rM   )r8   r9   )Údtypeg333333ã?T)rO   r   )ÚtorchÚlistr   ro   r+   rV   Úranger”   Úargmaxr   r7   r8   rh   rj   r^   Útensorr)   Úfloat32r/   ÚmeanÚstdrQ   ÚzipÚoperatorÚ
itemgetter)r.   Úlengthr¯   ro   re   Ú	qd_valuesÚtop_threasholdÚdecrease_intervalrZ   r[   Únext_minimum_idxÚpeak_idxr>   r©   ru   Ú	idle_timeÚnormalized_gainÚnormalized_selfÚheuristic_score_listÚ_r­   s                       @r   Úrank_eventszBasicEvaluation.rank_events  s�  ø€ ó 	ä¤¨×)>Ñ)>Ó ?Ó@ÐØ,<Ö= q�Q—]“]Ð=ˆ	Ð=àÐØˆØÐØˆØ”#�i“.Ò Ø˜‰|Ð/Ò/Ø�Q‘�ØÜ˜1˜q™5¤# i£.Ó1ò �ô $8ØÓ?Àqô$Ð ô " )°1Ð:JÔK�ð Ñ'¨I°hÑ,?À>Ó,QØ%×,Ñ,Ü Ø,¨XÑ6×<Ñ<Ð>NÈqÑ>Q×>WÑ>Wóôð
 -=Ð,HÑ(Èa�AÙð!ð" �‰FˆAð+ ”#�i“.Ó ð2 Ÿ™×*Ñ*Ó,ö
àØ×&Ñ&Ð'8Ô9ò ð
ˆ
ð 
ò
 ØŸ™Ø?IÖJ°e�—‘˜eÑ$×1Ó1ÒJØ—m‘mð %ó ˆIð Ÿ™ØEOÖP¸E�—‘˜eÑ$×7Ó7ÒPØ—m‘mð %ó ˆIð  )¨5¯:©:°iÓ+@Ñ@ÀEÇIÁIÈiÓDXÑXˆOØ(¨5¯:©:°iÓ+@Ñ@ÀEÇIÁIÈiÓDXÑXˆOØ#2°S¸?Ñ5JÑ#JÐ ô
 !'ÜÐ,¨jÓ9Ü ×+Ñ+¨AÓ.Ø ô!÷á�A�uò ðˆJñ ð $ G VÐ,ˆJØÐùòs >ùò:
ùò Kùò Qùós   ¨IÄIÅ IÆ IÈ:I$rº   Úprint_enablec                 ó  — | j                  |«      }|s|S |rdnd}|dj                  |D �cg c]@  }d› d|› dt        |j                  «      › d| j                  |   j
                  dz  d	›d
d› �	‘ŒB c}«      z  }|rt        |«       |S c c}w )NzOptimizable events:
zNo events to optimize
ú
zP--------------------------------------------------------------------------------z
Event:                z
Source code location: z
Percentage idle time: éd   z.2fz%
)rÅ   ÚjoinÚsource_code_locationr>   rh   r/   Úprint)r.   rº   rÆ   r©   Úoutputr>   s         r   Úget_optimizable_eventsz&BasicEvaluation.get_optimizable_eventsJ  s½   € Ø×%Ñ% fÓ-ˆ
ÙØÐÙ,6Ñ(Ð<Uˆà�$—)‘)ð (öð ð �Hð Ø�gð Ü+¨E¯K©KÓ8Ð9ð :Ø—|‘| EÑ*×=Ñ=ÀÑCÀCÐHð IØ€ò	òó	
ñ 		
ˆñ Ü�&ŒMØÐùòs   ¬AB	
N)rP   T)r0   r1   r2   r	   r?   ri   rn   rp   rÅ   r3   ÚboolrÎ   r   r   r   r`   r`   d   s9   „ ð
!˜Wó 
!ò=ò,\ ò|0ò8GñR¨Sð ÀDô r   r`   c                 óz   — |�|t        | «      k\  rt        | «      }t        ||«      D ]  } || |   «      sŒ|c S  y r   )rV   r±   )ÚseqÚ	predicater8   r9   rZ   s        r   r”   r”   _  sF   € Ø
€{�cœS ›X’oÜ�#‹hˆÜ�5˜#Óò ˆÙ�S˜‘VÕØŠHðð r   c                 ó   — | S r   r   r   s    r   r   r   h  s   € ˜a€ r   c                 óh   — | || } t        | «      dk(  ry | j                  t        | |¬«      «      |z   S )Nr   rN   )rV   r�   rR   )rÑ   rO   r8   r9   s       r   r²   r²   h  s6   € Ø
ˆe�Cˆ.€CÜ
ˆ3ƒx�1‚}ØØ�9‰9”S˜ #Ô&Ó'¨%Ñ/Ð/r   c                 ó~   — | �;t        j                  d| j                  «      }|€| j                  } Œ1| j                  S y)Nz
\.py\(.*\)zNo source code location found)ÚreÚsearchrH   Úparent)r>   Úmatchs     r   rË   rË   o  s:   € Ø
Ð
Ü—	‘	˜-¨¯©Ó4ˆØˆ=Ø—L‘LˆEØØ�z‰zÐØ*r   c                  óJ   — ddl m}   | «       5  	 d d d «       y # 1 sw Y   y xY w)Nr   r   )Útorch.autograd.profilerr	   r   s    r   Ú_init_for_cuda_graphsrÜ   }  s"   € Ý/á	‹ñ Ø÷÷ ñ ús   Ž™")r   N)Ú	functoolsr¸   rÖ   Úcollectionsr   Údataclassesr   Útypingr   r   r   rÛ   r	   Útorch.profilerr
   Útorch.autogradr   rÏ   r!   ÚpartialÚtraverse_dfsÚtraverse_bfsr'   r7   r;   r`   r”   r²   rË   rÜ   r   r   r   ú<module>ræ      sÕ   ðã Û Û 	Ý Ý !ß ,Ñ ,å +Ý %ñ Ý+ñ *>Èuñ *Èó *ð !ˆy× Ñ  Ñ4EÈtÔT€Ø ˆy× Ñ ØÑ,°eô€ð
 ÷
9ð 
9ó ð
9ð ÷ð ó ð÷+ñ +÷\xñ xóvñ   q¨dó 0ò+ór   