Ë
    ˆ\;jÁš  ã                   óà   — d dl Z d dlZd dlmZ d dlmZ d dlmZ d dlm	Z	m
Z
 ej                  j                  Z G d„ d«      Z G d„ d	e«      Z G d
„ de«      Z G d„ de«      Z G d„ de«      Zy)é    N)Úunique_name)Úwait_server_ready)Úcore)Údefault_main_programÚdefault_startup_programc                   óP   — e Zd ZdZd„ Zd„ Zd„ Zd„ Z	 dd„Zd„ Z	d„ Z
d	„ Zd
„ Zd„ Zy)Ú
CollectiveÚ c                 óè   — || _         d | _        d | _        d | _        d | _        d | _        d | _        d | _        t        j                  }|j                  «       | _        |j                  «       | _        y ©N)ÚnringsÚ	endpointsÚcurrent_endpointÚother_endpointsÚnranksÚrankÚstartup_programÚmain_programr   Úop_proto_and_checker_makerÚkOpRoleAttrNameÚop_role_keyÚkOpRoleVarAttrNameÚop_role_var_key)Úselfr   Úop_makers      úqG:\00. PROJECTS\API\Inventory\templateJSON\kerjaOCR\Lib\site-packages\paddle/distributed/transpiler/collective.pyÚ__init__zCollective.__init__   sk   € ØˆŒØˆŒØ $ˆÔØ#ˆÔØˆŒØˆŒ	Ø#ˆÔØ ˆÔÜ×2Ñ2ˆØ#×3Ñ3Ó5ˆÔØ'×:Ñ:Ó<ˆÕó    c                 óú  — t        |t        «      r|j                  d«      }|| _        |€t	        «       | _        || _        |€t        «       | _        t        |«      | _        | j                  dk(  r)| j                  dk7  r| j                  dk7  rt        d«      ‚|dk  rt        d«      ‚|| _        ||vrt        d|t        |«      «      ‚|| _        || _        |r(t        |«      }|d d  }|j                  |«       || _        || _        | j                  j#                  «       | j                  _        | j'                  «        | j
                  j#                  «       | j
                  _        | j)                  «        y )	NÚ,é   Úsingle_process_multi_threadÚboxz the number of endpoints must > 1r   zrank must >= 0z current endpoint %s is not in %s)Ú
isinstanceÚstrÚsplitr   r   r   r   Úlenr   ÚmodeÚ
ValueErrorr   r   r   Úremover   Ú	wait_portÚcloneÚ_origin_programÚ_transpile_startup_programÚ_transpile_main_program)	r   r   r   r   r   r   r+   r   r   s	            r   Ú	transpilezCollective.transpile,   s\  € ô �i¤Ô%Ø!Ÿ™¨Ó,ˆIà.ˆÔØÐ"Ü#:Ó#<ˆDÔ à(ˆÔØÐÜ 4Ó 6ˆDÔä˜)“nˆŒà�K‰K˜1ÒØ—	‘	Ð:Ò:Ø—	‘	˜UÒ"äÐ?Ó@Ð@à�!Š8ÜÐ-Ó.Ð.ØˆŒ	à 9Ñ,ÜØ2Ø Ü�I“óð ð #ˆŒØ 0ˆÔáÜ˜“^ˆFØ'©˜lˆOØ×"Ñ"Ð#3Ô4Ø#2ˆDÔ à"ˆŒà/3×/CÑ/C×/IÑ/IÓ/Kˆ×ÑÔ,Ø×'Ñ'Ô)à,0×,=Ñ,=×,CÑ,CÓ,Eˆ×ÑÔ)Ø×$Ñ$Õ&r   c                 ó   — t        d«      ‚)Nz'call the inherited method of subclasses)ÚNotImplementedError©r   s    r   r/   z"Collective._transpile_main_programe   s   € Ü!Ð"KÓLÐLr   c           	      óè   — t        | j                  «      D ]J  }| j                  | j                  | j                  | j
                  | j                  || j                  «       ŒL | j                  «        y r   )	Úranger   Ú_init_communicatorr   r   r   r   r+   Ú_broadcast_params)r   Úring_ids     r   r.   z%Collective._transpile_startup_programh   s[   € Ü˜TŸ[™[Ö)ˆGØ×#Ñ#Ø×$Ñ$Ø×%Ñ%Ø—‘Ø—	‘	ØØ—‘õð *ð 	×ÑÕ r   c                 ót  — dj                  |«      }t        |«      }	|d d  }
|
j                  |«       |j                  «       }|dk(  r|rt	        |
«       |j                  «       }t        j                  «       rò|j                  t        j                  d«      dt
        j                  j                  j                  ¬«      }|j                  di d|id|d	|d
|
| j                  t        j                   i¬«       |s8|j                  dd|ii d|	d|d|| j                  t        j                   i¬«       y |j                  dd|ii d|	d|d|| j                  t        j                   i¬«       y t        j"                  «       rº|j                  t        j                  d«      dt
        j                  j                  j                  ¬«      }|j                  di d|id|d	|d
|
| j                  t        j                   i¬«       |j                  dd|ii d|	d|d|d|| j                  t        j                   i¬«       y t$        j&                  j)                  «       j*                  t$        j,                  j/                  «       v rº|j                  t        j                  d«      dt
        j                  j                  j                  ¬«      }|j                  di d|id|d	|d
|
| j                  t        j                   i¬«       |j                  dd|ii d|	d|d|d|| j                  t        j                   i¬«       y y )Nr    r   Únccl_idT)ÚnameÚpersistableÚtypeÚc_gen_nccl_idÚOutr   Úendpointr   ©r=   ÚinputsÚoutputsÚattrsÚc_comm_initÚXr   r8   Úc_comm_init_multitrainerÚ	ntrainersÚ
trainer_idÚbkcl_idÚc_gen_bkcl_idr   Úxccl_idÚc_gen_xccl_id)Újoinr'   r*   Úglobal_blockr   r   Úis_compiled_with_cudaÚ
create_varr   ÚgenerateÚVarDescÚVarTypeÚRAWÚ	append_opr   ÚOpRoleÚForwardÚis_compiled_with_xpuÚpaddleÚdistributedÚParallelEnvÚdevice_typeÚdeviceÚget_all_custom_device_type)r   Úprogramr   r   r   r8   r+   Úhas_multitrainerÚendpoints_strr   r   ÚblockÚnccl_id_varÚbkcl_id_varÚxccl_id_vars                  r   r6   zCollective._init_communicatort   sG  € ð Ÿ™ Ó+ˆÜ�Y“ˆØ#¡A˜,ˆØ×ÑÐ/Ô0Ø×$Ñ$Ó&ˆà�1Š9™Ü˜oÔ.à×$Ñ$Ó&ˆÜ×%Ñ%Ô'Ø×*Ñ*Ü ×)Ñ)¨)Ó4Ø Ü—\‘\×)Ñ)×-Ñ-ð +ó ˆKð
 �O‰OØ$ØØ Ð,à˜DØÐ 0Ø% Ø×$Ñ$¤f§n¡nð	ð	 ô 
