§
     ’ÞjCˆ  ã                   ó.  — d Z ddlZddlmc mZ ddlmZmZm	Z	 ddl
mZmZmZmZmZ 	 ddlmZ n# eeef$ r dZY nw xY w	 ddlmZ n# eeef$ r dZY nw xY w	 ddlmZ n# eeef$ r dZY nw xY w	 dd	lmZ n# eef$ r dZY nw xY w	 dd
lmZ n># eeef$ r dZY n2e$ r+Z e e¦  «         !                    d¦  «        s‚ dZY dZ[ndZ[ww xY wej"        fddœd„Z#d„ Z$d„ Z%ddœd„Z&d„ Z'ddœd„Z(dIddddœd„Z)dddœd„Z*dJddœd„Z+d„ Z,dddœd „Z-d!„ Z.dd"œd#„Z/dKd$„Z0dddd%œd&„Z1dId'„Z2d(„ Z3d)Z4d*Z5d+Z6d,Z7d-Z8i Z9dLd.„Z:d/„ Z;dddddd0œd1„Z<d2„ Z=d3„ Z>d4„ Z?dd5œd6„Z@d7„ ZAd8„ ZBd9„ ZCdd:œd;„ZDd<„ ZEdMd=„ZFdd>œd?„ZGd@„ ZHdJddAœdB„ZIdC„ ZJdIdd:œdD„ZKdE„ ZLdF„ ZMdG„ ZNdJdH„ZOdS )Na¸  Activation operations shared by denoisers.

Owned inputs use x_list through the dispatch boundary. In-place operations borrow
their destination; residuals, weights and conditioning are always borrowed. Math
contracts are explicit: split-half RMS/RoPE rounds after normalization, matrix
RoPE keeps FP32 until its final cast, and complex RoPE rounds before rotation.
Whole-head normalization and compact rotary layouts remain model supplied.
é    Né   )Úint8_backendÚkernel_policyÚ
native_ops)ÚchooseÚcuda_inferenceÚdevice_supportedÚ
packed_fmaÚtake)Údenoiser_triton)Údenoiser_bits_triton)Úqk_quant_triton)Úadaln_triton)Úrms_rope_split_half_zinfer_schema(func):©ÚdtypesÚactc                ó2   — t          j        | |||¬¦  «        S )zyWhether layer(x) can run through the INT8 backend's fused kernel, with the input operation act ('gelu' needs WGPKernels).r   )r   Úcan_fuse_linear)ÚlayerÚxr   r   s       ú:C:\Users\johnn\OneDrive\Documents\AI\shared\kernels\ops.pyÚ
can_linearr   ,   s   € åÔ'¨¨q¸ÀSÐIÑIÔIÐIó    c                 óv   — |s | t          |¦  «        ¦  «        S t          j        | t          |¦  «        fi |¤ŽS )z<Use the shared qtype implementation and normal module hooks.)r   r   Úlinear_with_fusion)r   Úx_listÚfusions      r   Úlinearr   1   sA   € àð #Øˆu•T˜&‘\”\Ñ"Ô"Ð"ÝÔ*¨5µ$°v±,´,ÐIÐIÀ&ÐIÐIÐIr   c                 ó�  ‡— t          |¦  «        Št          j                             ¦   «         s~‰                     ¦   «         rjt          ˆfd„| D ¦   «         ¦  «        rOt          j        | ‰                     d‰j	        d         ¦  «        ¦  «        }t          ˆfd„|D ¦   «         ¦  «        S t          ˆfd„| D ¦   «         ¦  «        S )Nc              3   ó8   •K  — | ]}t          |‰¦  «        V — Œd S ©N)r   ©Ú.0Úmoduler   s     €r   ú	<genexpr>zproject_many.<locals>.<genexpr>;   s-   øè è € Ð@Ð@¨f•J˜v qÑ)Ô)Ð@Ð@Ð@Ð@Ð@Ð@r   éÿÿÿÿc              3   óf   •K  — | ]+} |j         g ‰j        d d…         ¢|j        d         ‘R Ž V — Œ,d S )Nr'   )ÚreshapeÚshape)r$   Úoutr   s     €r   r&   zproject_many.<locals>.<genexpr>=   sJ   øè è € ÐRÐRÀ3�[�S”[Ð> !¤'¨#¨2¨#¤,Ð>°´	¸"´Ð>Ð>Ð>ÐRÐRÐRÐRÐRÐRr   c              3   ó.   •K  — | ]} |‰¦  «        V — Œd S r"   © r#   s     €r   r&   zproject_many.<locals>.<genexpr>>   s+   øè è € Ð1Ð1˜v��˜‘”Ð1Ð1Ð1Ð1Ð1Ð1r   )r   ÚtorchÚcompilerÚis_compilingÚis_contiguousÚallr   Úlinear_multir)   r*   Útuple)Úmodulesr   Úoutputsr   s      @r   Úproject_manyr7   8   sÉ   ø€ ÝˆV‰Œ€AÝŒN×'Ò'Ñ)Ô)ð S¨a¯oªoÑ.?Ô.?ð SÝÐ@Ð@Ð@Ð@¸Ð@Ñ@Ô@Ñ@Ô@ðSåÔ+¨G°Q·Y²Y¸rÀ1Ä7È2Ä;Ñ5OÔ5OÑPÔPˆÝÐRÐRÐRÐRÈ'ÐRÑRÔRÑRÔRÐRÝÐ1Ð1Ð1Ð1¨Ð1Ñ1Ô1Ñ1Ô1Ð1r   F©Úapproximatec                ó¢   — t           duoF| j        t          j        k    o1t	          | d|¬¦  «        ot          | j        t          j        ¦  «         S )zuA BF16 activation on a CUDA GPU that runs FP16 kernels but is below the BF16 floor (Turing): the bits variants apply.N)é   é   )Úcapability_floorr9   )Ú_bits_tritonÚdtyper.   Úbfloat16r   r	   Údevice)r   r9   s     r   Ú_bf16_bits_eligiblerB   A   sP   € å Ð$ð ?¨¬µE´NÒ)Bð ?Ý˜q°6À{ÐSÑSÔSð?å$ Q¤X­u¬~Ñ>Ô>Ð>ð@r   c                 óÎ   ‡— | r| d         d         | d         d         z
  ndŠ‰dk    o=‰t          | ¦  «        z  |k    o't          ˆfd„t          | ¦  «        D ¦   «         ¦  «        S )z~Segments (start, stop, row) that tile the rows in equal spans with rows 0, 1, 2...: one modulation row per batch row or frame.r   r   c              3   óV   •K  — | ]#\  }\  }}}||‰z  k    o||‰z   k    o||k    V — Œ$d S r"   r-   )r$   ÚindexÚstartÚstopÚrowÚspans        €r   r&   z(_consecutive_segments.<locals>.<genexpr>L   sk   øè è € ð  Jð  JÑXqÐX]Ñ_qÐ`eÐgkÐmp�E˜U T™\Ò)ÐS¨d°e¸d±lÒ.BÐSÀsÈeÂ|ð  Jð  Jð  Jð  Jð  Jð  Jr   )Úlenr2   Ú	enumerate)ÚsegmentsÚtotalrI   s     @r   Ú_consecutive_segmentsrN   H   s£   ø€ à.6Ð=ˆ8�AŒ;�qŒ>˜H QœK¨œNÑ*Ð*¸A€DØ�1ŠHð J˜¥ H¡¤Ñ-°Ò6ð JÝð  Jð  Jð  Jð  JÕu~ð  @Hñ  vIô  vIð  Jñ  Jô  Jñ  Jô  JðKr   )r?   c                ó6  — t          | ¦  «        }|j        }|�€X|�€Ut          t          |¦  «        dd¦  «        t          j        j        j        u �r t          j	        ¦   «         �rt          ||j        d         ¦  «        rñt          |¦  «        |d         d         |d         d         z
  }	}|                     ||	|j        d         ¦  «        gd}} t          | |d|…                              | d         j        ¦  «                             d¦  «        |d|…                              | d         j        ¦  «                             d¦  «        |j        ¦  «                             ||	z  d¦  «        S |                     ¦   «         o4|du s |j        |j        k    o |j        |j        k    o|j        d         dk    }
t*          duo)t-          |t/          |j        j        ¦  «        ¬¦  «        o|
}| oC|du o?|
o=t3          |¦  «        o.|j        t          j        t          j        fv o|j        |j        k    }t9          d|p|¬	¦  «        r3|rt;          j        |||||¦  «        nt+          j        ||||||¦  «        S  ||¦  «        }|�|                     |¦  «        }|                     |j        ¦  «        |                     |j        ¦  «        }}|D ]E\  }}}|||…                              d
||         z   ¦  «                              ||         ¦  «         ŒF|S )af  norm(x), cast to dtype when given (an FP32 modulation after a 16-bit norm), then per segment (start, stop, row) of rows
    x * (1 + scale[row]) + shift[row] with PyTorch's roundings in the modulated dtype. norm may be weightless. The Triton kernel is
    bit-identical to the eager path except on the packed-FMA architecture, where it counts as approximate.NÚforwardr   r   r'   é    r8   zSegmented Norm Modulation©Úowned_tritong      ð?)!r   ÚweightÚgetattrÚtyper.   ÚnnÚ	LayerNormrP   r   Úallow_approximaterN   r*   rJ   ÚviewÚ_layer_norm_modulateÚtor?   Ú	unsqueezeÚepsr1   rA   Ú_tritonr   r
   rE   rB   Úfloat32r@   r   r>   Únorm_modulateÚmul_Úadd_)r   ÚnormÚshiftÚscalerL   r?   r   rT   ÚspansÚrowsÚlayoutÚfusedÚbitsrF   rG   rH   s                   r   ra   ra   O   sŠ  € õ 	ˆV‰Œ€AØŒ[€FØ‰˜&™.­WµT¸$±Z´ZÀÈDÑ-QÔ-QÕUZÔU]ÔUgÔUoÐ-oÑ-oõ  uBô  uTñ  uVô  uVÑ-oÝ% h°´¸´
