ó
    KëgjûO  ã                   óJ  • % S r SSKrSSKrSSKrSSKrSrSrSrS\4S jr	S\
S\4S	 jrS
\\\S4   -  S\4S jrS\S\S\S\S\\\S4   S4   S\\\\S4   -  S4   S\\S4   4S jr " S S5      rSq\S-  \S'   S\4S jr     SCS\S\S-  S\S-  S\\\S4   S4   S-  S\\\\S4   -  S4   S-  S\\\S4   S4   S-  4S jjrSSSSSSS.S\S\S\S\S\S \S!\S-  S"\S-  S\4S# jjrSS$SS%.S&\S'\S\S\S!\S\S\4S( jjr SDSS)SS*.S+\S\S\S \S\S-  S\4S, jjjr\SSSSS-.S.\S/\S0\S1\S\S!\S\S-  S\4S2 jjrS3S4SS5SSS6.S7\S8\S\S9\S\S\S\S \S!\S-  S\4S: jjr\S;.S<\S=\S0\S\4S> jjr\SS?.S<\S=\S@\S0\S \S\4SA jjr\S;.S<\S=\S0\4SB jjrg)Ea  
Unified Buffer (UB) Manager for Ascend NPU.

This module provides UB capacity detection and tiling strategy computation
for running Triton kernels on Ascend NPU. It automatically calculates
optimal block sizes based on UB capacity constraints to prevent UB overflow.
é    Niÿÿ  i €  i   Úreturnc                  óÆ   • [        [        S5      (       a   [        R                  R                  5       $  SSKJn   U " 5       $ ! [         a     Nf = f! [         a     gf = f)zDetect Ascend NPU availability.Únpur   ©Úis_torch_npu_availableF)ÚhasattrÚtorchr   Úis_availableÚ	ExceptionÚtransformers.utilsr   ÚImportErrorr   s    Ú©C:\Users\johnn\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.13_qbz5n2kfra8p0\LocalCache\local-packages\Python313\site-packages\fla/utils/ascend_ub_manager.pyÚis_npu_availabler      s_   € äŒu�e×Ñð	Ü—9‘9×)Ñ)Ó+Ð+ðÝ=á%Ó'Ð'øô ó 	Ùð	ûô ó Ùðús"   —A ¶A Á
AÁAÁ
A ÁA Úreasonc                 óR   • [         R                  " S[        S-   SU  3SS9  [        $ )NzUsing fallback UB capacity (é   z	 bytes): é   )Ú
stacklevel)ÚwarningsÚwarnÚ_FALLBACK_UB_CAPACITY_BITS)r   s    r   Ú_fallback_ub_capacityr   .   s2   € Ü‡M‚MØ
&Ô'AÀQÑ'FÐ&GÀyÐQWÐPXÐYØòô &Ð%ó    Ú
tiling_dim.c                 ó†   • [        U [        5      (       a  U 1$ [        U [        5      (       a  [        U 5      $ [        5       $ )zã
Normalize tiling dimension specification to a set of dimension indices.

Args:
    tiling_dim: Either an int (single dimension) or tuple of ints (multiple dimensions).

Returns:
    Set of dimension indices that can be tiled.
)Ú
isinstanceÚintÚtupleÚset)r   s    r   Ú_normalize_tiling_dimsr    6   s7   € ô �*œc×"Ñ"Øˆ|ÐÜ	�J¤×	&Ñ	&Ü�:‹Ðä‹uˆr   Úub_capacity_bitsÚsafety_marginÚ
dtype_sizeÚmemory_multiplierÚshapesÚtiling_dimsc                 óJ  ^• U(       a  U(       d  g/ n[        XE5       Hø  u  mn[        U5      nU(       d  [        SU S35      e[        U4S jU 5       5      (       a  [        SU ST S[	        T5       S35      eSn	[        T5       H$  u  p«X¨;  d  M  US	::  a  Sn	  OU	[        U5      -  n	M&     U	S	::  a  Sn	[        X-  5      n[        XÃU	-  U-  S
-  -  5      n[        SU5      n[        R                  " US-   5      S-  nUR                  U5        Mú     [        U5      $ )aó  
Default tiling strategy: calculate maximum safe block size based on UB capacity.

This is a unified strategy function that works for all kernels by abstracting
the memory calculation as: memory_multiplier * BLOCK_SIZE * unit_param * dtype_size * 8 bits

Args:
    ub_capacity_bits: UB capacity in bits
    safety_margin: Safety margin as a float (e.g., 0.80 for 80%)
    dtype_size: Size of data type in bytes (e.g., 2 for float16, 4 for float32)
    memory_multiplier: Memory multiplier for estimating peak memory usage
    shapes: Tuple of full shapes. Each shape is a tuple of dimension sizes.
        - For ROPE: ((n_q_head, hd), (n_kv_head, hd))
        - For GEGLU: ((n_cols,),)
    tiling_dims: Tuple specifying which dimensions can be tiled for each shape.
        Each element can be:
        - int: single dimension index (e.g., 0 for first dimension)
        - tuple of ints: multiple dimensions that can be tiled together
        - For ROPE: (0, 0) means first dimension of each shape can be tiled
        - For GEGLU: (0,) means first dimension of the shape can be tiled
        Length must match len(shapes).

Returns:
    Tuple of maximum safe block sizes, one for each shape.
    Each element is a power of 2.

Note:
    For each shape, fixed dimensions (non-tiling) are multiplied together to get unit_param.
    The final block size is computed in compute_default_tiling_strategy by taking
    min(desired_block_size, max_safe_block_size) where desired_block_size = triton.next_power_of_2(original_dim).
© úInvalid tiling_dim: ú9. tiling_dim must be an int or a non-empty tuple of ints.c              3   óV   >#   • U  H  oS :  =(       d    U[        T5      :¬  v •  M      g7f©r   N©Úlen)Ú.0Údim_idxÚshapes     €r   Ú	<genexpr>Ú$_default_strategy.<locals>.<genexpr>~   s$   øé € ÐRÂ>¸˜‰{×3˜g¬¨U«Ñ3Ô3Â>ùó   ƒ&)ú for shape ú-. All dimension indices must be in range [0, ú).g      ð?r   r   é   é   )Úzipr    Ú
ValueErrorÚanyr.   Ú	enumerateÚfloatr   ÚmaxÚtritonÚnext_power_of_2Úappendr   )r!   r"   r#   r$   r%   r&   Úmax_safe_sizesr   Útiling_dim_setÚ
unit_paramr0   Údim_sizeÚSAFE_UB_CAPACITY_BITSÚmax_block_sizeÚsafe_block_sizer1   s                  @r   Ú_default_strategyrJ   H   sW  ø€ öN žØð €Nä  Ö5Ñˆˆzä/°
Ó;ˆö ÜØ& z lÐ2kÐlóð ô ÔRÁ>ÓR×RÑRÜØ& z l°+¸e¸Wð E>Ü>AÀ%»j¸\ÈðMóð ð ˆ
Ü!*¨5Ö!1ÑˆGØÕ,Ø˜q“=à!$�JÙØœe H›oÑ-’
ñ "2ð ˜‹?ØˆJô !$Ð$4Ñ$DÓ EÐô Ð2È:Ñ7UÐXbÑ7bÐefÑ7fÑgÓhˆÜ˜Q Ó/ˆô !×0Ò0°À!Ñ1CÓDÈÑIˆØ×Ñ˜oÖ.ñS 6ôV �Ó Ð r   c                   ó”   • \ rS rSrSrSS\S-  4S jjr\S\4S j5       r\S\4S j5       r	\S\
4S	 j5       rS\
4S
 jrS\4S jrSrg)Ú	UBManageré£   zÆ
Unified Buffer Manager for Ascend NPU.

Provides UB capacity detection and management for Ascend NPU devices.
The UB capacity is used by tiling strategy functions to calculate optimal block sizes.
Nr!   c                 ój   • U R                  5       U l        U=(       d    U R                  5       U l        g)zs
Initialize UB Manager.

Args:
    ub_capacity_bits: UB capacity in bits. If None, will be detected automatically.
N)Ú_detect_npu_modelÚ
_npu_modelÚ_detect_ub_capacityÚ_ub_capacity_bits)Úselfr!   s     r   Ú__init__ÚUBManager.__init__«   s*   € ð ×0Ñ0Ó2ˆŒØ!1×!O°T×5MÑ5MÓ5OˆÕr   r   c                 ó   • U R                   $ )zGet UB capacity in bits.©rR   ©rS   s    r   r!   ÚUBManager.ub_capacity_bitsµ   s   € ð ×%Ñ%Ð%r   c                 ó    • U R                   S-  $ )zGet UB capacity in bytes.r   rW   rX   s    r   Úub_capacity_bytesÚUBManager.ub_capacity_bytesº   s   € ð ×%Ñ%¨Ñ*Ð*r   c                 ó   • U R                   $ )zGet detected NPU model name.)rP   rX   s    r   Ú	npu_modelÚUBManager.npu_model¿   s   € ð �‰Ðr   c                 óš   • [        5       (       d  g [        R                  R                  S5      nUR                  $ ! [
         a     gf = f)z(Detect NPU model from device properties.Úunknownr   Údefault)r   r	   r   Úget_device_propertiesÚnamer   )rS   Ú	dev_propss     r   rO   ÚUBManager._detect_npu_modelÄ   sF   € ä×!Ñ!Øð	ÜŸ	™	×7Ñ7¸Ó:ˆIà—>‘>Ð!øÜó 	Øàð	ús   ’*= ½
A
Á	A
c                 óö  • [         R                  " S5      nUb   [        U5      nUS:”  a  U$  [	        5       (       af   SSKJnJn  [        R                  nUR                  UR                  5       5      nU" U5        U" S5      nUb  US::  a  [        SU 35      eUS-  nU$ [        S5      $ ! [         a     NŒf = f! [         a    [        S5      s $ [         a  n	[        S	U	 S
35      s Sn	A	$ Sn	A	ff = f)z°
Detect UB capacity from environment variable or get_soc_spec.

Returns:
    UB capacity in bits. Falls back to a conservative default with a warning
    when detection fails.
ÚASCEND_UB_CAPACITY_BITSNr   )Úget_soc_specÚset_current_compile_soc_infoÚUB_SIZEz#Invalid UB_SIZE from get_soc_spec: r   zfCannot import tbe.common.platform.get_soc_spec. Source CANN set_env.sh or set ASCEND_UB_CAPACITY_BITS.z0Failed to detect UB capacity from get_soc_spec: z*. Set ASCEND_UB_CAPACITY_BITS to override.z>NPU is not available. Set ASCEND_UB_CAPACITY_BITS to override.)ÚosÚgetenvr   r;   r   Útbe.common.platformri   rj   r	   r   Úget_device_nameÚcurrent_devicer   r   r   )
rS   Úenv_capacityÚcapacity_bitsri   rj   ÚdeviceÚsoc_infoÚub_size_bytesr!   Úes
             r   rQ   ÚUBManager._detect_ub_capacityÒ   s-  € ô —y’yÐ!:Ó;ˆØÑ#ðÜ # LÓ 1�Ø  1Ó$Ø(Ð(ð %ô ×ÑðßZô Ÿ™�Ø!×1Ñ1°&×2GÑ2GÓ2IÓJ�Ù,¨XÔ6ñ !-¨YÓ 7�à Ñ(¨M¸QÓ,>Ü$Ð'JÈ=È/Ð%ZÓ[Ð[ð $1°1Ñ#4Ð Ø'Ð'ô %ØLó
ð 	
øôE ó Ùðûô. ó Ü,ðMóò ô ó Ü,ØFÀqÀcð J?ð ?óõ ûðús5   ›B/ ¿A$B? Â/
B<Â;B<Â?C8Ã	C8ÃC3Ã-C8Ã3C8)rP   rR   )N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r   rT   Úpropertyr!   r[   Ústrr^   rO   rQ   Ú__static_attributes__r(   r   r   rL   rL   £   s‚   † ññP¨¨t©õ Pð ð& #ó &ó ð&ð ð+ 3ó +ó ð+ð ð˜3ó ó ðð 3ô ð3
 S÷ 3
r   rL   Ú_ub_managerc                  ó0   • [         c
  [        5       q [         $ )zGet global UB manager instance.)r€   rL   r(   r   r   Úget_ub_managerr‚     s   € ô ÑÜ“kˆÜÐr   c                 ó@  ^• [        5       nUb  U(       a
  Ub  U(       d  g[        U5      [        U5      :w  a  gUb  US::  a  SnUb  US::  a  Sn[        UR                  U UUUU5      nU(       a  [        U5      [        U5      :w  a  g/ n[	        X4U5       Hù  u  p‰n
[        U5      m[        U	5      nU(       d  [        SU	 S35      e[        U4S jU 5       5      (       a  [        SU	 SU S	[        T5       S
35      eU H:  nTU   n[        R                  " U5      n[        Xê5      n[        SU5      nUTU'   M<     [        T5       H&  u  nnXË;  d  M  [        R                  " U5      TU'   M(     UR                  [        T5      5        Mû     [        U5      $ )a`	  
Compute tiling strategy using the default strategy function.

This function directly calls the default strategy and computes the final
tiling result. All kernels use the same unified strategy function, so
there's no need for kernel_name-based lookup.

Args:
    safety_margin: Safety margin as a float (e.g., 0.80 for 80%). Default is 0.80.
    dtype_size: Size of data type in bytes (e.g., 2 for float16, 4 for float32).
        Must be provided. If None or <= 0, defaults to 4 (float32).
    memory_multiplier: Memory multiplier for estimating peak memory usage.
        - For GEGLU: typically 10.0 for backward, 4.0 for forward
        - For ROPE: typically 3.0
        If None, defaults to 10.0 (conservative estimate).
    shapes: Tuple of full shapes. Each shape is a tuple of dimension sizes.
        - For ROPE: ((n_q_head, hd), (n_kv_head, hd))
        - For GEGLU: ((n_cols,),)
        Can pass original shapes (will handle padding internally) or padded shapes.
    tiling_dims: Tuple specifying which dimensions can be tiled for each shape.
        Each element can be:
        - int: single dimension index (e.g., 0 for first dimension)
        - tuple of ints: multiple dimensions that can be tiled together
        - For ROPE: (0, 0) means first dimension of each shape can be tiled
        - For GEGLU: (0,) means first dimension of the shape can be tiled
        Length must match len(shapes). Cannot be empty.

Returns:
    Tuple of tiled shapes with same structure as input shapes.
    Tiling dimensions are replaced with computed block sizes (power of 2),
    while non-tiling dimensions are padded to next power of 2.
    - For ROPE: ((block_size_q, pad_hd), (block_size_kv, pad_hd))
    - For GEGLU: ((block_size,),)
    Returns None if shapes or tiling_dims is None or empty.

Examples:
    >>> # ROPE forward
    >>> strategy = compute_default_tiling_strategy(
    ...     safety_margin=0.90,
    ...     dtype_size=4,
    ...     memory_multiplier=3.0,
    ...     shapes=((32, 128), (32, 128)),
    ...     tiling_dims=(0, 0)
    ... )
    >>> # Returns: ((block_size_q, 128), (block_size_kv, 128))
    >>> # GEGLU forward
    >>> strategy = compute_default_tiling_strategy(
    ...     safety_margin=0.80,
    ...     dtype_size=2,
    ...     memory_multiplier=7.0,
    ...     shapes=((4096,),),
    ...     tiling_dims=(0,)
    ... )
    >>> # Returns: ((block_size,),)
Nr   é   g      $@r)   r*   c              3   óV   >#   • U  H  oS :  =(       d    U[        T5      :¬  v •  M      g7fr,   r-   )r/   r0   Úresult_shapes     €r   r2   Ú2compute_default_tiling_strategy.<locals>.<genexpr>z  s%   øé € ÐYÊ.¸w˜‰{×:˜g¬¨\Ó):Ñ:Ô:Ê.ùr4   r5   r6   r7   r8   )r‚   r.   rJ   r!   r:   Úlistr    r;   r<   r@   rA   Úminr?   r=   rB   r   )r"   r#   r$   r%   r&   Ú
ub_managerÚmax_supportedÚresultr1   r   Úmax_saferD   r0   Úoriginal_dimÚdesiredÚ	final_valrF   r†   s                    @r   Úcompute_default_tiling_strategyr‘     sÄ  ø€ ô|  Ó!€Jà�~žV {Ñ':Æ+Øä
ˆ6ƒ{”c˜+Ó&Ó&ØàÑ˜Z¨1›_Øˆ
àÑ Ð$5¸Ó$:Ø Ðô &Ø×#Ñ#ØØØØØó€Mö œC Ó.´#°f³+Ó=Øð €FÜ'*¨6ÀÖ'NÑ#ˆ˜8Ü˜E“{ˆô 0°
Ó;ˆö ÜØ& z lÐ2kÐlóð ô ÔYÉ.ÓY×YÑYÜØ& z l°+¸e¸Wð E>Ü>AÀ,Ó>OÐ=PÐPRðTóð ó &ˆGØ'¨Ñ0ˆLÜ×,Ò,¨\Ó:ˆGÜ˜GÓ.ˆIÜ˜A˜yÓ)ˆIØ$-ˆL˜Ó!ñ &ô "+¨<Ö!8ÑˆG�XØÕ,Ü(.×(>Ò(>¸xÓ(H�˜WÓ%ñ "9ð 	�‰”e˜LÓ)Ö*ñ? (OôB �‹=Ðr   gÍÌÌÌÌÌì?r„   é   r8   )r"   r#   ÚfallbackÚ	min_blockÚ	max_blockr�   rF   r“   r”   r•   r�   c                óÎ   • Uc  [         R                  " U 5      n[        UUUU 44SS9nU(       a  [        XxS   S   5      O
[        Xt5      n	[	        XY5      n	Ub  [        X–5      n	U	$ )z:Compute UB-safe block size for a single tilable dimension.©r   ©r"   r#   r$   r%   r&   r   ©r@   rA   r‘   r‰   r?   )
rF   r$   r"   r#   r“   r”   r•   r�   Útile_shapesÚblocks
             r   Úcompute_ub_block_sizerœ   “  ss   € ð �Ü×(Ò(¨Ó2ˆä1Ø#ØØ+Ø�ˆ~Øñ€Kö 0;ŒC� Q™¨Ñ*Ô+ÄÀGÓ@V€EÜ�	Ó!€EØÑÜ�EÓ%ˆØ€Lr   i    )r"   r•   r“   Ú
vocab_sizeÚnum_rowsc                óº   • [        U UUUS9n[        S[        [        US5      -  5      n[        R                  " X-   S-
  U-  5      n[        [        Xh5      U5      $ )z:UB-safe vocab tile size respecting Ascend grid dim0 limit.©r"   r“   r8   )rœ   r?   ÚASCEND_MAX_GRID_DIMr@   rA   r‰   )	r�   rž   r$   r"   r•   r“   Úub_blockÚ
max_splitsÚgrid_mins	            r   Úcompute_vocab_block_sizer¥   °  sd   € ô %ØØØ#Øñ	€Hô �QÔ+¬s°8¸QÓ/?Ñ?Ó@€JÜ×%Ò% zÑ'>ÀÑ'BÀzÑ&QÓR€HÜŒs�8Ó&¨	Ó2Ð2r   i   )r"   r”   r“   Ú
n_elementsc                ó¤   • Uc  [         n[        U UUUS9n[        U[        R                  " U [
        -   S-
  [
        -  5      5      n[        XV5      $ )z<UB-safe block size for elementwise kernels under grid limit.r    r8   )Ú_FALLBACK_MAX_FUSED_BLOCKrœ   r?   r@   rA   r¡   r‰   )r¦   r$   r"   r”   r“   r¢   r¤   s          r   Úcompute_elementwise_block_sizer©   Å  s`   € ð ÑÜ,ˆÜ$ØØØ#Øñ	€Hô ØÜ×Ò 
Ô-@Ñ @À1Ñ DÔI\Ñ\Ó]ó€Hô ˆxÓ"Ð"r   )Úmax_gridÚmax_core_dimr"   r•   r$   Útotal_elementsÚis_backwardrª   r«   c          	      óú   • Uc  U(       a  SOSn[        U UUSSUS9n[        XsS-  5      n[        R                  " X5      U:”  a6  [        R                  " X5      n[	        [        R
                  " U5      S5      nU$ )z4UB-safe block size for flattened activation kernels.g      @g      @r’   é   )r"   r“   r”   r•   r   r8   )rœ   r‰   r@   Úcdivr?   rA   )r¬   r­   rª   r«   r"   r•   r$   r›   s           r   Úcompute_activation_block_sizer±   Ý  s|   € ð Ñ Þ#.™C°CÐÜ!ØØØ#ØØØñ€Eô � qÑ(Ó)€EÜ‡{‚{�>Ó)¨HÓ4Ü—’˜NÓ5ˆÜ”F×*Ò*¨5Ó1°1Ó5ˆØ€Lr   Tg333333ë?é   )Ú
tiling_rowr"   r#   r“   r”   r•   Úrow_dimÚ	fixed_dimr³   c                ó<  • U(       a  X44n	Sn
[         R                  " U 5      nOX44n	Sn
[         R                  " U5      n[        UUUU	U
S9nU(       a#  U(       a  US   S   OUS   S   n[        X½5      nO[        X¶5      n[	        X}5      nUb  [        XØ5      nU$ )z;UB-safe tile along one axis of a 2D [row, col] kernel tile.r—   )r8   r˜   r   r8   r™   )r´   rµ   r$   r³   r"   r#   r“   r”   r•   r%   r&   r�   rš   r›   s                 r   Úcompute_row_tile_block_sizer·   ù  s³   € ö ØÐ&Ð(ˆØˆÜ×(Ò(¨Ó1‰àÐ&Ð(ˆØˆÜ×(Ò(¨Ó3ˆä1Ø#ØØ+ØØñ€Kö Þ%/�˜A‘˜qÒ!°[À±^ÀAÑ5FˆÜ�GÓ#‰ä�GÓ&ˆÜ�	Ó!€EØÑÜ�EÓ%ˆØ€Lr   ©rª   Ú	axis_sizeÚother_grid_productc                ó4   • [        SU[        US5      -  5      $ )zLMax launch chunks along one grid axis while keeping the product <= max_grid.r8   )r?   )r¹   rº   rª   s      r   Úmax_grid_axis_chunksr¼   !  s   € ô ˆq�(œcÐ"4°aÓ8Ñ8Ó9Ð9r   )rª   r”   Úub_safe_blockc                ó,   • [        U[        X 5      5      $ )zCPick a UB-safe tile size; host-side chunking handles grid overflow.)r?   r‰   )r¹   rº   r½   rª   r”   s        r   Úcompute_grid_limited_tile_sizer¿   +  s   € ô ˆyœ#˜mÓ7Ó8Ð8r   c             #   ój   #   • [        XUS9n[        SX5       H  nU[        X0U-
  5      4v •  M     g7f)z=Yield ``(offset, chunk_len)`` for host-side grid-axis tiling.r¸   r   N)r¼   Úranger‰   )r¹   rº   rª   Ú
max_chunksÚoffsets        r   Úiter_axis_launch_chunksrÄ   7  s9   é € ô & iÈhÑW€JÜ˜˜9Ö1ˆØ”c˜*°&Ñ&8Ó9Ð9Ô9ò 2ùs   ‚13)gš™™™™™é?NNNN)g      @)r|   rl   r   r	   r@   r¡   r¨   r   Úboolr   r~   r   r   r   r   r    r>   rJ   rL   r€   Ú__annotations__r‚   r‘   rœ   r¥   r©   r±   r·   r¼   r¿   rÄ   r(   r   r   Ú<module>rÇ      sZ  ðòó 
Û ã Û ð Ð à&Ð à&Ð ð˜$ô ð& #ð &¨#ô &ð s¨U°3¸°8©_Ñ'<ð Àô ð$X!ØðX!àðX!ð ðX!ð ð	X!ð
 �%˜˜S˜‘/ 3Ð&Ñ'ðX!ð �s˜U 3¨ 8™_Ñ,¨cÐ1Ñ2ðX!ð ˆ3�ˆ8�_ôX!÷vb
ñ b
ðL !%€ˆY˜ÑÓ $ð˜	ô ð  Ø!Ø&*Ø15Ø<@ñ|Øð|à�d‘
ð|ð ˜t‘|ð|ð �%˜˜S˜‘/ 3Ð&Ñ'¨$Ñ.ð	|ð
 �s˜U 3¨ 8™_Ñ,¨cÐ1Ñ2°TÑ9ð|ð ˆ5��c�‰?˜CÐÑ  4Ñ'õ|ðF ØØØØ ØòØðàðð ð	ð
 ðð ðð ðð �T‰zðð �4‰Zðð 	õðD ØØò3Øð3àð3ð ð3ð
 ð3ð ð3ð ð3ð 	õ3ð.  #ð#ð ØØò#Øð#àð#ð ð	#ð
 ð#ð �D‰jð#ð 	ö#ð8 (ØØØØ&*òØðàðð ð	ð
 ðð ðð ðð ˜t‘|ðð 	õðB ØØØØØ ò%Øð%àð%ð ð%ð
 ð%ð ð%ð ð%ð ð%ð ð%ð �T‰zð%ð 	õ%ðX (ò	:Øð:àð:ð ð	:ð
 	õ:ð (Øò	9Øð	9àð	9ð ð	9ð
 ð	9ð ð	9ð 	õ	9ð  (ò		:Øð	:àð	:ð ö		:r   