ñ $à—‘Ø&Ø Ð-Øà  &Ø Ø! 7Ø×(Ñ(¬&¯.©.ð	ð	  õ 
ð —‘Ø3Ø Ð-Øà# VØ$ dØ! 7Ø×(Ñ(¬&¯.©.ð	ð	  õ 
ô ×&Ñ&Ô(Ø×*Ñ*Ü ×)Ñ)¨)Ó4Ø Ü—\‘\×)Ñ)×-Ñ-ð +ó ˆKð
 �O‰OØ$ØØ Ð,à˜DØÐ 0Ø% Ø×$Ñ$¤f§n¡nð	ð	 ô 
ð �O‰OØ"Ø˜[Ð)Øà˜fØ˜DØ˜wØ Ø×$Ñ$¤f§n¡nðð	 õ ô ×Ñ×*Ñ*Ó,×8Ñ8Ü�}‰}×7Ñ7Ó9ñ:ð  ×*Ñ*Ü ×)Ñ)¨)Ó4Ø Ü—\‘\×)Ñ)×-Ñ-ð +ó ˆKð
 �O‰OØ$ØØ Ð,à˜DØÐ 0Ø% Ø×$Ñ$¤f§n¡nð	ð	 ô 
ð �O‰OØ"Ø˜[Ð)Øà˜fØ˜DØ˜wØ Ø×$Ñ$¤f§n¡nðð	 õ ð':r   c                 ó°  — | j                   j                  «       }d}|j                  «       D ]X  }|j                  rŒ|dz   | j                  z  }|j                  dd|id|id|dd| j                  t        j                  i¬	«       ŒZ t        | j                  «      D ]7  }|j                  d
did|id|| j                  t        j                  i¬	«       Œ9 y )Néÿÿÿÿr!   Úc_broadcastrF   r?   r8   Úrootr   rA   Úc_sync_comm_stream)
r   rO   Úiter_parametersÚis_distributedr   rV   r   rW   rX   r5   )r   rc   r8   Úparams       r   r7   zCollective._broadcast_paramsð   sÙ   € Ø×$Ñ$×1Ñ1Ó3ˆØˆØ×*Ñ*Ö,ˆEØ×#Ò#Øà ‘{ d§k¡kÑ1ˆGØ�O‰OØ"Ø˜U�|Ø ˜à˜wØ˜AØ×$Ñ$¤f§n¡nðð	 õ 	ð -ô  ˜TŸ[™[Ö)ˆGØ�O‰OØ)Ø˜U�|Ø ˜Ø  '¨4×+;Ñ+;¼V¿^¹^ÐLð	 õ ñ *r   c                 óô   — | j                   |j                  vryt        |j                  «       | j                      «      }|t        t        j
                  «      z  xr |t        t        j                  «      z  S )NF)r   Ú
attr_namesÚintÚ	all_attrsrW   ÚBackwardÚLoss)r   ÚopÚop_roles      r   Ú_is_loss_grad_opzCollective._is_loss_grad_op  sY   € Ø×Ñ 2§=¡=Ñ0ØÜ�b—l‘l“n T×%5Ñ%5Ñ6Ó7ˆØœœVŸ_™_Ó-Ñ-ÒL°'¼CÄÇÁÓ<LÑ2LÐLr   c                 ó¶   — | j                   |j                  v xr@ t        |j                  «       | j                      «      t        t        j
                  «      z  S r   )r   rp   rq   rr   rW   rs   ©r   ru   s     r   Ú_is_backward_opzCollective._is_backward_op  óJ   € Ø×Ñ 2§=¡=Ð0ò !´SØ�L‰L‹N˜4×+Ñ+Ñ,ó6
ä”—‘Ó ñ6!ð 	!r   c                 ó^   — d|j                   v xr d|j                   v xr d|j                   v S )NÚParamÚGradÚLearningRate)Úinput_namesry   s     r   Ú_is_update_opzCollective._is_update_op  s5   € à�r—~‘~Ð%ò 1Ø˜"Ÿ.™.Ð(ò1à "§.¡.Ð0ð	
r   c                 ó¶   — | j                   |j                  v xr@ t        |j                  «       | j                      «      t        t        j
                  «      z  S r   )r   rp   rq   rr   rW   ÚOptimizery   s     r   Ú_is_optimizer_opzCollective._is_optimizer_op  r{   r   N)F)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r0   r/   r.   r6   r7   rw   rz   r�   r„   © r   r   r	   r	      sA   „ Ùò=ò7'òrMò
!ð( ózòxò6Mò!ò

ó!r   r	   c                   ó*   — e Zd ZdZdd„Zd„ Zd„ Zd„ Zy)ÚGradAllReducer
   c                 ó>   — t         j                  | |«       d| _        y )NÚgrad_allreduce)r	   r   r(   ©r   r   s     r   r   zGradAllReduce.__init__&  s   € Ü×Ñ˜D &Ô)Ø$ˆ�	r   c                 óD   — | j                  «        | j                  «        y r   )Ú_insert_scale_loss_grad_opsÚ_insert_allreduce_opsr3   s    r   r/   z%GradAllReduce._transpile_main_program*  s   € Ø×(Ñ(Ô*Ø×"Ñ"Õ$r   c                 ó~  — | j                   j                  «       }t        t        t	        |j
                  «      «      «      D ]y  \  }}| j                  |«      sŒ|j                  |j                  d      }|j                  |dz   dd|id|idd| j                  z  | j                  t        j                  i¬«       Œ{ y)	ú¡
        In order to keep the learning rate consistent in different numbers of
        training workers, we scale the loss grad by the number of workers
        r   r!   ÚscalerF   r?   ç      ð?rA   N)r   rO   ÚreversedÚlistÚ	enumerateÚopsrw   ÚvarsÚoutput_arg_namesÚ