Ñ;Ô;ð .põ
 ˜(‘m”m X¨a¤[°¤^°h¸q´kÀ!´nÑ%DˆtˆØ—V’V˜E 4¨¬°¬Ñ5Ô5Ð6¸�ˆÝ# F¨E°&°5°&¬M×,<Ò,<¸VÀA¼Y¼_Ñ,MÔ,M×,WÒ,WÐXYÑ,ZÔ,ZÐ\aÐbhÐchÐbhÔ\i×\lÒ\lÐmsÐtuÔmvÔm|Ñ\}Ô\}÷  ]Hò  ]Hð  IJñ  ]Kô  ]Kð  MQô  MUñ  Vô  V÷  [ò  [ð  \að  dhñ  \hð  jlñ  mô  mð  	mØ�_Š_ÑÔð  E F¨d NÐ$k°f´mÀqÄxÒ6OÐ6kÐTZÔT`ÐdeÔdkÒTkð  EÐqrÔqxÐy{Ôq|ð  AEò  rE€FÝ˜4ÐÐh¥N°1Å*ÈQÌXÌ^ÑB\ÔB\Ð$]Ñ$]Ô$]ÐhÐbh€EØˆIð ^˜% 4˜-ð ^¨Fð ^Õ7JÈ1Ñ7MÔ7Mð ^Ø”¥¤­u¬~Ð>Ð>ð^ØCHÄ;ÐRWÔR]ÒC]ð 	åÐ)¸¸ÀÐFÑFÔFð VØNRð  V�|Ô)¨!¨T°5¸%ÀÑJÔJÐJÕX_ÔXmÐnoÐquÐw|ð  Dð  FNð  PUñ  YVô  YVð  	VØˆˆQ‰Œ€AØÐØ�DŠD�‰KŒKˆØ—8’8˜AœGÑ$Ô$ e§h¢h¨q¬wÑ&7Ô&7ˆ5€EØ$ð >ð >Ñˆˆt�SØ	ˆ%�ˆ*Œ×Ò˜3  s¤Ñ+Ñ,Ô,×1Ò1°%¸´*Ñ=Ô=Ð=Ð=Ø€Hr   T)Úin_placeÚframesÚ	fused_addc                óö  ‡— t          | ¦  «        Š|p1‰j        dk    o&|j        dk    o|j        d         d‰j        d         fv }|�o®| �oª‰j        dk    �ož|j        dk    �o’|du�o�|j        |j        k    �o|‰                     ¦   «         �ogt	          ˆfd„||fD ¦   «         ¦  «        �oI|                     ¦   «         |                     ¦   «         k    �o|                     d¦  «        dk    �o|                     ¦   «         p9|                     d¦  «        |j        d         |                     d¦  «        z  k    o¶|j        d         ‰j        d         k    oš|j        d         ‰j        d         k    o~|j        d         dk    om‰j        d         |j        d         z  dk    oN|j        d         ‰j        d         k    r|                     ¦   «         p|j        d         |j        d         z  dk    }|ot          duot          ‰d	¬
¦  «        }|o| ot          ‰d	¬
¦  «        }	t          |rdnd|p|	¬¦  «        r&|	rt          nt                               ‰|||¦  «        S ‰j        }
|rƒ|j        d         ‰j        d         k    rg‰                     ‰j        d         |j        d         d‰j        d         ¦  «        Š|                     d¦  «        }|€dn|                     d¦  «        }|r2t          j        |d|z   ‰|r‰nd¬¦  «                             |
¦  «        S |r‰                     d|z   ¦  «        n‰d|z   z  Š|�|r‰                     |¦  «        n‰|z   Š‰                     |
¦  «        S )zCNative dtype arithmetic; optionally broadcast modulation per frame.é   r   Nc              3   óX   •K  — | ]$}|j         ‰j         k    o|j        ‰j        k    V — Œ%d S r"   ©r?   rA   ©r$   Útr   s     €r   r&   zscale_shift.<locals>.<genexpr>q   s;   øè è € Ð+pÐ+pÐ\]¨A¬G°q´wÒ,>Ð,WÀ1Ä8ÈqÌxÒCWÐ+pÐ+pÐ+pÐ+pÐ+pÐ+pr   é   r   r'   iÿÿ  Tr8   zFrame Scale/ShiftzScale/ShiftrR   )r+   )r   Úndimr*   r1   r2   Ústrider_   r   rB   r   r>   Úscale_shiftr)   r]   r.   Úaddcmulrb   rc   )r   rf   re   rl   rm   rn   Ú	broadcastri   rj   rk   r*   r   s              @r   rx   rx   l   s¹  ø€ åˆV‰Œ€AØÐa˜1œ6 Qš;Ð`¨5¬:¸ª?Ð`¸u¼{È1¼~ÐRSÐUVÔU\Ð]^ÔU_ÐQ`Ð?`€IØñ w 	˜Mñ w¨a¬f¸ªkñ w¸e¼jÈAºoñ wÐRWÐ_cÐRcñ wÐhmÔhsÐw|ô  xCò  iCñ wØ—/’/Ñ#Ô#ñwÝ(+Ð+pÐ+pÐ+pÐ+pÐbgÐinÐaoÐ+pÑ+pÔ+pÑ(pÔ(pñwà—,’,‘.”. E§L¢L¡N¤NÒ2ñwà7<·|²|ÀA±´È!Ò7Kñwð ×&Ò&Ñ(Ô(Ð_¨E¯LªL¸©O¬O¸u¼{È1¼~ÐPU×P\ÒP\Ð]^ÑP_ÔP_Ñ?_Ò,_ðwð ”+˜a”. A¤G¨A¤JÒ.ð	wð 49´;¸r´?ÀaÄgÈbÄkÒ3Qð	wð
 ”+˜a”. 1Ò$ðwð
 *+¬°¬°e´kÀ!´nÑ)DÈÒ)Iðwð ”;˜q”> Q¤W¨Q¤ZÒ/ÐI°E×4GÒ4GÑ4IÔ4IÐuÈUÌ[ÐYZÌ^Ð^cÔ^iÐjkÔ^lÑMlÐpuÒMuð ð ÐR•w dÐ*ÐR­~¸aÈTÐ/RÑ/RÔ/R€EØÐL˜%�iÐLÕ$7¸ÀtÐ$LÑ$LÔ$L€DÝ VÐ>Ð!Ð!°ÈUÈ]ÐVZÐ[Ñ[Ô[ð ZØ $Ð1•�­'×>Ò>¸qÀ%ÈÐPXÑYÔYÐYØŒG€EØð >�%”+˜a”. A¤G¨A¤JÒ.Ð.Ø�IŠI�a”g˜a”j %¤+¨a¤.°"°a´g¸b´kÑBÔBˆØ—’ Ñ"Ô"ˆØ˜��¨5¯?ª?¸1Ñ+=Ô+=ˆØð ^ÝŒ}˜U A¨¡I¨q¸8Ð6M°a°aÈÐNÑNÔN×VÒVÐW\Ñ]Ô]Ð]Ø%Ð:ˆ�Šˆq�5‰yÑÔÐ¨1°°E±	©?€AØÐØ%Ð4ˆA�FŠF�5‰MŒMˆM¨1¨u©9ˆØ�9Š9�UÑÔÐr   ©rl   rn   c                ód   —  |t          | ¦  «        ¦  «        }|gd}} t          | ||||¬¦  «        S )zçKeep the supplied norm's reduction/affine contract, then modulate.

    Unlike fused AdaLN this retains the native norm reduction and its rounding.
    Residual inputs may be borrowed by passing [residual]; the norm allocates.
    Nr{   )r   rx   )r   rd   rf   re   rl   rn   r   s          r   Únorm_scale_shiftr}   ˆ   s=   € ð 	ˆ�T�&‰\Œ\ÑÔ€AØ��TˆA€FÝ�v˜u e°hÈ)ÐTÑTÔTÐTr   ç�íµ ÷Æ°>)rm   c                óÖ  — t          | ¦  «        }|j        }|r¨|j        dk    r�|j        dk    r’|j        d         d|j        d         fvrv|j        d         }|                     |d         |z  |d         |z  |d         ¦  «        }|                     dd|d         ¦  «        |                     dd|d         ¦  «        }}|gd}} t          | |||¦  «                             |¦  «        S )a  layer_norm(x) * (1 + scale) + shift over the last dimension; scale and shift broadcast over x, or, with frames, hold one row per
    group of tokens (batch, groups, dim) for x (batch, tokens, dim) with groups dividing the tokens (a modulation per latent frame).rp   r   r   ru   r'   N)r   r*   rv   rZ   r)   r[   )r   re   rf   r^   rm   r   r*   Úgroupss           r   Úlayer_norm_modulater�   “   sæ   € õ 	ˆV‰Œ€AØŒG€EØð V�%”* ’/�/ a¤f°¢k k°e´kÀ!´nÈQÐPQÔPWÐXYÔPZÈOÐ6[Ð6[Ø”˜Q”ˆØ�FŠF�5˜”8˜fÑ$ e¨A¤h°&Ñ&8¸%À¼(ÑCÔCˆØ—}’} R¨¨E°!¬HÑ5Ô5°u·}²}ÀRÈÈEÐRSÌHÑ7UÔ7UˆuˆØ��TˆA€FÝ ¨¨u°cÑ:Ô:×?Ò?ÀÑFÔFÐFr   c                 óÂ  ‡— t          | ¦  «        Št          ‰t          j        t          j        fd¬¦  «        ob‰j        dv oY‰                     ¦   «         oE‰                     ¦   «         dk    o-‰j        d         dk    ot          ˆfd„||fD ¦   «         ¦  «        }t          d|ot          j        ‰j        ¦  «        |ot          d u¬	¦  «        }|d
