
    ͑i                       S SK Jr  S SKrS SKrS SKJr  S SKrS SKJ	r	J
r
JrJrJrJrJrJrJrJrJrJrJrJrJrJrJrJrJrJrJrJrJrJ r J!r!J"r"J#r#J$r$J%r%J&r&J'r'J(r(  S SK)J*r*  S SK+J,r,J-r-  \(       a  S SK.J/r/  S SKJ0r0   / S	Qr1S
 r2S r3S r4S r5S r6S r7\
" 5       \
" 5       4S jr8S r9S r:S r;  S         SS jjr<  S         SS jjr=      S                 SS jjr>SS jr?g)    )annotationsN)TYPE_CHECKING) State	ValueDictValueSet_as_listall_input_stop_gradient_trueall_output_grad_noneall_stop_gradient_trueargument_to_value
check_typedynamic_shape_prim_vjp_guardget_grad_semantic_infoget_real_op_inputsget_real_op_outputsget_split_opinverse_sort_opis_builtin_opis_control_flowis_inplace_net
op_has_vjpparent_total_ops	remove_opremove_useless_full_like_opsreturn_map_valuereturn_map_value_listsome_in_setupdate_if_output_stopgradient"update_no_grad_set_by_stopgradientupdate_tuple_pop_origin_inputs update_while_output_stopgradientvalue_in_blockwarning_oncewhile_prune_check)pir_op_name_guard)build_pipe_for_blockget_used_external_value)Sequence)Value)gradcalc_gradientcalc_gradient_helperc                `   [         R                  R                  SS9   [         R                  R	                  U5      (       a7  [         R                  R                  5       //UR                  U'    S S S 5        g UR                  5       (       a4  [         R                  R                  UU 5      nUR                  5       nU/nOrUR                  5       (       a  [        S5      e[         R                  " UU UR                  S9nUR                  5       nUR                  S5      R                  5       nXh/n[!        UUR"                  UR                  5          U5        UR                  5       (       a  U/UR                  U'   OU//UR                  U'   UsS S S 5        $ ! , (       d  f       g = f)NFenablezPThis kind of scene, where VectorType grad be fulled with zeros should not occur.)dtype   )paddleamp	auto_castpiris_fake_value
fake_valuevalue_to_valuegradis_dense_tensor_array_type_C_opscreate_array_likeget_defining_op
is_combine
ValueError	full_liker0   operand_sourceupdate_bwdop_structureop_to_opgrad)	float_value
copy_valuevaluestatebackward_ops
value_gradfull_like_opbackward_ops_full_ops	            [/var/www/html/banglarbhumi/venv/lib/python3.13/site-packages/paddle/autograd/ir_backward.pyappend_full_likerM   K   sy   			U		+::##E**06

0E0E0G/H.IE$$U+ 
,	+ 002288J &557L)NM""$$b   )) &&J
 &557L"11!4DDFG)3Mu4467	

   ""/9lE$$U+0:|nE$$U+C 