_insert_opr   r   rW   rs   )r   rc   Úidxru   Úloss_grad_vars        r   r�   z)GradAllReduce._insert_scale_loss_grad_ops.  s¯   € ð
 ×!Ñ!×.Ñ.Ó0ˆÜ¤¤Y¨u¯y©yÓ%9Ó :Ö;‰GˆC�Ø×$Ñ$ RÕ(Ø %§
¡
¨2×+>Ñ+>¸qÑ+AÑ B�Ø× Ñ Ø˜!‘GØ Ø Ð/Ø" MÐ2à  t§{¡{Ñ!2Ø×(Ñ(¬&¯/©/ðð !õ 	ñ <r   c                 ó:  — | j                   j                  «       }d}d }t        t        t	        |j
                  «      «      «      D �]L  \  }}| j                  |«      sŒ| j                  |j                  v sŒ2|j                  «       | j                     }t        |«      dk(  rŒ^t        |«      dz  dk(  sJ ‚|}t        dt        |«      d«      D ]Á  }|j                  ||      }	|j                  ||dz         }|	j                  rŒ7||k(  r>|dz  }|j                  |dd|id|i| j                  t         j"                  i¬«       |dz  }|dz   | j$                  z  }|j                  |d	d|id|id
|| j                  t         j"                  i¬«       ŒÃ �ŒO |€y t	        |j
                  «      D ]k  \  }}| j'                  |«      sŒt        | j$                  «      D ];  }|j                  ||z   dd|id|id
|| j                  t         j"                  i¬«       Œ=  y  y )Nrh   r   é   r!   Úc_sync_calc_streamrF   r?   rA   Úc_allreduce_sumr8   rk   )r   rO   r–   r—   r˜   r™   rz   r   rp   rr   r'   r5   rš   rm   rœ   r   rW   rs   r   r„   )
r   rc   r8   Úgradr�   ru   Úop_role_varÚoffsetÚirn   s
             r   r‘   z#GradAllReduce._insert_allreduce_opsB  s%  € Ø×!Ñ!×.Ñ.Ó0ˆØˆØˆÜ¤¤Y¨u¯y©yÓ%9Ó :×;‰GˆC�à×$Ñ$ RÕ(Ø×(Ñ(¨B¯M©MÒ9à Ÿl™l›n¨T×-AÑ-AÑB�ä�{Ó# qÒ(ØÜ˜;Ó'¨!Ñ+¨qÒ0Ð0Ð0à�Ü˜q¤# kÓ"2°AÖ6�AØ!ŸJ™J {°1¡~Ñ6�EØ Ÿ:™: k°!°a±%Ñ&8Ñ9�DØ×+Ò+Ø à ’}Ø !™˜Ø×(Ñ(Ø"Ø!5Ø$'¨ ;Ø%*¨D MØ#'×#3Ñ#3´V·_±_Ð"Eð )ô ð  !™˜ð  '¨™{¨d¯k©kÑ9�GØ×$Ñ$ØØ.Ø # T˜{Ø!&¨ à% wØ ×,Ñ,¬f¯o©oðð %õ 	ò) 7ð <ðV ˆ<Øä  §¡Ö+‰GˆC�Ø×$Ñ$ RÕ(Ü$ T§[¡[Ö1�GØ×$Ñ$Ø˜g™Ø1Ø # T˜{Ø!&¨ à% wØ ×,Ñ,¬f¯o©oðð %õ 	ð  2ñ ñ ,r   N©r    )r…   r†   r‡   rˆ   r   r/   r�   r‘   r‰   r   r   r‹   r‹   #  s   „ Ùó%ò%òó(?r   r‹   c                   ó*   — e Zd ZdZdd„Zd„ Zd„ Zd„ Zy)ÚLocalSGDr
   c                 óL   — t         j                  | |«       d| _        d| _        y )Nz	@SNAPSHOTÚ	local_sgd)r	   r   Úsnapshot_keyr(   rŽ   s     r   r   zLocalSGD.__init__‡  s!   € Ü×Ñ˜D &Ô)Ø'ˆÔØˆ�	r   c                 ó´  — t         j                  | «       | j                  j                  «       }g }|j	                  «       D ]   }|j
                  rŒ|j                  |«       Œ" |D ]o  }|j                  | j                  |j                  «      |j                  dd¬«      }|j                  dd|gid|gi| j                  t        j                  i¬«       Œq y )NT)r;   Úshaper<   Ústop_gradientÚassignrF   r?   rA   )r	   r.   r   rO   rl   rm   ÚappendrQ   Úsnapshot_namer;   r®   rV   r   rW   rX   )r   rc   Únon_dist_paramsrn   Úsnapshots        r   r.   z#LocalSGD._transpile_startup_programŒ  sÎ   € Ü×-Ñ-¨dÔ3à×$Ñ$×1Ñ1Ó3ˆØˆØ×*Ñ*Ö,ˆEØ×'Ó'Ø×&Ñ& uÕ-ð -ó %ˆEØ×'Ñ'Ø×'Ñ'¨¯
©
Ó3Ø—k‘kØ Ø"ð	 (ó ˆHð �O‰OØØ˜e˜W�~Ø  
Ð+Ø×'Ñ'¬¯©Ð8ð	 õ ñ %r   c                 ó    — || j                   z   S r   )r¬   )r   Ú
param_names     r   r²   zLocalSGD.snapshot_name£  s   € Ø˜D×-Ñ-Ñ-Ð-r   c                 ó~  — | j                   j                  «       }g }d}t        t        t	        |j
                  «      «      «      D �][  \  }}| j                  |«      sŒ|j                  |j                  d«      d      }|j                  rŒG|j                  | j                  |j                  «      |j                  dd|j                  ¬«      }|j                  |dz   d|g|gdœd	|gi| j                   t"        j$                  i¬