k    r"t          j                             ‰|||¦  «        S |dk    rt          j        ‰|||¦  «        S t#          j        ‰‰j        d         f|¬¦  «        Š‰g|j        ‰j        k    d c} }Št)          | |||¬¦  «        S )NT)r   r9   )ru   rp   r   r'   rQ   c           
   3   óv  •K  — | ]³}|j         d k    o£|j         ‰j         k    o“|j        ‰j        k    oƒ|j        ‰j        k    os|j        d         ‰j        d         k    oW|                     d¦  «        dk    o>t          d„ t          |j        ‰j        |j          d…         ¦  «        D ¦   «         ¦  «        V — Œ´dS )r   r'   r   c              3   ó4   K  — | ]\  }}|d k    p||k    V — ŒdS ©r   Nr-   )r$   ÚaÚbs      r   r&   z1_layer_norm_modulate.<locals>.<genexpr>.<genexpr>¦   s3   è è € ÐZÐZ±$°!°Q˜Q !šVÐ- q¨A¢vÐZÐZÐZÐZÐZÐZr   N)rv   r?   rA   r*   rw   r2   Úziprs   s     €r   r&   z'_layer_norm_modulate.<locals>.<genexpr>¤   së   øè è € ð tð tà_`ð ”V˜a’Zð [ A¤F¨a¬fÒ$4ð [¸¼ÀAÄGÒ9Kð [ÐPQÔPXÐ\]Ô\dÒPdð [Øœ œ¨¬°¬Ò3ð[Ø89¿ºÀ¹¼ÈÒ8Ið[åÐZÐZ½#¸a¼gÀqÄwÐPQÔPVÈwÈxÈxÔGXÑ:YÔ:YÐZÑZÔZÑZÔZðtð tð tð tð tð tr   ÚAdaLN)Ú
wgpkernelsÚtritonrŠ   r‹   ©r^   )rl   )r   r   r.   r@   Úfloat16rv   r1   Únumelr*   r2   r   r   Ú	availablerA   Ú_adaln_tritonÚimplementationÚadalnÚFÚ
layer_normr?   rx   )r   re   rf   r^   ÚvalidÚfamilyrl   r   s          @r   r[   r[       s›  ø€ ÝˆV‰Œ€AÝ˜A¥u¤~µu´}Ð&EÐSWÐXÑXÔXð tØ”˜6Ð!ðtØ&'§o¢oÑ&7Ô&7ðtØ<=¿GºG¹I¼IÈºMðtØNOÌgÐVXÌkÐ]aÒNaðtåð tð tð tð tàejÐlqÐdrðtñ tô tñ tô tð 
õ
 �G¨Ð(Pµ*Ô2FÀqÄxÑ2PÔ2PØ Ð>¥]¸$Ð%>ð@ñ @ô @€Fà�ÒÐÝÔ(×.Ò.¨q°%¸ÀÑDÔDÐDØ�ÒÐÝÔ" 1 e¨U°CÑ8Ô8Ð8Ý	Œ�Q˜œ œ˜¨CÐ0Ñ0Ô0€Aà˜#˜uœ{¨a¬gÒ5°tÐ€FˆH�aÝ�v˜u e°hÐ?Ñ?Ô?Ð?r   )Úpackedrl   c                óØ   — |r't          | ¦  «                             dd¦  «        \  }}n| \  }}|                      ¦   «          t          j        ||¬¦  «                             |¦  «        S )zéNative SiLU rounding, followed by native multiplication, without concat.

    Packed input is gate|value. Separate projections pass [gate, value]; both
    are consumed. No approximate kernel is promoted to a new model contract.
    ru   r'   )Úinplace)r   ÚchunkÚclearr“   Úsilurb   )r   r—   rl   ÚgateÚvalues        r   ÚswiglurŸ   ³   sf   € ð ð Ý˜6‘l”l×(Ò(¨¨BÑ/Ô/‰ˆˆeˆeà‰ˆˆeØ�Š‰ŒˆÝŒ6�$ Ð)Ñ)Ô)×.Ò.¨uÑ5Ô5Ð5r   c                 ó°   — t          | ¦  «        } | ||¦  «        ¦  «        }|                      ||¦  «        ¦  «         ~|gd}}t          ||¦  «        S )zéSeparate projections with native activation rounding and module hooks.

    Evaluate activation before up_proj so its source and result do not coexist
    with the up projection. All three projections keep their MMGP/LoRA hooks.
    N)r   rb   r   )r   Ú	gate_projÚup_projÚ	down_projÚ
activationr   r�   Ú	gate_lists           r   Ú	gated_mlpr¦   Á   s^   € õ 	ˆV‰Œ€AØˆ:�i�i ‘l”lÑ#Ô#€DØ‡I‚Iˆgˆg�a‰jŒjÑÔÐØ	Ø�f˜dˆt€IÝ�)˜YÑ'Ô'Ð'r   ©r—   c                ó  — |r't          | ¦  «                             dd¦  «        \  }}n| \  }}|                      ¦   «          dt          j        |dz  ¦  «        z  t          j        |¦  «        z  dt          j        |dz  ¦  «        z  z  S )z‘Bounded SiLU gate and saturated value, preserving native rounding.

    Packed input is value|gate; separate projections pass [gate, value].
    ru   r'   g      @g      9@)r   rš   r›   r.   ÚtanhÚsigmoid)r   r—   rž   r�   s       r   Úsitur«   Ï   s†   € ð
 ð Ý˜6‘l”l×(Ò(¨¨BÑ/Ô/‰ˆˆtˆtà‰ˆˆeØ�Š‰ŒˆØ•%”*˜T C™ZÑ(Ô(Ñ(­5¬=¸Ñ+>Ô+>Ñ>À4Í%Ì*ÐUZÐ]aÑUaÑJbÔJbÑCbÑcÐcr   c                 óà   — t          | |d         ¦  «        rt          | |d|||¬¦  «        S  | t          |¦  «        ¦  «        }|�(|                     |¦  «                             |¦  «         |S )Nr   rŸ   ©Ú	input_actÚresidualÚresidual_scaler+   )r   r   rŸ   rb   rc   )r   r   r¯   r°   Úoutputs        r   Úswiglu_linearr²   Ü   s�   € Ý�%˜ œÑ#Ô#ð CÝ�e˜V¨xÀ(Ø%3¸ðCñ Cô Cð 	CàˆU•6˜&‘>”>Ñ"Ô"€FØÐØ�Š�NÑ#Ô#×(Ò(¨Ñ2Ô2Ð2Ø€Mr   )r©   rj   rL   c                óÖ  — t          |¦  «        }|r|                     ¦   «         n|}|�|                      d| j        d         ¦  «        |                     d|j        d         ¦  «        }}|D ]8\  }	}
}|
|	k    r,||	|
…                              ||	|
…         ||         ¦  «         Œ9| S |r|                      ||¦  «        S |                     |¦  «         |                      |¦  «        S )a=  residual += gate * x in place, x handed off in x_list; gate broadcastable to x, or with segments [(start, stop, row)] over the
    rows of (batch * tokens) a table of gate rows (rows, dim) applied span by span, without a per-token gate tensor. tanh applies to
    the gate first; fused adds in one rounding (addcmul).Nr'   )r   r©   rZ   r*   Úaddcmul_rb   rc   )r¯   r   r�   r©   rj   rL   r   rh   ÚsourcerF   rG   rH   s               r   Úgated_residual_r¶   æ   sð   € õ 	ˆV‰Œ€AØÐ(ˆ4�9Š9‰;Œ;ˆ; D€DØÐØ—}’} R¨¬¸Ô);Ñ<Ô<¸a¿fºfÀRÈÌÐQSÌÑ>UÔ>UˆfˆØ (ð 	Ið 	IÑˆE�4˜Ø�eŠ|ˆ|Ø�U˜4�ZÔ ×)Ò)¨&°°t°Ô*<¸dÀ3¼iÑHÔHÐHøØˆØð *Ø× Ò   DÑ)Ô)Ð)Ø‡F‚Fˆ4�L„L€LØ�=Š=˜ÑÔÐr   c                 ó¤  — t          |¦  «        }t          | |¦  «        r®|j        |j        k    rž|                     ¦   «         rŠt	          |t
          t          f¦  «        r(t          j        | j	        f||j        |j
        ¬¦  «        n0|€dn,|                     d¦  «                             |j        ¦  «        }t          | |g|||¬¦  «        S  | |¦  «        }~|€|                     |¦  «        S t	          |t
          t          f¦  «        r|                     ||¬¦  «        n-|                     ||                     |j        ¦  «        ¦  «        S )zðresidual += scale * layer(x) (scale: None for 1, a number, or one value per output channel), written into residual: the INT8
    backend's residual epilogue (one rounding) where the layer supports it, else the layer's output added in place.rr   Nr'   ©r¯   r°   r+   )Úalpha)r   r   r?   r1   Ú
isinstanceÚintÚfloatr.   ÚfullÚout_featuresrA   r)   r\   r   rc   r´   )r   r   r¯   rf   r   ÚvectorÚys          r   Úlinear_residual_rÁ   ø   sB  € õ 	ˆV‰Œ€AÝ�%˜ÑÔð Z ¤°!´'Ò 9Ð 9¸h×>TÒ>TÑ>VÔ>VÐ 9Ý^hÐinÕqtÕv{Ðp|Ñ^}Ô^}ð K•%”*˜eÔ0Ð2°EÀÄÐQRÔQYÐZÑZÔZÐZØ˜-�$�$¨U¯]ª]¸2Ñ->Ô->×-AÒ-AÀ!Ä'Ñ-JÔ-Jð 	å�e˜a˜S¨8ÀFÐPXÐYÑYÔYÐYØˆˆa‰Œ€AØ	Ø€}Ø�}Š}˜QÑÔÐÝ,6°u½sÅE¸lÑ,KÔ,KÐxˆ8�=Š=˜ %ˆ=Ñ(Ô(Ð(ÐQY×QbÒQbÐcdÐfk×fnÒfnÐopÔovÑfwÔfwÑQxÔQxÐxr   c           	      óö  — t          |¦  «        }t          | |¦  «        o#|j        |j        k    o|                     ¦   «         }|D ]²\  }}}	||k    r¦|||…         }
|rUt	          | |||…         g|
||	                              |j        ¦  «        |
¬¦  «        }||
ur|
                     |¦  «         Œm|
                      | |||…         ¦  «        ||	                              |j        ¦  «        ¦  «         Œ³|S )züresidual[start:stop] += gate[row] * layer(x[start:stop]) for each segment (start, stop, row), written into residual: the INT8
    backend's residual epilogue (one rounding) where the layer supports it, else the layer's output scaled and added in place.r¸   )r   r   r?   r1   r   r\   Úcopy_r´   )r   r   r¯   r�   rL   r   rj   rF   rG   rH   Útargetr+   s               r   Úgated_linearrÅ     s  € õ 	ˆV‰Œ€AÝ�u˜aÑ Ô Ð[ X¤^°q´wÒ%>Ð[À8×CYÒCYÑC[ÔC[€EØ$ð Tð TÑˆˆt�SØ�%Š<ˆ<Ø˜e D˜jÔ)ˆFØð TÝ˜U Q u¨T z¤] O¸fÐUYÐZ]ÔU^×UaÒUaÐbcÔbiÑUjÔUjÐpvÐwÑwÔw�Ø˜fÐ$Ð$Ø—L’L Ñ%Ô%Ð%øà—’   a¨¨d¨
¤mÑ 4Ô 4°d¸3´i·l²lÀ8Ä>Ñ6RÔ6RÑSÔSÐSøØ€Or   i   é   é   é   g      è?c                 óÆ  — |j         €t          j                             ¦   «         n|j         }|t          vr,t          j                             |¦  «        j        t          |<   t          t          |         t          z  ¦  «        |z  }|rt          ||  t          z   ¦  «        }t          t          |t          z  t          z  |  t          z   ¦  «        }t          | |¦  «        S )a_  Rows per chunk of mlp(): the chunk's working set (expanded_row_bytes per row: the fc1 output, plus the up projection or the
    concatenated fc2 input of a prefix MLP) within MLP_L2_FRACTION of the device's L2 cache, and, for those double working sets,
    within a MLP_MIN_CHUNKS-th of the tokens; never fewer than MLP_MIN_ROWS nor more than MLP_MAX_CHUNKS chunks per call; the whole
    input when it is that short. A larger floor (2048 rows) used to override the budget for wide FFNs and raised their transient above
    the former per-model loops (Flux single blocks: 113 MB against 43 MB at 1024x1024).)rE   r.   ÚcudaÚcurrent_deviceÚ_l2_cache_bytesÚget_device_propertiesÚL2_cache_sizer»   ÚMLP_L2_FRACTIONÚminÚMLP_MIN_CHUNKSÚmaxÚMLP_MIN_ROWSÚMLP_ROW_MULTIPLEÚMLP_MAX_CHUNKS)ÚtokensÚexpanded_row_bytesrA   ÚdoublerE   Úbudgetrh   s          r   Úmlp_chunk_rowsrÚ      sÃ   € ð ,2¬<Ð+?�EŒJ×%Ò%Ñ'Ô'Ð'ÀVÄ\€EØ•OÐ#Ð#Ý!&¤×!AÒ!AÀ%Ñ!HÔ!HÔ!V�˜ÑÝ• Ô'­/Ñ9Ñ:Ô:Ð>PÑP€FØð ;Ý�V ˜w­.Ñ8Ð9Ñ:Ô:ˆÝ�|˜VÕ'7Ñ7Õ:JÑJÈvÈgÕYgÑNgÐLhÑiÔi€DÝˆv�tÑÔÐr   c                 óÜ   ‡ ‡‡‡— ‰                       ‰ j        d         d‰ j        d         ¦  «        Š ‰ j        d         ‰‰ j        d         z  cŠŠˆ ˆˆˆfd„t          |¦  «        D ¦   «         S )zÞmlp() segments for a gate of shape (batch or 1, groups, dim) over an input (batch, tokens, dim): groups is 1, or a number of
    frames that divides the tokens. A gate per token does not fit segments: apply it after mlp().r   r'   r   c                 óž   •— g | ]I}t          ‰¦  «        D ]7}|‰z  |‰z  z   |‰z  |d z   ‰z  z   ‰‰j        d         d k    r|nd|f         f‘Œ8ŒJS )r   r   )Úranger*   )r$   r‡   Úgr�   r€   rI   rÖ   s      €€€€r   ú
<listcomp>z!gate_segments.<locals>.<listcomp>5  s¨   ø€ ð  Wð  Wð  WÐmnõ  INð  OUñ  IVô  IVð  Wð  Wð  DEˆQ�‰Z˜!˜d™(Ñ" A¨¡J°!°a±%¸4±Ñ$?ÀÈ4Ì:ÐVWÌ=Ð[\ÒK\ÐK\ÀaÀaÐbcÐefÐFfÔAgÐhð  Wð  Wð  Wð  Wr   )r)   r*   rÝ   )r�   ÚbatchrÖ   r€   rI   s   ` `@@r   Úgate_segmentsrá   0  s“   øøøø€ ð �<Š<˜œ
 1œ r¨4¬:°b¬>Ñ:Ô:€DØ”:˜a”= &¨D¬J°q¬MÑ"9€L€FˆDð Wð  Wð  Wð  Wð  Wð  Wð  WÕrwÐx}Ñr~Ôr~ð  Wñ  Wô  Wð  Wr   )ÚupÚprefixr¯   r�   rL   c          
      ó¼  — t          | ¦  «        }	|	j        |	                     d|	j        d         ¦  «        }	}
|€|	n |                     d|	j        d         ¦  «        }|€dn |                     d|j        d         ¦  «        }|j        |€dn|j        z   |€dn|j        d         |j        z   z   }t	          |	j        d         ||	                     ¦   «         z  |	j        |dup|du¬¦  «        }|€|€|dv r|nd}|€d|	j        d         |fgn|D �]9\  }}}|€dn,|                     d¦  «                             |j	        ¦  «        }t          |||¦  «        D �]î}t          ||z   |¦  «        } ||	||…         ¦  «        }|rt          |||¬¦  «        r|nd}|€Ö|dk    r&|�$t          | ||	||…         ¦  «        gd¬	¦  «        n©|dk    rt          |g¦  «        n“|�$t          | ||	||…         ¦  «        gd¬	¦  «        nm|d
k    rt          |g¦  «        nW|dk    r$t          j        j                             |¦  «        n-t          j        j                             ||dk    rdnd¬¦  «        }|� t          j        |||…         |fd¬¦  «        }|||…         }|j	        |j	        k    r0|€|�,t          ||¦  «        rt+          ||g||€dn|||¬¦  «         �Œ…|�t+          ||g|¬¦  «        n
 ||¦  «        }~|€|                     |¦  «         �Œ¿|€|                     |¦  «         �ŒØ|                     ||¦  «         �Œð�Œ;|                     |
¦  «        S )al  fc2(act(fc1(x))) by chunks of tokens (mlp_chunk_rows): each chunk's output replaces its input rows, or is added to residual
    scaled by gate and written into residual. x, handed off in x_list, and residual have shape (..., dim) and are contiguous.
    act: 'gelu' (tanh approximation), 'gelu_erf', 'silu', 'situ' (fc1 rows value | gate), or 'swiglu' (fc1 rows gate | value).
    With up, fc1 is the gate and up is the value projection for situ/swiglu. prefix: rows
    (..., p) borrowed and concatenated before the activated fc1 output as fc2's input (fc2 reads p + the activation's width: the
    single-stream blocks of Flux, whose second linear takes the attention output and the MLP together). gate is one vector per channel
    for all tokens, or segments [(start, stop, vector)] over the flattened tokens (frames, spans, batch rows: gate_segments). Where
    the INT8 backend supports it, the activation is fused into fc2's kernel (gelu, packed swiglu, without prefix) and the gated residual
    into its epilogue, rounded once; otherwise the activation runs in place and the residual update follows. Returns x, or residual.r'   Nr   )rØ   )ÚgelurŸ   )r   r«   Fr§   rŸ   rœ   rå   r©   Únoner8   ©Údimr­   )r®   )r   r*   rZ   r¾   rÚ   Úelement_sizerA   r)   r\   r?   rÝ   rÐ   r   r«   rŸ   r.   ÚopsÚatenÚsilu_Úgelu_Úcatr   rÃ   rc   r´   )r   Úfc1Úfc2r   râ   rã   r¯   r�   rL   r   r*   r+   Úwidthrh   ÚfusablerF   rG   rf   ÚfirstÚlastÚhrj   rÄ   rÀ   s                           r   Úmlprö   8  s  € õ 	ˆV‰Œ€AØŒw˜Ÿš˜r 1¤7¨2¤;Ñ/Ô/ˆ1€EØÐˆ!ˆ! X§]¢]°2°q´w¸r´{Ñ%CÔ%C€CØ�^ˆTˆT¨¯ª°R¸¼ÀbÔ9IÑ)JÔ)J€FàÔ R Z  °R´_ÑEÈfÈnÈÈÐbhÔbnÐoqÔbrÐuxô  vFñ  cFñ  G€EÝ˜!œ' !œ* e¨a¯nªnÑ.>Ô.>Ñ&>ÀÄÐQSÐ[_ÐQ_ÐQuÐciÐquÐcuÐvÑvÔv€DØ�Z F N°sÐ>PÐ7PÐ7PˆcˆcÐVZ€GØ9AÐ9I  1¤7¨1¤:¨tÐ4Ð5Ð5Èxð *ñ *Ñˆˆt�UØ˜��¨5¯=ª=¸Ñ+<Ô+<×+?Ò+?ÀÄ	Ñ+JÔ+JˆÝ˜5 $¨Ñ-Ô-ð 	*ñ 	*ˆEÝ�u˜t‘| TÑ*Ô*ˆDØ��A�e˜D�j”MÑ"Ô"ˆAØ&ÐT­:°c¸1À'Ð+JÑ+JÔ+JÐT�G�GÐPTˆEØˆ}ØCFÈ&Â=À=ÐUWÐUc•T˜1˜b˜b  5¨ :¤Ñ/Ô/Ð0¸Ð?Ñ?Ô?Ð?Ðvyð  ~Dò  wDð  wDÕimÐopÐnqÑirÔirÐirØJLÈ.�& ! R R¨¨%°¨*¬Ñ%6Ô%6Ð!7ÀÐFÑFÔFÐFÐmpÐt|Òm|Ðm|Õ^dÐfgÐehÑ^iÔ^iÐ^iØ58¸F²]°]�%œ)œ.×.Ò.¨qÑ1Ô1Ð1ÍÌ	Ì×H\ÒH\Ð]^Ðvyð  ~Dò  wDð  wDÐlrÐlrð  JPÐH\ñ  IQô  IQð ð Ð!Ý”I˜v e¨D jÔ1°1Ð5¸2Ð>Ñ>Ô>�Ø˜˜t˜”_ˆFØŒ|˜qœwÒ&Ð&¨EÐ,=À(ÐBVÕ[eÐfiÐklÑ[mÔ[mÐBVÝ�s˜Q˜C¨5À8ÐCS¸4¸4ÐY_Ðpuð  |Bð  Cñ  Cô  Cð  CÙØ5:Ð5F•�s˜Q˜C¨5Ð1Ñ1Ô1Ð1ÈCÈCÐPQÉFÌFˆAØØÐØ—’˜Q‘”�‘Ø�Ø—’˜A‘”�‘à—’  5Ñ)Ô)Ð)Ñ)ñ+	*ð, �8Š8�E‰?Œ?Ðr   c                 óî   — t          | ¦  «        r$t          dt          d ut          d u¬¦  «        dk    r| S | d         | d         }}|  t	          j        || ||fd¬¦  «        j        g |j        ¢d‘d‘R Ž fS )	NzSplit-Half RMSNorm + RoPE)rS   Úkitchenrø   ©.r   ©.r   r'   rç   ru   )r   r   r_   Ú_kitchen_rms_roper.   Ústackr)   r*   )ÚropeÚcÚss      r   Úprepare_split_half_roper   e  s´   € Ý˜$ÑÔð ¥6Ð*EÕT[ÐcgÐTgõ  rCð  KOð  rOð  $Pñ  $Pô  $Pð  T]ò  $]ð  $]ØˆØ�Œ<˜˜fœ€q€AØÐ;•”˜a !  Q¨˜]°Ð3Ñ3Ô3Ô;ÐK¸Q¼WÐKÀaÐKÈÐKÐKÐKÐKÐKr   c                 ó¨   ‡ — t          ‰ ¦  «        r|d ust          d ust          ‰ ¦  «        o&t          ˆ fd„|j        |j        fD ¦   «         ¦  «        S )Nc              3   óX   •K  — | ]$}|j         ‰j         k    o|j        ‰j        k    V — Œ%d S r"   )rA   r?   )r$   Úpr   s     €r   r&   z*can_split_half_rms_rope.<locals>.<genexpr>n  s:   øè è € ÐhÐhÀA�A”H ¤Ò(Ð?¨Q¬W¸¼Ò-?ÐhÐhÐhÐhÐhÐhr   )r   r_   rB   r2   rT   )r   r—   Úq_normÚk_norms   `   r   Úcan_split_half_rms_roper  l  sh   ø€ Ý˜AÑÔÐN F°$Ð$6Ð$M½'ÈÐ:MÐhÕReÐfgÑRhÔRhð iÝÐhÐhÐhÐhÈ&Ì-ÐY_ÔYfÐIgÐhÑhÔhÑhÔhðjr   c                 óÜ  — | D ]“\  }}t          dd|d                              ¦   «         |                     ¦   «         z  z  ¦  «        }t          d|j        d         |¦  «        D ]1}|d d …|||z   …f         }|                      ||¦  «        ¦  «         Œ2Œ”|�Ñ|j        d         }|d         |d         }	}d }