,	+	+s   AF:DF
F-c                   [         R                  R                  5       S   n[         R                  R	                  SS9   / nUR
                  U    H)  nUS   c  M  UR                  [        US   U5      5        M+     SSKJ	n  / n	U" 5       R                  (       a  U" 5       R                  S;   a  U R                  5       S:X  at  UR                  [         R                  [         R                  4;   aF  U V
s/ s H  n
[         R                   " U
S5      PM     nn
U V
s/ s H  oR#                  5       PM     n	n
[%        U5      S:X  aE  UR
                  U    H!  nUR&                  U   R                  U5        M#     / UR
                  U'   GO-[%        U5      U::  a  US   nS	n/ nU[%        U5      :  aW  [         R(                  R+                  XU   5      nUR                  UR#                  5       5        US	-  nU[%        U5      :  a  MW  [-        X2R.                  U    X-   5        UR
                  U    H!  nUR&                  U   R                  U5        M#     U//UR
                  U'   GOM[%        U5      S	:X  a_  [-        UUR.                  U    U	5        UR
                  U    H!  nUR&                  U   R                  U5        M#     U/UR
                  U'   OUR1                  5       (       a   [         R(                  R3                  U5      nO[         R4                  " U5      nUR#                  5       nUR7                  S5      R#                  5       n[-        UUR.                  U    / U	QUPUP5        UR
                  U    H!  nUR&                  U   R                  U5        M#     U//UR
                  U'   S S S 5        g s  sn
f s  sn
f ! , (       d  f       g = f)
NFLAGS_max_inplace_grad_addFr.   r   )amp_global_state)float16bfloat6zbuiltin.parameterfloat32r1   )r2   	framework_global_flagsr3   r4   r8   appendr   paddle.amp.auto_castrP   use_master_grad	amp_dtypenamer0   rQ   bfloat16castr<   lenvalue_to_sumvaluegradr:   add_rA   rB   r9   add_n_arrayadd_nr@   )oprE   rF   rG   bwd_value_to_block_argument_map_MAX_ADD_NUM_
add_n_listitemrP   cast_opvtmp
grad_valueindexgrad_op_listadd_n_valueadd_n_op
combine_ops                     rL   append_add_nrp   p   sm    $$224$M 
		U		+ 
,,U3DAw"!!$T!W.MN 4 	:.. ",,0FF	00@@=GHZ&++a3ZJH4>?Jq((*JG?z?a//6++E299#> 7.0E$$U+_-#AJEL#j/)#]]//
u<MN
##J$>$>$@A
 #j/) #004g6L //6++E299#> 70:|nE$$U+_!"""2&
 //6++E299#> 7/9lE$$U+//11$mm77
C$ll:6"224H!003CCEJ"""2&0'0:0x0 //6++E299#> 70;}oE$$U+E 
,	+( I?+ 
,	+s8   OBO7!OOO7COF/O
O
Oc                Z    U H%  nU R                  U5        UR                  U5        M'     g N)rV   )rG   op_to_opgrad_listrl   grad_ops       rL   rA   rA      s(    G$  )      c                t    [        X45       H)  nU R                  X%   5        UR                  X%   5        M+     g rr   )rangerV   )rG   rs   rl   stedis         rL   update_bwdop_structure_r{      s2     2]LO,  1 ru   c                   U (       d  S/[        U5      -  n [        U 5      [        U5      :w  a  [        S5      eSS jn/ n[        U 5       H  u  pVX   nUc  [        SXwX$5      nXU'   M  U" Xv5      (       d+  [        SU SUR                   SU SUR                   35      eUR
                  UR
                  :w  a6  [        R                  " SU SUR
                   S	U SUR
                   35        UR                  5       n	[        UUR                  UR                  5          U	/5        U//UR                  U'   M     Un
[        5       nU GH  nX{;   a  M  UR                  5       R                  5        H  nUR                  5       (       a  M  XR                  ;   a  UR                  U5        M<  [         R"                  R%                  U5      (       a/  [         R"                  R'                  5       //UR                  U'   M  [        S
XX$5      nUR                  U5        U
R)                  U5        XR                  ;  d  M  U//UR                  U'   M     GM     X
U4$ )aR  
if grad_outputs is none, add fill_1 op to create grad_outputs,
else check whether outputs shape and dtype is same to grad_outputs, otherwise raise error.

if only part of op's outputs in outputs, add fill_0 op to create other grad_outputs.
eg: split.

update value_to_valuegrad and op_to_opgrad.

return complete_outputs, backward_ops.

Nz7grad_outputs should have the same length of as outputs.c                    [        U R                  5      [        UR                  5      :w  a  g[        U R                  UR                  5       H  u  p#US:X  d  US:X  a  M  X#:w  d  M    g   g)NFT)r]   shapezip)outputr*   o_dimg_dims       rL   _check_shape*prepare_grad_outputs.<locals>._check_shape   sV    v||DJJ/djj9LE{erk~ : ru   g      ?zThe shape of grad_output[z] z+ should be the same as the shape of output[zThe dtype of grad_output[z$ is not same as the dtype of output[        )returnbool)r]   r>   	enumeraterM   r   r0   warningswarnr<   rA   rB   r8   r   resultsr=   addr2   r5   r6   r7   rV   )grad_outputsoutputsrF   r   rG   rz   r*   r   rj   feedopcomplete_outputsvisited_outputopresults                rL   prepare_grad_outputsr      s]    vG,
<CL(E
 	
	 L\* <)VUJ )O-- /s"TZZL@klmknnpqwq}q}p~  ||tzz)/s"TZZL@defdggijpjvjviwx ))+F"""6#9#9#;<
 26xE$$V,1 +6 ZN#..088:H""$$333""8,::++H55..01:E,,X6 "2X"J #&&x0$++H5'?'???Il^00:' ; 0 <77ru   c                L   S/[        U 5      -  nS/[        U 5      -  nU(       a  [        U 5       Hs  u  pg[        [        U5      U5      (       a  SXV'   M%  [        [	        U5      U5      (       a0  SXV'   [        U5       H  nX;  d  M
  UR                  U5        M     Mo  SXF'   Mu     [        [        [        U 5      5      5       HW  u  pg[        [        U5      U5      (       a0  SXV'   [	        U5       H  n	X;  d  M
  UR                  U	5        M     MO  SXV'   SXF'   MY     [        U 5      n
[        U
5       H}  u  pgXV   SL d  M  UR                  5        H[  nUR                  5       (       aC  UR                  5       R                  5       nX;   a  XZR                  U5         SL a  SXV'   MW  MY  M[  M]     M     [        [        U 5      5       Vs/ s H  odU   (       d  M  X   PM     nn[        [        U 5      5       Vs/ s H  oeU   (       a  M  X   PM     nnX4$ s  snf s  snf )z
prune ops which do not in the path from inputs_set to outputs_set,
prune ops which do not in the path from outputs_set to inputs_set,

pruned op in total_ops is uneffective_ops, else is effective_ops

TF)r]   r   r   r   r   r   reversedlistr   has_one_use	first_useownerrk   rw   )	total_ops
inputs_setoutputs_setno_grad_setintersection_op_flagsunion_op_flagsrz   rb   rE   operandtotal_ops_listresultnext_opeffective_opsuneffective_opss                  rL   	prune_opsr   #  s    "FS^3Ws9~-N y)EA.r2J??$(!-b1:>>$(!04E/"u- 5 ,1%( * $y345*2.<< $N-b1-OOG, 2 !&N',!$ 6 )_N>*%**,%%''$..0668G,*+?+?+HI  -1)  -  ' + $C	N33Q7O	3   $C	N33!;L	3   ))s   HH>H!H!c                  ^^^^	^
^A^B^C UU	U
UBU4S jmBU
UAU4S jmAUUC4S jmCU4S jnUU	U
U4S jn[        U5      S:  a  US   R                  5       S:X  av  US   nU R                  5       S	:X  a  UR                  5       SS
 nOUR                  5       n[        U R	                  5       U5       H  u  nnUTR
                  U'   M     US
S nOUn[        U5      (       a  [        U5      nO[        U5      n/ nU H@  nUR                  5       S:w  d  M  UR                  5       S:w  d  M/  UR                  U5        MB     U   / nU GH  n[        U5      (       G	a  TB" U5      u  nnnTA" U5      u  nnUR                  5       S:X  GaU  UR                  S5      R                  5       nUR                  S5      R                  5       (       a  [        UU5         [         R"                  R$                  R'                  UUUUU5      nS
S
S
5        UR(                  S   nUR                  U5        UR                  U5        UR                  U5        [+        TTR,                  U   U/5        [        USS
 WSS
 5       H  u  nnUS   T
US   '   M     GMM  [+        TTR,                  U   UR                  S5      R/                  5       R1                  5       /5        GM  [        U5      S:X  d   [3        U5      (       d  [5        U5      (       a  UR                  5       S;  a  GM  [7        U5      (       a  UR                  5       S;  a  GM  UR                  5       S:X  Ga  [9        U5      n UR;                  5        H  n![=        U!5        M     UR?                  5       RA                  5       n"UR?                  5       RC                  5       n#/ n$/ n%U"R(                  S   R                  5       S:X  aR  U"R(                  S   R	                  5        H1  n&U$R                  U&/5        U%R                  U&RD                  /5        M3     / n'/ n(U#R(                  S   R                  5       S:X  aR  U#R(                  S   R	                  5        H1  n&U'R                  U&/5        U(R                  U&RD                  /5        M3     U$/ :w  d  U'/ :w  a  UU$-   U'-   nUU%-   U(-   n[        UU5         [         R"                  R$                  R'                  UUUUU5      n)S
S
S
5        UR(                  S   n*[+        TTR,                  U   U*/5        / n+[        UR;                  5       U*R;                  5       5       H  u  n,n-TRG                  U,5      n.U  HE  n/U/TRH                  ;   d  M  TRH                  U/   RG                  5       n0U+R                  U/U045        MG     / n1T
RG                  5       n2[K        UUSS
  V3s/ s H  n3U3S   PM
     sn3W) V4s/ s H  n4U4S   PM
     sn4U,U-U,R(                  TU1U.U2S9
  U+ H  n5U5S   TRH                  U5S   '   M     M     [M        U*U*R?                  5       RA                  5       R(                  S   U*R?                  5       RC                  5       R(                  S   5        U+ H  n5/ TRH                  U5S   '   M     U$/ :w  d  U'/ :w  a-  [O        U$5      n$[O        U'5      n'U SS
 U$-   U'-   n U" W)U 5        GM  TC" UW)U 5        GM  UR                  5       S	:X  Gah  [9        U5      n URQ                  5       RS                  5       n6TRG                  U65      n.[U        [W        U65      5       H  u  n7n3U3U.RH                  ;   a+  [        U.RH                  U3   5      S:  a  [Y        UU3TTT	5        U3U.RH                  ;  d  U.RH                  U3   / :X  a  [[        SU3U3U.T5        U.RH                  U3   S   n8TRH                  U3    H!  n9TR\                  U3   R                  U95        M#     / TRH                  U3'   UR                  [_        U8T	5      5        M     [=        U65        [        UU5         [         R"                  R$                  R'                  UUUUU5      n)S
S
S
5        UR(                  S   n*[+        TTR,                  U   U*/5        [a        U*5      u  n:n;U;Rc                  T	5        T
RG                  5       n2U*RQ                  5       RS                  5       n</ n1[K        UU V3s/ s H  n3U3S   PM
     sn3W) V4s/ s H  n4U4S   PM
     sn4U6U<U6R(                  TU1U.U;U25        [e        U*U<R(                  S   5        TC" UU)U 5        GM;  UR                  5       S:X  a  [        UR(                  5      n=[        UU5         [         R"                  R$                  R'                  UUUUU5      n)S
S
S
5        [        UR(                  5      n>[g        TTR,                  U   UR(                  U=U>5        TC" UW)[9        U5      5        GM  [        UR(                  5      n=[        UU5         [i        UR                  5       S-   5         [         R"                  R$                  R'                  UUUUU5      n)S
S
S
5        S
S
S
5        [        UR(                  5      n>[g        TTR,                  U   UR(                  U=U>5        TC" UW)UR                  5       5        G	M  URk                  5       S:X  a  URm                  5       S:w  d(  UR                  5       S:X  d  UR                  5       S:X  ah  UR	                  5        HQ  n?U?TRH                  ;  a  M  [        TRH                  U?   5      S:  a  [Y        UU?TTT	5        MB  / TR,                  U'   MS     G
M  Sn@UR	                  5        H  n?U?RD                  (       a  M  Sn@M     [o        U5      (       dH  [         R$                  Rq                  U5      (       d$  W@(       d  [s        SUR                  5        S35      e/ TR,                  U'   GM     X4:w  a  [u        U5      (       aZ  [w        UUS   T5        US   Ry                  5       Rw                  US   5        US   Ry                  5       Rw                  US   5        U" UU URz                  UU5        S
S
S
5        g
! , (       d  f       G
N= f! , (       d  f       GN= fs  sn3f s  sn4f ! , (       d  f       GN= fs  sn3f s  sn4f ! , (       d  f       GN\= f! , (       d  f       GN= f! , (       d  f       GN= f! , (       d  f       g
= f)a  
add grad_op in order of topological inverse sort
    eg:
    from :op1 -> v1 -> op2 -> v2 -> op3 -> v3
    to: og1_g <- v1_g <- op2_g <- v2_g <- op3_g <- v3_g

if op has grad_op, prepare its grad_op's inputs by value_to_valuegrad,
    eg:
    value_to_valuegrad[v3] = [[v3_g]];
    v2_g = call_vjp(op3, [[v2]], [[v3]],[[v3_g]], [[v2_stopgradient]])


special pattern:
    v11 -> combine_op -> v1 -> op -> v3
    v12 ->
                         v2 ->
    value_to_valuegrad[v3] = [[v3_g]]

    v1 is inside python api, we don't describe it in backward process(state)
    so v1_grad is inside vjp, we don't describe it in backward process(state)
    [[v11_g, v12_g], v2_g] = call_vjp(op, [[v11, v12]], [[v3]],[[v3_g]], [[v11_stopgradient, v12_stopgradient], v2_stop_gradient])


    op_vjp is:
    v11_g <- split_op <- v1_g <- op_g <- v3_g
    v12_g <-
                         v2_g <-

    value_to_valuegrad[v11] = [[v11_g]]
    value_to_valuegrad[v12] = [[v12_g]]
    value_to_valuegrad[v2] = [[v2_g]]

if op don't has grad_op:
    if it don't has input and it's output has more than
    one output_grad, add sumop for grad aggregation.
    (eg: full op and parameter op etc.)

    else continue to next op.
c                  > S/U R                  5       -  n/ n/ nU R                  5       S:X  a  U R                  S5      /nO7U R                  5       S:X  a  U R                  S5      /nOU R                  5       n[	        U5       GHw  u  pV[        UT5      /n[        UTR                  5      nUTR                  ;   a+  [        TR                  U   5      S:  a  [        U UTTT5        UTR                  ;  d)  TR                  U   / :X  d  TR                  U   S   S   c  UR                  5       (       dg  [        U5      b[  T" [        U5      5      u  nn	n
[        U5      X'   U
 Vs/ s H  ofS   PM	     nnU/TR                  W'   U	 Vs/ s H  oS   PM	     nnO[        SUS   UTT5        SX'   UR                  U5        TR                  U   S   nUS   c  SX'   UR                  [        UT5      5        GMz     U R                  5       S:X  a  U R                  S5      n[        UTR                  5      nUTR                  ;   a+  [        TR                  U   5      S:  a  [        U UTTT5        UTR                  ;  d  TR                  U   / :X  a  [        S[        UT5      UTT5        TR                  U   S   nUR                  [        UT5      5        XU4$ s  snf s  snf )	NFpd_op.array_write_r   zpd_op.assign_out_r1   r   Tpd_op.array_read)num_resultsrZ   r@   r   r   r   !inside_value_to_outside_value_mapr8   r]   rp   	use_emptyr   allrM   rV   r   )rb   	zero_flagr   output_gradsoutput_listrz   rE   	new_valuesplit_zero_flagsplit_outputssplit_output_gradgrad_valuesinforj   rG   rc   #control_flow_value_to_copyvalue_mapmake_output_with_output_gradrF   s                 rL   r   9append_backward_ops.<locals>.make_output_with_output_grad  s    Gbnn..	779,,,,Q/0KWWY--,,Q/0K**,K!+.HA (KLI %u>>E
 11100781< 3 U555++E2b8++E215a8@((\%-@-L 5\%5HI	'%)#&#7IL9J"K9J89JK"K7BmE,,U35B C]Ta]I CI %Yq\5% $(ILNN9%11%8;J!}$#	% ?s /~ 779**%%a(E$u>>E 000u//67!; $7 U555++E2b8 $B   11%8;J% ? <//A #L Cs   'K"K'c                  > / n/ n[        [        U 5      [        U 5      5       GH  u  p4U(       d  U R                  5       S;  a  UR	                  5       bv  UR	                  5       R                  5       S:X  aT  / nUR	                  5       R                  5        H  nUR                  [        UT
5      5        M      UR                  U5        O[        UT
5      /nUR                  U5        M  U R                  5       S:w  a  UR	                  5       b  UR	                  5       R                  5       S:X  ad  T" UR	                  5       5      u  nnUR                  U V	s/ s H  oS   PM	     sn	5        UR                  U V	s/ s H  oS   PM	     sn	5        GMs  [        UT
5      /nUR                  U5        UT;   d  UR                  SL a  UR                  S/5        GM  UR                  S/5        GM     X4$ s  sn	f s  sn	f )N)cf.tuple_pushpd_op.ifbuiltin.combiner   r   TF)	r   r   r   rZ   r<   operands_sourcerV   r   stop_gradient)rb   inputsinput_grad_stopgradientsinputgrad_semantic	tmp_inputri   combine_inputscombine_stop_gradientr   r   "make_input_with_input_stopgradientr   s             rL   r   ?append_backward_ops.<locals>.make_input_with_input_stopgradient	  s   #% $'r"$:2$>%
 E !GGI%BB--/;--/446:KK "I$446FFH!((, #%H  I MM), )!#F!I
 MM), 	_,))+7))+0026GG
 7u7L7L7NO")>B>4Aw>BC(//)>?)>!W)>?
 %U,OP	 i(K'5+>+>$+F,33TF;,33UG<c%
f // C?s   G9
?G>
c                  > Sn[        U[        U 5      5       H  u  pEU(       d  M  U R                  5       S:w  aj  UR                  5       bY  UR                  5       R                  5       S:X  a7  T" UR                  5       X   UR                  5       R	                  5       5        OWX   n[        U[        5      (       a  TR                  U   R                  U5        OTR                  U   R                  U/5        US-  nM     g )Nr   r   r   r1   )	r   r   rZ   r<   r   
isinstancer   r8   rV   )	rb   input_grads
all_inputsrz   r   r   
input_gradrF   update_input_grad_maps	          rL   r   2append_backward_ops.<locals>.update_input_grad_mapA  s    $'
4J24N$O E  	_,))+7))+0026GG%))+N))+;;= )^
j$//,,U3:::F,,U3::J<HFA) %Pru   c                  > [        U 5      [        U5      :X  d   S5       e[        X5       HY  u  p#[        U[        5      (       a   TR                  U   R                  U5        M:  TR                  U   R                  U/5        M[     g )Nz%input_grads should same to all_inputs)r]   r   r   r   r8   rV   )r   r   r   r   rF   s       rL   $update_if_double_grad_input_grad_mapAappend_backward_ops.<locals>.update_if_double_grad_input_grad_mapY  sy    ;3z?2 	
3	
2 "%Z!=E*d++((/66zB((/66
|D	 ">ru   c           	       > [        U5      u  nnU    / nUR                  5       S:X  a  [        R                  R                  R
                  R                  U5      nUR                  U5        [        [        US UR                  5        5      5       H  n	X9   n
[        X5      n
XU	'   M     [        X45       H  u  pUc  M
  [        UTR                  5      nUTR                  ;   a,  [        TR                  U   5      S:  a  [        UUTTT5        OX[        UT5      n[!        X5      (       d.  [        R
                  R#                  5       //TR                  U'   O[%        SXTT5        [        TR                  U   S   S   T5      nUR                  U5        M     [        R                  R                  R
                  R'                  U5        S S S 5        g ! , (       d  f       g = f)Npd_op.whiler1   r   r   )r   rZ   r2   base	libpaddler5   cf_has_elementsrV   rw   r]   num_operandsr   r   r   r8   rp   r"   r7   rM   cf_yield)blockbase_opbase_grad_opbase_inputsbase_inputs_gradfwd_block_argument_to_value_mapfwd_value_to_block_argument_mapinputs_gradnew_condidxoperandsrE   rH   r   r   rG   rc   r   rF   s                  rL   append_yield)append_backward_ops.<locals>.append_yieldc  s    g&	
++ K||~.!;;0044DDWM""8, [1I73G3G3I%J!KLC*/H/  H (0$ M &)%G!%(5BB E444533E:;a?$#!!(; !1B!I *);; $ZZ2245;007 )5, .,,U3A6q93

 "":.I &HL KK!!%%..{;g UUs   G G
G)r1   r~   zcf.yieldr   Nr   builtin.splitr   r      )r   r   pd_op.increment_)r   r   r   r   zcf.tuple_pop)r   r   zpd_op.pylayer_gradpd_op.full_likeTFzop 'z7' has no grad op, consider enable prim to decompose it.)>r]   rZ   r   r   r   r   r   r   r   rV   r   r@   r<   r   r   r   r2   rT   corecall_vjpopsrA   rB   r   r   r   r
   r	   r   blocksr&   as_if_op
true_blockfalse_blockr   copyr8   append_backward_opsr   r    as_while_opbodyr   r'   rp   rM   r^   r   r   updater!   r{   r%   r   r   r   is_forward_onlyr>   r$   r   get_parent_block	parent_op)Dr   r   base_input_grads	fwd_block	bwd_blockeffective_forward_opsr   rG   rF   rc   r   r   r   yield_opinside_outputsoutside_outputinside_outputforward_opsinverse_effective_forward_opsclear_effective_forward_opsrb   while_tuple_opsr   r   r   r   r   stackopcopy_outpop_opr   copy_outputorigin_inputs	sub_blockr   r   true_block_pop_inputs'true_block_pop_input_grad_stopgradientsr   false_block_pop_inputs(false_block_pop_input_grad_stopgradientsr   rt   inputs_used_by_other_opsub_fwd_blocksub_bwd_block	sub_stateinput_origin_gradsub_backward_ops'sub_control_flow_value_to_copyvalue_mapr   r   input_tuplewhile_blockrz   rj   ri   _#sub_bwd_value_to_block_argument_mapwhile_grad_blockbefore_ops_numafter_ops_numrE   all_results_stop_gradientr   r   r   sD         `````                                                      @@@rL   r   r   c  s   jo0 o0b60p0E?< ?<P 	!"Q&!"%**,
:(,<<>]* &557;N%557N-0OO~.
)NM  33MB.
 ,CR0+k""(0(=%(7(D%"$+779))bggi?.J'..r2 , 
-B"~~3O40	7L 7r:, 779/ //2BBDG~~a(22449"fE'-'7'7'<'<'E'E " & ' , 8(H F "+r!2'..v6'..r2'..w7.(%*<*<R*@6( 47"12J4/FK !,A @q	J4 /(!..r2$^^A.88:@@BC L)Q.y>>/=='') , 
 !30 '') , 
 !wwyJ.(:2(>)+I0; *5 &([[]%=%=%?
&(kkm&?&?&A02-BD?%>>!,113~E*4..*;*C*C*E 5 < <fX F G N N%+%9%9$:!" +F
 24.CE@&??1-224F*5//!*<*D*D*F 6 = =vh G H O O%+%9%9$:!" +G 2R75; !'"7!8"8!9 # !9"I!J"J!K 5 :"fE*0*:*:*?*?*H*H " & ' , 8+K F #,--"3.(%*<*<R*@7) 35/<?IIK)9=8M= ).

=(AI*7#)U-E-E#E272J2J(.3&&*df %0 %<$B$B)/(=%& +8 02, C H H J D 0 "7=abz Bzeqz BAL M:A M - - - 1 1 + 0 )Dk 0G$/N !& 8 8Q H 0G==F 6##,,.99;??C#,,.::<@@D
 ,CKGIE44[^D ,C 2R75; !?$9!" 2 !?$:!" 3 !.ab 1"7!8"8!9 *
 A +] 2 "K m3(:2(>&(nn&6&;&;&=$)JJ{$;	(13K@)HAu  %	(D(DD#&y'C'CE'J#Ka#O$0(*(-(-(4(G%& !&Y-I-I I#,#?#?#F"#L 0$'y,!" *3)E)Ee)LQ)OJ','?'?'F % ; ;E B I I# N (G>@E44U;(// 5$.$C!"3)> -[99"fE*0*:*:*?*?*H*H " & ' , 8+K F #,--"3.(%*<*<R*@7) .g6?;BB; @DDF @ ,3+>+>+@+E+E+G(+-(+39:6%U1X6:=HI[zZ][I','OO',%?C 9#%5%9%9"%= .b+}Mo5),Y]]);9"fE*0*:*:*?*?*H*H " & ' , 8+K F ),IMM(:/(!..r2%MM*) .-?-C *-Y]]);8VD-bggi'.AB*0*:*:*?*?*H*H " & ' , 8+K C E ),IMM(:/(!..r2%MM*) .R-?-?-A OO%*(A-wwy$55wwyN2!# (@(@@$u77>?!C( " % % , ? 68E..r2 ". 15-!#$2228=5 ". *"-- & ; ;B ? ? 9("2779+-de  .0E&&r*O .R ! 11)_Q%7?"335??#A&  "335??#A& ## k 
$ FEv FED !C Mn FE: ;I& FE4 CB EDc	 
s    Bu..s.Ku..t 
Bu.Au.'t6u.<tIu.$.tBu.t.,u.2t3A4u.5.t8#A:u.u:.u
	(u0D:u..C7u..
s=8u. 
t
u.
t+&u.8
uu.

uu
u+&u..
u<c                .   [        5       nU  H_  nUR                  5       (       d<  UR                  5        H&  n[        U5       H  nUR	                  U5        M     M(     MT  [        S5        Ma     [        5       nU H  nUR	                  U5        M     X&4$ )Nz#input provided by inputs has no use)r   r   all_used_opsr   r   r#   )r   r   outputs_fwd_setr  used_oprf   inputs_fwd_setr   s           rL   prepare_backward_prune_setr(  G  s    jO!!!..0.w7D#''- 8 1 >?  ZN6"  **ru   c                p   [        5       nU  H<  nUR                  U   / :w  d  M  UR                  UR                  U   S   S   5        M>     [        5       nU H<  nUR                  U   / :w  d  M  UR                  UR                  U   S   S   5        M>     [        5       nU HY  nUR                  5       (       a  M  [	        UR                  5       R                  5       5       H  nUR                  U5        M     M[     UR                  U5        [        5       n	UR                   HC  n
X;   d  M
  UR                  U
   / :w  d  M  U	R                  UR                  U
   S   S   5        ME     UR                   H4  n
X;   d  M
  UR                  U
   S    H  nU	R                  U5        M     M6     XFU	4$ )Nr   )	r   r8   r   r   r   r   r   r   r^   )r%  r'  r   rF   r   rf   r   inputs_set_tmpout_gradno_gradvar_setkeys              rL   create_backward_prune_setr.  X  s    *K##D)R/OOE44T:1=a@A   J##D)R/NN533D9!<Q?@  ZN!!##*8+=+=+?+E+E+GH""4( I  n%ZN''%":":3"?2"Eu77<Q?BC ( **33C8;""4( < +
 N22ru   c           	       ^
^ SS/m
S mU
U4S jnSnU R                    H  nUR                  c  M  Sn  O   U(       d  g [        U R                   5       GHr  nXAR                  ;  a  M  U" U5      nUR                  U    GHA  nUR	                  S5      (       a  UR                  SUR                  5        M8  UR                  c  MG  UR                  5       S;   ae  S	n[        UR                  5       5       HE  nU" UR                  U5      R                  5       5      n	US	:X  a  U	nM2  Xy:X  a  M9   S
U SU	 S35       e   OUn[        R                  R                  R                  R!                  UR                  R"                  UR                  R%                  5       UR                  R'                  5       U5      Ul        GMD     GMu     g )Nr   r   c                .   U R                  5       S:X  a5  U R                  S5      R                  5       R                  R                  nU$ U R                  5       S:X  a5  U R                  S5      R                  5       R                  R                  nU$ SnU$ )Nr   r   r   r~   )rZ   r@   r<   	dist_attrchunk_idr   )rb   op_chunk_ids     rL   infer_dist_skip_op_chunk_id?_complete_grad_op_chunk_id.<locals>.infer_dist_skip_op_chunk_id{  s    779'!!!$446@@II   WWY++))A,668BBKKK  Kru   c                  > U R                  S5      (       a  U R                  nU$ U R                  c   SnU R                  5       T;   a  T" U 5      nU$ U R                  R                  nUS:X  ag  U R                  5       S:X  aS  U R	                  S5      R                  5       nUR                  5       T;   a
  T" U5      nU$ UR                  R                  nU$ )Nr2  r~   zdist_op.reshardr   )has_attrr2  r1  rZ   r@   r<   )rb   r3  prev_opdist_skip_op_listr4  s      rL   get_op_chunk_id3_complete_grad_op_chunk_id.<locals>.get_op_chunk_id  s    ;;z""++K  \\!Kwwy--9"=  ,,//Kb RWWY2C%C++A.>>@<<>%66"=g"FK  #*"3"3"<"<Kru   FTr2  )z
pd_op.add_zpd_op.add_n_r~   z#Inconsistent prev_op chunk id with z != zp
{bwd_op.operand_source(operand_idx-1).get_defining_op()}
{bwd_op.operand_source(operand_idx).get_defining_op()})r   r1  r   rB   r7  set_int_attrr2  rZ   rw   r   r@   r<   r2   r   r   r5   create_op_dist_attributeprocess_meshr   r   )r   rF   r:  is_dist_programrb   fwd_op_chunk_idbwd_opbwd_op_chunk_idoperand_idxprev_op_chunk_idr9  r4  s             @@rL   _complete_grad_op_chunk_idrE  x  s   (*;<
" Oii<<#"O 
 uyy!''')"-((,F{{:&&##J<!!){{} >>"$#()<)<)>#?K'6--k:JJL($ '",*:.B A/ARRVWgVh iU UB $@ #2 %%))BB$$11$$--/$$,,.#	 1 - "ru   c                   [         R                  R                  R                  R	                  5       R                  5       n[        U5      n[        U5      (       a"  [        R                  " S5        UR                  $ [        U5      n[        XC5        U   [        X U5      u  nnn	S S S 5        [        U5      n
/ nW H  nX;  d  M
  UR                  U5        M     [        U5      n[!        U5      (       a  UnO[#        XjX5      u  p[%        X5      u  nn['        S S S UUUUW	U[)        5       5
        [+        UUX55      u  pn[-        XE5        / n[!        U	5      (       d  U(       a  [#        XUU5      u  nnUR/                  5         [1        U5      n[3        [5        U	5      5       H  nUR7                  5       S:X  ag  UR9                  S5      R;                  5       (       aA  UR=                  U5        UR=                  UR?                  S5      RA                  5       5        M|  M~  [C        U5      (       d  M  URE                  5        H  n[G        UURH                  U5        M     M     [3        U5       HV  nUR9                  S5      [        W5      ;   a  M#  UR9                  S5      R;                  5       (       d  MI  [K        UUU5        MX     UR/                  5         UR                  nU$ ! , (       d  f       GNK= f)Nz@all op in block stop_gradient is True, no grad will be calculater   r   r1   )&r2   r   r   r5   get_current_insertion_pointr   r   r   loggingwarningr8   r   r   r   r   rV   r   r   r(  r   r   r.  rE  turn_mapsetr   r   rZ   r   r   r   r@   r<   r   r   r   r   r   )r   r   r   r   r   rF   r   complete_grad_outputsr   rG   r   stop_gradient_false_outputsr   r   r   r  r%  r'  r,  
remove_opsrb   r  rA  input_grad_maps                           rL   r,   r,     s    KK!!%%AACIIKE%LEe$$N	
 ''' 'I 'u:	
 !>		
!	 
 &!J"$"$'..v6 # 67Ki   )#,;$
  'A'#O^  /H/+K^
 u,J,''F!k>
: 
NNZJd<01779))yy|%%''r"r003CCEF ( R  YY[	,Y	uM ) 2 "*-==x(=>>==%%''eVU+	 .
 
NN--NO 
s   K++
K:c                    [        U UU[        U5      S9n/ nU H&  nUR                  XF   / :w  a
  XF   S   S   OS5        M(     U$ )a  
calculate gradient of input

Args:
    outputs (Value|list(Value)|tuple(Value)): the output Value or
        Value list/tuple of the graph to compute gradients.
    inputs (Value|list(Value)|tuple(Value)): the input Value or
        Value list/tuple of the graph to compute gradients. The returned
        values of this API are the gradients of `inputs` .
    grad_outputs (Value|list(Value|None)|tuple(Value|None), optional):
        initial gradient values of `outputs` . If `grad_outputs` is None,
        the initial gradient values of `outputs` would be Values filled with 1;
        if `grad_outputs` is not None, it must have the same length as `outputs` ,
        and in this case, the initial gradient value of the i-th `outputs` would
        be: (1) a Value filled with 1 when the i-th element of `grad_outputs`
        is None; (2) the i-th element of `grad_outputs` when the i-th element of
        `grad_outputs` is a Value. Default None.
    no_grad_set (set(Value), optional):
        the Values whose gradients are not needed to compute. Default None.

Return:
    list[Value]:A list of gradients for inputs
    If an input does not affect targets, the corresponding gradient Tensor
    will be None
    TODO if allow_unused=False raise TypeError() if input_grad has None
r   r   r   N)r,   r   rV   )r   r   r   r   input_to_inputgrad_map	inputgradr   s          rL   r+   r+   &  sh    B 2![)	 I%,2 #)!,Q/	
  ru   c                V   [        U S[        R                  R                  [        [
        4S5        [        US[        R                  R                  [        [
        4S5        [        US[        R                  R                  [        [
        [        S5      4S5        [        US[        R                  R                  [        [
        [        [        [        S5      4S5        [        U 5      n [        U5      n[        U5      nUc  [        5       nO[        U5      n[        XX(5      n	U	$ )a%  
.. note::
    **This API is ONLY available in imperative mode.**

This API computes the sum of gradients of `outputs` with respect to each `inputs` .

Parameters:
    outputs (Value|list(Value)|tuple(Value)): the output Value or
        Value list/tuple of the graph to compute gradients.
    inputs (Value|list(Value)|tuple(Value)): the input Value or
        Value list/tuple of the graph to compute gradients. The returned
        values of this API are the gradients of `inputs` .
    grad_outputs (Value|list(Value|None)|tuple(Value|None), optional):
        initial gradient values of `outputs` . If `grad_outputs` is None,
        the initial gradient values of `outputs` would be Values filled with 1;
        if `grad_outputs` is not None, it must have the same length as `outputs` ,
        and in this case, the initial gradient value of the i-th `outputs` would
        be: (1) a Value filled with 1 when the i-th element of `grad_outputs`
        is None; (2) the i-th element of `grad_outputs` when the i-th element of
        `grad_outputs` is a Value. Default None.
    retain_graph (bool, optional): whether to retain the forward graph which
        is used to calculate the gradient. When it is True, the graph would
        be retained, in which way users can calculate backward twice for the
        same graph. When it is False, the graph would be freed. Default None,
        which means it is equal to `create_graph` .
    create_graph (bool, optional): whether to create the gradient graphs of
        the computing process. When it is True, higher order derivatives are
        supported to compute; when it is False, the gradient graphs of the
        computing process would be discarded. Default False.
    only_inputs (bool, optional): whether to only compute the gradients of
        `inputs` . If it is False, the gradients of all remaining leaf
        Values in the graph would be also computed and accumulated.
        If it is True, only the gradients of `inputs` would be computed.
        Default True. only_inputs=False is under development, and it is
        not supported yet.
    allow_unused (bool, optional): whether to raise error or return None if some
        Values of `inputs` are unreachable in the graph. If some Values of
        `inputs` are unreachable in the graph (i.e., their gradients are None),
        error would be raised if allow_unused=False, or None would be returned as
        their gradients if allow_unused=True. Default False.
    no_grad_vars (Value|list(Value)|tuple(Value)|set(Value), optional):
        the Values whose gradients are not needed to compute. Default None.

Returns:
    list: a list of Values, whose length is the same as the Value number
    inside `inputs`, and the i-th returned Value is the sum of gradients of
    `outputs` with respect to the i-th `inputs`.
r   z paddle.autograd.ir_backward.gradr   r   Nno_grad_vars)r   r2   r5   r)   r   tupletyperK  r   r   r+   )
r   r   r   retain_graphcreate_graphonly_inputsallow_unusedrU  r   r   s
             rL   r*   r*   X  s   t 			4'*	 			4'*	 			4T
3*	 JJJ	
 	+ wGfFL)Lj|,wJJru   c                   [        U S[        R                  R                  S5        Ub\  [        US[        [
        [        4S5        [        U5       H/  u  p4[        USU S3[        R                  R                  S5        M1     OU R                  5       R                  5       R                  n/ nU H^  nUR                  S5      (       d  M  UR                  5        Vs/ s H  owR                  (       d  M  UPM     nnUR                  U5        M`     Uc  [        5       n	O[        U5      n	[!        [#        U 5      / / [        U	5      S	9n
/ nU H(  nUR%                  UX   / :w  a
  X   S
   S
   OS45        M*     U$ s  snf )a>  
Parameters:
    loss (Value): The loss Tensor of the network
    parameter_list (Value|list(Value)|tuple(Value)):  List/Tuple of Parameters
        that need to be updated by optimizers.
        If it is None, all parameters
        will be updated.
        Default: None.
    no_grad_vars (Value|list(Value)|tuple(Value)|set(Value), optional):
        the Values whose gradients are not needed to compute. Default None.

Returns:
    list of tuple (Value): Pairs of parameter and its corresponding gradients.
    The key is the parameter and the value is gradient Tensor.
lossz+paddle.autograd.ir_backward.append_backwardNparameter_listzparameter_list[]zbase.backward.append_backwardpersistablerQ  r   )r   r2   r5   r)   r   rV  rK  r   r<   r   r   r7  r   r`  extendr   r,   r   rV   )r]  r^  r   rz   paramr   rb   r   persist_valueno_grad_set_rR  input_inputs_gradr   s                rL   append_backwardrf    s   " 

5	 !5#9		
 ".1HA!!A&

  /	 2 ""$557;;B;;}--%'ZZ\%165G5G\   !!-0  z,1
\*	    .4: +1!4Q7		
   =s   E=7E=)NN)
r   Value | Sequence[Value]r   rg  r   %Value | Sequence[Value | None] | Noner   set[Value] | Noner   r   )
r   rg  r   rg  r   rh  r   ri  r   list[Value | None])NNFTFN)r   rg  r   rg  r   rh  rX  bool | NonerY  rk  rZ  rk  r[  rk  rU  z+Value | Sequence[Value] | set[Value] | Noner   rj  )@
__future__r   rH  r   typingr   
paddle.pirr2   paddle.autograd.backward_utilsr   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   r    r!   r"   r#   r$   paddle.base.frameworkr%   paddle.base.libpaddle.pirr&   r'   collections.abcr(   r)   __all__rM   rp   rA   r{   r   r   r   r(  r.  rE  r,   r+   r*   rf   ru   rL   <module>ru     s   #     ! ! ! ! ! ! ! ! !D 4
 ( 
 <"JH>V*2W8t=*T %.K(1aH+"3@Oj ;?%)	Y$Y#Y 8Y #	Y
 Y~ ;?%)	/$/#/ 8/ #	/
 /j ;? $ %# %@Dd$d#d 8d 	d
 d d d >d dNKru   