«       |j                  |dz   dd|id	|i| j                   t"        j$                  i¬
«       |dz   | j&                  z  }|j                  |dz   dd|gid	|gid|| j                   t"        j$                  i¬
«       |j)                  ||f«       �Œ^ t+        | j&                  «      D ]7  }|j-                  ddid	|id|| j                   t"        j$                  i¬
«       Œ9 t        |«      D ]¼  }|d   }|d   }|j-                  dd|gid	|gidd| j.                  z  | j                   t"        j$                  i¬
«       |j-                  d|g|gdœd	|gi| j                   t"        j$                  i¬
«       |j-                  dd|gid	|gi| j                   t"        j$                  i¬
«       Œ¾ y )Nrh   r}   r   T)r;   r®   r<   r¯   Údtyper!   Úelementwise_sub)rF   ÚYr?   rA   r    r¡   rF   é   r¢   r8   rk   r”   r•   r°   )r   rO   r–   r—   r˜   r™   r�   rš   Úinputrm   rQ   r²   r;   r®   r¸   rœ   r   rW   rƒ   r   r±   r5   rV   r   )	r   rc   Úordered_param_snapshotr8   r�   ru   rn   r´   Úparam_snapshots	            r   r/   z LocalSGD._transpile_main_program¦  sâ  € Ø×!Ñ!×.Ñ.Ó0ˆØ!#ÐØˆÜ¤¤Y¨u¯y©yÓ%9Ó :×;‰GˆC�Ø×!Ñ! "Õ%ØŸ
™
 2§8¡8¨GÓ#4°QÑ#7Ñ8�Ø×'Ò'Øà ×+Ñ+Ø×+Ñ+¨E¯J©JÓ7ØŸ+™+Ø $Ø"&ØŸ+™+ð ,ó �ð × Ñ Ø˜!‘GØ*Ø"* °5°'Ñ:Ø" U GÐ,Ø×+Ñ+¬V¯_©_Ð=ð !ô ð × Ñ Ø˜!‘GØ-Ø ˜<Ø" E˜NØ×+Ñ+¬V¯_©_Ð=ð !ô ð # Q™;¨$¯+©+Ñ5�Ø× Ñ Ø˜!‘GØ*Ø % ˜>Ø" U GÐ,à! 7Ø×(Ñ(¬&¯/©/ðð !ô 	ð '×-Ñ-¨u°hÐ.?Ö@ðQ <ôT ˜TŸ[™[Ö)ˆGØ�O‰OØ)Ø˜U�|Ø ˜Ø  '¨4×+;Ñ+;¼V¿_¹_ÐMð	 õ ð *ô 'Ð'=Ö>ˆNØ" 1Ñ%ˆEØ% aÑ(ˆHØ�O‰OØØ˜e˜W�~Ø  Ð(à˜S 4§;¡;Ñ.Ø×$Ñ$¤f§o¡oðð	 ô ð �O‰OØ&Ø&˜Z¨u¨gÑ6Ø  Ð(Ø×'Ñ'¬¯©Ð9ð	 ô ð �O‰OØØ˜e˜W�~Ø  
Ð+Ø×'Ñ'¬¯©Ð9ð	 õ ñ% ?r   Nr§   )r…   r†   r‡   rˆ   r   r.   r²   r/   r‰   r   r   r©   r©   „  s   „ Ùó ò
ò..óMr   r©   c                   ó4   — e Zd ZdZd„ Zd„ Zd„ Zd„ Zd„ Zd„ Z	y)	ÚSingleProcessMultiThreadz*
    single process multi thread mode
    c                 ó4  — t         j                  | d«       d| _        t        t	        j
                  dd«      «      | _        t        t	        j
                  dd«      «      | _        t        t	        j
                  dd«      j                  d«      «      | _
        y )	Nr!   r"   ÚPADDLE_FUSE_ALLREDUCEÚ1ÚPADDLE_LOSS_SCALEÚFLAGS_selected_gpusz0,1,2,3,4,5,6,7r    )r‹   r   r(   rq   ÚosÚgetenvÚfuse_allreduceÚ
loss_scaler'   r&   Úgpu_numsr3   s    r   r   z!SingleProcessMultiThread.__init__û  sq   € Ü×Ñ˜t QÔ'Ø1ˆŒ	Ü!¤"§)¡)Ð,CÀSÓ"IÓJˆÔÜœbŸi™iÐ(;¸SÓAÓBˆŒÜÜ�I‰IÐ+Ð->Ó?×EÑEÀcÓJó
ˆ�r   c           
      óÄ  — d}t        | j                  «      dkD  r5t        | j                  D �ch c]  }|j                  d«      d   ’Œ c}«      }|dkD  rÆ|| _        t	        d«       t	        d| j
                  «       t	        d| j                  «       t	        d| j                  | j                  fz  «       t        | j                  «      D ]K  }| j                  | j                  | j
                  | j                  | j                  || j                  d«       ŒM y d| _        t	        d	«       | j                  j                  «       }|j                  d
ddi¬«       y c c}w )Nr   r!   Ú:ú2begin to _transpile_startup_program for multi-nodeúcurrent_endpoint: útotal endpoints: úrank: %d, ring_id: %dTú3begin to _transpile_startup_program for single-nodeÚc_comm_init_allr8   ©r=   rD   )r'   r   r&   r   Úprintr   r   r   r5   r6   r   r+   rO   rV   )r   Ú	nodes_numÚxr8   rc   s        r   r.   z3SingleProcessMultiThread._transpile_startup_program  s"  € Øˆ	Üˆt�~‰~Ó Ò"Ü°d·n²nÓE±n°˜QŸW™W S›\¨!›_°nÑEÓFˆIà�qŠ=Ø#ˆDŒKÜÐFÔGÜÐ&¨×(=Ñ(=Ô>ÜÐ% t§~¡~Ô6ÜÐ)¨T¯Y©Y¸¿¹Ð,DÑDÔEÜ  §¡Ö-�Ø×'Ñ'Ø×(Ñ(Ø×)Ñ)Ø—N‘NØ—I‘IØØ—N‘NØõñ .ð ˆDŒKÜÐGÔHØ×(Ñ(×5Ñ5Ó7ˆEØ�O‰OÐ!2¸9Àa¸.ˆOÕIùò- Fs   ®Ec                 ó  — | j                  «       }| j                  dk(  r|dk(  ry | j                  r| j                  |«       |dk(  ry | j                  dkD  rt	        d|z  «       | j                  «        y | j                  «        y )Nr   z*begin used fuse_allreduce param count = %s)Ú_get_update_param_countrÉ   r�   rÈ   rÔ   Ú_insert_fuse_allreduce_opsr‘   )r   Ú	param_cnts     r   r/   z0SingleProcessMultiThread._transpile_main_program  sx   € à×0Ñ0Ó2ˆ	Ø�?‰?˜aÒ I°¢NØà�?Š?Ø×,Ñ,¨YÔ7à˜Š>Øà×Ñ Ò"ÜÐ>À)ÑLÔMà×+Ñ+Õ-à×&Ñ&Õ(r   c                 óî  — d}| j                   j                  «       }t        t        t	        |j
                  «      «      «      D ]®  \  }}| j                  |«      sŒ| j                  |j                  vrŒ1|j                  «       | j                     }t        |«      dk(  rŒ]t        |«      dz  dk(  sJ ‚t        dt        |«      d«      D ]&  }|j                  ||      }|j                  rŒ"|dz   }Œ( Œ° |S )z-
        get need update param count
        r   r    r!   )r   rO   r–   r—   r˜   r™   rz   r   rp   rr   r'   r5   rš   rm   )r   Úparam_countrc   r�   ru   r¤   r¦   rn   s           r   rØ   z0SingleProcessMultiThread._get_update_param_count2  sé   € ð ˆØ×!Ñ!×.Ñ.Ó0ˆÜ¤¤Y¨u¯y©yÓ%9Ó :Ö;‰GˆC�Ø×'Ñ'¨Ô+ØØ×#Ñ#¨2¯=©=Ñ8ØØŸ,™,›.¨×)=Ñ)=Ñ>ˆKÜ�;Ó 1Ò$Øä�{Ó# aÑ'¨1Ò,Ð,Ð,Ü˜1œc +Ó.°Ö2�ØŸ