| D ]±\  }}|dd |…f         |d|d	|z  …f         }}|
�|
j        |j        k    rt          j        |¦  «        }
|
                     |¦  «         |                     |¦  «         	                    ||	d
¬¦  «         |                     |¦  «         	                    |
|	¦  «         Œ°d S d S )Nr   é   ©r   r   r   éþÿÿÿrù   rú   .ru   r'   ©rž   )
rÒ   rŽ   ré   rÝ   r*   rÃ   r.   Ú
empty_likerb   r´   )Útensorsrý   Útensorrd   rh   rF   ÚpartÚpairsÚcosineÚsineÚscratchÚ_ró   Úseconds                 r   Ú_native_split_half_norm_rope_r  q  s   € Øð #ð #‰ˆ�Ý�1�y f¨T¤l×&8Ò&8Ñ&:Ô&:¸V×=PÒ=PÑ=RÔ=RÑ&RÑSÑTÔTˆÝ˜1˜fœl¨1œo¨tÑ4Ô4ð 	#ð 	#ˆEØ˜!˜!˜!˜U 5¨4¡<Ð/Ð/Ô0ˆDØ�JŠJ�t�t˜D‘z”zÑ"Ô"Ð"Ð"ð	#ð ÐØ”
˜2”ˆØ˜F”| T¨&¤\�ˆØˆØ ð 	8ð 	8‰IˆF�AØ" 3¨¨¨ ;Ô/°¸¸UÀ1ÀuÁ9¸_Ð8LÔ1M�6ˆEØˆ '¤-°5´;Ò">Ð">ÝÔ*¨5Ñ1Ô1�Ø�MŠM˜%Ñ Ô Ð Ø�JŠJ�vÑÔ×'Ò'¨°¸BÐ'Ñ?Ô?Ð?Ø�KŠK˜ÑÔ×(Ò(¨°$Ñ7Ô7Ð7Ð7ð Ðð	8ð 	8r   )Úallow_fusionc                óª   — | �| n|}|�(|r&t          ||||¦  «        rt          | |||||¦  «        S t          d„ | |f||ffD ¦   «         |¦  «         | |fS )Nc                 ó    — g | ]\  }}|®||f‘ŒS r"   r-   )r$   r   rd   s      r   rß   z)split_half_norm_rope_.<locals>.<listcomp>ˆ  s&   € Ð"hÐ"hÐ"h±°°DÐZ[ÐZg A t 9ÐZgÐZgÐZgr   )r  Úsplit_half_rms_rope_r  )ÚqÚkrý   r—   r  r  r  r   s           r   Úsplit_half_norm_rope_r  „  s~   € Øˆ]ˆˆ €AØÐ˜LÐÕ-DÀQÈÐPVÐX^Ñ-_Ô-_ÐÝ# A q¨$°¸ÀÑGÔGÐGÝ!Ð"hÐ"h¸aÀ¸[È1ÈfÈ+Ð<VÐ"hÑ"hÔ"hÐjnÑoÔoÐoØˆaˆ4€Kr   c                 óº  — | |f||ffD �]N\  }}|€Œ	|�dt           �]t          |¦  «        rN|j        j        |j        k    r9|j        j        |j        k    r$t          j        ||j        ||j        d¬¦  «         Œot          dd|d                              ¦   «         | 	                    ¦   «         z  z  ¦  «        }t          d|j        d         |¦  «        D ]‚}|dd…|||z   …f         }	 ||	¦  «                             |j        ¦  «        }
|	                     |€|
n4t          |
|dd…|||z   …ddf         |dd…|||z   …ddf         d¬¦  «        ¦  «         Œƒ�ŒP| |fS )	a(  In place per-head RMSNorm (modules with .weight and .eps) then the rotation of channel pairs (2p, 2p + 1) of q and / or k
    (batch, tokens, heads, head_dim; the other None) by rope (1 | batch, tokens, 1, pairs, 2) cos / sin, a complex frequency table
    viewed as real; rope None normalizes only. The fused Triton kernel on CUDA inference tensors (FP32 statistics, the norm output
    rounded to the activation dtype, the rotation in FP32 with one rounding), else the norm module and paired_rope_ by chunks of
    tokens, without complex arithmetic.NT©Úinterleavedr   r  r	  r   .)r_   r   rT   rA   r?   Ú	rms_rope_r^   rÒ   rŽ   ré   rÝ   r*   r\   rÃ   Úpaired_rope_)r  r  rý   r  r  r   rd   rh   rF   r  Ú