™
 ;¨q¡>Ñ2�Ø×'Ò'ØØ)¨A™o‘ñ	 3ð <ð  Ðr   c                 óâ  — |dkD  rd| j                   z  | j                  z  }nd| j                  z  }t        d|z  «       | j                  j	                  «       }t        t        t        |j                  «      «      «      D ]l  \  }}| j                  |«      sŒ|j                  |j                  d      }|j                  |dz   dd|id|id|| j                  t        j                  i¬«       Œn y	)
r“   r   r•   z,begin _insert_scale_loss_grad_ops scale = %sr!   r”   rF   r?   rA   N)r   rÊ   rÔ   r   rO   r–   r—   r˜   r™   rw   rš   r›   rœ   r   rW   rs   )r   rÚ   r”   rc   r�   ru   rž   s          r   r�   z4SingleProcessMultiThread._insert_scale_loss_grad_opsJ  sà   € ð
 �qŠ=Ø˜$Ÿ+™+Ñ%¨¯©Ñ5‰Eà˜$Ÿ-™-Ñ'ˆEÜÐ<ÀÑFÔGØ×!Ñ!×.Ñ.Ó0ˆÜ¤¤Y¨u¯y©yÓ%9Ó :Ö;‰GˆC�Ø×(Ñ(¨Ô,ØØ!ŸJ™J r×':Ñ':¸1Ñ'=Ñ>ˆMØ×ÑØ�a‘ØØ˜]Ð+Ø Ð.Ø  t×'7Ñ'7¼¿¹ÐIð õ ñ	 <r   c           
      ó°  — | j                   j                  «       }d}d}g }d}t        t        t	        |j
                  «      «      «      D ]æ  \  }}| j                  |«      sŒ| j                  |j                  v sŒ1|j                  «       | j                     }t        |«      dk(  rŒ]t        |«      dz  dk(  sJ ‚|}	t        dt        |«      d«      D ]\  }
|j                  ||
      }|j                  ||
dz         }|j                  rŒ7|	|k(  sŒ=|j                  |«       t        ||	dz   «      }Œ^ Œè |€y| j                   dk(  rÎ|j#                  |dd|d   id|d   i| j$                  t&        j(                  i¬	«       |dz  }|dz   | j*                  z  }|j#                  |d
d|id|id|| j$                  t&        j(                  i¬	«       |dz  }|j#                  |dd|d   id|d   id|| j$                  t&        j(                  i¬	«       |dz  }y|}|j-                  ddgdt.        j0                  j2                  j4                  d¬«      }ddt.        j0                  j2                  j4                  dœ}|j#                  |dd|i||dœ|¬	«       |dz  }|j#                  |dd|id|i| j$                  t&        j(                  i¬	«       |dz  }|dz   | j*                  z  }|j#                  |dd|id|id|| j$                  t&        j(                  i¬	«       |dz  }|j#                  |dd|id|id|| j$                  t&        j(                  i¬	«       |dz  }y)ú;
        insert coalesce_tensor and all reduce ops
        rh   Nr   r    r!   r¡   rF   r?   rA   Úc_allreduce_xsumr8   rk   Úfused_outputFT©r;   r®   r<   r¸   r¯   )Ú	copy_dataÚset_constantr¸   Úcoalesce_tensorÚInput©ÚOutputÚFusedOutputr¢   )r   rO   r–   r—   r˜   r™   rz   r   rp   rr   r'   r5   rš   rm   r±   ÚmaxrÈ   rœ   r   rW   rs   r   rQ   r   rS   rT   ÚFP32)r   rc   r8   r£   Úinput_gradsÚglobal_offsetr�   ru   r¤   r¥   r¦   rn   Úoutput_gradsrá   Úcoalesce_tensor_attrss                  r   rÙ   z3SingleProcessMultiThread._insert_fuse_allreduce_opsa  sÄ  € ð ×!Ñ!×.Ñ.Ó0ˆØˆØˆØˆØˆÜ¤¤Y¨u¯y©yÓ%9Ó :Ö;‰GˆC�à×$Ñ$ RÕ(Ø×(Ñ(¨B¯M©MÒ9à Ÿl™l›n¨T×-AÑ-AÑB�Ü�{Ó# qÒ(ØÜ˜;Ó'¨!Ñ+¨qÒ0Ð0Ð0Ø�Ü˜q¤# kÓ"2°AÖ6�AØ!ŸJ™J {°1¡~Ñ6�EØ Ÿ:™: k°!°a±%Ñ&8Ñ9�DØ×+Ò+Ø Ø “}Ø#×*Ñ*¨4Ô0Ü(+¨M¸6ÀA¹:Ó(F™ñ 7ð <ð$ ˆ<Øà×Ñ !Ò#à×ÑØØ)Ø˜[¨™^Ð,Ø ¨A¡Ð/Ø×'Ñ'¬¯©Ð9ð ô ð ˜QÑˆMØ ‘{ d§k¡kÑ1ˆGØ×ÑØØ'Ø˜[Ð)Ø Ð,Ø  '¨4×+;Ñ+;¼V¿_¹_ÐMð ô ð ˜QÑˆMà×ÑØØ)Ø˜[¨™^Ð,Ø ¨A¡Ð/Ø  '¨4×+;Ñ+;¼V¿_¹_ÐMð ô ð ˜QÑ‰Mð 'ˆLà ×+Ñ+Ø#Ø�cØ!Ü—l‘l×*Ñ*×/Ñ/Ø"ð ,ó ˆLð "Ø %ÜŸ™×-Ñ-×2Ñ2ñ%Ð!ð
 ×ÑØØ&Ø Ð-Ø#/ÀÑMØ+ð ô ð ˜QÑˆMà×ÑØØ)Ø˜\Ð*Ø Ð-Ø×'Ñ'¬¯©Ð9ð ô ð ˜QÑˆMØ ‘{ d§k¡kÑ1ˆGØ×ÑØØ&Ø˜\Ð*Ø Ð-Ø  '¨4×+;Ñ+;¼V¿_¹_ÐMð ô ð ˜QÑˆMð ×ÑØØ)Ø˜\Ð*Ø Ð-Ø  '¨4×+;Ñ+;¼V¿_¹_ÐMð ô ð ˜QÑ‰Mr   N)
r…   r†   r‡   rˆ   r   r.   r/   rØ   r�   rÙ   r‰   r   r   rÀ   rÀ   ö  s'   „ ñò
òJò6)ò&ò0ó.nr   rÀ   c                   ó6   — e Zd ZdZd	d„Zd„ Zd„ Zd„ Zd„ Zd„ Z	y)
ÚMultiThreadr
   c                 óÄ   — t         j                  | |«       d| _        || _        d| _        t        j                  dd«      j                  d«      }t        |«      | _	        y )Nr#   é€   rÅ   z0,1,2,3,4,5,6,7,8r    )
r‹   r   r(   Ú
trans_modeÚfuse_grad_size_in_numrÆ   rÇ   r&   r'   Úgpu_num)r   r   rô   rÊ   s       r   r   zMultiThread.__init__Õ  sU   € Ü×Ñ˜t VÔ,ØˆŒ	Ø$ˆŒØ%(ˆÔ"Ü—9‘9Ð2Ð4GÓH×NÑNØó
ˆô ˜8“}ˆ�r   c                 ó,  — t        | j                  «      dkD  r¿t        d«       t        d| j                  «       t        d| j                  «       t        d| j                  | j
                  fz  «       t        | j
                  «      D ]K  }| j                  | j                  | j                  | j                  | j                  || j                  d«       ŒM y d| j                  v rut        d«       | j                  j                  «       }|j                  d	t        t        t        t!        j"                  d
«      j%                  d«      «      «      ddœ¬«       y t        d«       | j                  j                  «       }|j                  d	ddi¬«       y )Nr!   rÍ   rÎ   rÏ   rÐ   TÚxpuz:begin to _transpile_startup_program for single-node in XPUrÒ   rÅ   r    r   )Údevicesr8   rÓ   rÑ   r8   )r'   r   rÔ   r   r   r   r5   r6   r   r+   rô   rO   rV   r—   Úmaprq   rÆ   rÇ   r&   )r   r8   rc   s      r   r.   z&MultiThread._transpile_startup_programß  sP  € Üˆt�~‰~Ó Ò"ÜÐFÔGÜÐ&¨×(=Ñ(=Ô>ÜÐ% t§~¡~Ô6ÜÐ)¨T¯Y©Y¸¿¹Ð,DÑDÔEÜ  §¡Ö-�Ø×'Ñ'Ø×(Ñ(Ø×)Ñ)Ø—N‘NØ—I‘IØØ—N‘NØõñ .ð ˜Ÿ™Ñ'ÜØPôð ×,Ñ,×9Ñ9Ó;�Ø—‘Ø*ä#'ÜÜ #¤R§Y¡YÐ/DÓ%E×%KÑ%KÈCÓ%Póó$ð
 $%ñð  õ 
ô ÐKÔLØ×,Ñ,×9Ñ9Ó;�Ø—‘Ð%6¸yÈ!¸n�ÕMr   c                 óø  — | j                  «        | j                  dk(  rJt        d«       | j                  | j                  z  | _        | j                  «        | j                  «        y | j                  dk(  rt        d«       | j                  «        y | j                  dk(  r<t        t        j                  d«      j                  d«      «      dk(  rt        d	«       y t        d
«       | j                  «        y )NÚ
all_gatherz%begin to transpile in all-gather modeÚfuse_all_reducez*begin to transpile in fuse all-reduce modeÚall_reduce_xpurÅ   r    r!   zHskip transpile in all-reduce-xpu mode when number of devices is only onez%begin to transpile in all-reduce mode)r�   rô   rÔ   r   rö   Úallgather_ranksÚ_insert_allgather_opsÚ_update_adam_opsrÙ   r'   rÆ   rÇ   r&   r‘   r3   s    r   r/   z#MultiThread._transpile_main_program  sÃ   € Ø×(Ñ(Ô*Ø�?‰?˜lÒ*ÜÐ9Ô:Ø#'§;¡;°·±Ñ#=ˆDÔ Ø×&Ñ&Ô(Ø×!Ñ!Õ#Ø�_‰_Ð 1Ò1ÜÐ>Ô?Ø×+Ñ+Õ-à�O‰OÐ/Ò/Ü”B—I‘IÐ3Ó4×:Ñ:¸3Ó?Ó@ÀAÒEäØZõô Ð9Ô:Ø×&Ñ&Õ(r   c                 ó  — | j                   j                  «       }d}d}t        t        t	        |j
                  «      «      «      D �]¹  \  }}| j                  |«      sŒ| j                  |j                  v sŒ2|j                  «       | j                     }t        |«      dk(  rŒ^t        |«      dz  dk(  sJ ‚|}t        dt        |«      d«      D �]-  }|j                  ||      }	|j                  ||   dz   | j                  gt        |	j                  «      z   dt         j"                  j$                  j&                  d¬«      }