normalizeds              r   Úinterleaved_norm_rope_r$  Œ  sõ  € ð ˜�K ! V Ð-ð 
mñ 
m‰ˆˆ4Øˆ9ØØÐ¥Ð 3½ÀqÑ8IÔ8IÐ 3ÈdÌkÔN`ÐdeÔdlÒNlÐNlÐquÔq|ô  rCð  GHô  GNò  rNð  rNÝÔ˜a ¤¨d°D´HÈ$ÐOÑOÔOÐOØÝ�1�y a¨¤g§m¢m¡o¤o¸¿ºÑ8HÔ8HÑ&HÑIÑJÔJˆÝ˜1˜aœg aœj¨$Ñ/Ô/ð 	mð 	mˆEØ�Q�Q�Q˜˜e d™lÐ*Ð*Ô+ˆDØ˜˜d™œŸš q¤wÑ/Ô/ˆJØ�JŠJ T \�z�zµ|ÀJÐPTÐUVÐUVÐUVÐX]Ð^cÐfjÑ^jÐXjÐloÐqrÐUrÔPsÐuyÐz{Ðz{Ðz{ð  ~Cð  DIð  LPñ  DPð  ~Pð  RUð  WXð  {Xô  vYð  gkð  8lñ  8lô  8lñ  mô  mð  mð  mñ	mð ˆaˆ4€Kr   c                 ób  — |�7| �5|�3t          | |||j        |j        |j        |j        d         dz  ¬¦  «        S | |f||ffD ]ê\  }}|€Œ|�s|j        d         dk    rb|j        d         dz  }t          |dd…dd…d|…f         |dd…dd…|d…f         ||j        |j        |j        |j        d         dz  ¬¦  «         Œ}t	          |¦  «        r"t          j        ||j        ||j        ¦  «         Œ®t          �"t          j        ||j        ||j        ¦  «         Œ×t          ||fg|¦  «         Œë| |fS )zCBorrow Q/K destinations. Either can be absent for staged attention.Néýÿÿÿru   )ÚepsilonÚrot_dimr   )	rû   rT   r^   r*   rB   r>   r!  r_   r  )	r  r  rý   r—   r  r  r   rd   Úhalfs	            r   r  r     s~  € àÐ˜a˜m°°Ý   A v¨v¬}¸f¼mØ)/¬¸V¼\È"Ô=MÐPQÑ=QðSñ Sô Sð 	Sà˜�K ! V Ð-ð =ð =‰ˆˆ4Øˆ9ØØÐ !¤'¨!¤*¨q¢. .Ø”7˜1”: ‘?ˆDÝ˜a    1 1 1 e t e œn¨a°°°°1°1°1°d°e°e°¬n¸fÀdÄkÐSWÔS^Ø'+¤x¸¼ÀbÔ9IÈAÑ9MðOñ Oô Oð Oð Oå  Ñ#Ô#ð 	=ÝÔ" 1 d¤k°4¸¼ÑBÔBÐBÐBÝÐ ÝÔ˜a ¤¨d°D´HÑ=Ô=Ð=Ð=õ *¨A¨t¨9¨+°tÑ<Ô<Ð<Ð<Øˆaˆ4€Kr   c                 ó2  ‡‡‡— | €dS t          | t          ¦  «        r§ˆˆfd„| D ¦   «         Št          ˆfd„‰D ¦   «         ¦  «        rt          d¦  «        ‚t	          j        ‰t          j        ‰¬¦  «        }t          | ¦  «        D ]\  }\  }}}||||…<   Œt	          j        d„ ‰D ¦   «         ¦  «        ‰d         d	         |fS t          | t          ¦  «        rg | ¢d‘R S | j
        | j        €#t	          j        t          j        ¦  «        j        n| j        dfS )
a:  (weight, eps, weight_rows) of a per-head RMSNorm given as a module (.weight, .eps), as a (weight, eps) tuple, or as segments
    [(start, stop, module or tuple)] over the tokens with their own weights (stacked into (segments, D) rows, weight_rows the row of
    each token; one eps); (None, 0.0, None) for no norm.N)Ng        Nc                 ó:   •— g | ]\  }}}t          |‰‰¦  «        ‘ŒS r-   )Ú_norm_parameters)r$   r  ÚsegmentrA   rÖ   s      €€r   rß   z$_norm_parameters.<locals>.<listcomp>½  s,   ø€ ÐUÐUÐU¹}¸qÀ!ÀWÕ! '¨6°6Ñ:Ô:ÐUÐUÐUr   c              3   óH   •K  — | ]}|d          ‰d         d          k    V — ŒdS )r   r   Nr-   )r$   r  Úpartss     €r   r&   z#_norm_parameters.<locals>.<genexpr>¾  s4   øè è € Ð8Ð8¨$ˆt�AŒw˜% œ( 1œ+Ò%Ð8Ð8Ð8Ð8Ð8Ð8r   z5Segments of a fused q/k norm must share their epsilonrr   c                 ó   — g | ]
}|d          ‘ŒS )r   r-   )r$   r  s     r   rß   z$_norm_parameters.<locals>.<listcomp>Ã  s   € Ð6Ð6Ð6¨˜D œGÐ6Ð6Ð6r   r   r   )rº   ÚlistÚanyÚ
ValueErrorr.   ÚzerosÚint32rK   rü   r4   rT   r^   Úfinfor`   )	rd   rÖ   rA   rh   rE   rF   rG   r  r/  s	    ``     @r   r,  r,  ¶  s?  øøø€ ð €|ØˆÝ�$�ÑÔð KØUÐUÐUÐUÐUÐPTÐUÑUÔUˆÝÐ8Ð8Ð8Ð8°%Ð8Ñ8Ô8Ñ8Ô8ð 	VÝÐTÑUÔUÐUÝŒ{˜6­¬¸VÐDÑDÔDˆÝ'0°¡¤ð 	%ð 	%Ñ#ˆEÑ#�E˜4 Ø$ˆD��t�ÑÐÝŒ{Ð6Ð6°Ð6Ñ6Ô6Ñ7Ô7¸¸q¼À!¼ÀdÐJÐJÝ�$�ÑÔð Ø�ˆ{�dˆ{ˆ{ÐØŒ;¸$¼(Ð:J�œ¥E¤MÑ2Ô2Ô6Ð6ÐPTÔPXÐZ^Ð^Ð^r   r  c                óø  ‡— | �| n|Šˆfd„||fD ¦   «         \  \  }}	}
\  }}}t           �1t          |d¦  «        r!|                     |‰j        d         ¦  «        nd}|�S‰j        d         dvsDt	          ‰t
          j        t
          j        f¬¦  «        rt          ˆfd„||fD ¦   «         ¦  «        sdS ddg}|�ƒ|d         \  }}}}| 	                    d	¦  «        }|€t          j
        ||||||¬