|j                  ||d	z         }|	j(                  rŒ—||k(  r>|d	z  }|j+                  |d
d|id|i| j,                  t.        j0                  i¬«       |d	z  }|d	z   | j2                  z  }|j+                  |dd|id|
id| j                  d|| j,                  t.        j0                  i¬«       �Œ0 �Œ¼ |€yt	        |j
                  «      D ]k  \  }}| j5                  |«      sŒt        | j2                  «      D ];  }|j+                  ||z   dd|id|id|| j,                  t.        j0                  i¬«       Œ=  y y)z9
        insert allgather op to the main_program
        rh   Nr   r    Ú
_allgatherFTrâ   r!   r¡   rF   r?   rA   Úc_allgatherr   r8   rk   )r   rO   r–   r—   r˜   r™   rz   r   rp   rr   r'   r5   rš   rQ   rÿ   r®   r   rS   rT   rë   rm   rœ   r   rW   rs   r   r„   )r   rc   r8   r£   r�   ru   r¤   r¥   r¦   rn   Únew_grad_vars              r   r   z!MultiThread._insert_allgather_ops  s‰  € ð ×!Ñ!×.Ñ.Ó0ˆØˆØˆÜ¤¤Y¨u¯y©yÓ%9Ó :×;‰GˆC�à×$Ñ$ RÕ(Ø×(Ñ(¨B¯M©MÒ9à Ÿl™l›n¨T×-AÑ-AÑB�Ü�{Ó# qÒ(ØÜ˜;Ó'¨!Ñ+¨qÒ0Ð0Ð0à�Ü˜q¤# kÓ"2°A×6�AØ!ŸJ™J {°1¡~Ñ6�EØ#(×#3Ñ#3Ø(¨™^¨lÑ:Ø#×3Ñ3Ð4´t¸E¿K¹KÓ7HÑHØ$)Ü"Ÿl™l×2Ñ2×7Ñ7Ø&*ð $4ó $�Lð !Ÿ:™: k°!°a±%Ñ&8Ñ9�DØ×+Ò+Ø à ’}Ø !™˜Ø×(Ñ(Ø"Ø!5Ø$'¨ ;Ø%*¨D MØ#'×#3Ñ#3´V·_±_Ð"Eð )ô ð  !™˜ð  '¨™{¨d¯k©kÑ9�GØ×$Ñ$ØØ*Ø # T˜{Ø!&¨Ð 5à$ d×&:Ñ&:Ø% wØ ×,Ñ,¬f¯o©oðð %ö 
ò7 7ð <ðd ˆ<Øä  §¡Ö+‰GˆC�Ø×$Ñ$ RÕ(Ü$ T§[¡[Ö1�GØ×$Ñ$Ø˜g™Ø1Ø # T˜{Ø!&¨ à% wØ ×,Ñ,¬f¯o©oðð %õ 	ð  2ñ ñ ,r   c                 ó  — | j                   j                  «       }t        t        t	        |j
                  «      «      «      D �]<  \  }}| j                  |«      sŒ|}|j                  dk7  r|j                  dk7  rŒ:|j                  d«      d   }|j                  |j                  d«      d      |j                  |j                  d«      d      |j                  |j                  d«      d      |j                  |j                  d«      d      |j                  |j                  d«      d      |j                  |j                  d	«      d      d
œ}|j                  |j                  d«      d      |j                  |j                  d«      d      |j                  |j                  d«      d      |j                  |j                  d«      d      |j                  |j                  d«      d      dœ}|j                  d«      |j                  d«      |j                  d«      |j                  d«      |j                  d«      dœ}t        | j                  «      D �	cg c]r  }	|j                  |dz   t        |	«      z   |j                  |j                  d«      d      j                   dt"        j$                  j&                  j(                  d¬«      ‘Œt }
}	|j+                  |dd|j                  |j                  d«      d   dz      id|
i| j                  ddœ¬ «       |d!z  }t        | j                  «      D ]/  }	|
|	   |d"<   |j+                  ||j                  |||¬ «       |d!z  }Œ1 |j-                  |«       �Œ? y#c c}	w )$zC
        remove the original adam op, and add new adam ops
        ÚadamÚlambr}   r   r   ÚMoment1ÚMoment2ÚBeta1PowÚBeta2Pow)r}   r   r	  r
  r  r  ÚParamOutÚ
Moment1OutÚ
Moment2OutÚBeta1PowOutÚBeta2PowOut)r  r  r  r  r  ÚepsilonÚbeta1Úbeta2Ú	lazy_modeÚmin_row_size_to_use_multithread)r  r  r  r  r  Ú_FTrâ   r&   rF   r  r?   )ÚnumÚaxisrA   r!   r~   N)r   rO   r–   r—   r˜   r™   r„   r=   r¼   rš   ÚoutputÚattrr5   rÿ   rQ   r%   r®   r   rS   rT   rë   rœ   Ú
_remove_op)r   rc   r�   ru   r¥   r¶   rB   rC   rD   r¦   Ú
split_varss              r   r  zMultiThread._update_adam_opsf  sH  € ð ×!Ñ!×.Ñ.Ó0ˆä¤¤Y¨u¯y©yÓ%9Ó :×;‰GˆC�Ø×$Ñ$ RÕ(Ø�à—G‘G˜vÒ%¨"¯'©'°VÒ*;àØŸX™X gÓ.¨qÑ1�
à"ŸZ™Z¨¯©°Ó(9¸!Ñ(<Ñ=Ø$)§J¡J¨r¯x©x¸Ó/GÈÑ/JÑ$KØ$Ÿz™z¨"¯(©(°9Ó*=¸aÑ*@ÑAØ$Ÿz™z¨"¯(©(°9Ó*=¸aÑ*@ÑAØ %§
¡
¨2¯8©8°JÓ+?ÀÑ+BÑ CØ %§
¡
¨2¯8©8°JÓ+?ÀÑ+BÑ Cñ�ð !&§
¡
¨2¯9©9°ZÓ+@ÀÑ+CÑ DØ"'§*¡*¨R¯Y©Y°|Ó-DÀQÑ-GÑ"HØ"'§*¡*¨R¯Y©Y°|Ó-DÀQÑ-GÑ"HØ#(§:¡:¨b¯i©i¸Ó.FÀqÑ.IÑ#JØ#(§:¡:¨b¯i©i¸Ó.FÀqÑ.IÑ#Jñ�ð  "Ÿw™w yÓ1ØŸW™W WÓ-ØŸW™W WÓ-Ø!#§¡¨Ó!5Ø79·w±wØ9ó8ñ�ô" # 4×#7Ñ#7Ô8ó	ñ 9˜ð ×$Ñ$Ø'¨#Ñ-´°A³Ñ6Ø#Ÿj™j¨¯©°'Ó):¸1Ñ)=Ñ>×DÑDØ$)Ü"Ÿl™l×2Ñ2×7Ñ7Ø&*ð %õ ð 9ð ð 	ð × Ñ ØØ à˜UŸZ™Z¨¯©°Ó(9¸!Ñ(<¸|Ñ(KÑLðð # JÐ/Ø"&×"6Ñ"6ÀÑBð !ô ð ˜!‘�ä˜t×3Ñ3Ö4�AØ%/°¡]�F˜6‘NØ×$Ñ$ØØŸW™WØ%Ø 'Ø#ð %ô ð ˜a‘K‘Fð 5ð × Ñ  Ö(ñA <ùò@	s   É A7Nc                 ó\  — | j                   j                  «       }d| j                  z  }d}g }t        |j                  «      D ]Ù  }| j                  |«      sŒ| j                  |j                  v sŒ.|j                  «       | j                     }t        |«      dk(  rŒZt        |«      dz  dk(  sJ d«       ‚t        dt        |«      d«      D ]O  }||   }|j                  |«      }	||dz      }
|j                  |
«      }|	j                  rŒ?|j                  |«       ŒQ ŒÛ |€yg }d}|D ]m  }t        |«      dk(  s*t        |d   «      | j                  k(  s|j                  |k7  r|j                  |g«       |j                  }ŒZ|d   j                  |«       Œo g }t!        |j                  «      D ]½  \  }}| j#                  |«      sŒ|D ]   }|j%                  t'        j(                  d|d   j*                  › �«      |d   j                  dd	¬
«      }|j                  |«       |j-                  |dd|i||dœdd	dd	d|d   j                  | j.                  t0        j2                  i¬«       Œ¢  n t!        |j                  «      D ]‹  \  }}| j#                  |«      sŒ|D ]n  }|j-                  |dd|id|id|dd| j.                  t0        j2                  i¬«       |j-                  |dd|id|i| j.                  t0        j2                  i¬«       Œp  n t        |«      dk(  r|j5                  «        yt!        |j                  «      D ]T  \  }}| j#                  |«      sŒ|j-                  |dd|d   id|d   id|| j.                  t0        j2                  i¬«        n |j5                  «        y)rß   r   Nr    zRvars need to be one param var followed by one grad var, but got odd number of varsr!   rh   ÚFusedOutput_FT)r;   r¸   r<   r¯   rå   ræ   rç   rã   Ú	use_alignr¸   rA   r¢   rF   r?   r8   Úuse_calc_streamr¡   rk   )r   rO   r   r–   r™   rz   r   rp   rr   r'   r5   Úvarrm   r±   rõ   r¸   r˜   r„   rQ   r   rR   r;   rœ   r   rW   rs   Ú_sync_with_cpp)r   rc   r8   r£   Úparam_gradsru   r¤   r¦   r¶   rn   Ú	grad_nameÚsegmentsÚ
last_dtyper"  Ú
fused_varsr�   ÚsegmentÚtmp_varÚ	fused_vars                      r   rÙ   z&MultiThread._insert_fuse_allreduce_ops®  sÐ  € ð ×!Ñ!×.Ñ.Ó0ˆØ�d—k‘k‘/ˆØˆØˆä˜5Ÿ9™9Ö%ˆBà×$Ñ$ RÕ(Ø×(Ñ(¨B¯M©MÒ9à Ÿl™l›n¨T×-AÑ-AÑB�Ü�{Ó# qÒ(ØÜ˜;Ó'¨!Ñ+¨qÒ0ð ð1óÐ0ô ˜q¤# kÓ"2°AÖ6�AØ!,¨Q¡�JØ!ŸI™I jÓ1�EØ +¨A°©EÑ 2�IØ Ÿ9™9 YÓ/�DØ×+Ò+Ø Ø×&Ñ& tÕ,ñ 7ð &ð( ˆ<ØàˆØˆ
ãˆCä�H“ Ò"Ü�x ‘|Ó$¨×(BÑ(BÒBØ—9‘9 
Ò*à—‘  Ô&Ø ŸY™Y‘
à˜‘×#Ñ# CÕ(ð ð ˆ
Ü  §¡Ö+‰GˆC�Ø×$Ñ$ RÕ(Û'�Gà#×.Ñ.Ü(×1Ñ1Ø*¨7°1©:¯?©?Ð*;Ð<óð & a™j×.Ñ.Ø$)Ø&*ð /ó �Gð ×%Ñ% gÔ.Ø×$Ñ$ØØ.Ø '¨Ð1Ø+2À7Ñ Kà'¨Ø'¨Ø# W¨Q¡Z×%5Ñ%5Ø ×,Ñ,¬f¯o©oð	ð %õ ð  (ñ. ð3 ,ô8 ! §¡Ö+‰GˆC�Ø×$Ñ$ RÕ(Û!+�IØ×$Ñ$ØØ.Ø # YÐ/Ø!&¨	Ð 2à% wØ-¨uØ ×,Ñ,¬f¯o©oðð %ô 
ð ×$Ñ$ØØ1Ø # YÐ/Ø!&¨	Ð 2Ø#×/Ñ/´·±ÐAð %õ ð ",ñ& ð+ ,ô. ˆz‹?˜aÒØ× Ñ Ô"Øô ! §¡Ö+‰GˆC�Ø×$Ñ$ RÕ(Ø× Ñ ØØ-Ø ¨A¡Ð/Ø" J¨q¡MÐ2à! 7Ø×(Ñ(¬&¯/©/ðð !ô 	ñ ð ,ð 	×ÑÕr   N)r!   Ú
all_reduce)
r…   r†   r‡   rˆ   r   r.   r/   r   r  rÙ   r‰   r   r   rñ   rñ   Ò  s*   „ Ùó%ò%NòN)ò*IòVF)óPtr   rñ   )rÆ   rZ   Úpaddle.baser   Ú5paddle.distributed.fleet.base.private_helper_functionr   Úpaddle.frameworkr   Úpaddle.staticr   r   r   rW   r	   r‹   r©   rÀ   rñ   r‰   r   r   Ú<module>r1     sv   ðó 
ã Ý #õõ "ß Gà	×	(Ñ	(×	/Ñ	/€÷D!ñ D!ôN^�Jô ^ôBoˆzô oôdY˜}ô YôxP�-õ Pr   