¦  «        n!|                     |j        d         dd¦  «        }t          j        |||||||||||¬¦  «        |d<   ~| �.|d         \  }}}}t          j        | |||	||||||
¬¦
  «
        |d<   t          |¦  «        S )aÔ  The staged SageAttention 2 quantization of q and / or k (batch, tokens, heads, head_dim; the other None) fused with their
    per-head RMSNorm (a module with .weight and .eps, a (weight, eps) tuple, None, or segments [(start, stop, module or tuple)] over
    the tokens, each with its own weights, in the activation dtype or FP32: a joint attention's streams) and RoPE (rope: (1 | batch, tokens, 1, pairs, 2) cos / sin
    or (..., pairs, 2, 2) rotation matrices [[cos, -sin], [sin, cos]], read through their strides; None for no rotation; channel p
    with p + pairs, or interleaved 2p with 2p + 1): (q_quantized, k_quantized) as the core's staged_quantize_q / staged_quantize_k
    return them, quantized from the FP32 rotated rows (one rounding fewer than the in-place kernel followed by the core's
    quantizer), k's mean from FP32 partial sums. q is left as it is (staged_attention writes the output into it) and k is not
    modified (the caller releases it). None where the fusion does not apply (a core without fused_qk_layouts or a quantization
    layout the kernels do not reproduce, no CUDA inference, head_dim not 64 / 128, norm weights on another device / dtype): the
    caller runs norm_rope and the core's quantizers.Nc              3   óZ   •K  — | ]%}t          |‰j        d          ‰j        ¦  «        V — Œ&dS r…   )r,  r*   rA   )r$   rd   r   s     €r   r&   z.split_half_norm_rope_quant_.<locals>.<genexpr>Õ  sW   øè è € ð  <Gð  <GÐmqÕ<LÈTÐSTÔSZÐ[\ÔS]Ð_`Ô_gÑ<hÔ<hð  <Gð  <Gð  <Gð  <Gð  <Gð  <Gr   Úfused_qk_layoutsr'   )é@   é€   )r   c              3   óp   •K  — | ]0}|®|j         ‰j         k    o|j        ‰j        t          j        fv V — Œ1d S r"   )rA   r?   r.   r`   )r$   Úwr   s     €r   r&   z.split_half_norm_rope_quant_.<locals>.<genexpr>Ù  sh   øè è € ð  Dð  DÐXYÐuvð  vC�q”x 1¤8Ò+ÐS°´¸A¼GÅUÄ]Ð;SÐ0Sð  vCð  vCð  vCð  vCð  Dð  Dr   r  Úk_mean)r   Úweight_rowsr   )ÚmeanÚsm_scaleÚ	scale_epsr   r?  r   r  )rA  rB  r   r?  )Ú	_qk_quantÚhasattrr9  r*   r   r.   r@   r�   r2   ÚgetÚnorm_rope_meanÚexpandÚnorm_rope_quantizer4   )r  r  rý   r  r  ÚcoreÚsettingsr   Úq_weightÚq_epsÚq_rowsÚk_weightÚk_epsÚk_rowsÚlayoutsÚ	quantizedri   ÚblockrA  rB  r@  r   s                        @r   Úsplit_half_norm_rope_quant_rT  É  sc  ø€ ð ˆ]ˆˆ €Að <Gð  <Gð  <Gð  <GÐv|ð  Eð  vFð  <Gñ  <Gô  <GÑ8Ñ€Xˆu�fÑ8 ¨%°Ý>GÐ>SÕX_Ð`dÐfxÑXyÔXyÐ>Sˆd×#Ò# H¨a¬g°b¬kÑ:Ô:Ð:ð  @D€Gàˆ˜1œ7 2œ;¨iÐ7Ð7½~ÈaÕY^ÔYgÕinÔivÐXwÐ?xÑ?xÔ?xÐ7Ýð  Dð  Dð  Dð  DÐ^fÐhpÐ]qð  Dñ  Dô  Dñ  Dô  Dð 8àˆtØ�t�€IØ€}Ø-4°S¬\Ñ*ˆ��x Ø�|Š|˜HÑ%Ô%ˆØrvÐr~�yÔ'¨¨8°T¸5ÈkÐgmÐnÑnÔnÐnð  EI÷  EPò  EPð  QRô  QXð  YZô  Q[ð  ]_ð  acñ  Edô  EdˆÝ Ô3°A°xÀÀuÈfÐV[ÐbfÐqyð  FOØ@KÐY_ðañ aô aˆ	�!‰àØ€}Ø-4°S¬\Ñ*ˆ��x Ý Ô3°A°xÀÀuÈfÐV[Ðfnð  {DØ@KÐY_ðañ aô aˆ	�!‰å�ÑÔÐr   c                 óð   — t          t          d uot          | ¦  «        ¬¦  «        rt          j        | |||¦  «        S ddlm}  || |||¦  «         t          j        j         	                    | ¦  «         | S )NrR   r   )Úrms_norm_rope_)
r   r_   r   r!  Úshared.sol_attnrV  r.   ÚautogradÚgraphÚincrement_version)r   rT   rý   r^   rV  s        r   Úsol_rms_rope_r[  ê  s„   € Ý�7¨$Ð.ÐDµ>À!Ñ3DÔ3DÐEÑEÔEð 7ÝÔ   F¨D°#Ñ6Ô6Ð6Ø.Ð.Ð.Ð.Ð.Ð.Ø€N�1�f˜d CÑ(Ô(Ð(Ý	„NÔ×*Ò*¨1Ñ-Ô-Ð-Ø€Hr   c                 óv  ‡ ‡— t           duot          ‰ d¬¦  «        }| ot          ‰ d¬¦  «        }|s|oÞ‰                      d¦  «        dk    oÅ‰                      d¦  «        ‰ j        d         k    o¡t          |j        ¦  «        dv o‹dt          |j        ¦  «        cxk    odk    nc oid	|j        cxk    ot          |j        ¦  «        k     nc oB‰ j        d	         dk    p1‰                      d	¦  «        ‰ j        d         ‰ j        d         z  k    }|j	        rt          j        n‰ j        Š|o*t          ˆˆ fd
„g |j        ¢|j        ¢R D ¦   «         ¦  «        }t          d|¬¦  «        sdS |rt           nt                                ‰ ||||¦  «         t          j        j                             ‰ ¦  «         dS )zäTry compact split RoPE without materializing token-sized tables.

    False leaves x untouched for the model's layout-specific PyTorch fallback.
    Norm over all heads and its prepared statistics are deliberately external.
    NTr8   r'   r   ru   )r   rp   rp   r   c              3   óv   •K  — | ]3}|j         ‰j         k    o|j        ‰k    o|                     ¦   «         V — Œ4d S r"   )rA   r?   r1   )r$   rt   r?   r   s     €€r   r&   z compact_rope_.<locals>.<genexpr>  sc   øè è € ð Ið IØð œ( a¤hÒ.ÐY°1´7¸eÒ3CÐYÈÏÊÑHYÔHYð Ið Ið Ið Ið Ið Ir   zCompact Split RoPErR   F)r_   r   rB   rw   r*   rJ   Úaxis_cosÚ
grid_sizesÚpad_sizeÚuse_fp32_freqsr.   r`   r?   r2   Úaxis_sinr   r>   Ú
split_roperX  rY  rZ  )	r   Úcacheri   Ú
head_startÚdim_headÚnativerk   r•   r?   s	   `       @r   Úcompact_rope_rh  ó  s  øø€ õ ˜DÐ ÐH¥^°AÀ4Ð%HÑ%HÔ%H€FØˆ:ÐBÕ-¨a¸TÐBÑBÔB€DØˆn˜ð MØ—’˜"‘” Ò"ðMØ'(§x¢x°¡{¤{°a´g¸a´jÒ'@ðMå�V”_Ñ%Ô%¨Ð/ðMà45½¸VÔ=NÑ9OÔ9OÐ4TÐ4TÒ4TÐ4TÐSTÒ4TÐ4TÐ4TÐ4TðMð �e”nÐ;Ð;Ò;Ð;¥s¨6¬?Ñ';Ô';Ò;Ð;Ð;Ð;ðMð ”'˜!”* ’/ÐK Q§X¢X¨a¡[¤[°A´G¸A´JÀÄÈÄÑ4KÒ%Kð	 
ð
 #Ô1Ð>�EŒMˆM°q´w€EØð I•cð Ið Ið Ið Ið IØ#G V¤_Ð#G°v´Ð#GÐ#GðIñ Iô Iñ Iô I€EåÐ&°UÐ;Ñ;Ô;ð ØˆuØÐ&…\€\�w×2Ò2°1°e¸VÀZÐQYÑZÔZÐZÝ	„NÔ×*Ò*¨1Ñ-Ô-Ð-Øˆ4r   )Úoffset_in_weight_dtypec                óÖ  — t          | ¦  «        }|r\|j        rU|j        t          j        t          j        fv r6|j        |j        k    r&t          j        ||j        d         f|dz   |¦  «        S |r|dz    	                    ¦   «         n| 	                    ¦   «         dz   }t          j        | 	                    ¦   «         |j        d         f||¦  «         
                    |j        ¦  «        S )a¢  FP32 RMSNorm with the weight stored around zero: (weight + 1) added in FP32, or in the weight's dtype first (Krea 2's
    `scale + 1.0` on a BF16 parameter), then the product in FP32 and one final rounding. With the offset in the weight's dtype on a
    16-bit CUDA tensor, PyTorch's fused kernel does that arithmetic in FP32 without materializing FP32 copies of x (two of them cost
    a Krea 2 block 25 MiB of peak).r'   r   )r   Úis_cudar?   r.   r@   r�   r“   Úrms_normr*   r¼   r\   )r   rT   r^   ri  r   rf   s         r   Úzero_center_rms_normrm  
  sÌ   € õ
 	ˆV‰Œ€AØð > !¤)ð >°´½E¼NÍEÌMÐ;ZÐ0ZÐ0ZÐ_eÔ_kÐopÔovÒ_vÐ_vÝŒz˜!˜aœg bœk˜^¨V°a©Z¸Ñ=Ô=Ð=Ø$:ÐRˆV�a‰Z×ÒÑ Ô Ð ÀÇÂÁÄÐQRÑ@R€EÝŒ:�a—g’g‘i”i !¤'¨"¤+ °¸Ñ<Ô<×?Ò?ÀÄÑHÔHÐHr   c                 ón   — t          |¦  «        }|                      |                     ¦   «         ¦  «        S )zzx *= sigmoid(gate) in place, with PyTorch's native sigmoid rounding; the gate is consumed (its sigmoid is taken in place).)r   rb   Úsigmoid_)r   r¥   r�   s      r   Úsigmoid_gate_rp    s'   € å�	‰?Œ?€DØ�6Š6�$—-’-‘/”/Ñ"Ô"Ð"r   )Úmanualc                ó0  — t          | ¦  «        }|j        }|                     ¦   «         }|r3|t          j        t          j        |dz  dd¬¦  «        |z   ¦  «        z  }n#t          j        ||j        d         f|¬¦  «        }| 	                    |¦  «        S )zæUnweighted FP32 RMSNorm, rounded before a caller's weight multiply.

    Flux uses explicit square/mean/rsqrt; SenseNova uses native rms_norm. Keep
    those reductions distinct, and leave weight promotion to the norm module.
    ru   r'   T)rè   ÚkeepdimrŒ   )
r   r?   r¼   r.   Úrsqrtr@  r“   rl  r*   r\   )r   r^   rq  r   r?   s        r   Úrms_norm_roundedru    s‰   € õ 	ˆV‰Œ€AØŒG€EØ	�Š‰	Œ	€AØð 3Ø•”�EœJ q¨A¡v°2¸tÐDÑDÔDÀsÑJÑKÔKÑKˆˆåŒJ�q˜1œ7 2œ;˜.¨cÐ2Ñ2Ô2ˆØ�4Š4�‰;Œ;Ðr   c                 óP  — t          | ¦  «        }|j        |j        }} |                     ¦   «         j        g |dd…         ¢d‘d‘d‘R Ž }|d         |d         z  }|d         |d         z  }|                     |¦  «                             |¦  «                             |¦  «        S )zFFP32 matrix rotation with separate products, followed by a final cast.Nr'   r   ru   rù   rú   )r   r*   r?   r¼   r)   rc   r\   )r   Úfreqsr   r*   r?   r±   s         r   Úmatrix_roperx  ,  s¡   € åˆV‰Œ€AØ”7˜AœGˆ5€EØˆ�Š‰	Œ	ÔÐ0˜5  " œ:Ð0 rÐ0¨1Ð0¨aÐ0Ð0Ð0€AØ�6Œ]˜Q˜vœYÑ&€FØˆfŒ˜˜&œ	Ñ!€AØ�;Š;�q‰>Œ>×!Ò! %Ñ(Ô(×+Ò+¨EÑ2Ô2Ð2r   c                ó¼  — |r| dddd…f         | dddd…f         }}n|                       dd¬¦  «        \  }}|€|                     ¦   «         }n9|t          d„ |j        D ¦   «         ¦  «                 }|                     |¦  «         |                     |¦  «                             ||d¬	¦  «         |                     |¦  «                             ||¦  «         | S )
zJNative multiply then addcmul; borrow the destination and optional scratch..r   Nru   r   r'   rç   c              3   ó6   K  — | ]}t          d |¦  «        V — ŒdS ©r   N)Úslice)r$   Úsizes     r   r&   zpaired_rope_.<locals>.<genexpr>?  s*   è è € ÐGÐG°4¥ a¨¡¤ÐGÐGÐGÐGÐGÐGr   r  )rš   Úcloner4   r*   rÃ   rb   r´   )r   r  r  r  r   ró   r  s          r   r"  r"  6  sá   € àð +Ø˜#˜q˜t !˜t˜)œ a¨¨Q¨T°¨T¨	¤lˆvˆˆàŸš  r˜Ñ*Ô*‰ˆˆvØ€Ø—+’+‘-”-ˆˆà�%ÐGÐG¸5¼;ÐGÑGÔGÑGÔGÔHˆØ�Š�eÑÔÐØ	‡J‚JˆvÑÔ×Ò ¨°BÐÑ7Ô7Ð7Ø
‡K‚K�ÑÔ× Ò  ¨$Ñ/Ô/Ð/Ø€Hr   c                 óÆ   ‡— t          | ¦  «        }|j        }|                     ¦   «         }ˆfd„dD ¦   «         \  }}t          |||d¬¦  «                             |¦  «        S )zGQwen Image's FP32 multiply/addcmul rotation after native norm rounding.c              3   óx   •K  — | ]4}‰d |f                               d¦  «                              d¦  «        V — Œ5dS ).r   ru   N)r]   )r$   Úirw  s     €r   r&   z#interleaved_rope.<locals>.<genexpr>K  sG   øè è € ÐLÐLÀ�E˜#˜q˜&”M×+Ò+¨AÑ.Ô.×8Ò8¸Ñ;Ô;ÐLÐLÐLÐLÐLÐLr   )r   r   Tr  )r   r?   r¼   r"  r\   )r   rw  r   r?   r  r  s    `    r   Úinterleaved_roper‚  F  sd   ø€ åˆV‰Œ€AØŒG€EØ	�Š‰	Œ	€AØLÐLÐLÐLÀVÐLÑLÔL�L€FˆDÝ˜˜6 4°TÐ:Ñ:Ô:×=Ò=¸eÑDÔDÐDr   c                 ó†   — t          | ¦  «        }|d|f         }|                     |¦  «                             ||¦  «        S )zDNative-dtype rotation with model-supplied partner indices and signs..)r   rb   r´   )r   r  r  Úpartnerr   Úrotateds         r   Úindexed_roper†  O  s:   € åˆV‰Œ€AØ��W�Œo€GØ�6Š6�&‰>Œ>×"Ò" 7¨DÑ1Ô1Ð1r   c                 ó�  — t          | ¦  «        } ||¦  «                             |j        ¦  «        }|€|S t          j         |                     ¦   «         j        g |j        d d…         ¢d‘d‘R Ž ¦  «        }|                     | 	                    d¦  «        ¦  «         t          j
        |¦  «                             d¦  «        S )Nr'   ru   r   rp   )r   r\   r?   r.   Úview_as_complexr¼   r)   r*   rb   r]   Úview_as_realÚflatten)r   rd   rw  r   r…  s        r   Úcomplex_norm_roper‹  V  s¯   € ÝˆV‰Œ€AØˆˆQ‰Œ�
Š
�1”7ÑÔ€AØ€}ØˆÝÔ#Ð$5 A§G¢G¡I¤IÔ$5Ð$K°q´w¸sÀ¸s´|Ð$KÀRÐ$KÈÐ$KÐ$KÐ$KÑLÔL€GØ‡L‚L�—’ Ñ#Ô#Ñ$Ô$Ð$ÝÔ˜gÑ&Ô&×.Ò.¨qÑ1Ô1Ð1r   c                 ó  — t          | ¦  «        }|j        }|                     ¦   «         }||                     ¦   «                              dd¬¦  «                             |¦  «                             ¦   «         z  |                     ¦   «         z  }|                     dd¦  «                             d¦  «        }|d         |d         z  |d         |d         z  z    	                    d¦  «         
                    |¦  «        S )Nr'   T)rs  )r'   ru   r
  rù   rú   )r   r?   r¼   Úsquarer@  Úaddrt  Ú	unflattenr]   rŠ  r\   )r   rT   rw  r^   r   r?   r  s          r   Úmatrix_rms_roper�  `  sÎ   € ÝˆV‰Œ€AØŒG€EØ	�Š‰	Œ	€AØ	ˆA�HŠH‰JŒJ�OŠO˜B¨ˆOÑ-Ô-×1Ò1°#Ñ6Ô6×<Ò<Ñ>Ô>Ñ>ÀÇÂÁÄÑO€AØ�KŠK˜˜GÑ$Ô$×.Ò.¨rÑ2Ô2€EØ�&ŒM˜E &œMÑ)¨E°&¬M¸EÀ&¼MÑ,IÑI×RÒRÐSUÑVÔV×YÒYÐZ_Ñ`Ô`Ð`r   r"   )r~   )NN)Fr{  )PÚ__doc__r.   Útorch.nn.functionalrW   Ú
functionalr“   Ú r   r   r   Údispatchr   r   r	   r
   r   r   r_   ÚImportErrorÚOSErrorÚRuntimeErrorr   r>   r   rC  r   r�   Úcomfy_kitchenr   rû   r3  ÚexcÚstrÚ
startswithr@   r   r   r7   rB   rN   ra   rx   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,  rT  r[  rh  rm  rp  ru  rx  r"  r‚  r†  r‹  r�  r-   r   r   ú<module>r�     s  ððð ð €€€Ø Ð Ð Ð Ð Ð Ð Ð Ð Ø 5Ð 5Ð 5Ð 5Ð 5Ð 5Ð 5Ð 5Ð 5Ð 5Ø PÐ PÐ PÐ PÐ PÐ PÐ PÐ PÐ PÐ PÐ PÐ PÐ PÐ PðØ,Ð,Ð,Ð,Ð,Ð,Ð,øØ�W˜lÐ+ð ð ð Ø€G€G€GðøøøðØ6Ð6Ð6Ð6Ð6Ð6Ð6øØ�W˜lÐ+ð ð ð Ø€L€L€LðøøøðØ.Ð.Ð.Ð.Ð.Ð.Ð.øØ�W˜lÐ+ð ð ð Ø€I€I€IðøøøðØ/Ð/Ð/Ð/Ð/Ð/Ð/øØ�WÐð ð ð Ø€M€M€MðøøøðØGÐGÐGÐGÐGÐGÐGøØ�W˜lÐ+ð ð ð ØÐÐÐØð ð ð Øˆ3ˆs‰8Œ8×ÒÐ4Ñ5Ô5ð ØØÐÐÐÐÐÐøøøøðøøøð %*¤NÐ#4¸$ð Jð Jð Jð Jð Jð
Jð Jð Jð2ð 2ð 2ð +0ð @ð @ð @ð @ð @ðKð Kð Kð BFð ð ð ð ð ð:°tÀEÐUZð ð ð ð ð ð8 >BÈUð Uð Uð Uð Uð Uð
GÀ%ð 
Gð 
Gð 
Gð 
Gð 
Gð@ð @ð @ð& "¨Dð 6ð 6ð 6ð 6ð 6ð(ð (ð (ð  ð 
dð 
dð 
dð 
dð 
dðð ð ð ð 5:ÀÐQUð ð ð ð ð ð$yð yð yð yðð ð ð" €Ø€ØÐ Ø€Ø€Ø€ðð ð ð ð Wð Wð Wð &*°$ÀÈDÐ[_ð *ð *ð *ð *ð *ðZLð Lð Lðjð jð jð
8ð 8ð 8ð& OSð ð ð ð ð ðð ð ð(ð ð ð,_ð _ð _ð& \að ð ð ð ð ðBð ð ðð ð ð ð. INð 	Ið 	Ið 	Ið 	Ið 	Ið#ð #ð #ð°ð ð ð ð ð ð 3ð 3ð 3ð¸uð ð ð ð ð ð Eð Eð Eð2ð 2ð 2ð2ð 2ð 2ðað að að að að as`   ©0 °
=¼=ÁA Á
AÁAÁA  Á 
A-Á,A-Á1A8 Á8	BÂBÂB Â
C
ÂC
Â!CÃC
